├── .gitignore ├── COPYING.LIB ├── Readme.md ├── build └── msvc │ ├── LibTCGTranslateAArch64 │ ├── LibTCGTranslateAArch64.vcxproj │ └── LibTCGTranslateAArch64.vcxproj.filters │ ├── LibTCGTranslateARM │ ├── LibTCGTranslateARM.vcxproj │ └── LibTCGTranslateARM.vcxproj.filters │ ├── LibTCGTranslateX64 │ ├── LibTCGTranslateX64.vcxproj │ └── LibTCGTranslateX64.vcxproj.filters │ ├── LibTCGTranslateX86 │ ├── LibTCGTranslateX86.vcxproj │ └── LibTCGTranslateX86.vcxproj.filters │ ├── TCGTranslate.sln │ └── TestLibTCGTranslate │ ├── TestLibTCGTranslate.vcxproj │ └── TestLibTCGTranslate.vcxproj.filters ├── include ├── LibTCGTranslate.h └── lib │ ├── bitmap.h │ ├── bitops.h │ ├── internal.h │ ├── target │ ├── arm │ │ ├── cpu.h │ │ ├── helper-a64.h │ │ ├── helpers-arm.h │ │ └── translate.h │ ├── host-utils.h │ └── i386 │ │ ├── cpu.h │ │ ├── helpers-i386.h │ │ ├── ops_sse_header.h │ │ └── translate.h │ └── tcg │ ├── helper-gen.h │ ├── helper-head.h │ ├── helper-proto.h │ ├── helper-tcg.h │ ├── helpers-index.h │ ├── helpers.h │ ├── tcg-common.h │ ├── tcg-op.h │ ├── tcg-opc.h │ ├── tcg-target.h │ └── tcg.h ├── src ├── LibTCGTranslate.cpp └── lib │ ├── target │ ├── arm │ │ ├── translate-a64.c │ │ └── translate.c │ ├── host-utils.c │ └── i386 │ │ └── translate.c │ └── tcg │ ├── LICENSE │ ├── README │ ├── optimize.c │ ├── tcg-common.c │ ├── tcg-op.c │ └── tcg.c └── test └── test.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | /build/msvc/**/.vs/ 2 | /build/msvc/**/Debug/ 3 | /build/msvc/**/Release/ 4 | /build/msvc/**/x64/ 5 | /build/msvc/**/*.vcxproj.user -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | LibTCGTranslate 2 | =============== 3 | 4 | A library to translate native code for multiple architectures into Tiny Code Generator (TCG) based intermediate representation (IR), based upon the QEMU translators. 5 | 6 | Features 7 | -------- 8 | 9 | * Supports ARM (including Thumb and Thumb2), AArch64, x86 and x64 translators. 10 | * C API exposed. 11 | * C++ Wrapper. 12 | * Thread Safe (per LibTCGContext). 13 | * MSVC 2017 build solution. 14 | * Explicit condition code eflags access for the x86 and x64 translators. 15 | 16 | Build 17 | ----- 18 | 19 | Open the `.\build\msvc\TCGTranslate.sln` solution in Visual Studio 2017 and Build the solution. 20 | 21 | Test Usage 22 | ---------- 23 | 24 | After you build the solution you can examine translation using the TestLibTCGTranslate application. For example, the ARM instruction `str r2, [sp, #-0x4]!` is encoded as `04202DE5` and can be translated as follows: 25 | 26 | ``` 27 | >TestLibTCGTranslate.exe /arm /buffer 04202DE5 /max_insns 1 28 | insn_start 0x100000 29 | mov_i32 tmp5, sp 30 | movi_i32 tmp6, 0xfffffffc 31 | add_i32 tmp5, tmp5, tmp6 32 | mov_i32 tmp6, r2 33 | mov_i32 tmp7, tmp5 34 | qemu_st_i32 tmp6, tmp7, leul 35 | mov_i32 sp, tmp5 36 | goto_tb 0x1 37 | movi_i32 pc, 0x100004 38 | exit_tb 0x31a30c1 39 | ``` 40 | 41 | License 42 | ------- 43 | LibTCGTranslate is licensed under the GNU Lesser General Public license. See COPYING.LIB for more information. QEMU is a trademark of Fabrice Bellard. 44 | -------------------------------------------------------------------------------- /build/msvc/LibTCGTranslateAArch64/LibTCGTranslateAArch64.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 15.0 54 | {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60} 55 | Win32Proj 56 | LibTCGTranslate 57 | 10.0.17763.0 58 | LibTCGTranslateAArch64 59 | 60 | 61 | 62 | DynamicLibrary 63 | true 64 | v141 65 | Unicode 66 | 67 | 68 | DynamicLibrary 69 | false 70 | v141 71 | true 72 | Unicode 73 | 74 | 75 | DynamicLibrary 76 | true 77 | v141 78 | Unicode 79 | 80 | 81 | DynamicLibrary 82 | false 83 | v141 84 | true 85 | Unicode 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | true 107 | ..\..\..\include\;..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 108 | 109 | 110 | true 111 | ..\..\..\include\;..\include\;$(IncludePath) 112 | 113 | 114 | false 115 | ..\..\..\include\;..\..\..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 116 | 117 | 118 | false 119 | ..\..\..\include\;..\..\..\include\;$(IncludePath) 120 | 121 | 122 | 123 | 124 | 125 | Level3 126 | Disabled 127 | LIBTCGT_API_LIBRARY;TARGET_AARCH64;WIN32;_DEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 128 | true 129 | CompileAsCpp 130 | MultiThreadedDebugDLL 131 | false 132 | 133 | 134 | Windows 135 | true 136 | 137 | 138 | 139 | 140 | 141 | 142 | Level3 143 | Disabled 144 | LIBTCGT_API_LIBRARY;TARGET_AARCH64;_DEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 145 | true 146 | CompileAsCpp 147 | MultiThreadedDebugDLL 148 | false 149 | 150 | 151 | Windows 152 | true 153 | 154 | 155 | 156 | 157 | 158 | 159 | Level3 160 | MaxSpeed 161 | true 162 | true 163 | LIBTCGT_API_LIBRARY;TARGET_AARCH64;WIN32;NDEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 164 | true 165 | CompileAsCpp 166 | MultiThreadedDLL 167 | Guard 168 | 169 | 170 | Windows 171 | true 172 | true 173 | true 174 | /PDBALTPATH:$(TargetName).pdb %(AdditionalOptions) 175 | 176 | 177 | 178 | 179 | 180 | 181 | Level3 182 | MaxSpeed 183 | true 184 | true 185 | LIBTCGT_API_LIBRARY;TARGET_AARCH64;NDEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 186 | true 187 | CompileAsCpp 188 | MultiThreadedDLL 189 | Guard 190 | 191 | 192 | Windows 193 | true 194 | true 195 | true 196 | /PDBALTPATH:$(TargetName).pdb %(AdditionalOptions) 197 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /build/msvc/LibTCGTranslateAArch64/LibTCGTranslateAArch64.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {6a0c1608-0f90-406e-b9d4-f3a60360d760} 14 | 15 | 16 | {daad1ad8-65d0-4c8e-a7ce-6835a311c8de} 17 | 18 | 19 | {2c80095d-c3cf-4af3-b001-2faef69fe39c} 20 | 21 | 22 | {1d314a9a-54d3-48c7-9e25-c238268f96f6} 23 | 24 | 25 | {3abb2dbb-b065-412f-9bca-cd8f6768d493} 26 | 27 | 28 | {f5e99664-bd9f-4782-b622-4f8684bbdb23} 29 | 30 | 31 | {4c1ad7a9-eb2d-4e23-a241-4d4be2f34aab} 32 | 33 | 34 | {dca93a05-3652-4e7b-932d-5c6240e780ea} 35 | 36 | 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files\lib\target 43 | 44 | 45 | Source Files\lib\tcg 46 | 47 | 48 | Source Files\lib\tcg 49 | 50 | 51 | Source Files\lib\tcg 52 | 53 | 54 | Source Files\lib\tcg 55 | 56 | 57 | Source Files\lib\target\arm 58 | 59 | 60 | 61 | 62 | Header Files\lib\target\arm 63 | 64 | 65 | Header Files\lib\target\arm 66 | 67 | 68 | Header Files\lib\target\arm 69 | 70 | 71 | Header Files\lib\target 72 | 73 | 74 | Header Files\lib\tcg 75 | 76 | 77 | Header Files\lib\tcg 78 | 79 | 80 | Header Files\lib\tcg 81 | 82 | 83 | Header Files\lib\tcg 84 | 85 | 86 | Header Files\lib\tcg 87 | 88 | 89 | Header Files\lib\tcg 90 | 91 | 92 | Header Files\lib\tcg 93 | 94 | 95 | Header Files\lib\tcg 96 | 97 | 98 | Header Files\lib\tcg 99 | 100 | 101 | Header Files\lib\tcg 102 | 103 | 104 | Header Files\lib\tcg 105 | 106 | 107 | Header Files\lib 108 | 109 | 110 | Header Files\lib 111 | 112 | 113 | Header Files\lib 114 | 115 | 116 | Header Files 117 | 118 | 119 | Header Files\lib\target\arm 120 | 121 | 122 | -------------------------------------------------------------------------------- /build/msvc/LibTCGTranslateARM/LibTCGTranslateARM.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 15.0 53 | {C8E24A58-5BAA-4001-ACAF-67DB79506DD6} 54 | Win32Proj 55 | LibTCGTranslate 56 | 10.0.17763.0 57 | LibTCGTranslateARM 58 | 59 | 60 | 61 | DynamicLibrary 62 | true 63 | v141 64 | Unicode 65 | 66 | 67 | DynamicLibrary 68 | false 69 | v141 70 | true 71 | Unicode 72 | 73 | 74 | DynamicLibrary 75 | true 76 | v141 77 | Unicode 78 | 79 | 80 | DynamicLibrary 81 | false 82 | v141 83 | true 84 | Unicode 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | true 106 | ..\..\..\include\;..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 107 | 108 | 109 | true 110 | ..\..\..\include\;..\include\;$(IncludePath) 111 | 112 | 113 | false 114 | ..\..\..\include\;..\..\..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 115 | 116 | 117 | false 118 | ..\..\..\include\;..\..\..\include\;$(IncludePath) 119 | 120 | 121 | 122 | 123 | 124 | Level3 125 | Disabled 126 | LIBTCGT_API_LIBRARY;TARGET_ARM;WIN32;_DEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 127 | true 128 | CompileAsCpp 129 | MultiThreadedDebugDLL 130 | false 131 | 132 | 133 | Windows 134 | true 135 | 136 | 137 | 138 | 139 | 140 | 141 | Level3 142 | Disabled 143 | LIBTCGT_API_LIBRARY;TARGET_ARM;_DEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 144 | true 145 | CompileAsCpp 146 | MultiThreadedDebugDLL 147 | false 148 | 149 | 150 | Windows 151 | true 152 | 153 | 154 | 155 | 156 | 157 | 158 | Level3 159 | MaxSpeed 160 | true 161 | true 162 | LIBTCGT_API_LIBRARY;TARGET_ARM;WIN32;NDEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 163 | true 164 | CompileAsCpp 165 | MultiThreadedDLL 166 | Guard 167 | 168 | 169 | Windows 170 | true 171 | true 172 | true 173 | /PDBALTPATH:$(TargetName).pdb %(AdditionalOptions) 174 | 175 | 176 | 177 | 178 | 179 | 180 | Level3 181 | MaxSpeed 182 | true 183 | true 184 | LIBTCGT_API_LIBRARY;TARGET_ARM;NDEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 185 | true 186 | CompileAsCpp 187 | MultiThreadedDLL 188 | Guard 189 | 190 | 191 | Windows 192 | true 193 | true 194 | true 195 | /PDBALTPATH:$(TargetName).pdb %(AdditionalOptions) 196 | 197 | 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /build/msvc/LibTCGTranslateARM/LibTCGTranslateARM.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {6a0c1608-0f90-406e-b9d4-f3a60360d760} 14 | 15 | 16 | {daad1ad8-65d0-4c8e-a7ce-6835a311c8de} 17 | 18 | 19 | {2c80095d-c3cf-4af3-b001-2faef69fe39c} 20 | 21 | 22 | {1d314a9a-54d3-48c7-9e25-c238268f96f6} 23 | 24 | 25 | {3abb2dbb-b065-412f-9bca-cd8f6768d493} 26 | 27 | 28 | {f5e99664-bd9f-4782-b622-4f8684bbdb23} 29 | 30 | 31 | {4c1ad7a9-eb2d-4e23-a241-4d4be2f34aab} 32 | 33 | 34 | {dca93a05-3652-4e7b-932d-5c6240e780ea} 35 | 36 | 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files\lib\target\arm 43 | 44 | 45 | Source Files\lib\target 46 | 47 | 48 | Source Files\lib\tcg 49 | 50 | 51 | Source Files\lib\tcg 52 | 53 | 54 | Source Files\lib\tcg 55 | 56 | 57 | Source Files\lib\tcg 58 | 59 | 60 | 61 | 62 | Header Files\lib\target\arm 63 | 64 | 65 | Header Files\lib\target\arm 66 | 67 | 68 | Header Files\lib\target\arm 69 | 70 | 71 | Header Files\lib\target 72 | 73 | 74 | Header Files\lib\tcg 75 | 76 | 77 | Header Files\lib\tcg 78 | 79 | 80 | Header Files\lib\tcg 81 | 82 | 83 | Header Files\lib\tcg 84 | 85 | 86 | Header Files\lib\tcg 87 | 88 | 89 | Header Files\lib\tcg 90 | 91 | 92 | Header Files\lib\tcg 93 | 94 | 95 | Header Files\lib\tcg 96 | 97 | 98 | Header Files\lib\tcg 99 | 100 | 101 | Header Files\lib\tcg 102 | 103 | 104 | Header Files\lib\tcg 105 | 106 | 107 | Header Files\lib 108 | 109 | 110 | Header Files\lib 111 | 112 | 113 | Header Files\lib 114 | 115 | 116 | Header Files 117 | 118 | 119 | -------------------------------------------------------------------------------- /build/msvc/LibTCGTranslateX64/LibTCGTranslateX64.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 15.0 54 | {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE} 55 | Win32Proj 56 | LibTCGTranslate 57 | 10.0.17763.0 58 | LibTCGTranslateX64 59 | 60 | 61 | 62 | DynamicLibrary 63 | true 64 | v141 65 | Unicode 66 | 67 | 68 | DynamicLibrary 69 | false 70 | v141 71 | true 72 | Unicode 73 | 74 | 75 | DynamicLibrary 76 | true 77 | v141 78 | Unicode 79 | 80 | 81 | DynamicLibrary 82 | false 83 | v141 84 | true 85 | Unicode 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | true 107 | ..\..\..\include\;..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 108 | 109 | 110 | true 111 | ..\..\..\include\;..\include\;$(IncludePath) 112 | 113 | 114 | false 115 | ..\..\..\include\;..\..\..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 116 | 117 | 118 | false 119 | ..\..\..\include\;..\..\..\include\;$(IncludePath) 120 | 121 | 122 | 123 | 124 | 125 | Level3 126 | Disabled 127 | LIBTCGT_API_LIBRARY;TARGET_X86_64;WIN32;_DEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 128 | true 129 | CompileAsCpp 130 | MultiThreadedDebugDLL 131 | false 132 | 133 | 134 | Windows 135 | true 136 | 137 | 138 | 139 | 140 | 141 | 142 | Level3 143 | Disabled 144 | LIBTCGT_API_LIBRARY;TARGET_X86_64;_DEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 145 | true 146 | CompileAsCpp 147 | MultiThreadedDebugDLL 148 | false 149 | 150 | 151 | Windows 152 | true 153 | 154 | 155 | 156 | 157 | 158 | 159 | Level3 160 | MaxSpeed 161 | true 162 | true 163 | LIBTCGT_API_LIBRARY;TARGET_X86_64;WIN32;NDEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 164 | true 165 | CompileAsCpp 166 | MultiThreadedDLL 167 | Guard 168 | 169 | 170 | Windows 171 | true 172 | true 173 | true 174 | /PDBALTPATH:$(TargetName).pdb %(AdditionalOptions) 175 | 176 | 177 | 178 | 179 | 180 | 181 | Level3 182 | MaxSpeed 183 | true 184 | true 185 | LIBTCGT_API_LIBRARY;TARGET_X86_64;NDEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 186 | true 187 | CompileAsCpp 188 | MultiThreadedDLL 189 | Guard 190 | 191 | 192 | Windows 193 | true 194 | true 195 | true 196 | /PDBALTPATH:$(TargetName).pdb %(AdditionalOptions) 197 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /build/msvc/LibTCGTranslateX64/LibTCGTranslateX64.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {6a0c1608-0f90-406e-b9d4-f3a60360d760} 14 | 15 | 16 | {daad1ad8-65d0-4c8e-a7ce-6835a311c8de} 17 | 18 | 19 | {2c80095d-c3cf-4af3-b001-2faef69fe39c} 20 | 21 | 22 | {1d314a9a-54d3-48c7-9e25-c238268f96f6} 23 | 24 | 25 | {3abb2dbb-b065-412f-9bca-cd8f6768d493} 26 | 27 | 28 | {f5e99664-bd9f-4782-b622-4f8684bbdb23} 29 | 30 | 31 | {4c1ad7a9-eb2d-4e23-a241-4d4be2f34aab} 32 | 33 | 34 | {dca93a05-3652-4e7b-932d-5c6240e780ea} 35 | 36 | 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files\lib\target 43 | 44 | 45 | Source Files\lib\tcg 46 | 47 | 48 | Source Files\lib\tcg 49 | 50 | 51 | Source Files\lib\tcg 52 | 53 | 54 | Source Files\lib\tcg 55 | 56 | 57 | Source Files\lib\target\i386 58 | 59 | 60 | 61 | 62 | Header Files\lib\target\i386 63 | 64 | 65 | Header Files\lib\target\i386 66 | 67 | 68 | Header Files\lib\target\i386 69 | 70 | 71 | Header Files\lib\target 72 | 73 | 74 | Header Files\lib\tcg 75 | 76 | 77 | Header Files\lib\tcg 78 | 79 | 80 | Header Files\lib\tcg 81 | 82 | 83 | Header Files\lib\tcg 84 | 85 | 86 | Header Files\lib\tcg 87 | 88 | 89 | Header Files\lib\tcg 90 | 91 | 92 | Header Files\lib\tcg 93 | 94 | 95 | Header Files\lib\tcg 96 | 97 | 98 | Header Files\lib\tcg 99 | 100 | 101 | Header Files\lib\tcg 102 | 103 | 104 | Header Files\lib\tcg 105 | 106 | 107 | Header Files\lib 108 | 109 | 110 | Header Files\lib 111 | 112 | 113 | Header Files\lib 114 | 115 | 116 | Header Files 117 | 118 | 119 | Header Files\lib\target\i386 120 | 121 | 122 | -------------------------------------------------------------------------------- /build/msvc/LibTCGTranslateX86/LibTCGTranslateX86.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 15.0 54 | {50978472-2E8B-4ACB-AFA9-4B21625C9A83} 55 | Win32Proj 56 | LibTCGTranslate 57 | 10.0.17763.0 58 | LibTCGTranslateX86 59 | 60 | 61 | 62 | DynamicLibrary 63 | true 64 | v141 65 | Unicode 66 | 67 | 68 | DynamicLibrary 69 | false 70 | v141 71 | true 72 | Unicode 73 | 74 | 75 | DynamicLibrary 76 | true 77 | v141 78 | Unicode 79 | 80 | 81 | DynamicLibrary 82 | false 83 | v141 84 | true 85 | Unicode 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | true 107 | ..\..\..\include\;..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 108 | 109 | 110 | true 111 | ..\..\..\include\;..\include\;$(IncludePath) 112 | 113 | 114 | false 115 | ..\..\..\include\;..\..\..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 116 | 117 | 118 | false 119 | ..\..\..\include\;..\..\..\include\;$(IncludePath) 120 | 121 | 122 | 123 | 124 | 125 | Level3 126 | Disabled 127 | LIBTCGT_API_LIBRARY;TARGET_X86;WIN32;_DEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 128 | true 129 | CompileAsCpp 130 | MultiThreadedDebugDLL 131 | false 132 | 133 | 134 | Windows 135 | true 136 | 137 | 138 | 139 | 140 | 141 | 142 | Level3 143 | Disabled 144 | LIBTCGT_API_LIBRARY;TARGET_X86;_DEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 145 | true 146 | CompileAsCpp 147 | MultiThreadedDebugDLL 148 | false 149 | 150 | 151 | Windows 152 | true 153 | 154 | 155 | 156 | 157 | 158 | 159 | Level3 160 | MaxSpeed 161 | true 162 | true 163 | LIBTCGT_API_LIBRARY;TARGET_X86;WIN32;NDEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 164 | true 165 | CompileAsCpp 166 | MultiThreadedDLL 167 | Guard 168 | 169 | 170 | Windows 171 | true 172 | true 173 | true 174 | /PDBALTPATH:$(TargetName).pdb %(AdditionalOptions) 175 | 176 | 177 | 178 | 179 | 180 | 181 | Level3 182 | MaxSpeed 183 | true 184 | true 185 | LIBTCGT_API_LIBRARY;TARGET_X86;NDEBUG;LibTCGTranslate_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 186 | true 187 | CompileAsCpp 188 | MultiThreadedDLL 189 | Guard 190 | 191 | 192 | Windows 193 | true 194 | true 195 | true 196 | /PDBALTPATH:$(TargetName).pdb %(AdditionalOptions) 197 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /build/msvc/LibTCGTranslateX86/LibTCGTranslateX86.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {6a0c1608-0f90-406e-b9d4-f3a60360d760} 14 | 15 | 16 | {daad1ad8-65d0-4c8e-a7ce-6835a311c8de} 17 | 18 | 19 | {2c80095d-c3cf-4af3-b001-2faef69fe39c} 20 | 21 | 22 | {1d314a9a-54d3-48c7-9e25-c238268f96f6} 23 | 24 | 25 | {3abb2dbb-b065-412f-9bca-cd8f6768d493} 26 | 27 | 28 | {f5e99664-bd9f-4782-b622-4f8684bbdb23} 29 | 30 | 31 | {4c1ad7a9-eb2d-4e23-a241-4d4be2f34aab} 32 | 33 | 34 | {dca93a05-3652-4e7b-932d-5c6240e780ea} 35 | 36 | 37 | 38 | 39 | Source Files 40 | 41 | 42 | Source Files\lib\target 43 | 44 | 45 | Source Files\lib\tcg 46 | 47 | 48 | Source Files\lib\tcg 49 | 50 | 51 | Source Files\lib\tcg 52 | 53 | 54 | Source Files\lib\tcg 55 | 56 | 57 | Source Files\lib\target\i386 58 | 59 | 60 | 61 | 62 | Header Files\lib\target\i386 63 | 64 | 65 | Header Files\lib\target\i386 66 | 67 | 68 | Header Files\lib\target\i386 69 | 70 | 71 | Header Files\lib\target 72 | 73 | 74 | Header Files\lib\tcg 75 | 76 | 77 | Header Files\lib\tcg 78 | 79 | 80 | Header Files\lib\tcg 81 | 82 | 83 | Header Files\lib\tcg 84 | 85 | 86 | Header Files\lib\tcg 87 | 88 | 89 | Header Files\lib\tcg 90 | 91 | 92 | Header Files\lib\tcg 93 | 94 | 95 | Header Files\lib\tcg 96 | 97 | 98 | Header Files\lib\tcg 99 | 100 | 101 | Header Files\lib\tcg 102 | 103 | 104 | Header Files\lib\tcg 105 | 106 | 107 | Header Files\lib 108 | 109 | 110 | Header Files\lib 111 | 112 | 113 | Header Files\lib 114 | 115 | 116 | Header Files 117 | 118 | 119 | Header Files\lib\target\i386 120 | 121 | 122 | -------------------------------------------------------------------------------- /build/msvc/TCGTranslate.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26730.8 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibTCGTranslateARM", "LibTCGTranslateARM\LibTCGTranslateARM.vcxproj", "{C8E24A58-5BAA-4001-ACAF-67DB79506DD6}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestLibTCGTranslate", "TestLibTCGTranslate\TestLibTCGTranslate.vcxproj", "{FB8C68F0-24BE-4C0B-9C44-2497150693A7}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {C8E24A58-5BAA-4001-ACAF-67DB79506DD6} = {C8E24A58-5BAA-4001-ACAF-67DB79506DD6} 11 | {50978472-2E8B-4ACB-AFA9-4B21625C9A83} = {50978472-2E8B-4ACB-AFA9-4B21625C9A83} 12 | {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60} = {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60} 13 | {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE} = {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE} 14 | EndProjectSection 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibTCGTranslateAArch64", "LibTCGTranslateAArch64\LibTCGTranslateAArch64.vcxproj", "{3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60}" 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibTCGTranslateX86", "LibTCGTranslateX86\LibTCGTranslateX86.vcxproj", "{50978472-2E8B-4ACB-AFA9-4B21625C9A83}" 19 | EndProject 20 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibTCGTranslateX64", "LibTCGTranslateX64\LibTCGTranslateX64.vcxproj", "{6CE711FB-19D1-4924-843A-4C7D8B1F4BDE}" 21 | EndProject 22 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EABAB37-9FAF-4695-9AD3-C37C85388F14}" 23 | ProjectSection(SolutionItems) = preProject 24 | ..\..\Readme.md = ..\..\Readme.md 25 | ..\..\ToDo.md = ..\..\ToDo.md 26 | EndProjectSection 27 | EndProject 28 | Global 29 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 30 | Debug|x64 = Debug|x64 31 | Debug|x86 = Debug|x86 32 | Release|x64 = Release|x64 33 | Release|x86 = Release|x86 34 | EndGlobalSection 35 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 36 | {C8E24A58-5BAA-4001-ACAF-67DB79506DD6}.Debug|x64.ActiveCfg = Debug|x64 37 | {C8E24A58-5BAA-4001-ACAF-67DB79506DD6}.Debug|x64.Build.0 = Debug|x64 38 | {C8E24A58-5BAA-4001-ACAF-67DB79506DD6}.Debug|x86.ActiveCfg = Debug|Win32 39 | {C8E24A58-5BAA-4001-ACAF-67DB79506DD6}.Debug|x86.Build.0 = Debug|Win32 40 | {C8E24A58-5BAA-4001-ACAF-67DB79506DD6}.Release|x64.ActiveCfg = Release|x64 41 | {C8E24A58-5BAA-4001-ACAF-67DB79506DD6}.Release|x64.Build.0 = Release|x64 42 | {C8E24A58-5BAA-4001-ACAF-67DB79506DD6}.Release|x86.ActiveCfg = Release|Win32 43 | {C8E24A58-5BAA-4001-ACAF-67DB79506DD6}.Release|x86.Build.0 = Release|Win32 44 | {FB8C68F0-24BE-4C0B-9C44-2497150693A7}.Debug|x64.ActiveCfg = Debug|x64 45 | {FB8C68F0-24BE-4C0B-9C44-2497150693A7}.Debug|x64.Build.0 = Debug|x64 46 | {FB8C68F0-24BE-4C0B-9C44-2497150693A7}.Debug|x86.ActiveCfg = Debug|Win32 47 | {FB8C68F0-24BE-4C0B-9C44-2497150693A7}.Debug|x86.Build.0 = Debug|Win32 48 | {FB8C68F0-24BE-4C0B-9C44-2497150693A7}.Release|x64.ActiveCfg = Release|x64 49 | {FB8C68F0-24BE-4C0B-9C44-2497150693A7}.Release|x64.Build.0 = Release|x64 50 | {FB8C68F0-24BE-4C0B-9C44-2497150693A7}.Release|x86.ActiveCfg = Release|Win32 51 | {FB8C68F0-24BE-4C0B-9C44-2497150693A7}.Release|x86.Build.0 = Release|Win32 52 | {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60}.Debug|x64.ActiveCfg = Debug|x64 53 | {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60}.Debug|x64.Build.0 = Debug|x64 54 | {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60}.Debug|x86.ActiveCfg = Debug|Win32 55 | {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60}.Debug|x86.Build.0 = Debug|Win32 56 | {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60}.Release|x64.ActiveCfg = Release|x64 57 | {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60}.Release|x64.Build.0 = Release|x64 58 | {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60}.Release|x86.ActiveCfg = Release|Win32 59 | {3BC78AB3-0DC9-4E8B-A950-B1C0CA3B6C60}.Release|x86.Build.0 = Release|Win32 60 | {50978472-2E8B-4ACB-AFA9-4B21625C9A83}.Debug|x64.ActiveCfg = Debug|x64 61 | {50978472-2E8B-4ACB-AFA9-4B21625C9A83}.Debug|x64.Build.0 = Debug|x64 62 | {50978472-2E8B-4ACB-AFA9-4B21625C9A83}.Debug|x86.ActiveCfg = Debug|Win32 63 | {50978472-2E8B-4ACB-AFA9-4B21625C9A83}.Debug|x86.Build.0 = Debug|Win32 64 | {50978472-2E8B-4ACB-AFA9-4B21625C9A83}.Release|x64.ActiveCfg = Release|x64 65 | {50978472-2E8B-4ACB-AFA9-4B21625C9A83}.Release|x64.Build.0 = Release|x64 66 | {50978472-2E8B-4ACB-AFA9-4B21625C9A83}.Release|x86.ActiveCfg = Release|Win32 67 | {50978472-2E8B-4ACB-AFA9-4B21625C9A83}.Release|x86.Build.0 = Release|Win32 68 | {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE}.Debug|x64.ActiveCfg = Debug|x64 69 | {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE}.Debug|x64.Build.0 = Debug|x64 70 | {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE}.Debug|x86.ActiveCfg = Debug|Win32 71 | {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE}.Debug|x86.Build.0 = Debug|Win32 72 | {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE}.Release|x64.ActiveCfg = Release|x64 73 | {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE}.Release|x64.Build.0 = Release|x64 74 | {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE}.Release|x86.ActiveCfg = Release|Win32 75 | {6CE711FB-19D1-4924-843A-4C7D8B1F4BDE}.Release|x86.Build.0 = Release|Win32 76 | EndGlobalSection 77 | GlobalSection(SolutionProperties) = preSolution 78 | HideSolutionNode = FALSE 79 | EndGlobalSection 80 | GlobalSection(ExtensibilityGlobals) = postSolution 81 | SolutionGuid = {5A142936-434A-4B24-8C1D-09B5B20DC898} 82 | EndGlobalSection 83 | EndGlobal 84 | -------------------------------------------------------------------------------- /build/msvc/TestLibTCGTranslate/TestLibTCGTranslate.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 15.0 23 | {FB8C68F0-24BE-4C0B-9C44-2497150693A7} 24 | Win32Proj 25 | TestLibTCGTranslate 26 | 10.0.17763.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v141 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v141 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v141 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v141 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | ..\..\..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 76 | ..\Debug\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 77 | 78 | 79 | true 80 | ..\..\..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 81 | ..\x64\Debug\;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 82 | 83 | 84 | false 85 | ..\..\..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 86 | ..\Release\;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(NETFXKitsDir)Lib\um\x86 87 | 88 | 89 | false 90 | ..\..\..\include\;$(VC_IncludePath);$(WindowsSDK_IncludePath); 91 | ..\x64\Release\;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64 92 | 93 | 94 | 95 | NotUsing 96 | Level3 97 | Disabled 98 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 99 | true 100 | MultiThreadedDebugDLL 101 | false 102 | 103 | 104 | Console 105 | true 106 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 107 | 108 | 109 | 110 | 111 | NotUsing 112 | Level3 113 | Disabled 114 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 115 | true 116 | MultiThreadedDebugDLL 117 | false 118 | 119 | 120 | Console 121 | true 122 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 123 | 124 | 125 | 126 | 127 | NotUsing 128 | Level3 129 | MaxSpeed 130 | true 131 | true 132 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 133 | true 134 | MultiThreadedDLL 135 | Guard 136 | 137 | 138 | Console 139 | true 140 | true 141 | true 142 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 143 | 144 | 145 | 146 | 147 | NotUsing 148 | Level3 149 | MaxSpeed 150 | true 151 | true 152 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 153 | true 154 | MultiThreadedDLL 155 | Guard 156 | 157 | 158 | Console 159 | true 160 | true 161 | true 162 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /build/msvc/TestLibTCGTranslate/TestLibTCGTranslate.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | -------------------------------------------------------------------------------- /include/lib/bitmap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Bitmap Module 3 | * 4 | * Copyright (C) 2010 Corentin Chary 5 | * 6 | * Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h 7 | * 8 | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. 9 | * See the COPYING.LIB file in the top-level directory. 10 | */ 11 | 12 | #ifndef BITMAP_H 13 | #define BITMAP_H 14 | 15 | 16 | #include "lib/bitops.h" 17 | 18 | /* 19 | * The available bitmap operations and their rough meaning in the 20 | * case that the bitmap is a single unsigned long are thus: 21 | * 22 | * Note that nbits should be always a compile time evaluable constant. 23 | * Otherwise many inlines will generate horrible code. 24 | * 25 | * bitmap_zero(dst, nbits) *dst = 0UL 26 | * bitmap_fill(dst, nbits) *dst = ~0UL 27 | * bitmap_copy(dst, src, nbits) *dst = *src 28 | * bitmap_and(dst, src1, src2, nbits) *dst = *src1 & *src2 29 | * bitmap_or(dst, src1, src2, nbits) *dst = *src1 | *src2 30 | * bitmap_xor(dst, src1, src2, nbits) *dst = *src1 ^ *src2 31 | * bitmap_andnot(dst, src1, src2, nbits) *dst = *src1 & ~(*src2) 32 | * bitmap_complement(dst, src, nbits) *dst = ~(*src) 33 | * bitmap_equal(src1, src2, nbits) Are *src1 and *src2 equal? 34 | * bitmap_intersects(src1, src2, nbits) Do *src1 and *src2 overlap? 35 | * bitmap_empty(src, nbits) Are all bits zero in *src? 36 | * bitmap_full(src, nbits) Are all bits set in *src? 37 | * bitmap_set(dst, pos, nbits) Set specified bit area 38 | * bitmap_set_atomic(dst, pos, nbits) Set specified bit area with atomic ops 39 | * bitmap_clear(dst, pos, nbits) Clear specified bit area 40 | * bitmap_test_and_clear_atomic(dst, pos, nbits) Test and clear area 41 | * bitmap_find_next_zero_area(buf, len, pos, n, mask) Find bit free area 42 | */ 43 | 44 | /* 45 | * Also the following operations apply to bitmaps. 46 | * 47 | * set_bit(bit, addr) *addr |= bit 48 | * clear_bit(bit, addr) *addr &= ~bit 49 | * change_bit(bit, addr) *addr ^= bit 50 | * test_bit(bit, addr) Is bit set in *addr? 51 | * test_and_set_bit(bit, addr) Set bit and return old value 52 | * test_and_clear_bit(bit, addr) Clear bit and return old value 53 | * test_and_change_bit(bit, addr) Change bit and return old value 54 | * find_first_zero_bit(addr, nbits) Position first zero bit in *addr 55 | * find_first_bit(addr, nbits) Position first set bit in *addr 56 | * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit 57 | * find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit 58 | */ 59 | 60 | #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) 61 | #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) 62 | 63 | #define DECLARE_BITMAP(name,bits) \ 64 | unsigned long name[BITS_TO_LONGS(bits)] 65 | 66 | #define small_nbits(nbits) \ 67 | ((nbits) <= BITS_PER_LONG) 68 | 69 | int slow_bitmap_empty(const unsigned long *bitmap, long bits); 70 | int slow_bitmap_full(const unsigned long *bitmap, long bits); 71 | int slow_bitmap_equal(const unsigned long *bitmap1, 72 | const unsigned long *bitmap2, long bits); 73 | void slow_bitmap_complement(unsigned long *dst, const unsigned long *src, 74 | long bits); 75 | int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1, 76 | const unsigned long *bitmap2, long bits); 77 | void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1, 78 | const unsigned long *bitmap2, long bits); 79 | void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, 80 | const unsigned long *bitmap2, long bits); 81 | int slow_bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, 82 | const unsigned long *bitmap2, long bits); 83 | int slow_bitmap_intersects(const unsigned long *bitmap1, 84 | const unsigned long *bitmap2, long bits); 85 | 86 | static inline void bitmap_zero(unsigned long *dst, long nbits) 87 | { 88 | if (small_nbits(nbits)) { 89 | *dst = 0UL; 90 | } 91 | else { 92 | long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); 93 | memset(dst, 0, len); 94 | } 95 | } 96 | 97 | #endif /* BITMAP_H */ -------------------------------------------------------------------------------- /include/lib/bitops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Bitops Module 3 | * 4 | * Copyright (C) 2010 Corentin Chary 5 | * 6 | * Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h 7 | * 8 | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. 9 | * See the COPYING.LIB file in the top-level directory. 10 | */ 11 | 12 | #ifndef BITOPS_H 13 | #define BITOPS_H 14 | 15 | #include "lib/internal.h" 16 | 17 | #define BITS_PER_BYTE CHAR_BIT 18 | #define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE) 19 | 20 | #define BIT(nr) (1UL << (nr)) 21 | #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) 22 | #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) 23 | #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) 24 | 25 | #define MAKE_64BIT_MASK(shift, length) \ 26 | (((~0ULL) >> (64 - (length))) << (shift)) 27 | 28 | /** 29 | * set_bit - Set a bit in memory 30 | * @nr: the bit to set 31 | * @addr: the address to start counting from 32 | */ 33 | static inline void set_bit(long nr, unsigned long *addr) 34 | { 35 | unsigned long mask = BIT_MASK(nr); 36 | unsigned long *p = addr + BIT_WORD(nr); 37 | 38 | *p |= mask; 39 | } 40 | 41 | /** 42 | * set_bit_atomic - Set a bit in memory atomically 43 | * @nr: the bit to set 44 | * @addr: the address to start counting from 45 | */ 46 | static inline void set_bit_atomic(long nr, unsigned long *addr) 47 | { 48 | unsigned long mask = BIT_MASK(nr); 49 | unsigned long *p = addr + BIT_WORD(nr); 50 | 51 | atomic_or(p, mask); 52 | } 53 | 54 | /** 55 | * clear_bit - Clears a bit in memory 56 | * @nr: Bit to clear 57 | * @addr: Address to start counting from 58 | */ 59 | static inline void clear_bit(long nr, unsigned long *addr) 60 | { 61 | unsigned long mask = BIT_MASK(nr); 62 | unsigned long *p = addr + BIT_WORD(nr); 63 | 64 | *p &= ~mask; 65 | } 66 | 67 | /** 68 | * change_bit - Toggle a bit in memory 69 | * @nr: Bit to change 70 | * @addr: Address to start counting from 71 | */ 72 | static inline void change_bit(long nr, unsigned long *addr) 73 | { 74 | unsigned long mask = BIT_MASK(nr); 75 | unsigned long *p = addr + BIT_WORD(nr); 76 | 77 | *p ^= mask; 78 | } 79 | 80 | /** 81 | * test_and_set_bit - Set a bit and return its old value 82 | * @nr: Bit to set 83 | * @addr: Address to count from 84 | */ 85 | static inline int test_and_set_bit(long nr, unsigned long *addr) 86 | { 87 | unsigned long mask = BIT_MASK(nr); 88 | unsigned long *p = addr + BIT_WORD(nr); 89 | unsigned long old = *p; 90 | 91 | *p = old | mask; 92 | return (old & mask) != 0; 93 | } 94 | 95 | /** 96 | * test_and_clear_bit - Clear a bit and return its old value 97 | * @nr: Bit to clear 98 | * @addr: Address to count from 99 | */ 100 | static inline int test_and_clear_bit(long nr, unsigned long *addr) 101 | { 102 | unsigned long mask = BIT_MASK(nr); 103 | unsigned long *p = addr + BIT_WORD(nr); 104 | unsigned long old = *p; 105 | 106 | *p = old & ~mask; 107 | return (old & mask) != 0; 108 | } 109 | 110 | /** 111 | * test_and_change_bit - Change a bit and return its old value 112 | * @nr: Bit to change 113 | * @addr: Address to count from 114 | */ 115 | static inline int test_and_change_bit(long nr, unsigned long *addr) 116 | { 117 | unsigned long mask = BIT_MASK(nr); 118 | unsigned long *p = addr + BIT_WORD(nr); 119 | unsigned long old = *p; 120 | 121 | *p = old ^ mask; 122 | return (old & mask) != 0; 123 | } 124 | 125 | /** 126 | * test_bit - Determine whether a bit is set 127 | * @nr: bit number to test 128 | * @addr: Address to start counting from 129 | */ 130 | static inline int test_bit(long nr, const unsigned long *addr) 131 | { 132 | return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); 133 | } 134 | 135 | /** 136 | * find_last_bit - find the last set bit in a memory region 137 | * @addr: The address to start the search at 138 | * @size: The maximum size to search 139 | * 140 | * Returns the bit number of the first set bit, or size. 141 | */ 142 | unsigned long find_last_bit(const unsigned long *addr, 143 | unsigned long size); 144 | 145 | /** 146 | * find_next_bit - find the next set bit in a memory region 147 | * @addr: The address to base the search on 148 | * @offset: The bitnumber to start searching at 149 | * @size: The bitmap size in bits 150 | */ 151 | unsigned long find_next_bit(const unsigned long *addr, 152 | unsigned long size, 153 | unsigned long offset); 154 | 155 | /** 156 | * find_next_zero_bit - find the next cleared bit in a memory region 157 | * @addr: The address to base the search on 158 | * @offset: The bitnumber to start searching at 159 | * @size: The bitmap size in bits 160 | */ 161 | 162 | unsigned long find_next_zero_bit(const unsigned long *addr, 163 | unsigned long size, 164 | unsigned long offset); 165 | 166 | /** 167 | * find_first_bit - find the first set bit in a memory region 168 | * @addr: The address to start the search at 169 | * @size: The maximum size to search 170 | * 171 | * Returns the bit number of the first set bit. 172 | */ 173 | static inline unsigned long find_first_bit(const unsigned long *addr, 174 | unsigned long size) 175 | { 176 | unsigned long result, tmp; 177 | 178 | for (result = 0; result < size; result += BITS_PER_LONG) { 179 | tmp = *addr++; 180 | if (tmp) { 181 | result += ctzl(tmp); 182 | return result < size ? result : size; 183 | } 184 | } 185 | /* Not found */ 186 | return size; 187 | } 188 | 189 | /** 190 | * find_first_zero_bit - find the first cleared bit in a memory region 191 | * @addr: The address to start the search at 192 | * @size: The maximum size to search 193 | * 194 | * Returns the bit number of the first cleared bit. 195 | */ 196 | static inline unsigned long find_first_zero_bit(const unsigned long *addr, 197 | unsigned long size) 198 | { 199 | return find_next_zero_bit(addr, size, 0); 200 | } 201 | 202 | /** 203 | * rol8 - rotate an 8-bit value left 204 | * @word: value to rotate 205 | * @shift: bits to roll 206 | */ 207 | static inline uint8_t rol8(uint8_t word, unsigned int shift) 208 | { 209 | return (word << shift) | (word >> ((8 - shift) & 7)); 210 | } 211 | 212 | /** 213 | * ror8 - rotate an 8-bit value right 214 | * @word: value to rotate 215 | * @shift: bits to roll 216 | */ 217 | static inline uint8_t ror8(uint8_t word, unsigned int shift) 218 | { 219 | return (word >> shift) | (word << ((8 - shift) & 7)); 220 | } 221 | 222 | /** 223 | * rol16 - rotate a 16-bit value left 224 | * @word: value to rotate 225 | * @shift: bits to roll 226 | */ 227 | static inline uint16_t rol16(uint16_t word, unsigned int shift) 228 | { 229 | return (word << shift) | (word >> ((16 - shift) & 15)); 230 | } 231 | 232 | /** 233 | * ror16 - rotate a 16-bit value right 234 | * @word: value to rotate 235 | * @shift: bits to roll 236 | */ 237 | static inline uint16_t ror16(uint16_t word, unsigned int shift) 238 | { 239 | return (word >> shift) | (word << ((16 - shift) & 15)); 240 | } 241 | 242 | /** 243 | * rol32 - rotate a 32-bit value left 244 | * @word: value to rotate 245 | * @shift: bits to roll 246 | */ 247 | static inline uint32_t rol32(uint32_t word, unsigned int shift) 248 | { 249 | return (word << shift) | (word >> ((32 - shift) & 31)); 250 | } 251 | 252 | /** 253 | * ror32 - rotate a 32-bit value right 254 | * @word: value to rotate 255 | * @shift: bits to roll 256 | */ 257 | static inline uint32_t ror32(uint32_t word, unsigned int shift) 258 | { 259 | return (word >> shift) | (word << ((32 - shift) & 31)); 260 | } 261 | 262 | /** 263 | * rol64 - rotate a 64-bit value left 264 | * @word: value to rotate 265 | * @shift: bits to roll 266 | */ 267 | static inline uint64_t rol64(uint64_t word, unsigned int shift) 268 | { 269 | return (word << shift) | (word >> ((64 - shift) & 63)); 270 | } 271 | 272 | /** 273 | * ror64 - rotate a 64-bit value right 274 | * @word: value to rotate 275 | * @shift: bits to roll 276 | */ 277 | static inline uint64_t ror64(uint64_t word, unsigned int shift) 278 | { 279 | return (word >> shift) | (word << ((64 - shift) & 63)); 280 | } 281 | 282 | /** 283 | * extract32: 284 | * @value: the value to extract the bit field from 285 | * @start: the lowest bit in the bit field (numbered from 0) 286 | * @length: the length of the bit field 287 | * 288 | * Extract from the 32 bit input @value the bit field specified by the 289 | * @start and @length parameters, and return it. The bit field must 290 | * lie entirely within the 32 bit word. It is valid to request that 291 | * all 32 bits are returned (ie @length 32 and @start 0). 292 | * 293 | * Returns: the value of the bit field extracted from the input value. 294 | */ 295 | static inline uint32_t extract32(uint32_t value, int start, int length) 296 | { 297 | assert(start >= 0 && length > 0 && length <= 32 - start); 298 | return (value >> start) & (~0U >> (32 - length)); 299 | } 300 | 301 | /** 302 | * extract64: 303 | * @value: the value to extract the bit field from 304 | * @start: the lowest bit in the bit field (numbered from 0) 305 | * @length: the length of the bit field 306 | * 307 | * Extract from the 64 bit input @value the bit field specified by the 308 | * @start and @length parameters, and return it. The bit field must 309 | * lie entirely within the 64 bit word. It is valid to request that 310 | * all 64 bits are returned (ie @length 64 and @start 0). 311 | * 312 | * Returns: the value of the bit field extracted from the input value. 313 | */ 314 | static inline uint64_t extract64(uint64_t value, int start, int length) 315 | { 316 | assert(start >= 0 && length > 0 && length <= 64 - start); 317 | return (value >> start) & (~0ULL >> (64 - length)); 318 | } 319 | 320 | /** 321 | * sextract32: 322 | * @value: the value to extract the bit field from 323 | * @start: the lowest bit in the bit field (numbered from 0) 324 | * @length: the length of the bit field 325 | * 326 | * Extract from the 32 bit input @value the bit field specified by the 327 | * @start and @length parameters, and return it, sign extended to 328 | * an int32_t (ie with the most significant bit of the field propagated 329 | * to all the upper bits of the return value). The bit field must lie 330 | * entirely within the 32 bit word. It is valid to request that 331 | * all 32 bits are returned (ie @length 32 and @start 0). 332 | * 333 | * Returns: the sign extended value of the bit field extracted from the 334 | * input value. 335 | */ 336 | static inline int32_t sextract32(uint32_t value, int start, int length) 337 | { 338 | assert(start >= 0 && length > 0 && length <= 32 - start); 339 | /* Note that this implementation relies on right shift of signed 340 | * integers being an arithmetic shift. 341 | */ 342 | return ((int32_t)(value << (32 - length - start))) >> (32 - length); 343 | } 344 | 345 | /** 346 | * sextract64: 347 | * @value: the value to extract the bit field from 348 | * @start: the lowest bit in the bit field (numbered from 0) 349 | * @length: the length of the bit field 350 | * 351 | * Extract from the 64 bit input @value the bit field specified by the 352 | * @start and @length parameters, and return it, sign extended to 353 | * an int64_t (ie with the most significant bit of the field propagated 354 | * to all the upper bits of the return value). The bit field must lie 355 | * entirely within the 64 bit word. It is valid to request that 356 | * all 64 bits are returned (ie @length 64 and @start 0). 357 | * 358 | * Returns: the sign extended value of the bit field extracted from the 359 | * input value. 360 | */ 361 | static inline int64_t sextract64(uint64_t value, int start, int length) 362 | { 363 | assert(start >= 0 && length > 0 && length <= 64 - start); 364 | /* Note that this implementation relies on right shift of signed 365 | * integers being an arithmetic shift. 366 | */ 367 | return ((int64_t)(value << (64 - length - start))) >> (64 - length); 368 | } 369 | 370 | /** 371 | * deposit32: 372 | * @value: initial value to insert bit field into 373 | * @start: the lowest bit in the bit field (numbered from 0) 374 | * @length: the length of the bit field 375 | * @fieldval: the value to insert into the bit field 376 | * 377 | * Deposit @fieldval into the 32 bit @value at the bit field specified 378 | * by the @start and @length parameters, and return the modified 379 | * @value. Bits of @value outside the bit field are not modified. 380 | * Bits of @fieldval above the least significant @length bits are 381 | * ignored. The bit field must lie entirely within the 32 bit word. 382 | * It is valid to request that all 32 bits are modified (ie @length 383 | * 32 and @start 0). 384 | * 385 | * Returns: the modified @value. 386 | */ 387 | static inline uint32_t deposit32(uint32_t value, int start, int length, 388 | uint32_t fieldval) 389 | { 390 | uint32_t mask; 391 | assert(start >= 0 && length > 0 && length <= 32 - start); 392 | mask = (~0U >> (32 - length)) << start; 393 | return (value & ~mask) | ((fieldval << start) & mask); 394 | } 395 | 396 | /** 397 | * deposit64: 398 | * @value: initial value to insert bit field into 399 | * @start: the lowest bit in the bit field (numbered from 0) 400 | * @length: the length of the bit field 401 | * @fieldval: the value to insert into the bit field 402 | * 403 | * Deposit @fieldval into the 64 bit @value at the bit field specified 404 | * by the @start and @length parameters, and return the modified 405 | * @value. Bits of @value outside the bit field are not modified. 406 | * Bits of @fieldval above the least significant @length bits are 407 | * ignored. The bit field must lie entirely within the 64 bit word. 408 | * It is valid to request that all 64 bits are modified (ie @length 409 | * 64 and @start 0). 410 | * 411 | * Returns: the modified @value. 412 | */ 413 | static inline uint64_t deposit64(uint64_t value, int start, int length, 414 | uint64_t fieldval) 415 | { 416 | uint64_t mask; 417 | assert(start >= 0 && length > 0 && length <= 64 - start); 418 | mask = (~0ULL >> (64 - length)) << start; 419 | return (value & ~mask) | ((fieldval << start) & mask); 420 | } 421 | 422 | /** 423 | * half_shuffle32: 424 | * @value: 32-bit value (of which only the bottom 16 bits are of interest) 425 | * 426 | * Given an input value: 427 | * xxxx xxxx xxxx xxxx ABCD EFGH IJKL MNOP 428 | * return the value where the bottom 16 bits are spread out into 429 | * the odd bits in the word, and the even bits are zeroed: 430 | * 0A0B 0C0D 0E0F 0G0H 0I0J 0K0L 0M0N 0O0P 431 | * 432 | * Any bits set in the top half of the input are ignored. 433 | * 434 | * Returns: the shuffled bits. 435 | */ 436 | static inline uint32_t half_shuffle32(uint32_t x) 437 | { 438 | /* This algorithm is from _Hacker's Delight_ section 7-2 "Shuffling Bits". 439 | * It ignores any bits set in the top half of the input. 440 | */ 441 | x = ((x & 0xFF00) << 8) | (x & 0x00FF); 442 | x = ((x << 4) | x) & 0x0F0F0F0F; 443 | x = ((x << 2) | x) & 0x33333333; 444 | x = ((x << 1) | x) & 0x55555555; 445 | return x; 446 | } 447 | 448 | /** 449 | * half_shuffle64: 450 | * @value: 64-bit value (of which only the bottom 32 bits are of interest) 451 | * 452 | * Given an input value: 453 | * xxxx xxxx xxxx .... xxxx xxxx ABCD EFGH IJKL MNOP QRST UVWX YZab cdef 454 | * return the value where the bottom 32 bits are spread out into 455 | * the odd bits in the word, and the even bits are zeroed: 456 | * 0A0B 0C0D 0E0F 0G0H 0I0J 0K0L 0M0N .... 0U0V 0W0X 0Y0Z 0a0b 0c0d 0e0f 457 | * 458 | * Any bits set in the top half of the input are ignored. 459 | * 460 | * Returns: the shuffled bits. 461 | */ 462 | static inline uint64_t half_shuffle64(uint64_t x) 463 | { 464 | /* This algorithm is from _Hacker's Delight_ section 7-2 "Shuffling Bits". 465 | * It ignores any bits set in the top half of the input. 466 | */ 467 | x = ((x & 0xFFFF0000ULL) << 16) | (x & 0xFFFF); 468 | x = ((x << 8) | x) & 0x00FF00FF00FF00FFULL; 469 | x = ((x << 4) | x) & 0x0F0F0F0F0F0F0F0FULL; 470 | x = ((x << 2) | x) & 0x3333333333333333ULL; 471 | x = ((x << 1) | x) & 0x5555555555555555ULL; 472 | return x; 473 | } 474 | 475 | /** 476 | * half_unshuffle32: 477 | * @value: 32-bit value (of which only the odd bits are of interest) 478 | * 479 | * Given an input value: 480 | * xAxB xCxD xExF xGxH xIxJ xKxL xMxN xOxP 481 | * return the value where all the odd bits are compressed down 482 | * into the low half of the word, and the high half is zeroed: 483 | * 0000 0000 0000 0000 ABCD EFGH IJKL MNOP 484 | * 485 | * Any even bits set in the input are ignored. 486 | * 487 | * Returns: the unshuffled bits. 488 | */ 489 | static inline uint32_t half_unshuffle32(uint32_t x) 490 | { 491 | /* This algorithm is from _Hacker's Delight_ section 7-2 "Shuffling Bits". 492 | * where it is called an inverse half shuffle. 493 | */ 494 | x &= 0x55555555; 495 | x = ((x >> 1) | x) & 0x33333333; 496 | x = ((x >> 2) | x) & 0x0F0F0F0F; 497 | x = ((x >> 4) | x) & 0x00FF00FF; 498 | x = ((x >> 8) | x) & 0x0000FFFF; 499 | return x; 500 | } 501 | 502 | /** 503 | * half_unshuffle64: 504 | * @value: 64-bit value (of which only the odd bits are of interest) 505 | * 506 | * Given an input value: 507 | * xAxB xCxD xExF xGxH xIxJ xKxL xMxN .... xUxV xWxX xYxZ xaxb xcxd xexf 508 | * return the value where all the odd bits are compressed down 509 | * into the low half of the word, and the high half is zeroed: 510 | * 0000 0000 0000 .... 0000 0000 ABCD EFGH IJKL MNOP QRST UVWX YZab cdef 511 | * 512 | * Any even bits set in the input are ignored. 513 | * 514 | * Returns: the unshuffled bits. 515 | */ 516 | static inline uint64_t half_unshuffle64(uint64_t x) 517 | { 518 | /* This algorithm is from _Hacker's Delight_ section 7-2 "Shuffling Bits". 519 | * where it is called an inverse half shuffle. 520 | */ 521 | x &= 0x5555555555555555ULL; 522 | x = ((x >> 1) | x) & 0x3333333333333333ULL; 523 | x = ((x >> 2) | x) & 0x0F0F0F0F0F0F0F0FULL; 524 | x = ((x >> 4) | x) & 0x00FF00FF00FF00FFULL; 525 | x = ((x >> 8) | x) & 0x0000FFFF0000FFFFULL; 526 | x = ((x >> 16) | x) & 0x00000000FFFFFFFFULL; 527 | return x; 528 | } 529 | 530 | #endif 531 | -------------------------------------------------------------------------------- /include/lib/internal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "lib/tcg/tcg-target.h" 16 | 17 | #pragma warning( disable : 4003 4002 4146 ) 18 | 19 | #define NEED_CPU_H 1 20 | 21 | #if defined(TARGET_ARM) 22 | #define TARGET_LONG_BITS 32 23 | #define TARGET_LONG_SIZE 4 24 | #define TARGET_INSN_START_EXTRA_WORDS 2 25 | 26 | #define arch_gen_intermediate_code gen_intermediate_code_arm 27 | #define arch_translate_init arm_translate_init 28 | #define arch_cpu_init arm_cpu_init 29 | #elif defined(TARGET_AARCH64) 30 | #define TARGET_LONG_BITS 64 31 | #define TARGET_LONG_SIZE 8 32 | #define TARGET_INSN_START_EXTRA_WORDS 2 33 | 34 | #define arch_gen_intermediate_code gen_intermediate_code_a64 35 | #define arch_translate_init a64_translate_init 36 | #define arch_cpu_init a64_cpu_init 37 | #elif defined(TARGET_X86) 38 | #define TARGET_LONG_BITS 32 39 | #define TARGET_LONG_SIZE 4 40 | #define TARGET_INSN_START_EXTRA_WORDS 1 41 | 42 | #define arch_gen_intermediate_code gen_intermediate_code_i386 43 | #define arch_translate_init i386_translate_init 44 | #define arch_cpu_init i386_cpu_init 45 | #elif defined(TARGET_X86_64) 46 | #define TARGET_LONG_BITS 64 47 | #define TARGET_LONG_SIZE 8 48 | #define TARGET_INSN_START_EXTRA_WORDS 1 49 | 50 | #define arch_gen_intermediate_code gen_intermediate_code_i386 51 | #define arch_translate_init i386_translate_init 52 | #define arch_cpu_init i386_cpu_init 53 | #else 54 | #error No Target set 55 | #endif 56 | 57 | #define TARGET_PAGE_BITS 12 58 | #define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS) 59 | #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1) 60 | #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK) 61 | 62 | #define CPU_COMMON \ 63 | bool singlestep_enabled; \ 64 | void * libtct_ctx; 65 | 66 | #if TARGET_LONG_SIZE == 4 67 | typedef int32_t target_long; 68 | typedef uint32_t target_ulong; 69 | #define TARGET_FMT_lx "%08x" 70 | #define TARGET_FMT_ld "%d" 71 | #define TARGET_FMT_lu "%u" 72 | #elif TARGET_LONG_SIZE == 8 73 | typedef int64_t target_long; 74 | typedef uint64_t target_ulong; 75 | #define TARGET_FMT_lx "%016" PRIx64 76 | #define TARGET_FMT_ld "%" PRId64 77 | #define TARGET_FMT_lu "%" PRIu64 78 | #else 79 | #error TARGET_LONG_SIZE undefined 80 | #endif 81 | 82 | extern size_t cpu_ld_code(void *env, target_ulong addr, uint8_t * buffer, size_t size); 83 | extern uint8_t cpu_ldub_code(void *env, target_ulong addr); 84 | extern uint16_t cpu_lduw_code(void *env, target_ulong addr); 85 | extern uint32_t cpu_ldul_code(void *env, target_ulong addr); 86 | extern uint64_t cpu_lduq_code(void *env, target_ulong addr); 87 | extern int8_t cpu_ldsb_code(void *env, target_ulong addr); 88 | extern int16_t cpu_ldsw_code(void *env, target_ulong addr); 89 | extern int32_t cpu_ldsl_code(void *env, target_ulong addr); 90 | extern int64_t cpu_ldsq_code(void *env, target_ulong addr); 91 | 92 | #define g_assert assert 93 | #define qemu_log printf 94 | #define qemu_logfile stdout 95 | #define g_assert_not_reached() 96 | #define qemu_log_mask 97 | #define __builtin_constant_p(x) 0 98 | #define abort() 99 | #define cpu_abort 100 | #define LOG_UNIMP 0 101 | #define likely(x) (x) 102 | #define unlikely(x) (x) 103 | 104 | #define container_of(ptr, type, member) ((type *)((char *)(ptr) -offsetof(type,member))) 105 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 106 | 107 | #define QEMU_NORETURN 108 | #define QEMU_PACKED 109 | #define QEMU_ARTIFICIAL 110 | #define QEMU_BUILD_BUG_ON(x) 111 | #define QEMU_GNUC_PREREQ(x,y) 0 112 | #define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m)) 113 | #define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m)) 114 | #define __attribute__(x) 115 | #define trace_guest_mem_before_tcg(p1,p2,p3,p4) 116 | #define semihosting_enabled() 0 117 | #define gemu_log_mask(p1, p2, p3, p4) 118 | 119 | #ifndef MIN 120 | #define MIN(a, b) (((a) < (b)) ? (a) : (b)) 121 | #endif 122 | #ifndef MAX 123 | #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 124 | #endif 125 | 126 | #ifndef glue 127 | #define xglue(x, y) x##y 128 | #define glue(x, y) xglue(x, y) 129 | #define stringify(s) tostring(s) 130 | #define tostring(s) #s 131 | #endif 132 | 133 | #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) 134 | #define CHAR_BIT 8 135 | #define BITS_PER_BYTE CHAR_BIT 136 | #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) 137 | #define MAKE_64BIT_MASK(shift, length) (((~0ULL) >> (64 - (length))) << (shift)) 138 | 139 | #define FIELD(reg, field, shift, length) \ 140 | enum : int { R_ ## reg ## _ ## field ## _SHIFT = (shift)}; \ 141 | enum : int { R_ ## reg ## _ ## field ## _LENGTH = (length)}; \ 142 | enum : __int64 { R_ ## reg ## _ ## field ## _MASK = MAKE_64BIT_MASK(shift, length)}; 143 | 144 | 145 | #define atomic_inc(ptr) ((void) InterlockedIncrement(ptr)) 146 | #define atomic_dec(ptr) ((void) InterlockedDecrement(ptr)) 147 | #define atomic_add(ptr, n) ((void) InterlockedAdd((LONG*)ptr, (LONG)n)) 148 | #define atomic_sub(ptr, n) ((void) InterlockedAdd((LONG*)ptr, (LONG)-n)) 149 | #define atomic_or(ptr, n) ((void) InterlockedAdd((LONG*)ptr, (LONG)n)) 150 | 151 | #define ctzl ctz32 152 | #define clzl clz32 153 | 154 | static uint32_t __inline ctz32(uint32_t value) 155 | { 156 | unsigned long trailing_zero = 0; 157 | 158 | if (_BitScanForward(&trailing_zero, value)) 159 | return trailing_zero; 160 | 161 | return 32; 162 | } 163 | 164 | static uint32_t __inline ctz64(uint64_t value) 165 | { 166 | unsigned long trailing_zero = 0; 167 | 168 | #ifdef _X86_ 169 | if (_InlineBitScanForward64(&trailing_zero, value)) 170 | return trailing_zero; 171 | #else 172 | if (_BitScanForward64(&trailing_zero, value)) 173 | return trailing_zero; 174 | #endif 175 | 176 | return 64; 177 | } 178 | 179 | static uint32_t __inline clz32(uint32_t value) 180 | { 181 | unsigned long leading_zero = 0; 182 | 183 | if (_BitScanReverse(&leading_zero, value)) 184 | return 31 - leading_zero; 185 | 186 | return 32; 187 | } 188 | 189 | static uint32_t __inline clz64(uint64_t value) 190 | { 191 | unsigned long leading_zero = 0; 192 | 193 | #ifdef _X86_ 194 | if (_InlineBitScanReverse64(&leading_zero, value)) 195 | return 63 - leading_zero; 196 | #else 197 | if (_BitScanReverse64(&leading_zero, value)) 198 | return 63 - leading_zero; 199 | #endif 200 | 201 | return 64; 202 | } 203 | 204 | static uint32_t __inline ctpop32(uint32_t value) 205 | { 206 | return __popcnt(value); 207 | } 208 | 209 | static uint64_t __inline ctpop64(uint64_t value) 210 | { 211 | #ifdef _WIN64 212 | return __popcnt64(value); 213 | #else 214 | return ctpop32(value & 0xffffffff) + ctpop32((value >> 32) & 0xffffffff); 215 | #endif 216 | } 217 | 218 | #define DISAS_NEXT 0 219 | #define DISAS_JUMP 1 220 | #define DISAS_UPDATE 2 221 | #define DISAS_TB_JUMP 3 222 | 223 | #define CF_COUNT_MASK 0x7fff 224 | #define CF_LAST_IO 0x8000 225 | #define CF_NOCACHE 0x10000 226 | #define CF_USE_ICOUNT 0x20000 227 | #define CF_IGNORE_ICOUNT 0x40000 228 | #define TB_JMP_RESET_OFFSET_INVALID 0xffff 229 | 230 | #if defined(TARGET_ARM) || defined(TARGET_AARCH64) 231 | 232 | #define CP_REG_SIZE_SHIFT 52 233 | #define CP_REG_SIZE_MASK 0x00f0000000000000ULL 234 | #define CP_REG_SIZE_U32 0x0020000000000000ULL 235 | #define CP_REG_SIZE_U64 0x0030000000000000ULL 236 | #define CP_REG_ARM 0x4000000000000000ULL 237 | #define CP_REG_ARCH_MASK 0xff00000000000000ULL 238 | 239 | #define CP_REG_ARM64 0x6000000000000000ULL 240 | #define CP_REG_ARM_COPROC_MASK 0x000000000FFF0000 241 | #define CP_REG_ARM_COPROC_SHIFT 16 242 | #define CP_REG_ARM64_SYSREG (0x0013 << CP_REG_ARM_COPROC_SHIFT) 243 | #define CP_REG_ARM64_SYSREG_OP0_MASK 0x000000000000c000 244 | #define CP_REG_ARM64_SYSREG_OP0_SHIFT 14 245 | #define CP_REG_ARM64_SYSREG_OP1_MASK 0x0000000000003800 246 | #define CP_REG_ARM64_SYSREG_OP1_SHIFT 11 247 | #define CP_REG_ARM64_SYSREG_CRN_MASK 0x0000000000000780 248 | #define CP_REG_ARM64_SYSREG_CRN_SHIFT 7 249 | #define CP_REG_ARM64_SYSREG_CRM_MASK 0x0000000000000078 250 | #define CP_REG_ARM64_SYSREG_CRM_SHIFT 3 251 | #define CP_REG_ARM64_SYSREG_OP2_MASK 0x0000000000000007 252 | #define CP_REG_ARM64_SYSREG_OP2_SHIFT 0 253 | #define CP_REG_ARM64_SYSREG_CP (CP_REG_ARM64_SYSREG >> CP_REG_ARM_COPROC_SHIFT) 254 | 255 | #define ARM_EL_EC_SHIFT 26 256 | #define ARM_EL_IL_SHIFT 25 257 | #define ARM_EL_ISV_SHIFT 24 258 | #define ARM_EL_IL (1 << ARM_EL_IL_SHIFT) 259 | #define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT) 260 | 261 | #define syn_uncategorized() 0 262 | #define syn_aa32_svc(imm16, is_16bit) 1 263 | #define syn_aa32_hvc(imm16) 2 264 | #define syn_aa32_smc(void) 3 265 | #define syn_aa32_bkpt(imm16, is_16bit) 4 266 | #define syn_cp14_rt_trap(cv, cond, opc1, opc2, crn, crm, rt, isread, is_16bit) 5 267 | #define syn_cp15_rt_trap(cv, cond, opc1, opc2, crn, crm, rt, isread, is_16bit) 6 268 | #define syn_cp14_rrt_trap(cv, cond, opc1, crm, rt, rt2, isread, is_16bit) 7 269 | #define syn_cp15_rrt_trap(cv, cond, opc1, crm, rt, rt2, isread, is_16bit) 8 270 | #define syn_fp_access_trap(cv, cond, is_16bit) 9 271 | #define syn_data_abort_with_iss(same_el, sas, sse, srt, sf, ar, ea, cm, s1ptw, wnr, fsc, is_16bit) 10 272 | #define syn_swstep(same_el, isv, ex) 11 273 | #define syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread) 12 274 | #define syn_aa64_svc(imm16) 13 275 | #define syn_aa64_hvc(imm16) 14 276 | #define syn_aa64_smc(imm16) 15 277 | #define syn_aa64_bkpt(imm16) 16 278 | 279 | #elif defined(TARGET_X86) || defined(TARGET_X86_64) 280 | #define SVM_IOIO_TYPE_MASK 1 281 | #define SVM_EXIT_READ_CR0 1 282 | #define SVM_EXIT_WRITE_CR0 2 283 | #define SVM_EXIT_IDTR_READ 3 284 | #define SVM_EXIT_GDTR_READ 4 285 | #define SVM_EXIT_LDTR_READ 5 286 | #define SVM_EXIT_TR_READ 6 287 | #define SVM_EXIT_IDTR_WRITE 7 288 | #define SVM_EXIT_GDTR_WRITE 8 289 | #define SVM_EXIT_LDTR_WRITE 9 290 | #define SVM_EXIT_TR_WRITE 10 291 | #define SVM_EXIT_PUSHF 11 292 | #define SVM_EXIT_POPF 12 293 | #define SVM_EXIT_IRET 13 294 | #define SVM_EXIT_INVD 14 295 | #define SVM_EXIT_WBINVD 15 296 | #define SVM_EXIT_WRITE_DR0 16 297 | #define SVM_EXIT_READ_DR0 17 298 | #define SVM_EXIT_RSM 18 299 | #endif 300 | 301 | #define EXCP_INTERRUPT 0x10000 302 | #define EXCP_HLT 0x10001 303 | #define EXCP_DEBUG 0x10002 304 | #define EXCP_HALTED 0x10003 305 | #define EXCP_YIELD 0x10004 306 | #define EXCP_ATOMIC 0x10005 307 | 308 | #define FEATURE_ENABLE( DC, FEATURE ) (DC)->features |= (1ULL << (FEATURE)) 309 | #define FEATURE_DISABLE( DC, FEATURE ) (DC)->features &= ~(1ULL << (FEATURE)) 310 | #define FEATURE_HAS(DC, FEATURE) (((DC)->features & (1ULL << FEATURE)) != 0) 311 | 312 | typedef void * GHashTable; 313 | 314 | typedef int(*fprintf_function)(FILE *handle, const char *format, ...); 315 | 316 | typedef uint8_t flag; 317 | 318 | typedef uint16_t float16; 319 | 320 | typedef uint32_t float32; 321 | 322 | typedef uint64_t float64; 323 | 324 | typedef struct floatx80 325 | { 326 | uint64_t low; 327 | uint16_t high; 328 | } floatx80; 329 | 330 | typedef struct float_status { 331 | signed char float_detect_tininess; 332 | signed char float_rounding_mode; 333 | uint8_t float_exception_flags; 334 | signed char floatx80_rounding_precision; 335 | flag flush_to_zero; 336 | flag flush_inputs_to_zero; 337 | flag default_nan_mode; 338 | flag snan_bit_is_one; 339 | } float_status; 340 | 341 | typedef union { 342 | float64 d; 343 | #if defined(HOST_WORDS_BIGENDIAN) 344 | struct { 345 | uint32_t upper; 346 | uint32_t lower; 347 | } l; 348 | #else 349 | struct { 350 | uint32_t lower; 351 | uint32_t upper; 352 | } l; 353 | #endif 354 | uint64_t ll; 355 | } CPU_DoubleU; 356 | 357 | typedef struct TCGLabel TCGLabel; 358 | 359 | struct TranslationBlock { 360 | target_ulong pc; 361 | target_ulong cs_base; 362 | uint32_t flags; 363 | uint16_t size; 364 | uint16_t icount; 365 | uint32_t cflags; 366 | uint32_t trace_vcpu_dstate; 367 | uint16_t invalid; 368 | void *tc_ptr; 369 | uint8_t *tc_search; 370 | struct TranslationBlock *orig_tb; 371 | struct TranslationBlock *page_next[2]; 372 | uint16_t jmp_reset_offset[2]; 373 | #ifdef USE_DIRECT_JUMP 374 | uint16_t jmp_insn_offset[2]; 375 | #else 376 | uintptr_t jmp_target_addr[2]; 377 | #endif 378 | uintptr_t jmp_list_next[2]; 379 | uintptr_t jmp_list_first; 380 | }; 381 | 382 | #if defined(TARGET_ARM) || defined(TARGET_AARCH64) 383 | enum arm_exception_class { 384 | EC_UNCATEGORIZED = 0x00, 385 | EC_WFX_TRAP = 0x01, 386 | EC_CP15RTTRAP = 0x03, 387 | EC_CP15RRTTRAP = 0x04, 388 | EC_CP14RTTRAP = 0x05, 389 | EC_CP14DTTRAP = 0x06, 390 | EC_ADVSIMDFPACCESSTRAP = 0x07, 391 | EC_FPIDTRAP = 0x08, 392 | EC_CP14RRTTRAP = 0x0c, 393 | EC_ILLEGALSTATE = 0x0e, 394 | EC_AA32_SVC = 0x11, 395 | EC_AA32_HVC = 0x12, 396 | EC_AA32_SMC = 0x13, 397 | EC_AA64_SVC = 0x15, 398 | EC_AA64_HVC = 0x16, 399 | EC_AA64_SMC = 0x17, 400 | EC_SYSTEMREGISTERTRAP = 0x18, 401 | EC_INSNABORT = 0x20, 402 | EC_INSNABORT_SAME_EL = 0x21, 403 | EC_PCALIGNMENT = 0x22, 404 | EC_DATAABORT = 0x24, 405 | EC_DATAABORT_SAME_EL = 0x25, 406 | EC_SPALIGNMENT = 0x26, 407 | EC_AA32_FPTRAP = 0x28, 408 | EC_AA64_FPTRAP = 0x2c, 409 | EC_SERROR = 0x2f, 410 | EC_BREAKPOINT = 0x30, 411 | EC_BREAKPOINT_SAME_EL = 0x31, 412 | EC_SOFTWARESTEP = 0x32, 413 | EC_SOFTWARESTEP_SAME_EL = 0x33, 414 | EC_WATCHPOINT = 0x34, 415 | EC_WATCHPOINT_SAME_EL = 0x35, 416 | EC_AA32_BKPT = 0x38, 417 | EC_VECTORCATCH = 0x3a, 418 | EC_AA64_BKPT = 0x3c, 419 | }; 420 | #endif 421 | 422 | enum { 423 | float_round_nearest_even = 0, 424 | float_round_down = 1, 425 | float_round_up = 2, 426 | float_round_to_zero = 3, 427 | float_round_ties_away = 4, 428 | float_round_to_odd = 5, 429 | }; 430 | 431 | enum arm_fprounding { 432 | FPROUNDING_TIEEVEN = 0, 433 | FPROUNDING_POSINF, 434 | FPROUNDING_NEGINF, 435 | FPROUNDING_ZERO, 436 | FPROUNDING_TIEAWAY, 437 | FPROUNDING_ODD 438 | }; 439 | -------------------------------------------------------------------------------- /include/lib/target/arm/helper-a64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AArch64 specific helper definitions 3 | * 4 | * Copyright (c) 2013 Alexander Graf 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64) 20 | DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64) 21 | DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64) 22 | DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr) 23 | DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr) 24 | DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr) 25 | DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr) 26 | DEF_HELPER_FLAGS_5(simd_tbl, TCG_CALL_NO_RWG_SE, i64, env, i64, i64, i32, i32) 27 | DEF_HELPER_FLAGS_3(vfp_mulxs, TCG_CALL_NO_RWG, f32, f32, f32, ptr) 28 | DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr) 29 | DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr) 30 | DEF_HELPER_FLAGS_3(neon_cge_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr) 31 | DEF_HELPER_FLAGS_3(neon_cgt_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr) 32 | DEF_HELPER_FLAGS_3(recpsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr) 33 | DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) 34 | DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr) 35 | DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr) 36 | DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64) 37 | DEF_HELPER_FLAGS_1(neon_addlp_u8, TCG_CALL_NO_RWG_SE, i64, i64) 38 | DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64) 39 | DEF_HELPER_FLAGS_1(neon_addlp_u16, TCG_CALL_NO_RWG_SE, i64, i64) 40 | DEF_HELPER_FLAGS_2(frecpx_f64, TCG_CALL_NO_RWG, f64, f64, ptr) 41 | DEF_HELPER_FLAGS_2(frecpx_f32, TCG_CALL_NO_RWG, f32, f32, ptr) 42 | DEF_HELPER_FLAGS_2(fcvtx_f64_to_f32, TCG_CALL_NO_RWG, f32, f64, env) 43 | DEF_HELPER_FLAGS_3(crc32_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32) 44 | DEF_HELPER_FLAGS_3(crc32c_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32) 45 | DEF_HELPER_FLAGS_4(paired_cmpxchg64_le, TCG_CALL_NO_WG, i64, env, i64, i64, i64) 46 | DEF_HELPER_FLAGS_4(paired_cmpxchg64_be, TCG_CALL_NO_WG, i64, env, i64, i64, i64) 47 | -------------------------------------------------------------------------------- /include/lib/target/arm/translate.h: -------------------------------------------------------------------------------- 1 | #ifndef TARGET_ARM_TRANSLATE_H 2 | #define TARGET_ARM_TRANSLATE_H 3 | 4 | #include "lib/internal.h" 5 | #include "lib/target/arm/cpu.h" 6 | 7 | typedef struct DisasContext 8 | { 9 | target_ulong pc; 10 | uint32_t insn; 11 | int is_jmp; 12 | int condjmp; 13 | TCGLabel *condlabel; 14 | int condexec_mask; 15 | int condexec_cond; 16 | struct TranslationBlock *tb; 17 | int singlestep_enabled; 18 | int thumb; 19 | int sctlr_b; 20 | TCGMemOp be_data; 21 | #if !defined(CONFIG_USER_ONLY) 22 | int user; 23 | #endif 24 | ARMMMUIdx mmu_idx; 25 | bool tbi0; 26 | bool tbi1; 27 | bool ns; 28 | int fp_excp_el; 29 | bool secure_routed_to_el3; 30 | bool vfp_enabled; 31 | int vec_len; 32 | int vec_stride; 33 | bool v7m_handler_mode; 34 | uint32_t svc_imm; 35 | int aarch64; 36 | int current_el; 37 | GHashTable *cp_regs; 38 | uint64_t features; 39 | bool fp_access_checked; 40 | bool ss_active; 41 | bool pstate_ss; 42 | bool is_ldex; 43 | bool ss_same_el; 44 | int c15_cpar; 45 | int insn_start_idx; 46 | #define TMP_A64_MAX 16 47 | int tmp_a64_count; 48 | TCGv_i64 tmp_a64[TMP_A64_MAX]; 49 | } DisasContext; 50 | 51 | typedef struct DisasCompare 52 | { 53 | TCGCond cond; 54 | TCGv_i32 value; 55 | bool value_global; 56 | } DisasCompare; 57 | 58 | #define DISAS_WFI 4 59 | #define DISAS_SWI 5 60 | #define DISAS_EXC 6 61 | #define DISAS_WFE 7 62 | #define DISAS_HVC 8 63 | #define DISAS_SMC 9 64 | #define DISAS_YIELD 10 65 | #define DISAS_BX_EXCRET 11 66 | #define DISAS_EXIT 12 67 | 68 | #if defined(TARGET_ARM) 69 | void arm_translate_init(TCGContext * s); 70 | void gen_intermediate_code_arm(TCGContext * s, CPUARMState *cs, TranslationBlock *tb); 71 | #elif defined(TARGET_AARCH64) 72 | void a64_translate_init(TCGContext * s); 73 | void gen_intermediate_code_a64(TCGContext * s, CPUARMState *cs, TranslationBlock *tb); 74 | #endif 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /include/lib/target/host-utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Utility compute operations used by translated code. 3 | * 4 | * Copyright (c) 2007 Thiemo Seufer 5 | * Copyright (c) 2007 Jocelyn Mayer 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #ifndef HOST_UTILS_H 27 | #define HOST_UTILS_H 28 | 29 | #include "lib/internal.h" 30 | 31 | #ifdef CONFIG_INT128 32 | static inline void mulu64(uint64_t *plow, uint64_t *phigh, 33 | uint64_t a, uint64_t b) 34 | { 35 | __uint128_t r = (__uint128_t)a * b; 36 | *plow = r; 37 | *phigh = r >> 64; 38 | } 39 | 40 | static inline void muls64(uint64_t *plow, uint64_t *phigh, 41 | int64_t a, int64_t b) 42 | { 43 | __int128_t r = (__int128_t)a * b; 44 | *plow = r; 45 | *phigh = r >> 64; 46 | } 47 | 48 | /* compute with 96 bit intermediate result: (a*b)/c */ 49 | static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) 50 | { 51 | return (__int128_t)a * b / c; 52 | } 53 | 54 | static inline int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor) 55 | { 56 | if (divisor == 0) { 57 | return 1; 58 | } 59 | else { 60 | __uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow; 61 | __uint128_t result = dividend / divisor; 62 | *plow = result; 63 | *phigh = dividend % divisor; 64 | return result > UINT64_MAX; 65 | } 66 | } 67 | 68 | static inline int divs128(int64_t *plow, int64_t *phigh, int64_t divisor) 69 | { 70 | if (divisor == 0) { 71 | return 1; 72 | } 73 | else { 74 | __int128_t dividend = ((__int128_t)*phigh << 64) | *plow; 75 | __int128_t result = dividend / divisor; 76 | *plow = result; 77 | *phigh = dividend % divisor; 78 | return result != *plow; 79 | } 80 | } 81 | #else 82 | void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b); 83 | void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b); 84 | int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor); 85 | int divs128(int64_t *plow, int64_t *phigh, int64_t divisor); 86 | 87 | static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) 88 | { 89 | union { 90 | uint64_t ll; 91 | struct { 92 | #ifdef HOST_WORDS_BIGENDIAN 93 | uint32_t high, low; 94 | #else 95 | uint32_t low, high; 96 | #endif 97 | } l; 98 | } u, res; 99 | uint64_t rl, rh; 100 | 101 | u.ll = a; 102 | rl = (uint64_t)u.l.low * (uint64_t)b; 103 | rh = (uint64_t)u.l.high * (uint64_t)b; 104 | rh += (rl >> 32); 105 | res.l.high = rh / c; 106 | res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c; 107 | return res.ll; 108 | } 109 | #endif 110 | 111 | /** 112 | * clo32 - count leading ones in a 32-bit value. 113 | * @val: The value to search 114 | * 115 | * Returns 32 if the value is -1. 116 | */ 117 | static inline int clo32(uint32_t val) 118 | { 119 | return clz32(~val); 120 | } 121 | 122 | /** 123 | * clo64 - count leading ones in a 64-bit value. 124 | * @val: The value to search 125 | * 126 | * Returns 64 if the value is -1. 127 | */ 128 | static inline int clo64(uint64_t val) 129 | { 130 | return clz64(~val); 131 | } 132 | 133 | /** 134 | * cto32 - count trailing ones in a 32-bit value. 135 | * @val: The value to search 136 | * 137 | * Returns 32 if the value is -1. 138 | */ 139 | static inline int cto32(uint32_t val) 140 | { 141 | return ctz32(~val); 142 | } 143 | 144 | /** 145 | * cto64 - count trailing ones in a 64-bit value. 146 | * @val: The value to search 147 | * 148 | * Returns 64 if the value is -1. 149 | */ 150 | static inline int cto64(uint64_t val) 151 | { 152 | return ctz64(~val); 153 | } 154 | 155 | /** 156 | * clrsb32 - count leading redundant sign bits in a 32-bit value. 157 | * @val: The value to search 158 | * 159 | * Returns the number of bits following the sign bit that are equal to it. 160 | * No special cases; output range is [0-31]. 161 | */ 162 | static inline int clrsb32(uint32_t val) 163 | { 164 | #if QEMU_GNUC_PREREQ(4, 7) 165 | return __builtin_clrsb(val); 166 | #else 167 | return clz32(val ^ ((int32_t)val >> 1)) - 1; 168 | #endif 169 | } 170 | 171 | /** 172 | * clrsb64 - count leading redundant sign bits in a 64-bit value. 173 | * @val: The value to search 174 | * 175 | * Returns the number of bits following the sign bit that are equal to it. 176 | * No special cases; output range is [0-63]. 177 | */ 178 | static inline int clrsb64(uint64_t val) 179 | { 180 | #if QEMU_GNUC_PREREQ(4, 7) 181 | return __builtin_clrsbll(val); 182 | #else 183 | return clz64(val ^ ((int64_t)val >> 1)) - 1; 184 | #endif 185 | } 186 | 187 | /** 188 | * revbit8 - reverse the bits in an 8-bit value. 189 | * @x: The value to modify. 190 | */ 191 | static inline uint8_t revbit8(uint8_t x) 192 | { 193 | /* Assign the correct nibble position. */ 194 | x = ((x & 0xf0) >> 4) 195 | | ((x & 0x0f) << 4); 196 | /* Assign the correct bit position. */ 197 | x = ((x & 0x88) >> 3) 198 | | ((x & 0x44) >> 1) 199 | | ((x & 0x22) << 1) 200 | | ((x & 0x11) << 3); 201 | return x; 202 | } 203 | 204 | /* Host type specific sizes of these routines. */ 205 | 206 | #if ULONG_MAX == UINT32_MAX 207 | # define clzl clz32 208 | # define ctzl ctz32 209 | # define clol clo32 210 | # define ctol cto32 211 | # define ctpopl ctpop32 212 | # define revbitl revbit32 213 | #elif ULONG_MAX == UINT64_MAX 214 | # define clzl clz64 215 | # define ctzl ctz64 216 | # define clol clo64 217 | # define ctol cto64 218 | # define ctpopl ctpop64 219 | # define revbitl revbit64 220 | #else 221 | # error Unknown sizeof long 222 | #endif 223 | 224 | static inline bool is_power_of_2(uint64_t value) 225 | { 226 | if (!value) { 227 | return false; 228 | } 229 | 230 | return !(value & (value - 1)); 231 | } 232 | 233 | /* round down to the nearest power of 2*/ 234 | static inline int64_t pow2floor(int64_t value) 235 | { 236 | if (!is_power_of_2(value)) { 237 | value = 0x8000000000000000ULL >> clz64(value); 238 | } 239 | return value; 240 | } 241 | 242 | /* round up to the nearest power of 2 (0 if overflow) */ 243 | static inline uint64_t pow2ceil(uint64_t value) 244 | { 245 | uint8_t nlz = clz64(value); 246 | 247 | if (is_power_of_2(value)) { 248 | return value; 249 | } 250 | if (!nlz) { 251 | return 0; 252 | } 253 | return 1ULL << (64 - nlz); 254 | } 255 | 256 | /** 257 | * urshift - 128-bit Unsigned Right Shift. 258 | * @plow: in/out - lower 64-bit integer. 259 | * @phigh: in/out - higher 64-bit integer. 260 | * @shift: in - bytes to shift, between 0 and 127. 261 | * 262 | * Result is zero-extended and stored in plow/phigh, which are 263 | * input/output variables. Shift values outside the range will 264 | * be mod to 128. In other words, the caller is responsible to 265 | * verify/assert both the shift range and plow/phigh pointers. 266 | */ 267 | void urshift(uint64_t *plow, uint64_t *phigh, int32_t shift); 268 | 269 | /** 270 | * ulshift - 128-bit Unsigned Left Shift. 271 | * @plow: in/out - lower 64-bit integer. 272 | * @phigh: in/out - higher 64-bit integer. 273 | * @shift: in - bytes to shift, between 0 and 127. 274 | * @overflow: out - true if any 1-bit is shifted out. 275 | * 276 | * Result is zero-extended and stored in plow/phigh, which are 277 | * input/output variables. Shift values outside the range will 278 | * be mod to 128. In other words, the caller is responsible to 279 | * verify/assert both the shift range and plow/phigh pointers. 280 | */ 281 | void ulshift(uint64_t *plow, uint64_t *phigh, int32_t shift, bool *overflow); 282 | 283 | #endif -------------------------------------------------------------------------------- /include/lib/target/i386/helpers-i386.h: -------------------------------------------------------------------------------- 1 | DEF_HELPER_3v(write_eflags, void, env, tl, i32) 2 | DEF_HELPER_1(read_eflags, tl, env) 3 | DEF_HELPER_2v(divb_AL, void, env, tl) 4 | DEF_HELPER_2v(idivb_AL, void, env, tl) 5 | DEF_HELPER_2v(divw_AX, void, env, tl) 6 | DEF_HELPER_2v(idivw_AX, void, env, tl) 7 | DEF_HELPER_2v(divl_EAX, void, env, tl) 8 | DEF_HELPER_2v(idivl_EAX, void, env, tl) 9 | #ifdef TARGET_X86_64 10 | DEF_HELPER_2v(divq_EAX, void, env, tl) 11 | DEF_HELPER_2v(idivq_EAX, void, env, tl) 12 | #endif 13 | DEF_HELPER_FLAGS_2v(cr4_testbit, TCG_CALL_NO_WG, void, env, i32) 14 | 15 | DEF_HELPER_FLAGS_2v(bndck, TCG_CALL_NO_WG, void, env, i32) 16 | DEF_HELPER_FLAGS_3(bndldx32, TCG_CALL_NO_WG, i64, env, tl, tl) 17 | DEF_HELPER_FLAGS_3(bndldx64, TCG_CALL_NO_WG, i64, env, tl, tl) 18 | DEF_HELPER_FLAGS_5v(bndstx32, TCG_CALL_NO_WG, void, env, tl, tl, i64, i64) 19 | DEF_HELPER_FLAGS_5v(bndstx64, TCG_CALL_NO_WG, void, env, tl, tl, i64, i64) 20 | DEF_HELPER_1v(bnd_jmp, void, env) 21 | 22 | DEF_HELPER_2v(aam, void, env, int) 23 | DEF_HELPER_2v(aad, void, env, int) 24 | DEF_HELPER_1v(aaa, void, env) 25 | DEF_HELPER_1v(aas, void, env) 26 | DEF_HELPER_1v(daa, void, env) 27 | DEF_HELPER_1v(das, void, env) 28 | 29 | DEF_HELPER_2(lsl, tl, env, tl) 30 | DEF_HELPER_2(lar, tl, env, tl) 31 | DEF_HELPER_2v(verr, void, env, tl) 32 | DEF_HELPER_2v(verw, void, env, tl) 33 | DEF_HELPER_2v(lldt, void, env, int) 34 | DEF_HELPER_2v(ltr, void, env, int) 35 | DEF_HELPER_3v(load_seg, void, env, int, int) 36 | DEF_HELPER_4v(ljmp_protected, void, env, int, tl, tl) 37 | DEF_HELPER_5v(lcall_real, void, env, int, tl, int, int) 38 | DEF_HELPER_5v(lcall_protected, void, env, int, tl, int, tl) 39 | DEF_HELPER_2v(iret_real, void, env, int) 40 | DEF_HELPER_3v(iret_protected, void, env, int, int) 41 | DEF_HELPER_3v(lret_protected, void, env, int, int) 42 | DEF_HELPER_2(read_crN, tl, env, int) 43 | DEF_HELPER_3v(write_crN, void, env, int, tl) 44 | DEF_HELPER_2v(lmsw, void, env, tl) 45 | DEF_HELPER_1v(clts, void, env) 46 | DEF_HELPER_FLAGS_3v(set_dr, TCG_CALL_NO_WG, void, env, int, tl) 47 | DEF_HELPER_FLAGS_2(get_dr, TCG_CALL_NO_WG, tl, env, int) 48 | DEF_HELPER_2v(invlpg, void, env, tl) 49 | 50 | DEF_HELPER_1v(sysenter, void, env) 51 | DEF_HELPER_2v(sysexit, void, env, int) 52 | #ifdef TARGET_X86_64 53 | DEF_HELPER_2v(syscall, void, env, int) 54 | DEF_HELPER_2v(sysret, void, env, int) 55 | #endif 56 | DEF_HELPER_2v(hlt, void, env, int) 57 | DEF_HELPER_2v(monitor, void, env, tl) 58 | DEF_HELPER_2v(mwait, void, env, int) 59 | DEF_HELPER_2v(pause, void, env, int) 60 | DEF_HELPER_1v(debug, void, env) 61 | DEF_HELPER_1v(reset_rf, void, env) 62 | DEF_HELPER_3v(raise_interrupt, void, env, int, int) 63 | DEF_HELPER_2v(raise_exception, void, env, int) 64 | DEF_HELPER_1v(cli, void, env) 65 | DEF_HELPER_1v(sti, void, env) 66 | DEF_HELPER_1v(clac, void, env) 67 | DEF_HELPER_1v(stac, void, env) 68 | DEF_HELPER_3v(boundw, void, env, tl, int) 69 | DEF_HELPER_3v(boundl, void, env, tl, int) 70 | DEF_HELPER_1v(rsm, void, env) 71 | DEF_HELPER_2v(into, void, env, int) 72 | DEF_HELPER_2v(cmpxchg8b_unlocked, void, env, tl) 73 | DEF_HELPER_2v(cmpxchg8b, void, env, tl) 74 | #ifdef TARGET_X86_64 75 | DEF_HELPER_2v(cmpxchg16b_unlocked, void, env, tl) 76 | DEF_HELPER_2v(cmpxchg16b, void, env, tl) 77 | #endif 78 | DEF_HELPER_1v(single_step, void, env) 79 | DEF_HELPER_1v(rechecking_single_step, void, env) 80 | DEF_HELPER_1v(cpuid, void, env) 81 | DEF_HELPER_1v(rdtsc, void, env) 82 | DEF_HELPER_1v(rdtscp, void, env) 83 | DEF_HELPER_1v(rdpmc, void, env) 84 | DEF_HELPER_1v(rdmsr, void, env) 85 | DEF_HELPER_1v(wrmsr, void, env) 86 | 87 | DEF_HELPER_2v(check_iob, void, env, i32) 88 | DEF_HELPER_2v(check_iow, void, env, i32) 89 | DEF_HELPER_2v(check_iol, void, env, i32) 90 | DEF_HELPER_3v(outb, void, env, i32, i32) 91 | DEF_HELPER_2(inb, tl, env, i32) 92 | DEF_HELPER_3v(outw, void, env, i32, i32) 93 | DEF_HELPER_2(inw, tl, env, i32) 94 | DEF_HELPER_3v(outl, void, env, i32, i32) 95 | DEF_HELPER_2(inl, tl, env, i32) 96 | DEF_HELPER_FLAGS_4v(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl) 97 | 98 | DEF_HELPER_3v(svm_check_intercept_param, void, env, i32, i64) 99 | DEF_HELPER_4v(svm_check_io, void, env, i32, i32, i32) 100 | DEF_HELPER_3v(vmrun, void, env, int, int) 101 | DEF_HELPER_1v(vmmcall, void, env) 102 | DEF_HELPER_2v(vmload, void, env, int) 103 | DEF_HELPER_2v(vmsave, void, env, int) 104 | DEF_HELPER_1v(stgi, void, env) 105 | DEF_HELPER_1v(clgi, void, env) 106 | DEF_HELPER_1v(skinit, void, env) 107 | DEF_HELPER_2v(invlpga, void, env, int) 108 | 109 | /* x86 FPU */ 110 | 111 | DEF_HELPER_2v(flds_FT0, void, env, i32) 112 | DEF_HELPER_2v(fldl_FT0, void, env, i64) 113 | DEF_HELPER_2v(fildl_FT0, void, env, s32) 114 | DEF_HELPER_2v(flds_ST0, void, env, i32) 115 | DEF_HELPER_2v(fldl_ST0, void, env, i64) 116 | DEF_HELPER_2v(fildl_ST0, void, env, s32) 117 | DEF_HELPER_2v(fildll_ST0, void, env, s64) 118 | DEF_HELPER_1(fsts_ST0, i32, env) 119 | DEF_HELPER_1(fstl_ST0, i64, env) 120 | DEF_HELPER_1(fist_ST0, s32, env) 121 | DEF_HELPER_1(fistl_ST0, s32, env) 122 | DEF_HELPER_1(fistll_ST0, s64, env) 123 | DEF_HELPER_1(fistt_ST0, s32, env) 124 | DEF_HELPER_1(fisttl_ST0, s32, env) 125 | DEF_HELPER_1(fisttll_ST0, s64, env) 126 | DEF_HELPER_2v(fldt_ST0, void, env, tl) 127 | DEF_HELPER_2v(fstt_ST0, void, env, tl) 128 | DEF_HELPER_1v(fpush, void, env) 129 | DEF_HELPER_1v(fpop, void, env) 130 | DEF_HELPER_1v(fdecstp, void, env) 131 | DEF_HELPER_1v(fincstp, void, env) 132 | DEF_HELPER_2v(ffree_STN, void, env, int) 133 | DEF_HELPER_1v(fmov_ST0_FT0, void, env) 134 | DEF_HELPER_2v(fmov_FT0_STN, void, env, int) 135 | DEF_HELPER_2v(fmov_ST0_STN, void, env, int) 136 | DEF_HELPER_2v(fmov_STN_ST0, void, env, int) 137 | DEF_HELPER_2v(fxchg_ST0_STN, void, env, int) 138 | DEF_HELPER_1v(fcom_ST0_FT0, void, env) 139 | DEF_HELPER_1v(fucom_ST0_FT0, void, env) 140 | DEF_HELPER_1v(fcomi_ST0_FT0, void, env) 141 | DEF_HELPER_1v(fucomi_ST0_FT0, void, env) 142 | DEF_HELPER_1v(fadd_ST0_FT0, void, env) 143 | DEF_HELPER_1v(fmul_ST0_FT0, void, env) 144 | DEF_HELPER_1v(fsub_ST0_FT0, void, env) 145 | DEF_HELPER_1v(fsubr_ST0_FT0, void, env) 146 | DEF_HELPER_1v(fdiv_ST0_FT0, void, env) 147 | DEF_HELPER_1v(fdivr_ST0_FT0, void, env) 148 | DEF_HELPER_2v(fadd_STN_ST0, void, env, int) 149 | DEF_HELPER_2v(fmul_STN_ST0, void, env, int) 150 | DEF_HELPER_2v(fsub_STN_ST0, void, env, int) 151 | DEF_HELPER_2v(fsubr_STN_ST0, void, env, int) 152 | DEF_HELPER_2v(fdiv_STN_ST0, void, env, int) 153 | DEF_HELPER_2v(fdivr_STN_ST0, void, env, int) 154 | DEF_HELPER_1v(fchs_ST0, void, env) 155 | DEF_HELPER_1v(fabs_ST0, void, env) 156 | DEF_HELPER_1v(fxam_ST0, void, env) 157 | DEF_HELPER_1v(fld1_ST0, void, env) 158 | DEF_HELPER_1v(fldl2t_ST0, void, env) 159 | DEF_HELPER_1v(fldl2e_ST0, void, env) 160 | DEF_HELPER_1v(fldpi_ST0, void, env) 161 | DEF_HELPER_1v(fldlg2_ST0, void, env) 162 | DEF_HELPER_1v(fldln2_ST0, void, env) 163 | DEF_HELPER_1v(fldz_ST0, void, env) 164 | DEF_HELPER_1v(fldz_FT0, void, env) 165 | DEF_HELPER_1(fnstsw, i32, env) 166 | DEF_HELPER_1(fnstcw, i32, env) 167 | DEF_HELPER_2v(fldcw, void, env, i32) 168 | DEF_HELPER_1v(fclex, void, env) 169 | DEF_HELPER_1v(fwait, void, env) 170 | DEF_HELPER_1v(fninit, void, env) 171 | DEF_HELPER_2v(fbld_ST0, void, env, tl) 172 | DEF_HELPER_2v(fbst_ST0, void, env, tl) 173 | DEF_HELPER_1v(f2xm1, void, env) 174 | DEF_HELPER_1v(fyl2x, void, env) 175 | DEF_HELPER_1v(fptan, void, env) 176 | DEF_HELPER_1v(fpatan, void, env) 177 | DEF_HELPER_1v(fxtract, void, env) 178 | DEF_HELPER_1v(fprem1, void, env) 179 | DEF_HELPER_1v(fprem, void, env) 180 | DEF_HELPER_1v(fyl2xp1, void, env) 181 | DEF_HELPER_1v(fsqrt, void, env) 182 | DEF_HELPER_1v(fsincos, void, env) 183 | DEF_HELPER_1v(frndint, void, env) 184 | DEF_HELPER_1v(fscale, void, env) 185 | DEF_HELPER_1v(fsin, void, env) 186 | DEF_HELPER_1v(fcos, void, env) 187 | DEF_HELPER_3v(fstenv, void, env, tl, int) 188 | DEF_HELPER_3v(fldenv, void, env, tl, int) 189 | DEF_HELPER_3v(fsave, void, env, tl, int) 190 | DEF_HELPER_3v(frstor, void, env, tl, int) 191 | DEF_HELPER_FLAGS_2v(fxsave, TCG_CALL_NO_WG, void, env, tl) 192 | DEF_HELPER_FLAGS_2v(fxrstor, TCG_CALL_NO_WG, void, env, tl) 193 | DEF_HELPER_FLAGS_3v(xsave, TCG_CALL_NO_WG, void, env, tl, i64) 194 | DEF_HELPER_FLAGS_3v(xsaveopt, TCG_CALL_NO_WG, void, env, tl, i64) 195 | DEF_HELPER_FLAGS_3v(xrstor, TCG_CALL_NO_WG, void, env, tl, i64) 196 | DEF_HELPER_FLAGS_2(xgetbv, TCG_CALL_NO_WG, i64, env, i32) 197 | DEF_HELPER_FLAGS_3v(xsetbv, TCG_CALL_NO_WG, void, env, i32, i64) 198 | DEF_HELPER_FLAGS_2(rdpkru, TCG_CALL_NO_WG, i64, env, i32) 199 | DEF_HELPER_FLAGS_3v(wrpkru, TCG_CALL_NO_WG, void, env, i32, i64) 200 | 201 | DEF_HELPER_FLAGS_2(pdep, TCG_CALL_NO_RWG_SE, tl, tl, tl) 202 | DEF_HELPER_FLAGS_2(pext, TCG_CALL_NO_RWG_SE, tl, tl, tl) 203 | 204 | /* MMX/SSE */ 205 | 206 | DEF_HELPER_2v(ldmxcsr, void, env, i32) 207 | DEF_HELPER_1v(enter_mmx, void, env) 208 | DEF_HELPER_1v(emms, void, env) 209 | DEF_HELPER_3v(movq, void, env, ptr, ptr) 210 | 211 | #define SHIFT 0 212 | #include "lib/target/i386/ops_sse_header.h" 213 | #define SHIFT 1 214 | #include "lib/target/i386/ops_sse_header.h" 215 | 216 | DEF_HELPER_3(rclb, tl, env, tl, tl) 217 | DEF_HELPER_3(rclw, tl, env, tl, tl) 218 | DEF_HELPER_3(rcll, tl, env, tl, tl) 219 | DEF_HELPER_3(rcrb, tl, env, tl, tl) 220 | DEF_HELPER_3(rcrw, tl, env, tl, tl) 221 | DEF_HELPER_3(rcrl, tl, env, tl, tl) 222 | #ifdef TARGET_X86_64 223 | DEF_HELPER_3(rclq, tl, env, tl, tl) 224 | DEF_HELPER_3(rcrq, tl, env, tl, tl) 225 | #endif 226 | -------------------------------------------------------------------------------- /include/lib/target/i386/ops_sse_header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4/PNI support 3 | * 4 | * Copyright (c) 2005 Fabrice Bellard 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, see . 18 | */ 19 | #if SHIFT == 0 20 | #define Reg MMXReg 21 | #define SUFFIX _mmx 22 | #else 23 | #define Reg ZMMReg 24 | #define SUFFIX _xmm 25 | #endif 26 | 27 | #define dh_alias_Reg ptr 28 | #define dh_alias_ZMMReg ptr 29 | #define dh_alias_MMXReg ptr 30 | #define dh_ctype_Reg Reg * 31 | #define dh_ctype_ZMMReg ZMMReg * 32 | #define dh_ctype_MMXReg MMXReg * 33 | #define dh_is_signed_Reg dh_is_signed_ptr 34 | #define dh_is_signed_ZMMReg dh_is_signed_ptr 35 | #define dh_is_signed_MMXReg dh_is_signed_ptr 36 | 37 | DEF_HELPER_3v(glue(psrlw, SUFFIX), void, env, Reg, Reg) 38 | DEF_HELPER_3v(glue(psraw, SUFFIX), void, env, Reg, Reg) 39 | DEF_HELPER_3v(glue(psllw, SUFFIX), void, env, Reg, Reg) 40 | DEF_HELPER_3v(glue(psrld, SUFFIX), void, env, Reg, Reg) 41 | DEF_HELPER_3v(glue(psrad, SUFFIX), void, env, Reg, Reg) 42 | DEF_HELPER_3v(glue(pslld, SUFFIX), void, env, Reg, Reg) 43 | DEF_HELPER_3v(glue(psrlq, SUFFIX), void, env, Reg, Reg) 44 | DEF_HELPER_3v(glue(psllq, SUFFIX), void, env, Reg, Reg) 45 | 46 | #if SHIFT == 1 47 | DEF_HELPER_3v(glue(psrldq, SUFFIX), void, env, Reg, Reg) 48 | DEF_HELPER_3v(glue(pslldq, SUFFIX), void, env, Reg, Reg) 49 | #endif 50 | 51 | #define SSE_HELPER_B(name, F)\ 52 | DEF_HELPER_3v(glue(name, SUFFIX), void, env, Reg, Reg) 53 | 54 | #define SSE_HELPER_W(name, F)\ 55 | DEF_HELPER_3v(glue(name, SUFFIX), void, env, Reg, Reg) 56 | 57 | #define SSE_HELPER_L(name, F)\ 58 | DEF_HELPER_3v(glue(name, SUFFIX), void, env, Reg, Reg) 59 | 60 | #define SSE_HELPER_Q(name, F)\ 61 | DEF_HELPER_3v(glue(name, SUFFIX), void, env, Reg, Reg) 62 | 63 | SSE_HELPER_B(paddb, FADD) 64 | SSE_HELPER_W(paddw, FADD) 65 | SSE_HELPER_L(paddl, FADD) 66 | SSE_HELPER_Q(paddq, FADD) 67 | 68 | SSE_HELPER_B(psubb, FSUB) 69 | SSE_HELPER_W(psubw, FSUB) 70 | SSE_HELPER_L(psubl, FSUB) 71 | SSE_HELPER_Q(psubq, FSUB) 72 | 73 | SSE_HELPER_B(paddusb, FADDUB) 74 | SSE_HELPER_B(paddsb, FADDSB) 75 | SSE_HELPER_B(psubusb, FSUBUB) 76 | SSE_HELPER_B(psubsb, FSUBSB) 77 | 78 | SSE_HELPER_W(paddusw, FADDUW) 79 | SSE_HELPER_W(paddsw, FADDSW) 80 | SSE_HELPER_W(psubusw, FSUBUW) 81 | SSE_HELPER_W(psubsw, FSUBSW) 82 | 83 | SSE_HELPER_B(pminub, FMINUB) 84 | SSE_HELPER_B(pmaxub, FMAXUB) 85 | 86 | SSE_HELPER_W(pminsw, FMINSW) 87 | SSE_HELPER_W(pmaxsw, FMAXSW) 88 | 89 | SSE_HELPER_Q(pand, FAND) 90 | SSE_HELPER_Q(pandn, FANDN) 91 | SSE_HELPER_Q(por, FOR) 92 | SSE_HELPER_Q(pxor, FXOR) 93 | 94 | SSE_HELPER_B(pcmpgtb, FCMPGTB) 95 | SSE_HELPER_W(pcmpgtw, FCMPGTW) 96 | SSE_HELPER_L(pcmpgtl, FCMPGTL) 97 | 98 | SSE_HELPER_B(pcmpeqb, FCMPEQ) 99 | SSE_HELPER_W(pcmpeqw, FCMPEQ) 100 | SSE_HELPER_L(pcmpeql, FCMPEQ) 101 | 102 | SSE_HELPER_W(pmullw, FMULLW) 103 | #if SHIFT == 0 104 | SSE_HELPER_W(pmulhrw, FMULHRW) 105 | #endif 106 | SSE_HELPER_W(pmulhuw, FMULHUW) 107 | SSE_HELPER_W(pmulhw, FMULHW) 108 | 109 | SSE_HELPER_B(pavgb, FAVG) 110 | SSE_HELPER_W(pavgw, FAVG) 111 | 112 | DEF_HELPER_3v(glue(pmuludq, SUFFIX), void, env, Reg, Reg) 113 | DEF_HELPER_3v(glue(pmaddwd, SUFFIX), void, env, Reg, Reg) 114 | 115 | DEF_HELPER_3v(glue(psadbw, SUFFIX), void, env, Reg, Reg) 116 | DEF_HELPER_4v(glue(maskmov, SUFFIX), void, env, Reg, Reg, tl) 117 | DEF_HELPER_2v(glue(movl_mm_T0, SUFFIX), void, Reg, i32) 118 | #ifdef TARGET_X86_64 119 | DEF_HELPER_2v(glue(movq_mm_T0, SUFFIX), void, Reg, i64) 120 | #endif 121 | 122 | #if SHIFT == 0 123 | DEF_HELPER_3v(glue(pshufw, SUFFIX), void, Reg, Reg, int) 124 | #else 125 | DEF_HELPER_3v(shufps, void, Reg, Reg, int) 126 | DEF_HELPER_3v(shufpd, void, Reg, Reg, int) 127 | DEF_HELPER_3v(glue(pshufd, SUFFIX), void, Reg, Reg, int) 128 | DEF_HELPER_3v(glue(pshuflw, SUFFIX), void, Reg, Reg, int) 129 | DEF_HELPER_3v(glue(pshufhw, SUFFIX), void, Reg, Reg, int) 130 | #endif 131 | 132 | #if SHIFT == 1 133 | /* FPU ops */ 134 | /* XXX: not accurate */ 135 | 136 | #define SSE_HELPER_S(name, F) \ 137 | DEF_HELPER_3v(name ## ps, void, env, Reg, Reg) \ 138 | DEF_HELPER_3v(name ## ss, void, env, Reg, Reg) \ 139 | DEF_HELPER_3v(name ## pd, void, env, Reg, Reg) \ 140 | DEF_HELPER_3v(name ## sd, void, env, Reg, Reg) 141 | 142 | SSE_HELPER_S(add, FPU_ADD) 143 | SSE_HELPER_S(sub, FPU_SUB) 144 | SSE_HELPER_S(mul, FPU_MUL) 145 | SSE_HELPER_S(div, FPU_DIV) 146 | SSE_HELPER_S(min, FPU_MIN) 147 | SSE_HELPER_S(max, FPU_MAX) 148 | SSE_HELPER_S(sqrt, FPU_SQRT) 149 | 150 | 151 | DEF_HELPER_3v(cvtps2pd, void, env, Reg, Reg) 152 | DEF_HELPER_3v(cvtpd2ps, void, env, Reg, Reg) 153 | DEF_HELPER_3v(cvtss2sd, void, env, Reg, Reg) 154 | DEF_HELPER_3v(cvtsd2ss, void, env, Reg, Reg) 155 | DEF_HELPER_3v(cvtdq2ps, void, env, Reg, Reg) 156 | DEF_HELPER_3v(cvtdq2pd, void, env, Reg, Reg) 157 | DEF_HELPER_3v(cvtpi2ps, void, env, ZMMReg, MMXReg) 158 | DEF_HELPER_3v(cvtpi2pd, void, env, ZMMReg, MMXReg) 159 | DEF_HELPER_3v(cvtsi2ss, void, env, ZMMReg, i32) 160 | DEF_HELPER_3v(cvtsi2sd, void, env, ZMMReg, i32) 161 | 162 | #ifdef TARGET_X86_64 163 | DEF_HELPER_3v(cvtsq2ss, void, env, ZMMReg, i64) 164 | DEF_HELPER_3v(cvtsq2sd, void, env, ZMMReg, i64) 165 | #endif 166 | 167 | DEF_HELPER_3v(cvtps2dq, void, env, ZMMReg, ZMMReg) 168 | DEF_HELPER_3v(cvtpd2dq, void, env, ZMMReg, ZMMReg) 169 | DEF_HELPER_3v(cvtps2pi, void, env, MMXReg, ZMMReg) 170 | DEF_HELPER_3v(cvtpd2pi, void, env, MMXReg, ZMMReg) 171 | DEF_HELPER_2(cvtss2si, s32, env, ZMMReg) 172 | DEF_HELPER_2(cvtsd2si, s32, env, ZMMReg) 173 | #ifdef TARGET_X86_64 174 | DEF_HELPER_2(cvtss2sq, s64, env, ZMMReg) 175 | DEF_HELPER_2(cvtsd2sq, s64, env, ZMMReg) 176 | #endif 177 | 178 | DEF_HELPER_3v(cvttps2dq, void, env, ZMMReg, ZMMReg) 179 | DEF_HELPER_3v(cvttpd2dq, void, env, ZMMReg, ZMMReg) 180 | DEF_HELPER_3v(cvttps2pi, void, env, MMXReg, ZMMReg) 181 | DEF_HELPER_3v(cvttpd2pi, void, env, MMXReg, ZMMReg) 182 | DEF_HELPER_2(cvttss2si, s32, env, ZMMReg) 183 | DEF_HELPER_2(cvttsd2si, s32, env, ZMMReg) 184 | #ifdef TARGET_X86_64 185 | DEF_HELPER_2(cvttss2sq, s64, env, ZMMReg) 186 | DEF_HELPER_2(cvttsd2sq, s64, env, ZMMReg) 187 | #endif 188 | 189 | DEF_HELPER_3v(rsqrtps, void, env, ZMMReg, ZMMReg) 190 | DEF_HELPER_3v(rsqrtss, void, env, ZMMReg, ZMMReg) 191 | DEF_HELPER_3v(rcpps, void, env, ZMMReg, ZMMReg) 192 | DEF_HELPER_3v(rcpss, void, env, ZMMReg, ZMMReg) 193 | DEF_HELPER_3v(extrq_r, void, env, ZMMReg, ZMMReg) 194 | DEF_HELPER_4v(extrq_i, void, env, ZMMReg, int, int) 195 | DEF_HELPER_3v(insertq_r, void, env, ZMMReg, ZMMReg) 196 | DEF_HELPER_4v(insertq_i, void, env, ZMMReg, int, int) 197 | DEF_HELPER_3v(haddps, void, env, ZMMReg, ZMMReg) 198 | DEF_HELPER_3v(haddpd, void, env, ZMMReg, ZMMReg) 199 | DEF_HELPER_3v(hsubps, void, env, ZMMReg, ZMMReg) 200 | DEF_HELPER_3v(hsubpd, void, env, ZMMReg, ZMMReg) 201 | DEF_HELPER_3v(addsubps, void, env, ZMMReg, ZMMReg) 202 | DEF_HELPER_3v(addsubpd, void, env, ZMMReg, ZMMReg) 203 | 204 | #define SSE_HELPER_CMP(name, F) \ 205 | DEF_HELPER_3v(name ## ps, void, env, Reg, Reg) \ 206 | DEF_HELPER_3v(name ## ss, void, env, Reg, Reg) \ 207 | DEF_HELPER_3v(name ## pd, void, env, Reg, Reg) \ 208 | DEF_HELPER_3v(name ## sd, void, env, Reg, Reg) 209 | 210 | SSE_HELPER_CMP(cmpeq, FPU_CMPEQ) 211 | SSE_HELPER_CMP(cmplt, FPU_CMPLT) 212 | SSE_HELPER_CMP(cmple, FPU_CMPLE) 213 | SSE_HELPER_CMP(cmpunord, FPU_CMPUNORD) 214 | SSE_HELPER_CMP(cmpneq, FPU_CMPNEQ) 215 | SSE_HELPER_CMP(cmpnlt, FPU_CMPNLT) 216 | SSE_HELPER_CMP(cmpnle, FPU_CMPNLE) 217 | SSE_HELPER_CMP(cmpord, FPU_CMPORD) 218 | 219 | DEF_HELPER_3v(ucomiss, void, env, Reg, Reg) 220 | DEF_HELPER_3v(comiss, void, env, Reg, Reg) 221 | DEF_HELPER_3v(ucomisd, void, env, Reg, Reg) 222 | DEF_HELPER_3v(comisd, void, env, Reg, Reg) 223 | DEF_HELPER_2(movmskps, i32, env, Reg) 224 | DEF_HELPER_2(movmskpd, i32, env, Reg) 225 | #endif 226 | 227 | DEF_HELPER_2(glue(pmovmskb, SUFFIX), i32, env, Reg) 228 | DEF_HELPER_3v(glue(packsswb, SUFFIX), void, env, Reg, Reg) 229 | DEF_HELPER_3v(glue(packuswb, SUFFIX), void, env, Reg, Reg) 230 | DEF_HELPER_3v(glue(packssdw, SUFFIX), void, env, Reg, Reg) 231 | #define UNPCK_OP(base_name, base) \ 232 | DEF_HELPER_3v(glue(punpck ## base_name ## bw, SUFFIX), void, env, Reg, Reg) \ 233 | DEF_HELPER_3v(glue(punpck ## base_name ## wd, SUFFIX), void, env, Reg, Reg) \ 234 | DEF_HELPER_3v(glue(punpck ## base_name ## dq, SUFFIX), void, env, Reg, Reg) 235 | 236 | UNPCK_OP(l, 0) 237 | UNPCK_OP(h, 1) 238 | 239 | #if SHIFT == 1 240 | DEF_HELPER_3v(glue(punpcklqdq, SUFFIX), void, env, Reg, Reg) 241 | DEF_HELPER_3v(glue(punpckhqdq, SUFFIX), void, env, Reg, Reg) 242 | #endif 243 | 244 | /* 3DNow! float ops */ 245 | #if SHIFT == 0 246 | DEF_HELPER_3v(pi2fd, void, env, MMXReg, MMXReg) 247 | DEF_HELPER_3v(pi2fw, void, env, MMXReg, MMXReg) 248 | DEF_HELPER_3v(pf2id, void, env, MMXReg, MMXReg) 249 | DEF_HELPER_3v(pf2iw, void, env, MMXReg, MMXReg) 250 | DEF_HELPER_3v(pfacc, void, env, MMXReg, MMXReg) 251 | DEF_HELPER_3v(pfadd, void, env, MMXReg, MMXReg) 252 | DEF_HELPER_3v(pfcmpeq, void, env, MMXReg, MMXReg) 253 | DEF_HELPER_3v(pfcmpge, void, env, MMXReg, MMXReg) 254 | DEF_HELPER_3v(pfcmpgt, void, env, MMXReg, MMXReg) 255 | DEF_HELPER_3v(pfmax, void, env, MMXReg, MMXReg) 256 | DEF_HELPER_3v(pfmin, void, env, MMXReg, MMXReg) 257 | DEF_HELPER_3v(pfmul, void, env, MMXReg, MMXReg) 258 | DEF_HELPER_3v(pfnacc, void, env, MMXReg, MMXReg) 259 | DEF_HELPER_3v(pfpnacc, void, env, MMXReg, MMXReg) 260 | DEF_HELPER_3v(pfrcp, void, env, MMXReg, MMXReg) 261 | DEF_HELPER_3v(pfrsqrt, void, env, MMXReg, MMXReg) 262 | DEF_HELPER_3v(pfsub, void, env, MMXReg, MMXReg) 263 | DEF_HELPER_3v(pfsubr, void, env, MMXReg, MMXReg) 264 | DEF_HELPER_3v(pswapd, void, env, MMXReg, MMXReg) 265 | #endif 266 | 267 | /* SSSE3 op helpers */ 268 | DEF_HELPER_3v(glue(phaddw, SUFFIX), void, env, Reg, Reg) 269 | DEF_HELPER_3v(glue(phaddd, SUFFIX), void, env, Reg, Reg) 270 | DEF_HELPER_3v(glue(phaddsw, SUFFIX), void, env, Reg, Reg) 271 | DEF_HELPER_3v(glue(phsubw, SUFFIX), void, env, Reg, Reg) 272 | DEF_HELPER_3v(glue(phsubd, SUFFIX), void, env, Reg, Reg) 273 | DEF_HELPER_3v(glue(phsubsw, SUFFIX), void, env, Reg, Reg) 274 | DEF_HELPER_3v(glue(pabsb, SUFFIX), void, env, Reg, Reg) 275 | DEF_HELPER_3v(glue(pabsw, SUFFIX), void, env, Reg, Reg) 276 | DEF_HELPER_3v(glue(pabsd, SUFFIX), void, env, Reg, Reg) 277 | DEF_HELPER_3v(glue(pmaddubsw, SUFFIX), void, env, Reg, Reg) 278 | DEF_HELPER_3v(glue(pmulhrsw, SUFFIX), void, env, Reg, Reg) 279 | DEF_HELPER_3v(glue(pshufb, SUFFIX), void, env, Reg, Reg) 280 | DEF_HELPER_3v(glue(psignb, SUFFIX), void, env, Reg, Reg) 281 | DEF_HELPER_3v(glue(psignw, SUFFIX), void, env, Reg, Reg) 282 | DEF_HELPER_3v(glue(psignd, SUFFIX), void, env, Reg, Reg) 283 | DEF_HELPER_4v(glue(palignr, SUFFIX), void, env, Reg, Reg, s32) 284 | 285 | /* SSE4.1 op helpers */ 286 | #if SHIFT == 1 287 | DEF_HELPER_3v(glue(pblendvb, SUFFIX), void, env, Reg, Reg) 288 | DEF_HELPER_3v(glue(blendvps, SUFFIX), void, env, Reg, Reg) 289 | DEF_HELPER_3v(glue(blendvpd, SUFFIX), void, env, Reg, Reg) 290 | DEF_HELPER_3v(glue(ptest, SUFFIX), void, env, Reg, Reg) 291 | DEF_HELPER_3v(glue(pmovsxbw, SUFFIX), void, env, Reg, Reg) 292 | DEF_HELPER_3v(glue(pmovsxbd, SUFFIX), void, env, Reg, Reg) 293 | DEF_HELPER_3v(glue(pmovsxbq, SUFFIX), void, env, Reg, Reg) 294 | DEF_HELPER_3v(glue(pmovsxwd, SUFFIX), void, env, Reg, Reg) 295 | DEF_HELPER_3v(glue(pmovsxwq, SUFFIX), void, env, Reg, Reg) 296 | DEF_HELPER_3v(glue(pmovsxdq, SUFFIX), void, env, Reg, Reg) 297 | DEF_HELPER_3v(glue(pmovzxbw, SUFFIX), void, env, Reg, Reg) 298 | DEF_HELPER_3v(glue(pmovzxbd, SUFFIX), void, env, Reg, Reg) 299 | DEF_HELPER_3v(glue(pmovzxbq, SUFFIX), void, env, Reg, Reg) 300 | DEF_HELPER_3v(glue(pmovzxwd, SUFFIX), void, env, Reg, Reg) 301 | DEF_HELPER_3v(glue(pmovzxwq, SUFFIX), void, env, Reg, Reg) 302 | DEF_HELPER_3v(glue(pmovzxdq, SUFFIX), void, env, Reg, Reg) 303 | DEF_HELPER_3v(glue(pmuldq, SUFFIX), void, env, Reg, Reg) 304 | DEF_HELPER_3v(glue(pcmpeqq, SUFFIX), void, env, Reg, Reg) 305 | DEF_HELPER_3v(glue(packusdw, SUFFIX), void, env, Reg, Reg) 306 | DEF_HELPER_3v(glue(pminsb, SUFFIX), void, env, Reg, Reg) 307 | DEF_HELPER_3v(glue(pminsd, SUFFIX), void, env, Reg, Reg) 308 | DEF_HELPER_3v(glue(pminuw, SUFFIX), void, env, Reg, Reg) 309 | DEF_HELPER_3v(glue(pminud, SUFFIX), void, env, Reg, Reg) 310 | DEF_HELPER_3v(glue(pmaxsb, SUFFIX), void, env, Reg, Reg) 311 | DEF_HELPER_3v(glue(pmaxsd, SUFFIX), void, env, Reg, Reg) 312 | DEF_HELPER_3v(glue(pmaxuw, SUFFIX), void, env, Reg, Reg) 313 | DEF_HELPER_3v(glue(pmaxud, SUFFIX), void, env, Reg, Reg) 314 | DEF_HELPER_3v(glue(pmulld, SUFFIX), void, env, Reg, Reg) 315 | DEF_HELPER_3v(glue(phminposuw, SUFFIX), void, env, Reg, Reg) 316 | DEF_HELPER_4v(glue(roundps, SUFFIX), void, env, Reg, Reg, i32) 317 | DEF_HELPER_4v(glue(roundpd, SUFFIX), void, env, Reg, Reg, i32) 318 | DEF_HELPER_4v(glue(roundss, SUFFIX), void, env, Reg, Reg, i32) 319 | DEF_HELPER_4v(glue(roundsd, SUFFIX), void, env, Reg, Reg, i32) 320 | DEF_HELPER_4v(glue(blendps, SUFFIX), void, env, Reg, Reg, i32) 321 | DEF_HELPER_4v(glue(blendpd, SUFFIX), void, env, Reg, Reg, i32) 322 | DEF_HELPER_4v(glue(pblendw, SUFFIX), void, env, Reg, Reg, i32) 323 | DEF_HELPER_4v(glue(dpps, SUFFIX), void, env, Reg, Reg, i32) 324 | DEF_HELPER_4v(glue(dppd, SUFFIX), void, env, Reg, Reg, i32) 325 | DEF_HELPER_4v(glue(mpsadbw, SUFFIX), void, env, Reg, Reg, i32) 326 | #endif 327 | 328 | /* SSE4.2 op helpers */ 329 | #if SHIFT == 1 330 | DEF_HELPER_3v(glue(pcmpgtq, SUFFIX), void, env, Reg, Reg) 331 | DEF_HELPER_4v(glue(pcmpestri, SUFFIX), void, env, Reg, Reg, i32) 332 | DEF_HELPER_4v(glue(pcmpestrm, SUFFIX), void, env, Reg, Reg, i32) 333 | DEF_HELPER_4v(glue(pcmpistri, SUFFIX), void, env, Reg, Reg, i32) 334 | DEF_HELPER_4v(glue(pcmpistrm, SUFFIX), void, env, Reg, Reg, i32) 335 | DEF_HELPER_3(crc32, tl, i32, tl, i32) 336 | #endif 337 | 338 | /* AES-NI op helpers */ 339 | #if SHIFT == 1 340 | DEF_HELPER_3v(glue(aesdec, SUFFIX), void, env, Reg, Reg) 341 | DEF_HELPER_3v(glue(aesdeclast, SUFFIX), void, env, Reg, Reg) 342 | DEF_HELPER_3v(glue(aesenc, SUFFIX), void, env, Reg, Reg) 343 | DEF_HELPER_3v(glue(aesenclast, SUFFIX), void, env, Reg, Reg) 344 | DEF_HELPER_3v(glue(aesimc, SUFFIX), void, env, Reg, Reg) 345 | DEF_HELPER_4v(glue(aeskeygenassist, SUFFIX), void, env, Reg, Reg, i32) 346 | DEF_HELPER_4v(glue(pclmulqdq, SUFFIX), void, env, Reg, Reg, i32) 347 | #endif 348 | 349 | #undef SHIFT 350 | #undef Reg 351 | #undef SUFFIX 352 | 353 | #undef SSE_HELPER_B 354 | #undef SSE_HELPER_W 355 | #undef SSE_HELPER_L 356 | #undef SSE_HELPER_Q 357 | #undef SSE_HELPER_S 358 | #undef SSE_HELPER_CMP 359 | #undef UNPCK_OP 360 | -------------------------------------------------------------------------------- /include/lib/target/i386/translate.h: -------------------------------------------------------------------------------- 1 | #ifndef TARGET_I386_TRANSLATE_H 2 | #define TARGET_I386_TRANSLATE_H 3 | 4 | #include "lib/internal.h" 5 | #include "lib/target/i386/cpu.h" 6 | 7 | typedef struct DisasContext { 8 | /* current insn context */ 9 | int override; /* -1 if no override */ 10 | int prefix; 11 | TCGMemOp aflag; 12 | TCGMemOp dflag; 13 | target_ulong pc_start; 14 | target_ulong pc; /* pc = eip + cs_base */ 15 | int is_jmp; /* 1 = means jump (stop translation), 2 means CPU 16 | static state change (stop translation) */ 17 | /* current block context */ 18 | target_ulong cs_base; /* base of CS segment */ 19 | int pe; /* protected mode */ 20 | int code32; /* 32 bit code segment */ 21 | #ifdef TARGET_X86_64 22 | int lma; /* long mode active */ 23 | int code64; /* 64 bit code segment */ 24 | int rex_x, rex_b; 25 | #endif 26 | int vex_l; /* vex vector length */ 27 | int vex_v; /* vex vvvv register, without 1's compliment. */ 28 | int ss32; /* 32 bit stack segment */ 29 | CCOp cc_op; /* current CC operation */ 30 | int addseg; /* non zero if either DS/ES/SS have a non zero base */ 31 | int f_st; /* currently unused */ 32 | int vm86; /* vm86 mode */ 33 | int cpl; 34 | int iopl; 35 | int tf; /* TF cpu flag */ 36 | int singlestep_enabled; /* "hardware" single step enabled */ 37 | int jmp_opt; /* use direct block chaining for direct jumps */ 38 | int repz_opt; /* optimize jumps within repz instructions */ 39 | int mem_index; /* select memory access functions */ 40 | uint64_t flags; /* all execution flags */ 41 | struct TranslationBlock *tb; 42 | int popl_esp_hack; /* for correct popl with esp base handling */ 43 | int rip_offset; /* only used in x86_64, but left for simplicity */ 44 | int cpuid_features; 45 | int cpuid_ext_features; 46 | int cpuid_ext2_features; 47 | int cpuid_ext3_features; 48 | int cpuid_7_0_ebx_features; 49 | int cpuid_xsave_features; 50 | } DisasContext; 51 | 52 | void i386_translate_init(TCGContext * s); 53 | 54 | void gen_intermediate_code_i386(TCGContext * s, CPUX86State *cs, TranslationBlock *tb); 55 | 56 | #endif -------------------------------------------------------------------------------- /include/lib/tcg/helper-gen.h: -------------------------------------------------------------------------------- 1 | #ifndef _HELPER_GEN_H 2 | #define _HELPER_GEN_H 3 | 4 | #include "lib/tcg/helper-head.h" 5 | 6 | #define DEF_HELPER_FLAGS_0(name, flags, ret) \ 7 | static inline void glue(gen_helper_, name)(TCGContext *s, dh_retvar_decl0(ret)) \ 8 | { \ 9 | tcg_gen_callN(s, TCGHelpersIndex::HELPER_IDX(name), dh_retvar(ret), 0, NULL); \ 10 | } 11 | 12 | #define DEF_HELPER_FLAGS_0v DEF_HELPER_FLAGS_0 13 | 14 | #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \ 15 | static inline void glue(gen_helper_, name)(TCGContext *s, dh_retvar_decl(ret) \ 16 | dh_arg_decl(t1, 1)) \ 17 | { \ 18 | TCGArg args[1] = { dh_arg(t1, 1) }; \ 19 | tcg_gen_callN(s, TCGHelpersIndex::HELPER_IDX(name), dh_retvar(ret), 1, args); \ 20 | } 21 | 22 | #define DEF_HELPER_FLAGS_1v DEF_HELPER_FLAGS_1 23 | 24 | #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \ 25 | static inline void glue(gen_helper_, name)(TCGContext *s, dh_retvar_decl(ret) \ 26 | dh_arg_decl(t1, 1), dh_arg_decl(t2, 2)) \ 27 | { \ 28 | TCGArg args[2] = { dh_arg(t1, 1), dh_arg(t2, 2) }; \ 29 | tcg_gen_callN(s, TCGHelpersIndex::HELPER_IDX(name), dh_retvar(ret), 2, args); \ 30 | } 31 | 32 | #define DEF_HELPER_FLAGS_2v DEF_HELPER_FLAGS_2 33 | 34 | #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) \ 35 | static inline void glue(gen_helper_, name)(TCGContext *s, dh_retvar_decl(ret) \ 36 | dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \ 37 | { \ 38 | TCGArg args[3] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3) }; \ 39 | tcg_gen_callN(s, TCGHelpersIndex::HELPER_IDX(name), dh_retvar(ret), 3, args); \ 40 | } 41 | 42 | #define DEF_HELPER_FLAGS_3v DEF_HELPER_FLAGS_3 43 | 44 | #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \ 45 | static inline void glue(gen_helper_, name)(TCGContext *s, dh_retvar_decl(ret) \ 46 | dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), \ 47 | dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \ 48 | { \ 49 | TCGArg args[4] = { dh_arg(t1, 1), dh_arg(t2, 2), \ 50 | dh_arg(t3, 3), dh_arg(t4, 4) }; \ 51 | tcg_gen_callN(s, TCGHelpersIndex::HELPER_IDX(name), dh_retvar(ret), 4, args); \ 52 | } 53 | 54 | #define DEF_HELPER_FLAGS_4v DEF_HELPER_FLAGS_4 55 | 56 | #define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) \ 57 | static inline void glue(gen_helper_, name)(TCGContext *s, dh_retvar_decl(ret) \ 58 | dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \ 59 | dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \ 60 | { \ 61 | TCGArg args[5] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \ 62 | dh_arg(t4, 4), dh_arg(t5, 5) }; \ 63 | tcg_gen_callN(s, TCGHelpersIndex::HELPER_IDX(name), dh_retvar(ret), 5, args); \ 64 | } 65 | 66 | #define DEF_HELPER_FLAGS_5v DEF_HELPER_FLAGS_5 67 | 68 | #include "lib/tcg/helpers.h" 69 | 70 | #undef DEF_HELPER_FLAGS_0 71 | 72 | #undef DEF_HELPER_FLAGS_0v 73 | 74 | #undef DEF_HELPER_FLAGS_1 75 | 76 | #undef DEF_HELPER_FLAGS_1v 77 | 78 | #undef DEF_HELPER_FLAGS_2 79 | 80 | #undef DEF_HELPER_FLAGS_2v 81 | 82 | #undef DEF_HELPER_FLAGS_3 83 | 84 | #undef DEF_HELPER_FLAGS_3v 85 | 86 | #undef DEF_HELPER_FLAGS_4 87 | 88 | #undef DEF_HELPER_FLAGS_4v 89 | 90 | #undef DEF_HELPER_FLAGS_5 91 | 92 | #undef DEF_HELPER_FLAGS_5v 93 | 94 | #endif -------------------------------------------------------------------------------- /include/lib/tcg/helper-head.h: -------------------------------------------------------------------------------- 1 | #ifndef _HELPER_HEAD_H 2 | #define _HELPER_HEAD_H 3 | 4 | #include "lib/internal.h" 5 | #include "lib/tcg/tcg.h" 6 | #if defined(TARGET_ARM) || defined(TARGET_AARCH64) 7 | #include "lib/target/arm/cpu.h" 8 | #elif defined(TARGET_X86) || defined(TARGET_X86_64) 9 | #include "lib/target/i386/cpu.h" 10 | #endif 11 | 12 | #define HELPER(name) glue(helper_, name) 13 | 14 | #define HELPER_IDX(name) glue(helper_idx_, name) 15 | 16 | #define GET_TCGV_i32 GET_TCGV_I32 17 | #define GET_TCGV_i64 GET_TCGV_I64 18 | #define GET_TCGV_ptr GET_TCGV_PTR 19 | 20 | #define dh_alias_i32 i32 21 | #define dh_alias_s32 i32 22 | #define dh_alias_int i32 23 | #define dh_alias_i64 i64 24 | #define dh_alias_s64 i64 25 | #define dh_alias_f32 i32 26 | #define dh_alias_f64 i64 27 | #define dh_alias_ptr ptr 28 | #define dh_alias_void void 29 | #define dh_alias_noreturn noreturn 30 | #define dh_alias(t) glue(dh_alias_, t) 31 | 32 | #define dh_ctype_i32 uint32_t 33 | #define dh_ctype_s32 int32_t 34 | #define dh_ctype_int int 35 | #define dh_ctype_i64 uint64_t 36 | #define dh_ctype_s64 int64_t 37 | #define dh_ctype_f32 float32 38 | #define dh_ctype_f64 float64 39 | #define dh_ctype_ptr void * 40 | #define dh_ctype_void void 41 | #define dh_ctype_noreturn void QEMU_NORETURN 42 | #define dh_ctype(t) dh_ctype_##t 43 | 44 | #ifdef NEED_CPU_H 45 | # ifdef TARGET_LONG_BITS 46 | # if TARGET_LONG_BITS == 32 47 | # define dh_alias_tl i32 48 | # else 49 | # define dh_alias_tl i64 50 | # endif 51 | # endif 52 | # define dh_alias_env ptr 53 | # define dh_ctype_tl target_ulong 54 | # define dh_ctype_env CPUArchState * 55 | #endif 56 | 57 | #define dh_retvar_decl0_void void 58 | #define dh_retvar_decl0_noreturn void 59 | #define dh_retvar_decl0_i32 TCGv_i32 retval 60 | #define dh_retvar_decl0_i64 TCGv_i64 retval 61 | #define dh_retvar_decl0_ptr TCGv_ptr retval 62 | #define dh_retvar_decl0(t) glue(dh_retvar_decl0_, dh_alias(t)) 63 | 64 | #define dh_retvar_decl_void 65 | #define dh_retvar_decl_noreturn 66 | #define dh_retvar_decl_i32 TCGv_i32 retval, 67 | #define dh_retvar_decl_i64 TCGv_i64 retval, 68 | #define dh_retvar_decl_ptr TCGv_ptr retval, 69 | #define dh_retvar_decl(t) glue(dh_retvar_decl_, dh_alias(t)) 70 | 71 | #define dh_retvar_void TCG_CALL_DUMMY_ARG 72 | #define dh_retvar_noreturn TCG_CALL_DUMMY_ARG 73 | #define dh_retvar_i32 GET_TCGV_i32(retval) 74 | #define dh_retvar_i64 GET_TCGV_i64(retval) 75 | #define dh_retvar_ptr GET_TCGV_ptr(retval) 76 | #define dh_retvar(t) glue(dh_retvar_, dh_alias(t)) 77 | 78 | #define dh_is_64bit_void 0 79 | #define dh_is_64bit_noreturn 0 80 | #define dh_is_64bit_i32 0 81 | #define dh_is_64bit_i64 1 82 | #define dh_is_64bit_ptr (sizeof(void *) == 8) 83 | #define dh_is_64bit(t) glue(dh_is_64bit_, dh_alias(t)) 84 | 85 | #define dh_is_signed_void 0 86 | #define dh_is_signed_noreturn 0 87 | #define dh_is_signed_i32 0 88 | #define dh_is_signed_s32 1 89 | #define dh_is_signed_i64 0 90 | #define dh_is_signed_s64 1 91 | #define dh_is_signed_f32 0 92 | #define dh_is_signed_f64 0 93 | #define dh_is_signed_tl 0 94 | #define dh_is_signed_int 1 95 | #define dh_is_signed_ptr 0 96 | #define dh_is_signed_env dh_is_signed_ptr 97 | #define dh_is_signed(t) dh_is_signed_##t 98 | 99 | #define dh_sizemask(t, n) \ 100 | ((dh_is_64bit(t) << (n*2)) | (dh_is_signed(t) << (n*2+1))) 101 | 102 | #define dh_arg(t, n) \ 103 | glue(GET_TCGV_, dh_alias(t))(glue(arg, n)) 104 | 105 | #define dh_arg_decl(t, n) glue(TCGv_, dh_alias(t)) glue(arg, n) 106 | 107 | #define DEF_HELPER_0(name, ret) \ 108 | DEF_HELPER_FLAGS_0(name, 0, ret) 109 | 110 | #define DEF_HELPER_0v(name, ret) \ 111 | DEF_HELPER_FLAGS_0v(name, 0, ret) 112 | 113 | #define DEF_HELPER_1(name, ret, t1) \ 114 | DEF_HELPER_FLAGS_1(name, 0, ret, t1) 115 | 116 | #define DEF_HELPER_1v(name, ret, t1) \ 117 | DEF_HELPER_FLAGS_1v(name, 0, ret, t1) 118 | 119 | #define DEF_HELPER_2(name, ret, t1, t2) \ 120 | DEF_HELPER_FLAGS_2(name, 0, ret, t1, t2) 121 | 122 | #define DEF_HELPER_2v(name, ret, t1, t2) \ 123 | DEF_HELPER_FLAGS_2v(name, 0, ret, t1, t2) 124 | 125 | #define DEF_HELPER_3(name, ret, t1, t2, t3) \ 126 | DEF_HELPER_FLAGS_3(name, 0, ret, t1, t2, t3) 127 | 128 | #define DEF_HELPER_3v(name, ret, t1, t2, t3) \ 129 | DEF_HELPER_FLAGS_3v(name, 0, ret, t1, t2, t3) 130 | 131 | #define DEF_HELPER_4(name, ret, t1, t2, t3, t4) \ 132 | DEF_HELPER_FLAGS_4(name, 0, ret, t1, t2, t3, t4) 133 | 134 | #define DEF_HELPER_4v(name, ret, t1, t2, t3, t4) \ 135 | DEF_HELPER_FLAGS_4v(name, 0, ret, t1, t2, t3, t4) 136 | 137 | #define DEF_HELPER_5(name, ret, t1, t2, t3, t4, t5) \ 138 | DEF_HELPER_FLAGS_5(name, 0, ret, t1, t2, t3, t4, t5) 139 | 140 | #define DEF_HELPER_5v(name, ret, t1, t2, t3, t4, t5) \ 141 | DEF_HELPER_FLAGS_5v(name, 0, ret, t1, t2, t3, t4, t5) 142 | 143 | #endif -------------------------------------------------------------------------------- /include/lib/tcg/helper-proto.h: -------------------------------------------------------------------------------- 1 | #ifndef _HELPER_PROTO_H 2 | #define _HELPER_PROTO_H 3 | 4 | #include "lib/tcg/helper-head.h" 5 | 6 | #ifdef DEF_HELPER_PROTO_IMPL 7 | #define DEF_HELPER_BODY { return 0; }; 8 | #define DEF_HELPER_BODYv {}; 9 | #else 10 | #define DEF_HELPER_BODY ; 11 | #define DEF_HELPER_BODYv ; 12 | #endif 13 | 14 | #define DEF_HELPER_FLAGS_0(name, flags, ret) dh_ctype(ret) HELPER(name) DEF_HELPER_BODY 15 | 16 | #define DEF_HELPER_FLAGS_0v(name, flags, ret) dh_ctype(ret) HELPER(name) DEF_HELPER_BODYv 17 | 18 | #define DEF_HELPER_FLAGS_1(name, flags, ret, t1) dh_ctype(ret) HELPER(name) (dh_ctype(t1)) DEF_HELPER_BODY 19 | 20 | #define DEF_HELPER_FLAGS_1v(name, flags, ret, t1) dh_ctype(ret) HELPER(name) (dh_ctype(t1)) DEF_HELPER_BODYv 21 | 22 | #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)) DEF_HELPER_BODY 23 | 24 | #define DEF_HELPER_FLAGS_2v(name, flags, ret, t1, t2) dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2)) DEF_HELPER_BODYv 25 | 26 | #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3) dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3)) DEF_HELPER_BODY 27 | 28 | #define DEF_HELPER_FLAGS_3v(name, flags, ret, t1, t2, t3) dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3)) DEF_HELPER_BODYv 29 | 30 | #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), dh_ctype(t4)) DEF_HELPER_BODY 31 | 32 | #define DEF_HELPER_FLAGS_4v(name, flags, ret, t1, t2, t3, t4) dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), dh_ctype(t4)) DEF_HELPER_BODYv 33 | 34 | #define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5) dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), dh_ctype(t4), dh_ctype(t5)) DEF_HELPER_BODY 35 | 36 | #define DEF_HELPER_FLAGS_5v(name, flags, ret, t1, t2, t3, t4, t5) dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), dh_ctype(t4), dh_ctype(t5)) DEF_HELPER_BODYv 37 | 38 | #include "lib/tcg/helpers.h" 39 | 40 | #undef DEF_HELPER_BODY 41 | 42 | #undef DEF_HELPER_BODYv 43 | 44 | #undef DEF_HELPER_PROTO_IMPL 45 | 46 | #undef DEF_HELPER_FLAGS_0 47 | 48 | #undef DEF_HELPER_FLAGS_0v 49 | 50 | #undef DEF_HELPER_FLAGS_1 51 | 52 | #undef DEF_HELPER_FLAGS_1v 53 | 54 | #undef DEF_HELPER_FLAGS_2 55 | 56 | #undef DEF_HELPER_FLAGS_2v 57 | 58 | #undef DEF_HELPER_FLAGS_3 59 | 60 | #undef DEF_HELPER_FLAGS_3v 61 | 62 | #undef DEF_HELPER_FLAGS_4 63 | 64 | #undef DEF_HELPER_FLAGS_4v 65 | 66 | #undef DEF_HELPER_FLAGS_5 67 | 68 | #undef DEF_HELPER_FLAGS_5v 69 | 70 | #endif -------------------------------------------------------------------------------- /include/lib/tcg/helper-tcg.h: -------------------------------------------------------------------------------- 1 | #ifndef _HELPER_TCG_H 2 | #define _HELPER_TCG_H 3 | 4 | #include "lib/tcg/helper-head.h" 5 | 6 | #define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) { HELPER(NAME), tostring(NAME), FLAGS, dh_sizemask(ret, 0) }, 7 | 8 | #define DEF_HELPER_FLAGS_0v DEF_HELPER_FLAGS_0 9 | 10 | #define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) { HELPER(NAME), tostring(NAME), FLAGS, dh_sizemask(ret, 0) | dh_sizemask(t1, 1) }, 11 | 12 | #define DEF_HELPER_FLAGS_1v DEF_HELPER_FLAGS_1 13 | 14 | #define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) { HELPER(NAME), tostring(NAME), FLAGS, dh_sizemask(ret, 0) | dh_sizemask(t1, 1) | dh_sizemask(t2, 2) }, 15 | 16 | #define DEF_HELPER_FLAGS_2v DEF_HELPER_FLAGS_2 17 | 18 | #define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) { HELPER(NAME), tostring(NAME), FLAGS, dh_sizemask(ret, 0) | dh_sizemask(t1, 1) | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) }, 19 | 20 | #define DEF_HELPER_FLAGS_3v DEF_HELPER_FLAGS_3 21 | 22 | #define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) { HELPER(NAME), tostring(NAME), FLAGS, dh_sizemask(ret, 0) | dh_sizemask(t1, 1) | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) }, 23 | 24 | #define DEF_HELPER_FLAGS_4v DEF_HELPER_FLAGS_4 25 | 26 | #define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) { HELPER(NAME), tostring(NAME), FLAGS, dh_sizemask(ret, 0) | dh_sizemask(t1, 1) | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) | dh_sizemask(t5, 5) }, 27 | 28 | #define DEF_HELPER_FLAGS_5v DEF_HELPER_FLAGS_5 29 | 30 | #include "lib/tcg/helpers.h" 31 | 32 | #undef DEF_HELPER_FLAGS_0 33 | 34 | #undef DEF_HELPER_FLAGS_0v 35 | 36 | #undef DEF_HELPER_FLAGS_1 37 | 38 | #undef DEF_HELPER_FLAGS_1v 39 | 40 | #undef DEF_HELPER_FLAGS_2 41 | 42 | #undef DEF_HELPER_FLAGS_2v 43 | 44 | #undef DEF_HELPER_FLAGS_3 45 | 46 | #undef DEF_HELPER_FLAGS_3v 47 | 48 | #undef DEF_HELPER_FLAGS_4 49 | 50 | #undef DEF_HELPER_FLAGS_4v 51 | 52 | #undef DEF_HELPER_FLAGS_5 53 | 54 | #undef DEF_HELPER_FLAGS_5v 55 | 56 | #endif -------------------------------------------------------------------------------- /include/lib/tcg/helpers-index.h: -------------------------------------------------------------------------------- 1 | #include "lib/tcg/helper-head.h" 2 | 3 | #define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) HELPER_IDX(NAME), 4 | 5 | #define DEF_HELPER_FLAGS_0v DEF_HELPER_FLAGS_0 6 | 7 | #define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) HELPER_IDX(NAME), 8 | 9 | #define DEF_HELPER_FLAGS_1v DEF_HELPER_FLAGS_1 10 | 11 | #define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) HELPER_IDX(NAME), 12 | 13 | #define DEF_HELPER_FLAGS_2v DEF_HELPER_FLAGS_2 14 | 15 | #define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) HELPER_IDX(NAME), 16 | 17 | #define DEF_HELPER_FLAGS_3v DEF_HELPER_FLAGS_3 18 | 19 | #define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) HELPER_IDX(NAME), 20 | 21 | #define DEF_HELPER_FLAGS_4v DEF_HELPER_FLAGS_4 22 | 23 | #define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) HELPER_IDX(NAME), 24 | 25 | #define DEF_HELPER_FLAGS_5v DEF_HELPER_FLAGS_5 26 | 27 | #include "lib/tcg/helpers.h" 28 | 29 | #undef DEF_HELPER_FLAGS_0 30 | 31 | #undef DEF_HELPER_FLAGS_0v 32 | 33 | #undef DEF_HELPER_FLAGS_1 34 | 35 | #undef DEF_HELPER_FLAGS_1v 36 | 37 | #undef DEF_HELPER_FLAGS_2 38 | 39 | #undef DEF_HELPER_FLAGS_2v 40 | 41 | #undef DEF_HELPER_FLAGS_3 42 | 43 | #undef DEF_HELPER_FLAGS_3v 44 | 45 | #undef DEF_HELPER_FLAGS_4 46 | 47 | #undef DEF_HELPER_FLAGS_4v 48 | 49 | #undef DEF_HELPER_FLAGS_5 50 | 51 | #undef DEF_HELPER_FLAGS_5v 52 | -------------------------------------------------------------------------------- /include/lib/tcg/helpers.h: -------------------------------------------------------------------------------- 1 | DEF_HELPER_FLAGS_2(div_i32, TCG_CALL_NO_RWG_SE, s32, s32, s32) 2 | DEF_HELPER_FLAGS_2(rem_i32, TCG_CALL_NO_RWG_SE, s32, s32, s32) 3 | DEF_HELPER_FLAGS_2(divu_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32) 4 | DEF_HELPER_FLAGS_2(remu_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32) 5 | 6 | DEF_HELPER_FLAGS_2(div_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64) 7 | DEF_HELPER_FLAGS_2(rem_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64) 8 | DEF_HELPER_FLAGS_2(divu_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) 9 | DEF_HELPER_FLAGS_2(remu_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) 10 | 11 | DEF_HELPER_FLAGS_2(shl_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) 12 | DEF_HELPER_FLAGS_2(shr_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) 13 | DEF_HELPER_FLAGS_2(sar_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64) 14 | 15 | DEF_HELPER_FLAGS_2(mulsh_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64) 16 | DEF_HELPER_FLAGS_2(muluh_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) 17 | 18 | DEF_HELPER_FLAGS_2(clz_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32) 19 | DEF_HELPER_FLAGS_2(ctz_i32, TCG_CALL_NO_RWG_SE, i32, i32, i32) 20 | DEF_HELPER_FLAGS_2(clz_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) 21 | DEF_HELPER_FLAGS_2(ctz_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64) 22 | DEF_HELPER_FLAGS_1(clrsb_i32, TCG_CALL_NO_RWG_SE, i32, i32) 23 | DEF_HELPER_FLAGS_1(clrsb_i64, TCG_CALL_NO_RWG_SE, i64, i64) 24 | DEF_HELPER_FLAGS_1(ctpop_i32, TCG_CALL_NO_RWG_SE, i32, i32) 25 | DEF_HELPER_FLAGS_1(ctpop_i64, TCG_CALL_NO_RWG_SE, i64, i64) 26 | 27 | DEF_HELPER_FLAGS_2(lookup_tb_ptr, TCG_CALL_NO_WG_SE, ptr, env, tl) 28 | 29 | DEF_HELPER_FLAGS_1v(exit_atomic, TCG_CALL_NO_WG, noreturn, env) 30 | 31 | #ifdef CONFIG_SOFTMMU 32 | 33 | DEF_HELPER_FLAGS_5(atomic_cmpxchgb, TCG_CALL_NO_WG, 34 | i32, env, tl, i32, i32, i32) 35 | DEF_HELPER_FLAGS_5(atomic_cmpxchgw_be, TCG_CALL_NO_WG, 36 | i32, env, tl, i32, i32, i32) 37 | DEF_HELPER_FLAGS_5(atomic_cmpxchgw_le, TCG_CALL_NO_WG, 38 | i32, env, tl, i32, i32, i32) 39 | DEF_HELPER_FLAGS_5(atomic_cmpxchgl_be, TCG_CALL_NO_WG, 40 | i32, env, tl, i32, i32, i32) 41 | DEF_HELPER_FLAGS_5(atomic_cmpxchgl_le, TCG_CALL_NO_WG, 42 | i32, env, tl, i32, i32, i32) 43 | #ifdef CONFIG_ATOMIC64 44 | DEF_HELPER_FLAGS_5(atomic_cmpxchgq_be, TCG_CALL_NO_WG, 45 | i64, env, tl, i64, i64, i32) 46 | DEF_HELPER_FLAGS_5(atomic_cmpxchgq_le, TCG_CALL_NO_WG, 47 | i64, env, tl, i64, i64, i32) 48 | #endif 49 | 50 | #ifdef CONFIG_ATOMIC64 51 | #define GEN_ATOMIC_HELPERS(NAME) \ 52 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), b), \ 53 | TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ 54 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_le), \ 55 | TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ 56 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_be), \ 57 | TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ 58 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_le), \ 59 | TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ 60 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_be), \ 61 | TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ 62 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), q_le), \ 63 | TCG_CALL_NO_WG, i64, env, tl, i64, i32) \ 64 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), q_be), \ 65 | TCG_CALL_NO_WG, i64, env, tl, i64, i32) 66 | #else 67 | #define GEN_ATOMIC_HELPERS(NAME) \ 68 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), b), \ 69 | TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ 70 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_le), \ 71 | TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ 72 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), w_be), \ 73 | TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ 74 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_le), \ 75 | TCG_CALL_NO_WG, i32, env, tl, i32, i32) \ 76 | DEF_HELPER_FLAGS_4(glue(glue(atomic_, NAME), l_be), \ 77 | TCG_CALL_NO_WG, i32, env, tl, i32, i32) 78 | #endif 79 | 80 | #else 81 | 82 | DEF_HELPER_FLAGS_4(atomic_cmpxchgb, TCG_CALL_NO_WG, i32, env, tl, i32, i32) 83 | DEF_HELPER_FLAGS_4(atomic_cmpxchgw_be, TCG_CALL_NO_WG, i32, env, tl, i32, i32) 84 | DEF_HELPER_FLAGS_4(atomic_cmpxchgw_le, TCG_CALL_NO_WG, i32, env, tl, i32, i32) 85 | DEF_HELPER_FLAGS_4(atomic_cmpxchgl_be, TCG_CALL_NO_WG, i32, env, tl, i32, i32) 86 | DEF_HELPER_FLAGS_4(atomic_cmpxchgl_le, TCG_CALL_NO_WG, i32, env, tl, i32, i32) 87 | #ifdef CONFIG_ATOMIC64 88 | DEF_HELPER_FLAGS_4(atomic_cmpxchgq_be, TCG_CALL_NO_WG, i64, env, tl, i64, i64) 89 | DEF_HELPER_FLAGS_4(atomic_cmpxchgq_le, TCG_CALL_NO_WG, i64, env, tl, i64, i64) 90 | #endif 91 | 92 | #ifdef CONFIG_ATOMIC64 93 | #define GEN_ATOMIC_HELPERS(NAME) \ 94 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), b), \ 95 | TCG_CALL_NO_WG, i32, env, tl, i32) \ 96 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), w_le), \ 97 | TCG_CALL_NO_WG, i32, env, tl, i32) \ 98 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), w_be), \ 99 | TCG_CALL_NO_WG, i32, env, tl, i32) \ 100 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), l_le), \ 101 | TCG_CALL_NO_WG, i32, env, tl, i32) \ 102 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), l_be), \ 103 | TCG_CALL_NO_WG, i32, env, tl, i32) \ 104 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), q_le), \ 105 | TCG_CALL_NO_WG, i64, env, tl, i64) \ 106 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), q_be), \ 107 | TCG_CALL_NO_WG, i64, env, tl, i64) 108 | #else 109 | #define GEN_ATOMIC_HELPERS(NAME) \ 110 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), b), \ 111 | TCG_CALL_NO_WG, i32, env, tl, i32) \ 112 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), w_le), \ 113 | TCG_CALL_NO_WG, i32, env, tl, i32) \ 114 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), w_be), \ 115 | TCG_CALL_NO_WG, i32, env, tl, i32) \ 116 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), l_le), \ 117 | TCG_CALL_NO_WG, i32, env, tl, i32) \ 118 | DEF_HELPER_FLAGS_3(glue(glue(atomic_, NAME), l_be), \ 119 | TCG_CALL_NO_WG, i32, env, tl, i32) 120 | #endif 121 | 122 | #endif 123 | 124 | GEN_ATOMIC_HELPERS(fetch_add) 125 | GEN_ATOMIC_HELPERS(fetch_and) 126 | GEN_ATOMIC_HELPERS(fetch_or) 127 | GEN_ATOMIC_HELPERS(fetch_xor) 128 | 129 | GEN_ATOMIC_HELPERS(add_fetch) 130 | GEN_ATOMIC_HELPERS(and_fetch) 131 | GEN_ATOMIC_HELPERS(or_fetch) 132 | GEN_ATOMIC_HELPERS(xor_fetch) 133 | 134 | GEN_ATOMIC_HELPERS(xchg) 135 | 136 | #undef GEN_ATOMIC_HELPERS 137 | 138 | #if defined(TARGET_ARM) || defined(TARGET_AARCH64) 139 | #include "lib/target/arm/helpers-arm.h" 140 | #endif 141 | 142 | #if defined(TARGET_AARCH64) 143 | #include "lib/target/arm/helper-a64.h" 144 | #endif 145 | 146 | #if defined(TARGET_X86) || defined(TARGET_X86_64) 147 | #include "lib/target/i386/helpers-i386.h" 148 | 149 | #endif -------------------------------------------------------------------------------- /include/lib/tcg/tcg-common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny Code Generator for QEMU 3 | * 4 | * Copyright (c) 2008 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifndef _TCG_COMMON_H 26 | #define _TCG_COMMON_H 27 | 28 | #include 29 | 30 | #include "lib/tcg/tcg-target.h" 31 | 32 | typedef void*(__cdecl * TCG_FUNC_MALLOC)(size_t); 33 | 34 | typedef void(__cdecl * TCG_FUNC_FREE)(void *); 35 | 36 | /* Helper does not read globals (either directly or through an exception). It 37 | implies TCG_CALL_NO_WRITE_GLOBALS. */ 38 | #define TCG_CALL_NO_READ_GLOBALS 0x0010 39 | /* Helper does not write globals */ 40 | #define TCG_CALL_NO_WRITE_GLOBALS 0x0020 41 | /* Helper can be safely suppressed if the return value is not used. */ 42 | #define TCG_CALL_NO_SIDE_EFFECTS 0x0040 43 | 44 | #define TCG_MAX_OP_ARGS 16 45 | 46 | /* Bits for TCGOpDef->flags, 8 bits available. */ 47 | typedef enum TCGOpFlags : uint8_t { 48 | TCG_OPF_NONE = 0x0, 49 | /* Instruction defines the end of a basic block. */ 50 | TCG_OPF_BB_END = 0x01, 51 | /* Instruction clobbers call registers and potentially update globals. */ 52 | TCG_OPF_CALL_CLOBBER = 0x02, 53 | /* Instruction has side effects: it cannot be removed if its outputs 54 | are not used, and might trigger exceptions. */ 55 | TCG_OPF_SIDE_EFFECTS = 0x04, 56 | /* Instruction operands are 64-bits (otherwise 32-bits). */ 57 | TCG_OPF_64BIT = 0x08, 58 | /* Instruction is optional and not implemented by the host, or insn 59 | is generic and should not be implemened by the host. */ 60 | TCG_OPF_NOT_PRESENT = 0x10, 61 | } TCGOpFlags; 62 | 63 | typedef enum TCGOpcode : unsigned char { 64 | #define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name, 65 | #include "lib/tcg/tcg-opc.h" 66 | #undef DEF 67 | NB_OPS, 68 | } TCGOpcode; 69 | 70 | /* Conditions. Note that these are laid out for easy manipulation by 71 | the functions below: 72 | bit 0 is used for inverting; 73 | bit 1 is signed, 74 | bit 2 is unsigned, 75 | bit 3 is used with bit 0 for swapping signed/unsigned. */ 76 | typedef enum TCGCond : unsigned char { 77 | /* non-signed */ 78 | TCG_COND_NEVER = 0 | 0 | 0 | 0, 79 | TCG_COND_ALWAYS = 0 | 0 | 0 | 1, 80 | TCG_COND_EQ = 8 | 0 | 0 | 0, 81 | TCG_COND_NE = 8 | 0 | 0 | 1, 82 | /* signed */ 83 | TCG_COND_LT = 0 | 0 | 2 | 0, 84 | TCG_COND_GE = 0 | 0 | 2 | 1, 85 | TCG_COND_LE = 8 | 0 | 2 | 0, 86 | TCG_COND_GT = 8 | 0 | 2 | 1, 87 | /* unsigned */ 88 | TCG_COND_LTU = 0 | 4 | 0 | 0, 89 | TCG_COND_GEU = 0 | 4 | 0 | 1, 90 | TCG_COND_LEU = 8 | 4 | 0 | 0, 91 | TCG_COND_GTU = 8 | 4 | 0 | 1, 92 | /* invalid (all bits set) */ 93 | TCG_COND_INVALID = 8 | 4 | 2 | 1 94 | } TCGCond; 95 | 96 | typedef enum TCGBar : unsigned char { 97 | /* Used to indicate the type of accesses on which ordering 98 | is to be ensured. Modeled after SPARC barriers. 99 | 100 | This is of the form TCG_MO_A_B where A is before B in program order. 101 | */ 102 | TCG_MO_LD_LD = 0x01, 103 | TCG_MO_ST_LD = 0x02, 104 | TCG_MO_LD_ST = 0x04, 105 | TCG_MO_ST_ST = 0x08, 106 | TCG_MO_ALL = 0x0F, /* OR of the above */ 107 | 108 | /* Used to indicate the kind of ordering which is to be ensured by the 109 | instruction. These types are derived from x86/aarch64 instructions. 110 | It should be noted that these are different from C11 semantics. */ 111 | TCG_BAR_LDAQ = 0x10, /* Following ops will not come forward */ 112 | TCG_BAR_STRL = 0x20, /* Previous ops will not be delayed */ 113 | TCG_BAR_SC = 0x30, /* No ops cross barrier; OR of the above */ 114 | } TCGBar; 115 | 116 | /* Constants for qemu_ld and qemu_st for the Memory Operation field. */ 117 | typedef enum TCGMemOp : unsigned char { 118 | MO_8 = 0, 119 | MO_16 = 1, 120 | MO_32 = 2, 121 | MO_64 = 3, 122 | MO_SIZE = 3, /* Mask for the above. */ 123 | 124 | MO_SIGN = 4, /* Sign-extended, otherwise zero-extended. */ 125 | 126 | MO_BSWAP = 8, /* Host reverse endian. */ 127 | #ifdef HOST_WORDS_BIGENDIAN 128 | MO_LE = MO_BSWAP, 129 | MO_BE = 0, 130 | #else 131 | MO_LE = 0, 132 | MO_BE = MO_BSWAP, 133 | #endif 134 | #ifdef TARGET_WORDS_BIGENDIAN 135 | MO_TE = MO_BE, 136 | #else 137 | MO_TE = MO_LE, 138 | #endif 139 | 140 | /* MO_UNALN accesses are never checked for alignment. 141 | * MO_ALIGN accesses will result in a call to the CPU's 142 | * do_unaligned_access hook if the guest address is not aligned. 143 | * The default depends on whether the target CPU defines ALIGNED_ONLY. 144 | * 145 | * Some architectures (e.g. ARMv8) need the address which is aligned 146 | * to a size more than the size of the memory access. 147 | * Some architectures (e.g. SPARCv9) need an address which is aligned, 148 | * but less strictly than the natural alignment. 149 | * 150 | * MO_ALIGN supposes the alignment size is the size of a memory access. 151 | * 152 | * There are three options: 153 | * - unaligned access permitted (MO_UNALN). 154 | * - an alignment to the size of an access (MO_ALIGN); 155 | * - an alignment to a specified size, which may be more or less than 156 | * the access size (MO_ALIGN_x where 'x' is a size in bytes); 157 | */ 158 | MO_ASHIFT = 4, 159 | MO_AMASK = 7 << MO_ASHIFT, 160 | #ifdef ALIGNED_ONLY 161 | MO_ALIGN = 0, 162 | MO_UNALN = MO_AMASK, 163 | #else 164 | MO_ALIGN = MO_AMASK, 165 | MO_UNALN = 0, 166 | #endif 167 | MO_ALIGN_2 = 1 << MO_ASHIFT, 168 | MO_ALIGN_4 = 2 << MO_ASHIFT, 169 | MO_ALIGN_8 = 3 << MO_ASHIFT, 170 | MO_ALIGN_16 = 4 << MO_ASHIFT, 171 | MO_ALIGN_32 = 5 << MO_ASHIFT, 172 | MO_ALIGN_64 = 6 << MO_ASHIFT, 173 | 174 | /* Combinations of the above, for ease of use. */ 175 | MO_UB = MO_8, 176 | MO_UW = MO_16, 177 | MO_UL = MO_32, 178 | MO_SB = MO_SIGN | MO_8, 179 | MO_SW = MO_SIGN | MO_16, 180 | MO_SL = MO_SIGN | MO_32, 181 | MO_Q = MO_64, 182 | 183 | MO_LEUW = MO_LE | MO_UW, 184 | MO_LEUL = MO_LE | MO_UL, 185 | MO_LESW = MO_LE | MO_SW, 186 | MO_LESL = MO_LE | MO_SL, 187 | MO_LEQ = MO_LE | MO_Q, 188 | 189 | MO_BEUW = MO_BE | MO_UW, 190 | MO_BEUL = MO_BE | MO_UL, 191 | MO_BESW = MO_BE | MO_SW, 192 | MO_BESL = MO_BE | MO_SL, 193 | MO_BEQ = MO_BE | MO_Q, 194 | 195 | MO_TEUW = MO_TE | MO_UW, 196 | MO_TEUL = MO_TE | MO_UL, 197 | MO_TESW = MO_TE | MO_SW, 198 | MO_TESL = MO_TE | MO_SL, 199 | MO_TEQ = MO_TE | MO_Q, 200 | 201 | MO_SSIZE = MO_SIZE | MO_SIGN, 202 | 203 | MO_UNKNOWN 204 | 205 | } TCGMemOp; 206 | 207 | typedef enum TCGRegType : unsigned char 208 | { 209 | TCG_REG_UNKNOWN = 0, 210 | TCG_REG_GLOBAL, 211 | TCG_REG_LOCAL, 212 | TCG_REG_TEMP 213 | } TCGRegType; 214 | 215 | typedef enum TCGArgAccess : unsigned char 216 | { 217 | TCG_ACCESS_UNKNOWN = 0, 218 | TCG_ACCESS_READ, 219 | TCG_ACCESS_WRITE 220 | } TCGArgAccess; 221 | 222 | typedef enum TCGArgType : unsigned char 223 | { 224 | TCG_TYPE_UNKNOWN = 0, 225 | TCG_TYPE_REGISTER, 226 | TCG_TYPE_CONSTANT, 227 | // A TCG_TYPE_CONSTANT may be one of the following depending on the opc. 228 | TCG_TYPE_BAR, 229 | TCG_TYPE_COND, 230 | TCG_TYPE_MEMOP, 231 | TCG_TYPE_LABEL, 232 | TCG_TYPE_HELPER, 233 | TCG_TYPE_IMMEDIATE, 234 | // Reserved for future use 235 | TCG_TYPE_RESERVED1, 236 | TCG_TYPE_RESERVED2, 237 | TCG_TYPE_RESERVED3, 238 | TCG_TYPE_RESERVED4, 239 | TCG_TYPE_RESERVED5, 240 | TCG_TYPE_RESERVED6, 241 | TCG_TYPE_RESERVED7, 242 | TCG_TYPE_RESERVED8 243 | } TCGArgType; 244 | 245 | typedef enum TCGArch : unsigned char { 246 | TCG_ARCH_UNKNOWN = 0, 247 | TCG_ARCH_ARM, 248 | TCG_ARCH_AARCH64, 249 | TCG_ARCH_X86, 250 | TCG_ARCH_X64 251 | } TCGArch; 252 | 253 | #endif -------------------------------------------------------------------------------- /include/lib/tcg/tcg-opc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny Code Generator for QEMU 3 | * 4 | * Copyright (c) 2008 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | /* 26 | * DEF(name, oargs, iargs, cargs, flags) 27 | */ 28 | 29 | #define IMPL(X) (__builtin_constant_p(X) && !(X) ? TCG_OPF_NOT_PRESENT : 0) 30 | #if TCG_TARGET_REG_BITS == 32 31 | # define IMPL64 TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT 32 | #else 33 | # define IMPL64 TCG_OPF_64BIT 34 | #endif 35 | 36 | /* predefined ops */ 37 | DEF(discard, 1, 0, 0, TCG_OPF_NOT_PRESENT) 38 | DEF(set_label, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT) 39 | /* variable number of parameters */ 40 | DEF(call, 0, 0, 3, TCG_OPF_CALL_CLOBBER | TCG_OPF_NOT_PRESENT) 41 | DEF(br, 0, 0, 1, TCG_OPF_BB_END) 42 | DEF(mb, 0, 0, 1, 0) 43 | DEF(mov_i32, 1, 1, 0, TCG_OPF_NOT_PRESENT) 44 | DEF(movi_i32, 1, 0, 1, TCG_OPF_NOT_PRESENT) 45 | DEF(setcond_i32, 1, 2, 1, 0) 46 | DEF(movcond_i32, 1, 4, 1, IMPL(TCG_TARGET_HAS_movcond_i32)) 47 | /* load/store */ 48 | DEF(ld8u_i32, 1, 1, 1, 0) 49 | DEF(ld8s_i32, 1, 1, 1, 0) 50 | DEF(ld16u_i32, 1, 1, 1, 0) 51 | DEF(ld16s_i32, 1, 1, 1, 0) 52 | DEF(ld_i32, 1, 1, 1, 0) 53 | DEF(st8_i32, 0, 2, 1, 0) 54 | DEF(st16_i32, 0, 2, 1, 0) 55 | DEF(st_i32, 0, 2, 1, 0) 56 | /* arith */ 57 | DEF(add_i32, 1, 2, 0, 0) 58 | DEF(sub_i32, 1, 2, 0, 0) 59 | DEF(mul_i32, 1, 2, 0, 0) 60 | DEF(div_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32)) 61 | DEF(divu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32)) 62 | DEF(rem_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rem_i32)) 63 | DEF(remu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rem_i32)) 64 | DEF(div2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32)) 65 | DEF(divu2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32)) 66 | DEF(and_i32, 1, 2, 0, 0) 67 | DEF(or_i32, 1, 2, 0, 0) 68 | DEF(xor_i32, 1, 2, 0, 0) 69 | /* shifts/rotates */ 70 | DEF(shl_i32, 1, 2, 0, 0) 71 | DEF(shr_i32, 1, 2, 0, 0) 72 | DEF(sar_i32, 1, 2, 0, 0) 73 | DEF(rotl_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32)) 74 | DEF(rotr_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32)) 75 | DEF(deposit_i32, 1, 2, 2, IMPL(TCG_TARGET_HAS_deposit_i32)) 76 | DEF(extract_i32, 1, 1, 2, IMPL(TCG_TARGET_HAS_extract_i32)) 77 | DEF(sextract_i32, 1, 1, 2, IMPL(TCG_TARGET_HAS_sextract_i32)) 78 | DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END) 79 | DEF(add2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_add2_i32)) 80 | DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_sub2_i32)) 81 | DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_mulu2_i32)) 82 | DEF(muls2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_muls2_i32)) 83 | DEF(muluh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i32)) 84 | DEF(mulsh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i32)) 85 | DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | IMPL(TCG_TARGET_REG_BITS == 32)) 86 | DEF(setcond2_i32, 1, 4, 1, IMPL(TCG_TARGET_REG_BITS == 32)) 87 | DEF(ext8s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8s_i32)) 88 | DEF(ext16s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext16s_i32)) 89 | DEF(ext8u_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8u_i32)) 90 | DEF(ext16u_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext16u_i32)) 91 | DEF(bswap16_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_bswap16_i32)) 92 | DEF(bswap32_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_bswap32_i32)) 93 | DEF(not_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_not_i32)) 94 | DEF(neg_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_neg_i32)) 95 | DEF(andc_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_andc_i32)) 96 | DEF(orc_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_orc_i32)) 97 | DEF(eqv_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_eqv_i32)) 98 | DEF(nand_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nand_i32)) 99 | DEF(nor_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nor_i32)) 100 | DEF(clz_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_clz_i32)) 101 | DEF(ctz_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_ctz_i32)) 102 | DEF(ctpop_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ctpop_i32)) 103 | DEF(mov_i64, 1, 1, 0, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT) 104 | DEF(movi_i64, 1, 0, 1, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT) 105 | DEF(setcond_i64, 1, 2, 1, IMPL64) 106 | DEF(movcond_i64, 1, 4, 1, IMPL64 | IMPL(TCG_TARGET_HAS_movcond_i64)) 107 | /* load/store */ 108 | DEF(ld8u_i64, 1, 1, 1, IMPL64) 109 | DEF(ld8s_i64, 1, 1, 1, IMPL64) 110 | DEF(ld16u_i64, 1, 1, 1, IMPL64) 111 | DEF(ld16s_i64, 1, 1, 1, IMPL64) 112 | DEF(ld32u_i64, 1, 1, 1, IMPL64) 113 | DEF(ld32s_i64, 1, 1, 1, IMPL64) 114 | DEF(ld_i64, 1, 1, 1, IMPL64) 115 | DEF(st8_i64, 0, 2, 1, IMPL64) 116 | DEF(st16_i64, 0, 2, 1, IMPL64) 117 | DEF(st32_i64, 0, 2, 1, IMPL64) 118 | DEF(st_i64, 0, 2, 1, IMPL64) 119 | /* arith */ 120 | DEF(add_i64, 1, 2, 0, IMPL64) 121 | DEF(sub_i64, 1, 2, 0, IMPL64) 122 | DEF(mul_i64, 1, 2, 0, IMPL64) 123 | DEF(div_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64)) 124 | DEF(divu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64)) 125 | DEF(rem_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rem_i64)) 126 | DEF(remu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rem_i64)) 127 | DEF(div2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64)) 128 | DEF(divu2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64)) 129 | DEF(and_i64, 1, 2, 0, IMPL64) 130 | DEF(or_i64, 1, 2, 0, IMPL64) 131 | DEF(xor_i64, 1, 2, 0, IMPL64) 132 | /* shifts/rotates */ 133 | DEF(shl_i64, 1, 2, 0, IMPL64) 134 | DEF(shr_i64, 1, 2, 0, IMPL64) 135 | DEF(sar_i64, 1, 2, 0, IMPL64) 136 | DEF(rotl_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64)) 137 | DEF(rotr_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64)) 138 | DEF(deposit_i64, 1, 2, 2, IMPL64 | IMPL(TCG_TARGET_HAS_deposit_i64)) 139 | DEF(extract_i64, 1, 1, 2, IMPL64 | IMPL(TCG_TARGET_HAS_extract_i64)) 140 | DEF(sextract_i64, 1, 1, 2, IMPL64 | IMPL(TCG_TARGET_HAS_sextract_i64)) 141 | /* size changing ops */ 142 | DEF(ext_i32_i64, 1, 1, 0, IMPL64) 143 | DEF(extu_i32_i64, 1, 1, 0, IMPL64) 144 | DEF(extrl_i64_i32, 1, 1, 0,IMPL(TCG_TARGET_HAS_extrl_i64_i32)| (TCG_TARGET_REG_BITS == 32 ? TCG_OPF_NOT_PRESENT : 0)) 145 | DEF(extrh_i64_i32, 1, 1, 0,IMPL(TCG_TARGET_HAS_extrh_i64_i32)| (TCG_TARGET_REG_BITS == 32 ? TCG_OPF_NOT_PRESENT : 0)) 146 | DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | IMPL64) 147 | DEF(ext8s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8s_i64)) 148 | DEF(ext16s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16s_i64)) 149 | DEF(ext32s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32s_i64)) 150 | DEF(ext8u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8u_i64)) 151 | DEF(ext16u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16u_i64)) 152 | DEF(ext32u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32u_i64)) 153 | DEF(bswap16_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_bswap16_i64)) 154 | DEF(bswap32_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_bswap32_i64)) 155 | DEF(bswap64_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_bswap64_i64)) 156 | DEF(not_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_not_i64)) 157 | DEF(neg_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_neg_i64)) 158 | DEF(andc_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_andc_i64)) 159 | DEF(orc_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_orc_i64)) 160 | DEF(eqv_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_eqv_i64)) 161 | DEF(nand_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nand_i64)) 162 | DEF(nor_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nor_i64)) 163 | DEF(clz_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_clz_i64)) 164 | DEF(ctz_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ctz_i64)) 165 | DEF(ctpop_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ctpop_i64)) 166 | DEF(add2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_add2_i64)) 167 | DEF(sub2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_sub2_i64)) 168 | DEF(mulu2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulu2_i64)) 169 | DEF(muls2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muls2_i64)) 170 | DEF(muluh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i64)) 171 | DEF(mulsh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i64)) 172 | 173 | #define TLADDR_ARGS (TARGET_LONG_BITS <= TCG_TARGET_REG_BITS ? 1 : 2) 174 | #define DATA64_ARGS (TCG_TARGET_REG_BITS == 64 ? 1 : 2) 175 | 176 | /* QEMU specific */ 177 | DEF(insn_start, 0, 0, TLADDR_ARGS * TARGET_INSN_START_WORDS,TCG_OPF_NOT_PRESENT) 178 | DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_END) 179 | DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_END) 180 | DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_END | IMPL(TCG_TARGET_HAS_goto_ptr)) 181 | DEF(qemu_ld_i32, 1, TLADDR_ARGS, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS) 182 | DEF(qemu_st_i32, 0, TLADDR_ARGS + 1, 1,TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS) 183 | DEF(qemu_ld_i64, DATA64_ARGS, TLADDR_ARGS, 1,TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT) 184 | DEF(qemu_st_i64, 0, TLADDR_ARGS + DATA64_ARGS, 1,TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT) 185 | 186 | #ifdef TCG_OPC_CUSTOM 187 | TCG_OPC_CUSTOM 188 | #endif 189 | 190 | #undef TLADDR_ARGS 191 | #undef DATA64_ARGS 192 | #undef IMPL 193 | #undef IMPL64 194 | #undef DEF 195 | -------------------------------------------------------------------------------- /include/lib/tcg/tcg-target.h: -------------------------------------------------------------------------------- 1 | #ifndef TCG_TARGET_H 2 | #define TCG_TARGET_H 3 | 4 | #define TCG_TARGET_REG_BITS 64 5 | #define TCG_TARGET_NB_REGS 1 6 | #define TCG_TARGET_INSN_UNIT_SIZE 8 7 | #define TCG_TARGET_CALL_ALIGN_ARGS 1 8 | 9 | typedef enum TCGReg { 10 | TCREG_NONE=0, 11 | TCG_AREG0= TCREG_NONE 12 | } TCGReg; 13 | 14 | #define TCG_TARGET_HAS_add2_i32 0 15 | #define TCG_TARGET_HAS_add2_i64 0 16 | #define TCG_TARGET_HAS_andc_i32 0 17 | #define TCG_TARGET_HAS_andc_i64 0 18 | #define TCG_TARGET_HAS_bswap16_i32 0 19 | #define TCG_TARGET_HAS_bswap16_i64 0 20 | #define TCG_TARGET_HAS_bswap32_i32 0 21 | #define TCG_TARGET_HAS_bswap32_i64 0 22 | #define TCG_TARGET_HAS_bswap64_i64 0 23 | #define TCG_TARGET_HAS_clz_i32 0 24 | #define TCG_TARGET_HAS_clz_i64 0 25 | #define TCG_TARGET_HAS_ctpop_i32 0 26 | #define TCG_TARGET_HAS_ctpop_i64 0 27 | #define TCG_TARGET_HAS_ctz_i32 0 28 | #define TCG_TARGET_HAS_ctz_i64 0 29 | #define TCG_TARGET_HAS_deposit_i32 0 30 | #define TCG_TARGET_HAS_deposit_i64 0 31 | #define TCG_TARGET_HAS_div2_i32 0 32 | #define TCG_TARGET_HAS_div2_i64 0 33 | #define TCG_TARGET_HAS_div_i32 1 34 | #define TCG_TARGET_HAS_div_i64 1 35 | #define TCG_TARGET_HAS_eqv_i32 0 36 | #define TCG_TARGET_HAS_eqv_i64 0 37 | #define TCG_TARGET_HAS_ext16s_i32 1 38 | #define TCG_TARGET_HAS_ext16s_i64 1 39 | #define TCG_TARGET_HAS_ext16u_i32 1 40 | #define TCG_TARGET_HAS_ext16u_i64 1 41 | #define TCG_TARGET_HAS_ext32s_i64 1 42 | #define TCG_TARGET_HAS_ext32u_i64 1 43 | #define TCG_TARGET_HAS_ext8s_i32 1 44 | #define TCG_TARGET_HAS_ext8s_i64 1 45 | #define TCG_TARGET_HAS_ext8u_i32 1 46 | #define TCG_TARGET_HAS_ext8u_i64 1 47 | #define TCG_TARGET_HAS_extract_i32 0 48 | #define TCG_TARGET_HAS_extract_i64 0 49 | #define TCG_TARGET_HAS_extrh_i64_i32 0 50 | #define TCG_TARGET_HAS_extrl_i64_i32 0 51 | #define TCG_TARGET_HAS_goto_ptr 1 52 | #define TCG_TARGET_HAS_movcond_i32 1 53 | #define TCG_TARGET_HAS_movcond_i64 1 54 | #define TCG_TARGET_HAS_muls2_i32 0 55 | #define TCG_TARGET_HAS_muls2_i64 0 56 | #define TCG_TARGET_HAS_mulsh_i32 1 57 | #define TCG_TARGET_HAS_mulsh_i64 1 58 | #define TCG_TARGET_HAS_mulu2_i32 0 59 | #define TCG_TARGET_HAS_mulu2_i64 0 60 | #define TCG_TARGET_HAS_muluh_i32 1 61 | #define TCG_TARGET_HAS_muluh_i64 1 62 | #define TCG_TARGET_HAS_nand_i32 0 63 | #define TCG_TARGET_HAS_nand_i64 0 64 | #define TCG_TARGET_HAS_neg_i32 1 65 | #define TCG_TARGET_HAS_neg_i64 1 66 | #define TCG_TARGET_HAS_nor_i32 0 67 | #define TCG_TARGET_HAS_nor_i64 0 68 | #define TCG_TARGET_HAS_not_i32 1 69 | #define TCG_TARGET_HAS_not_i64 1 70 | #define TCG_TARGET_HAS_orc_i32 0 71 | #define TCG_TARGET_HAS_orc_i64 0 72 | #define TCG_TARGET_HAS_rem_i32 1 73 | #define TCG_TARGET_HAS_rem_i64 1 74 | #define TCG_TARGET_HAS_rot_i32 0 75 | #define TCG_TARGET_HAS_rot_i64 0 76 | #define TCG_TARGET_HAS_sextract_i32 0 77 | #define TCG_TARGET_HAS_sextract_i64 0 78 | #define TCG_TARGET_HAS_sub2_i32 0 79 | #define TCG_TARGET_HAS_sub2_i64 0 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/lib/target/host-utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Utility compute operations used by translated code. 3 | * 4 | * Copyright (c) 2003 Fabrice Bellard 5 | * Copyright (c) 2007 Aurelien Jarno 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #include "lib/internal.h" 27 | 28 | #ifndef CONFIG_INT128 29 | /* Long integer helpers */ 30 | static inline void mul64(uint64_t *plow, uint64_t *phigh, 31 | uint64_t a, uint64_t b) 32 | { 33 | typedef union { 34 | uint64_t ll; 35 | struct { 36 | #ifdef HOST_WORDS_BIGENDIAN 37 | uint32_t high, low; 38 | #else 39 | uint32_t low, high; 40 | #endif 41 | } l; 42 | } LL; 43 | LL rl, rm, rn, rh, a0, b0; 44 | uint64_t c; 45 | 46 | a0.ll = a; 47 | b0.ll = b; 48 | 49 | rl.ll = (uint64_t)a0.l.low * b0.l.low; 50 | rm.ll = (uint64_t)a0.l.low * b0.l.high; 51 | rn.ll = (uint64_t)a0.l.high * b0.l.low; 52 | rh.ll = (uint64_t)a0.l.high * b0.l.high; 53 | 54 | c = (uint64_t)rl.l.high + rm.l.low + rn.l.low; 55 | rl.l.high = c; 56 | c >>= 32; 57 | c = c + rm.l.high + rn.l.high + rh.l.low; 58 | rh.l.low = c; 59 | rh.l.high += (uint32_t)(c >> 32); 60 | 61 | *plow = rl.ll; 62 | *phigh = rh.ll; 63 | } 64 | 65 | /* Unsigned 64x64 -> 128 multiplication */ 66 | void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b) 67 | { 68 | mul64(plow, phigh, a, b); 69 | } 70 | 71 | /* Signed 64x64 -> 128 multiplication */ 72 | void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b) 73 | { 74 | uint64_t rh; 75 | 76 | mul64(plow, &rh, a, b); 77 | 78 | /* Adjust for signs. */ 79 | if (b < 0) { 80 | rh -= a; 81 | } 82 | if (a < 0) { 83 | rh -= b; 84 | } 85 | *phigh = rh; 86 | } 87 | 88 | /* Unsigned 128x64 division. Returns 1 if overflow (divide by zero or */ 89 | /* quotient exceeds 64 bits). Otherwise returns quotient via plow and */ 90 | /* remainder via phigh. */ 91 | int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor) 92 | { 93 | uint64_t dhi = *phigh; 94 | uint64_t dlo = *plow; 95 | unsigned i; 96 | uint64_t carry = 0; 97 | 98 | if (divisor == 0) { 99 | return 1; 100 | } 101 | else if (dhi == 0) { 102 | *plow = dlo / divisor; 103 | *phigh = dlo % divisor; 104 | return 0; 105 | } 106 | else if (dhi > divisor) { 107 | return 1; 108 | } 109 | else { 110 | 111 | for (i = 0; i < 64; i++) { 112 | carry = dhi >> 63; 113 | dhi = (dhi << 1) | (dlo >> 63); 114 | if (carry || (dhi >= divisor)) { 115 | dhi -= divisor; 116 | carry = 1; 117 | } 118 | else { 119 | carry = 0; 120 | } 121 | dlo = (dlo << 1) | carry; 122 | } 123 | 124 | *plow = dlo; 125 | *phigh = dhi; 126 | return 0; 127 | } 128 | } 129 | 130 | int divs128(int64_t *plow, int64_t *phigh, int64_t divisor) 131 | { 132 | int sgn_dvdnd = *phigh < 0; 133 | int sgn_divsr = divisor < 0; 134 | int overflow = 0; 135 | 136 | if (sgn_dvdnd) { 137 | *plow = ~(*plow); 138 | *phigh = ~(*phigh); 139 | if (*plow == (int64_t)-1) { 140 | *plow = 0; 141 | (*phigh)++; 142 | } 143 | else { 144 | (*plow)++; 145 | } 146 | } 147 | 148 | if (sgn_divsr) { 149 | divisor = 0 - divisor; 150 | } 151 | 152 | overflow = divu128((uint64_t *)plow, (uint64_t *)phigh, (uint64_t)divisor); 153 | 154 | if (sgn_dvdnd ^ sgn_divsr) { 155 | *plow = 0 - *plow; 156 | } 157 | 158 | if (!overflow) { 159 | if ((*plow < 0) ^ (sgn_dvdnd ^ sgn_divsr)) { 160 | overflow = 1; 161 | } 162 | } 163 | 164 | return overflow; 165 | } 166 | #endif 167 | 168 | /** 169 | * urshift - 128-bit Unsigned Right Shift. 170 | * @plow: in/out - lower 64-bit integer. 171 | * @phigh: in/out - higher 64-bit integer. 172 | * @shift: in - bytes to shift, between 0 and 127. 173 | * 174 | * Result is zero-extended and stored in plow/phigh, which are 175 | * input/output variables. Shift values outside the range will 176 | * be mod to 128. In other words, the caller is responsible to 177 | * verify/assert both the shift range and plow/phigh pointers. 178 | */ 179 | void urshift(uint64_t *plow, uint64_t *phigh, int32_t shift) 180 | { 181 | shift &= 127; 182 | if (shift == 0) { 183 | return; 184 | } 185 | 186 | uint64_t h = *phigh >> (shift & 63); 187 | if (shift >= 64) { 188 | *plow = h; 189 | *phigh = 0; 190 | } 191 | else { 192 | *plow = (*plow >> (shift & 63)) | (*phigh << (64 - (shift & 63))); 193 | *phigh = h; 194 | } 195 | } 196 | 197 | /** 198 | * ulshift - 128-bit Unsigned Left Shift. 199 | * @plow: in/out - lower 64-bit integer. 200 | * @phigh: in/out - higher 64-bit integer. 201 | * @shift: in - bytes to shift, between 0 and 127. 202 | * @overflow: out - true if any 1-bit is shifted out. 203 | * 204 | * Result is zero-extended and stored in plow/phigh, which are 205 | * input/output variables. Shift values outside the range will 206 | * be mod to 128. In other words, the caller is responsible to 207 | * verify/assert both the shift range and plow/phigh pointers. 208 | */ 209 | void ulshift(uint64_t *plow, uint64_t *phigh, int32_t shift, bool *overflow) 210 | { 211 | uint64_t low = *plow; 212 | uint64_t high = *phigh; 213 | 214 | shift &= 127; 215 | if (shift == 0) { 216 | return; 217 | } 218 | 219 | /* check if any bit will be shifted out */ 220 | urshift(&low, &high, 128 - shift); 221 | if (low | high) { 222 | *overflow = true; 223 | } 224 | 225 | if (shift >= 64) { 226 | *phigh = *plow << (shift & 63); 227 | *plow = 0; 228 | } 229 | else { 230 | *phigh = (*plow >> (64 - (shift & 63))) | (*phigh << (shift & 63)); 231 | *plow = *plow << shift; 232 | } 233 | } -------------------------------------------------------------------------------- /src/lib/tcg/LICENSE: -------------------------------------------------------------------------------- 1 | All the files in this directory and subdirectories are released under 2 | a BSD like license (see header in each file). No other license is 3 | accepted. 4 | -------------------------------------------------------------------------------- /src/lib/tcg/tcg-common.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny Code Generator for QEMU 3 | * 4 | * Copyright (c) 2008 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #include "lib/internal.h" 26 | #include "lib/tcg/tcg.h" 27 | 28 | #if defined(CONFIG_TCG_INTERPRETER) 29 | uintptr_t tci_tb_ptr; 30 | #endif 31 | 32 | TCGOpDef tcg_op_defs[] = { 33 | #define DEF(s, oargs, iargs, cargs, flags) \ 34 | { #s, oargs, iargs, cargs, iargs + oargs + cargs, (TCGOpFlags)(flags) }, 35 | #include "lib/tcg/tcg-opc.h" 36 | #undef DEF 37 | }; 38 | const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs); 39 | --------------------------------------------------------------------------------