asmjit 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/asmjit.gemspec +1 -1
  4. data/ext/asmjit/asmjit/.editorconfig +10 -0
  5. data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
  6. data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
  7. data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
  8. data/ext/asmjit/asmjit/.gitignore +6 -0
  9. data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
  10. data/ext/asmjit/asmjit/LICENSE.md +17 -0
  11. data/ext/asmjit/asmjit/README.md +69 -0
  12. data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
  13. data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
  14. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
  15. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
  16. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
  17. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
  18. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
  19. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
  20. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
  21. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
  22. data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
  23. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
  24. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
  25. data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
  26. data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
  27. data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
  28. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
  29. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
  30. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
  31. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
  32. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
  33. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
  34. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
  35. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
  36. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
  37. data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
  38. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
  39. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
  40. data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
  41. data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
  42. data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
  43. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
  44. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
  45. data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
  46. data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
  47. data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
  48. data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
  49. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
  50. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
  51. data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
  52. data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
  53. data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
  54. data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
  55. data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
  56. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
  57. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
  58. data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
  59. data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
  60. data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
  61. data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
  62. data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
  63. data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
  64. data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
  65. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
  66. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
  67. data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
  68. data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
  69. data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
  70. data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
  71. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
  72. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
  73. data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
  74. data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
  75. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
  76. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
  77. data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
  78. data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
  79. data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
  80. data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
  81. data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
  82. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
  83. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
  84. data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
  85. data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
  86. data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
  87. data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
  88. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
  89. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
  90. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
  91. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
  92. data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
  93. data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
  94. data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
  95. data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
  96. data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
  97. data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
  98. data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
  99. data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
  100. data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
  101. data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
  102. data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
  103. data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
  104. data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
  105. data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
  106. data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
  107. data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
  108. data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
  109. data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
  110. data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
  111. data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
  112. data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
  113. data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
  114. data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
  115. data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
  116. data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
  117. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
  118. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
  119. data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
  120. data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
  121. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
  122. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
  123. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
  124. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
  125. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
  126. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
  127. data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
  128. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
  129. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
  130. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
  131. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
  132. data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
  133. data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
  134. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
  135. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
  136. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
  137. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
  138. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
  139. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
  140. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
  141. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
  142. data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
  143. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
  144. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
  145. data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
  146. data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
  147. data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
  148. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
  149. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
  150. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
  151. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
  152. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
  153. data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
  154. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
  155. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
  156. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
  157. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
  158. data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
  159. data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
  160. data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
  161. data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
  162. data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
  163. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
  164. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
  165. data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
  166. data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
  167. data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
  168. data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
  169. data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
  170. data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
  171. data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
  172. data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
  173. data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
  174. data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
  175. data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
  176. data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
  177. data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
  178. data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
  179. data/ext/asmjit/asmjit/test/broken.cpp +312 -0
  180. data/ext/asmjit/asmjit/test/broken.h +148 -0
  181. data/ext/asmjit/asmjit/test/cmdline.h +61 -0
  182. data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
  183. data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
  184. data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
  185. data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
  186. data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
  187. data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
  188. data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
  189. data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
  190. data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
  191. data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
  192. data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
  193. data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
  194. data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
  195. data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
  196. data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
  197. data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
  198. data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
  199. data/ext/asmjit/asmjit.cc +18 -0
  200. data/lib/asmjit/version.rb +1 -1
  201. metadata +197 -2
@@ -0,0 +1,1085 @@
1
+ // This file is part of AsmJit project <https://asmjit.com>
2
+ //
3
+ // See asmjit.h or LICENSE.md for license and copyright information
4
+ // SPDX-License-Identifier: Zlib
5
+
6
+ #ifndef ASMJIT_X86_X86OPERAND_H_INCLUDED
7
+ #define ASMJIT_X86_X86OPERAND_H_INCLUDED
8
+
9
+ #include "../core/archtraits.h"
10
+ #include "../core/operand.h"
11
+ #include "../core/type.h"
12
+ #include "../x86/x86globals.h"
13
+
14
+ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
15
+
16
+ //! \addtogroup asmjit_x86
17
+ //! \{
18
+
19
+ class Reg;
20
+ class Mem;
21
+
22
+ class Gp;
23
+ class Gpb;
24
+ class GpbLo;
25
+ class GpbHi;
26
+ class Gpw;
27
+ class Gpd;
28
+ class Gpq;
29
+ class Vec;
30
+ class Xmm;
31
+ class Ymm;
32
+ class Zmm;
33
+ class Mm;
34
+ class KReg;
35
+ class SReg;
36
+ class CReg;
37
+ class DReg;
38
+ class St;
39
+ class Bnd;
40
+ class Tmm;
41
+ class Rip;
42
+
43
+ //! Register traits (X86).
44
+ //!
45
+ //! Register traits contains information about a particular register type. It's used by asmjit to setup register
46
+ //! information on-the-fly and to populate tables that contain register information (this way it's possible to change
47
+ //! register types and groups without having to reorder these tables).
48
+ template<RegType kRegType>
49
+ struct RegTraits : public BaseRegTraits {};
50
+
51
+ //! \cond
52
+ // <--------------------+-----+-------------------------+------------------------+---+---+------------------+
53
+ // | Reg | Reg-Type | Reg-Group |Sz |Cnt| TypeId |
54
+ // <--------------------+-----+-------------------------+------------------------+---+---+------------------+
55
+ ASMJIT_DEFINE_REG_TRAITS(Rip , RegType::kX86_Rip , RegGroup::kX86_Rip , 0 , 1 , TypeId::kVoid );
56
+ ASMJIT_DEFINE_REG_TRAITS(GpbLo, RegType::kX86_GpbLo , RegGroup::kGp , 1 , 16, TypeId::kInt8 );
57
+ ASMJIT_DEFINE_REG_TRAITS(GpbHi, RegType::kX86_GpbHi , RegGroup::kGp , 1 , 4 , TypeId::kInt8 );
58
+ ASMJIT_DEFINE_REG_TRAITS(Gpw , RegType::kX86_Gpw , RegGroup::kGp , 2 , 16, TypeId::kInt16 );
59
+ ASMJIT_DEFINE_REG_TRAITS(Gpd , RegType::kX86_Gpd , RegGroup::kGp , 4 , 16, TypeId::kInt32 );
60
+ ASMJIT_DEFINE_REG_TRAITS(Gpq , RegType::kX86_Gpq , RegGroup::kGp , 8 , 16, TypeId::kInt64 );
61
+ ASMJIT_DEFINE_REG_TRAITS(Xmm , RegType::kX86_Xmm , RegGroup::kVec , 16, 32, TypeId::kInt32x4 );
62
+ ASMJIT_DEFINE_REG_TRAITS(Ymm , RegType::kX86_Ymm , RegGroup::kVec , 32, 32, TypeId::kInt32x8 );
63
+ ASMJIT_DEFINE_REG_TRAITS(Zmm , RegType::kX86_Zmm , RegGroup::kVec , 64, 32, TypeId::kInt32x16);
64
+ ASMJIT_DEFINE_REG_TRAITS(KReg , RegType::kX86_KReg , RegGroup::kX86_K , 0 , 8 , TypeId::kVoid );
65
+ ASMJIT_DEFINE_REG_TRAITS(Mm , RegType::kX86_Mm , RegGroup::kX86_MM , 8 , 8 , TypeId::kMmx64 );
66
+ ASMJIT_DEFINE_REG_TRAITS(SReg , RegType::kX86_SReg , RegGroup::kX86_SReg , 2 , 7 , TypeId::kVoid );
67
+ ASMJIT_DEFINE_REG_TRAITS(CReg , RegType::kX86_CReg , RegGroup::kX86_CReg , 0 , 16, TypeId::kVoid );
68
+ ASMJIT_DEFINE_REG_TRAITS(DReg , RegType::kX86_DReg , RegGroup::kX86_DReg , 0 , 16, TypeId::kVoid );
69
+ ASMJIT_DEFINE_REG_TRAITS(St , RegType::kX86_St , RegGroup::kX86_St , 10, 8 , TypeId::kFloat80 );
70
+ ASMJIT_DEFINE_REG_TRAITS(Bnd , RegType::kX86_Bnd , RegGroup::kX86_Bnd , 16, 4 , TypeId::kVoid );
71
+ ASMJIT_DEFINE_REG_TRAITS(Tmm , RegType::kX86_Tmm , RegGroup::kX86_Tmm , 0 , 8 , TypeId::kVoid );
72
+ //! \endcond
73
+
74
+ //! Register (X86).
75
+ class Reg : public BaseReg {
76
+ public:
77
+ ASMJIT_DEFINE_ABSTRACT_REG(Reg, BaseReg)
78
+
79
+ //! Tests whether the register is a GPB register (8-bit).
80
+ inline constexpr bool isGpb() const noexcept { return size() == 1; }
81
+ //! Tests whether the register is a low GPB register (8-bit).
82
+ inline constexpr bool isGpbLo() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbLo>::kSignature); }
83
+ //! Tests whether the register is a high GPB register (8-bit).
84
+ inline constexpr bool isGpbHi() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_GpbHi>::kSignature); }
85
+ //! Tests whether the register is a GPW register (16-bit).
86
+ inline constexpr bool isGpw() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpw>::kSignature); }
87
+ //! Tests whether the register is a GPD register (32-bit).
88
+ inline constexpr bool isGpd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpd>::kSignature); }
89
+ //! Tests whether the register is a GPQ register (64-bit).
90
+ inline constexpr bool isGpq() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Gpq>::kSignature); }
91
+ //! Tests whether the register is an XMM register (128-bit).
92
+ inline constexpr bool isXmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Xmm>::kSignature); }
93
+ //! Tests whether the register is a YMM register (256-bit).
94
+ inline constexpr bool isYmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Ymm>::kSignature); }
95
+ //! Tests whether the register is a ZMM register (512-bit).
96
+ inline constexpr bool isZmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Zmm>::kSignature); }
97
+ //! Tests whether the register is an MMX register (64-bit).
98
+ inline constexpr bool isMm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Mm>::kSignature); }
99
+ //! Tests whether the register is a K register (64-bit).
100
+ inline constexpr bool isKReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_KReg>::kSignature); }
101
+ //! Tests whether the register is a segment register.
102
+ inline constexpr bool isSReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_SReg>::kSignature); }
103
+ //! Tests whether the register is a control register.
104
+ inline constexpr bool isCReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_CReg>::kSignature); }
105
+ //! Tests whether the register is a debug register.
106
+ inline constexpr bool isDReg() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_DReg>::kSignature); }
107
+ //! Tests whether the register is an FPU register (80-bit).
108
+ inline constexpr bool isSt() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_St>::kSignature); }
109
+ //! Tests whether the register is a bound register.
110
+ inline constexpr bool isBnd() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Bnd>::kSignature); }
111
+ //! Tests whether the register is a TMM register.
112
+ inline constexpr bool isTmm() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Tmm>::kSignature); }
113
+ //! Tests whether the register is RIP.
114
+ inline constexpr bool isRip() const noexcept { return hasBaseSignature(RegTraits<RegType::kX86_Rip>::kSignature); }
115
+
116
+ template<RegType REG_TYPE>
117
+ inline void setRegT(uint32_t rId) noexcept {
118
+ setSignature(OperandSignature{RegTraits<REG_TYPE>::kSignature});
119
+ setId(rId);
120
+ }
121
+
122
+ inline void setTypeAndId(RegType type, uint32_t id) noexcept {
123
+ setSignature(signatureOf(type));
124
+ setId(id);
125
+ }
126
+
127
+ static inline RegGroup groupOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToGroup(type); }
128
+ static inline TypeId typeIdOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToTypeId(type); }
129
+ static inline OperandSignature signatureOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kX86).regTypeToSignature(type); }
130
+
131
+ template<RegType REG_TYPE>
132
+ static inline RegGroup groupOfT() noexcept { return RegGroup(RegTraits<REG_TYPE>::kGroup); }
133
+
134
+ template<RegType REG_TYPE>
135
+ static inline TypeId typeIdOfT() noexcept { return TypeId(RegTraits<REG_TYPE>::kTypeId); }
136
+
137
+ template<RegType REG_TYPE>
138
+ static inline OperandSignature signatureOfT() noexcept { return OperandSignature{RegTraits<REG_TYPE>::kSignature}; }
139
+
140
+ static inline OperandSignature signatureOfVecByType(TypeId typeId) noexcept {
141
+ return OperandSignature{typeId <= TypeId::_kVec128End ? uint32_t(RegTraits<RegType::kX86_Xmm>::kSignature) :
142
+ typeId <= TypeId::_kVec256End ? uint32_t(RegTraits<RegType::kX86_Ymm>::kSignature) :
143
+ uint32_t(RegTraits<RegType::kX86_Zmm>::kSignature)};
144
+ }
145
+
146
+ static inline OperandSignature signatureOfVecBySize(uint32_t size) noexcept {
147
+ return OperandSignature{size <= 16 ? uint32_t(RegTraits<RegType::kX86_Xmm>::kSignature) :
148
+ size <= 32 ? uint32_t(RegTraits<RegType::kX86_Ymm>::kSignature) :
149
+ uint32_t(RegTraits<RegType::kX86_Zmm>::kSignature)};
150
+ }
151
+
152
+ //! Tests whether the `op` operand is either a low or high 8-bit GPB register.
153
+ static inline bool isGpb(const Operand_& op) noexcept {
154
+ // Check operand type, register group, and size. Not interested in register type.
155
+ return op.signature().subset(Signature::kOpTypeMask | Signature::kRegGroupMask | Signature::kSizeMask) ==
156
+ (Signature::fromOpType(OperandType::kReg) | Signature::fromRegGroup(RegGroup::kGp) | Signature::fromSize(1));
157
+ }
158
+
159
+ static inline bool isGpbLo(const Operand_& op) noexcept { return op.as<Reg>().isGpbLo(); }
160
+ static inline bool isGpbHi(const Operand_& op) noexcept { return op.as<Reg>().isGpbHi(); }
161
+ static inline bool isGpw(const Operand_& op) noexcept { return op.as<Reg>().isGpw(); }
162
+ static inline bool isGpd(const Operand_& op) noexcept { return op.as<Reg>().isGpd(); }
163
+ static inline bool isGpq(const Operand_& op) noexcept { return op.as<Reg>().isGpq(); }
164
+ static inline bool isXmm(const Operand_& op) noexcept { return op.as<Reg>().isXmm(); }
165
+ static inline bool isYmm(const Operand_& op) noexcept { return op.as<Reg>().isYmm(); }
166
+ static inline bool isZmm(const Operand_& op) noexcept { return op.as<Reg>().isZmm(); }
167
+ static inline bool isMm(const Operand_& op) noexcept { return op.as<Reg>().isMm(); }
168
+ static inline bool isKReg(const Operand_& op) noexcept { return op.as<Reg>().isKReg(); }
169
+ static inline bool isSReg(const Operand_& op) noexcept { return op.as<Reg>().isSReg(); }
170
+ static inline bool isCReg(const Operand_& op) noexcept { return op.as<Reg>().isCReg(); }
171
+ static inline bool isDReg(const Operand_& op) noexcept { return op.as<Reg>().isDReg(); }
172
+ static inline bool isSt(const Operand_& op) noexcept { return op.as<Reg>().isSt(); }
173
+ static inline bool isBnd(const Operand_& op) noexcept { return op.as<Reg>().isBnd(); }
174
+ static inline bool isTmm(const Operand_& op) noexcept { return op.as<Reg>().isTmm(); }
175
+ static inline bool isRip(const Operand_& op) noexcept { return op.as<Reg>().isRip(); }
176
+
177
+ static inline bool isGpb(const Operand_& op, uint32_t rId) noexcept { return isGpb(op) & (op.id() == rId); }
178
+ static inline bool isGpbLo(const Operand_& op, uint32_t rId) noexcept { return isGpbLo(op) & (op.id() == rId); }
179
+ static inline bool isGpbHi(const Operand_& op, uint32_t rId) noexcept { return isGpbHi(op) & (op.id() == rId); }
180
+ static inline bool isGpw(const Operand_& op, uint32_t rId) noexcept { return isGpw(op) & (op.id() == rId); }
181
+ static inline bool isGpd(const Operand_& op, uint32_t rId) noexcept { return isGpd(op) & (op.id() == rId); }
182
+ static inline bool isGpq(const Operand_& op, uint32_t rId) noexcept { return isGpq(op) & (op.id() == rId); }
183
+ static inline bool isXmm(const Operand_& op, uint32_t rId) noexcept { return isXmm(op) & (op.id() == rId); }
184
+ static inline bool isYmm(const Operand_& op, uint32_t rId) noexcept { return isYmm(op) & (op.id() == rId); }
185
+ static inline bool isZmm(const Operand_& op, uint32_t rId) noexcept { return isZmm(op) & (op.id() == rId); }
186
+ static inline bool isMm(const Operand_& op, uint32_t rId) noexcept { return isMm(op) & (op.id() == rId); }
187
+ static inline bool isKReg(const Operand_& op, uint32_t rId) noexcept { return isKReg(op) & (op.id() == rId); }
188
+ static inline bool isSReg(const Operand_& op, uint32_t rId) noexcept { return isSReg(op) & (op.id() == rId); }
189
+ static inline bool isCReg(const Operand_& op, uint32_t rId) noexcept { return isCReg(op) & (op.id() == rId); }
190
+ static inline bool isDReg(const Operand_& op, uint32_t rId) noexcept { return isDReg(op) & (op.id() == rId); }
191
+ static inline bool isSt(const Operand_& op, uint32_t rId) noexcept { return isSt(op) & (op.id() == rId); }
192
+ static inline bool isBnd(const Operand_& op, uint32_t rId) noexcept { return isBnd(op) & (op.id() == rId); }
193
+ static inline bool isTmm(const Operand_& op, uint32_t rId) noexcept { return isTmm(op) & (op.id() == rId); }
194
+ static inline bool isRip(const Operand_& op, uint32_t rId) noexcept { return isRip(op) & (op.id() == rId); }
195
+ };
196
+
197
+ //! General purpose register (X86).
198
+ class Gp : public Reg {
199
+ public:
200
+ ASMJIT_DEFINE_ABSTRACT_REG(Gp, Reg)
201
+
202
+ //! Physical id (X86).
203
+ //!
204
+ //! \note Register indexes have been reduced to only support general purpose registers. There is no need to
205
+ //! have enumerations with number suffix that expands to the exactly same value as the suffix value itself.
206
+ enum Id : uint32_t {
207
+ kIdAx = 0, //!< Physical id of AL|AH|AX|EAX|RAX registers.
208
+ kIdCx = 1, //!< Physical id of CL|CH|CX|ECX|RCX registers.
209
+ kIdDx = 2, //!< Physical id of DL|DH|DX|EDX|RDX registers.
210
+ kIdBx = 3, //!< Physical id of BL|BH|BX|EBX|RBX registers.
211
+ kIdSp = 4, //!< Physical id of SPL|SP|ESP|RSP registers.
212
+ kIdBp = 5, //!< Physical id of BPL|BP|EBP|RBP registers.
213
+ kIdSi = 6, //!< Physical id of SIL|SI|ESI|RSI registers.
214
+ kIdDi = 7, //!< Physical id of DIL|DI|EDI|RDI registers.
215
+ kIdR8 = 8, //!< Physical id of R8B|R8W|R8D|R8 registers (64-bit only).
216
+ kIdR9 = 9, //!< Physical id of R9B|R9W|R9D|R9 registers (64-bit only).
217
+ kIdR10 = 10, //!< Physical id of R10B|R10W|R10D|R10 registers (64-bit only).
218
+ kIdR11 = 11, //!< Physical id of R11B|R11W|R11D|R11 registers (64-bit only).
219
+ kIdR12 = 12, //!< Physical id of R12B|R12W|R12D|R12 registers (64-bit only).
220
+ kIdR13 = 13, //!< Physical id of R13B|R13W|R13D|R13 registers (64-bit only).
221
+ kIdR14 = 14, //!< Physical id of R14B|R14W|R14D|R14 registers (64-bit only).
222
+ kIdR15 = 15 //!< Physical id of R15B|R15W|R15D|R15 registers (64-bit only).
223
+ };
224
+
225
+ //! Casts this register to 8-bit (LO) part.
226
+ inline GpbLo r8() const noexcept;
227
+ //! Casts this register to 8-bit (LO) part.
228
+ inline GpbLo r8Lo() const noexcept;
229
+ //! Casts this register to 8-bit (HI) part.
230
+ inline GpbHi r8Hi() const noexcept;
231
+ //! Casts this register to 16-bit.
232
+ inline Gpw r16() const noexcept;
233
+ //! Casts this register to 32-bit.
234
+ inline Gpd r32() const noexcept;
235
+ //! Casts this register to 64-bit.
236
+ inline Gpq r64() const noexcept;
237
+ };
238
+
239
+ //! Vector register (XMM|YMM|ZMM) (X86).
240
+ class Vec : public Reg {
241
+ ASMJIT_DEFINE_ABSTRACT_REG(Vec, Reg)
242
+
243
+ //! Casts this register to XMM (clone).
244
+ inline Xmm xmm() const noexcept;
245
+ //! Casts this register to YMM.
246
+ inline Ymm ymm() const noexcept;
247
+ //! Casts this register to ZMM.
248
+ inline Zmm zmm() const noexcept;
249
+
250
+ //! Casts this register to a register that has half the size (or XMM if it's already XMM).
251
+ inline Vec half() const noexcept {
252
+ return Vec(type() == RegType::kX86_Zmm ? signatureOfT<RegType::kX86_Ymm>() : signatureOfT<RegType::kX86_Xmm>(), id());
253
+ }
254
+ };
255
+
256
+ //! Segment register (X86).
257
+ class SReg : public Reg {
258
+ ASMJIT_DEFINE_FINAL_REG(SReg, Reg, RegTraits<RegType::kX86_SReg>)
259
+
260
+ //! X86 segment id.
261
+ enum Id : uint32_t {
262
+ //! No segment (default).
263
+ kIdNone = 0,
264
+ //! ES segment.
265
+ kIdEs = 1,
266
+ //! CS segment.
267
+ kIdCs = 2,
268
+ //! SS segment.
269
+ kIdSs = 3,
270
+ //! DS segment.
271
+ kIdDs = 4,
272
+ //! FS segment.
273
+ kIdFs = 5,
274
+ //! GS segment.
275
+ kIdGs = 6,
276
+
277
+ //! Count of X86 segment registers supported by AsmJit.
278
+ //!
279
+ //! \note X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS. X64 architecture lowers them down to
280
+ //! just FS and GS. AsmJit supports 7 segment registers - all addressable in both X86 and X64 modes and one extra
281
+ //! called `SReg::kIdNone`, which is AsmJit specific and means that there is no segment register specified.
282
+ kIdCount = 7
283
+ };
284
+ };
285
+
286
+ //! GPB low or high register (X86).
287
+ class Gpb : public Gp { ASMJIT_DEFINE_ABSTRACT_REG(Gpb, Gp) };
288
+ //! GPB low register (X86).
289
+ class GpbLo : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbLo, Gpb, RegTraits<RegType::kX86_GpbLo>) };
290
+ //! GPB high register (X86).
291
+ class GpbHi : public Gpb { ASMJIT_DEFINE_FINAL_REG(GpbHi, Gpb, RegTraits<RegType::kX86_GpbHi>) };
292
+ //! GPW register (X86).
293
+ class Gpw : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpw, Gp, RegTraits<RegType::kX86_Gpw>) };
294
+ //! GPD register (X86).
295
+ class Gpd : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpd, Gp, RegTraits<RegType::kX86_Gpd>) };
296
+ //! GPQ register (X86_64).
297
+ class Gpq : public Gp { ASMJIT_DEFINE_FINAL_REG(Gpq, Gp, RegTraits<RegType::kX86_Gpq>) };
298
+
299
+ //! 128-bit XMM register (SSE+).
300
+ class Xmm : public Vec {
301
+ ASMJIT_DEFINE_FINAL_REG(Xmm, Vec, RegTraits<RegType::kX86_Xmm>)
302
+ //! Casts this register to a register that has half the size (XMM).
303
+ inline Xmm half() const noexcept { return Xmm(id()); }
304
+ };
305
+
306
+ //! 256-bit YMM register (AVX+).
307
+ class Ymm : public Vec {
308
+ ASMJIT_DEFINE_FINAL_REG(Ymm, Vec, RegTraits<RegType::kX86_Ymm>)
309
+ //! Casts this register to a register that has half the size (XMM).
310
+ inline Xmm half() const noexcept { return Xmm(id()); }
311
+ };
312
+
313
+ //! 512-bit ZMM register (AVX512+).
314
+ class Zmm : public Vec {
315
+ ASMJIT_DEFINE_FINAL_REG(Zmm, Vec, RegTraits<RegType::kX86_Zmm>)
316
+ //! Casts this register to a register that has half the size (YMM).
317
+ inline Ymm half() const noexcept { return Ymm(id()); }
318
+ };
319
+
320
+ //! 64-bit MMX register (MMX+).
321
+ class Mm : public Reg { ASMJIT_DEFINE_FINAL_REG(Mm, Reg, RegTraits<RegType::kX86_Mm>) };
322
+ //! 64-bit K register (AVX512+).
323
+ class KReg : public Reg { ASMJIT_DEFINE_FINAL_REG(KReg, Reg, RegTraits<RegType::kX86_KReg>) };
324
+ //! 32-bit or 64-bit control register (X86).
325
+ class CReg : public Reg { ASMJIT_DEFINE_FINAL_REG(CReg, Reg, RegTraits<RegType::kX86_CReg>) };
326
+ //! 32-bit or 64-bit debug register (X86).
327
+ class DReg : public Reg { ASMJIT_DEFINE_FINAL_REG(DReg, Reg, RegTraits<RegType::kX86_DReg>) };
328
+ //! 80-bit FPU register (X86).
329
+ class St : public Reg { ASMJIT_DEFINE_FINAL_REG(St, Reg, RegTraits<RegType::kX86_St>) };
330
+ //! 128-bit BND register (BND+).
331
+ class Bnd : public Reg { ASMJIT_DEFINE_FINAL_REG(Bnd, Reg, RegTraits<RegType::kX86_Bnd>) };
332
+ //! 8192-bit TMM register (AMX).
333
+ class Tmm : public Reg { ASMJIT_DEFINE_FINAL_REG(Tmm, Reg, RegTraits<RegType::kX86_Tmm>) };
334
+ //! RIP register (X86).
335
+ class Rip : public Reg { ASMJIT_DEFINE_FINAL_REG(Rip, Reg, RegTraits<RegType::kX86_Rip>) };
336
+
337
+ //! \cond
338
+ inline GpbLo Gp::r8() const noexcept { return GpbLo(id()); }
339
+ inline GpbLo Gp::r8Lo() const noexcept { return GpbLo(id()); }
340
+ inline GpbHi Gp::r8Hi() const noexcept { return GpbHi(id()); }
341
+ inline Gpw Gp::r16() const noexcept { return Gpw(id()); }
342
+ inline Gpd Gp::r32() const noexcept { return Gpd(id()); }
343
+ inline Gpq Gp::r64() const noexcept { return Gpq(id()); }
344
+ inline Xmm Vec::xmm() const noexcept { return Xmm(id()); }
345
+ inline Ymm Vec::ymm() const noexcept { return Ymm(id()); }
346
+ inline Zmm Vec::zmm() const noexcept { return Zmm(id()); }
347
+ //! \endcond
348
+
349
+ //! \namespace asmjit::x86::regs
350
+ //!
351
+ //! Registers provided by X86 and X64 ISAs are in both `asmjit::x86` and
352
+ //! `asmjit::x86::regs` namespaces so they can be included with using directive.
353
+ //! For example `using namespace asmjit::x86::regs` would include all registers,
354
+ //! but not other X86-specific API, whereas `using namespace asmjit::x86` would
355
+ //! include everything X86-specific.
356
+ #ifndef _DOXYGEN
357
+ namespace regs {
358
+ #endif
359
+
360
+ //! Creates an 8-bit low GPB register operand.
361
+ static constexpr GpbLo gpb(uint32_t rId) noexcept { return GpbLo(rId); }
362
+ //! Creates an 8-bit low GPB register operand.
363
+ static constexpr GpbLo gpb_lo(uint32_t rId) noexcept { return GpbLo(rId); }
364
+ //! Creates an 8-bit high GPB register operand.
365
+ static constexpr GpbHi gpb_hi(uint32_t rId) noexcept { return GpbHi(rId); }
366
+ //! Creates a 16-bit GPW register operand.
367
+ static constexpr Gpw gpw(uint32_t rId) noexcept { return Gpw(rId); }
368
+ //! Creates a 32-bit GPD register operand.
369
+ static constexpr Gpd gpd(uint32_t rId) noexcept { return Gpd(rId); }
370
+ //! Creates a 64-bit GPQ register operand (64-bit).
371
+ static constexpr Gpq gpq(uint32_t rId) noexcept { return Gpq(rId); }
372
+ //! Creates a 128-bit XMM register operand.
373
+ static constexpr Xmm xmm(uint32_t rId) noexcept { return Xmm(rId); }
374
+ //! Creates a 256-bit YMM register operand.
375
+ static constexpr Ymm ymm(uint32_t rId) noexcept { return Ymm(rId); }
376
+ //! Creates a 512-bit ZMM register operand.
377
+ static constexpr Zmm zmm(uint32_t rId) noexcept { return Zmm(rId); }
378
+ //! Creates a 64-bit Mm register operand.
379
+ static constexpr Mm mm(uint32_t rId) noexcept { return Mm(rId); }
380
+ //! Creates a 64-bit K register operand.
381
+ static constexpr KReg k(uint32_t rId) noexcept { return KReg(rId); }
382
+ //! Creates a 32-bit or 64-bit control register operand.
383
+ static constexpr CReg cr(uint32_t rId) noexcept { return CReg(rId); }
384
+ //! Creates a 32-bit or 64-bit debug register operand.
385
+ static constexpr DReg dr(uint32_t rId) noexcept { return DReg(rId); }
386
+ //! Creates an 80-bit st register operand.
387
+ static constexpr St st(uint32_t rId) noexcept { return St(rId); }
388
+ //! Creates a 128-bit bound register operand.
389
+ static constexpr Bnd bnd(uint32_t rId) noexcept { return Bnd(rId); }
390
+ //! Creates a TMM register operand.
391
+ static constexpr Tmm tmm(uint32_t rId) noexcept { return Tmm(rId); }
392
+
393
+ static constexpr GpbLo al = GpbLo(Gp::kIdAx);
394
+ static constexpr GpbLo bl = GpbLo(Gp::kIdBx);
395
+ static constexpr GpbLo cl = GpbLo(Gp::kIdCx);
396
+ static constexpr GpbLo dl = GpbLo(Gp::kIdDx);
397
+ static constexpr GpbLo spl = GpbLo(Gp::kIdSp);
398
+ static constexpr GpbLo bpl = GpbLo(Gp::kIdBp);
399
+ static constexpr GpbLo sil = GpbLo(Gp::kIdSi);
400
+ static constexpr GpbLo dil = GpbLo(Gp::kIdDi);
401
+ static constexpr GpbLo r8b = GpbLo(Gp::kIdR8);
402
+ static constexpr GpbLo r9b = GpbLo(Gp::kIdR9);
403
+ static constexpr GpbLo r10b = GpbLo(Gp::kIdR10);
404
+ static constexpr GpbLo r11b = GpbLo(Gp::kIdR11);
405
+ static constexpr GpbLo r12b = GpbLo(Gp::kIdR12);
406
+ static constexpr GpbLo r13b = GpbLo(Gp::kIdR13);
407
+ static constexpr GpbLo r14b = GpbLo(Gp::kIdR14);
408
+ static constexpr GpbLo r15b = GpbLo(Gp::kIdR15);
409
+
410
+ static constexpr GpbHi ah = GpbHi(Gp::kIdAx);
411
+ static constexpr GpbHi bh = GpbHi(Gp::kIdBx);
412
+ static constexpr GpbHi ch = GpbHi(Gp::kIdCx);
413
+ static constexpr GpbHi dh = GpbHi(Gp::kIdDx);
414
+
415
+ static constexpr Gpw ax = Gpw(Gp::kIdAx);
416
+ static constexpr Gpw bx = Gpw(Gp::kIdBx);
417
+ static constexpr Gpw cx = Gpw(Gp::kIdCx);
418
+ static constexpr Gpw dx = Gpw(Gp::kIdDx);
419
+ static constexpr Gpw sp = Gpw(Gp::kIdSp);
420
+ static constexpr Gpw bp = Gpw(Gp::kIdBp);
421
+ static constexpr Gpw si = Gpw(Gp::kIdSi);
422
+ static constexpr Gpw di = Gpw(Gp::kIdDi);
423
+ static constexpr Gpw r8w = Gpw(Gp::kIdR8);
424
+ static constexpr Gpw r9w = Gpw(Gp::kIdR9);
425
+ static constexpr Gpw r10w = Gpw(Gp::kIdR10);
426
+ static constexpr Gpw r11w = Gpw(Gp::kIdR11);
427
+ static constexpr Gpw r12w = Gpw(Gp::kIdR12);
428
+ static constexpr Gpw r13w = Gpw(Gp::kIdR13);
429
+ static constexpr Gpw r14w = Gpw(Gp::kIdR14);
430
+ static constexpr Gpw r15w = Gpw(Gp::kIdR15);
431
+
432
+ static constexpr Gpd eax = Gpd(Gp::kIdAx);
433
+ static constexpr Gpd ebx = Gpd(Gp::kIdBx);
434
+ static constexpr Gpd ecx = Gpd(Gp::kIdCx);
435
+ static constexpr Gpd edx = Gpd(Gp::kIdDx);
436
+ static constexpr Gpd esp = Gpd(Gp::kIdSp);
437
+ static constexpr Gpd ebp = Gpd(Gp::kIdBp);
438
+ static constexpr Gpd esi = Gpd(Gp::kIdSi);
439
+ static constexpr Gpd edi = Gpd(Gp::kIdDi);
440
+ static constexpr Gpd r8d = Gpd(Gp::kIdR8);
441
+ static constexpr Gpd r9d = Gpd(Gp::kIdR9);
442
+ static constexpr Gpd r10d = Gpd(Gp::kIdR10);
443
+ static constexpr Gpd r11d = Gpd(Gp::kIdR11);
444
+ static constexpr Gpd r12d = Gpd(Gp::kIdR12);
445
+ static constexpr Gpd r13d = Gpd(Gp::kIdR13);
446
+ static constexpr Gpd r14d = Gpd(Gp::kIdR14);
447
+ static constexpr Gpd r15d = Gpd(Gp::kIdR15);
448
+
449
+ static constexpr Gpq rax = Gpq(Gp::kIdAx);
450
+ static constexpr Gpq rbx = Gpq(Gp::kIdBx);
451
+ static constexpr Gpq rcx = Gpq(Gp::kIdCx);
452
+ static constexpr Gpq rdx = Gpq(Gp::kIdDx);
453
+ static constexpr Gpq rsp = Gpq(Gp::kIdSp);
454
+ static constexpr Gpq rbp = Gpq(Gp::kIdBp);
455
+ static constexpr Gpq rsi = Gpq(Gp::kIdSi);
456
+ static constexpr Gpq rdi = Gpq(Gp::kIdDi);
457
+ static constexpr Gpq r8 = Gpq(Gp::kIdR8);
458
+ static constexpr Gpq r9 = Gpq(Gp::kIdR9);
459
+ static constexpr Gpq r10 = Gpq(Gp::kIdR10);
460
+ static constexpr Gpq r11 = Gpq(Gp::kIdR11);
461
+ static constexpr Gpq r12 = Gpq(Gp::kIdR12);
462
+ static constexpr Gpq r13 = Gpq(Gp::kIdR13);
463
+ static constexpr Gpq r14 = Gpq(Gp::kIdR14);
464
+ static constexpr Gpq r15 = Gpq(Gp::kIdR15);
465
+
466
+ static constexpr Xmm xmm0 = Xmm(0);
467
+ static constexpr Xmm xmm1 = Xmm(1);
468
+ static constexpr Xmm xmm2 = Xmm(2);
469
+ static constexpr Xmm xmm3 = Xmm(3);
470
+ static constexpr Xmm xmm4 = Xmm(4);
471
+ static constexpr Xmm xmm5 = Xmm(5);
472
+ static constexpr Xmm xmm6 = Xmm(6);
473
+ static constexpr Xmm xmm7 = Xmm(7);
474
+ static constexpr Xmm xmm8 = Xmm(8);
475
+ static constexpr Xmm xmm9 = Xmm(9);
476
+ static constexpr Xmm xmm10 = Xmm(10);
477
+ static constexpr Xmm xmm11 = Xmm(11);
478
+ static constexpr Xmm xmm12 = Xmm(12);
479
+ static constexpr Xmm xmm13 = Xmm(13);
480
+ static constexpr Xmm xmm14 = Xmm(14);
481
+ static constexpr Xmm xmm15 = Xmm(15);
482
+ static constexpr Xmm xmm16 = Xmm(16);
483
+ static constexpr Xmm xmm17 = Xmm(17);
484
+ static constexpr Xmm xmm18 = Xmm(18);
485
+ static constexpr Xmm xmm19 = Xmm(19);
486
+ static constexpr Xmm xmm20 = Xmm(20);
487
+ static constexpr Xmm xmm21 = Xmm(21);
488
+ static constexpr Xmm xmm22 = Xmm(22);
489
+ static constexpr Xmm xmm23 = Xmm(23);
490
+ static constexpr Xmm xmm24 = Xmm(24);
491
+ static constexpr Xmm xmm25 = Xmm(25);
492
+ static constexpr Xmm xmm26 = Xmm(26);
493
+ static constexpr Xmm xmm27 = Xmm(27);
494
+ static constexpr Xmm xmm28 = Xmm(28);
495
+ static constexpr Xmm xmm29 = Xmm(29);
496
+ static constexpr Xmm xmm30 = Xmm(30);
497
+ static constexpr Xmm xmm31 = Xmm(31);
498
+
499
+ static constexpr Ymm ymm0 = Ymm(0);
500
+ static constexpr Ymm ymm1 = Ymm(1);
501
+ static constexpr Ymm ymm2 = Ymm(2);
502
+ static constexpr Ymm ymm3 = Ymm(3);
503
+ static constexpr Ymm ymm4 = Ymm(4);
504
+ static constexpr Ymm ymm5 = Ymm(5);
505
+ static constexpr Ymm ymm6 = Ymm(6);
506
+ static constexpr Ymm ymm7 = Ymm(7);
507
+ static constexpr Ymm ymm8 = Ymm(8);
508
+ static constexpr Ymm ymm9 = Ymm(9);
509
+ static constexpr Ymm ymm10 = Ymm(10);
510
+ static constexpr Ymm ymm11 = Ymm(11);
511
+ static constexpr Ymm ymm12 = Ymm(12);
512
+ static constexpr Ymm ymm13 = Ymm(13);
513
+ static constexpr Ymm ymm14 = Ymm(14);
514
+ static constexpr Ymm ymm15 = Ymm(15);
515
+ static constexpr Ymm ymm16 = Ymm(16);
516
+ static constexpr Ymm ymm17 = Ymm(17);
517
+ static constexpr Ymm ymm18 = Ymm(18);
518
+ static constexpr Ymm ymm19 = Ymm(19);
519
+ static constexpr Ymm ymm20 = Ymm(20);
520
+ static constexpr Ymm ymm21 = Ymm(21);
521
+ static constexpr Ymm ymm22 = Ymm(22);
522
+ static constexpr Ymm ymm23 = Ymm(23);
523
+ static constexpr Ymm ymm24 = Ymm(24);
524
+ static constexpr Ymm ymm25 = Ymm(25);
525
+ static constexpr Ymm ymm26 = Ymm(26);
526
+ static constexpr Ymm ymm27 = Ymm(27);
527
+ static constexpr Ymm ymm28 = Ymm(28);
528
+ static constexpr Ymm ymm29 = Ymm(29);
529
+ static constexpr Ymm ymm30 = Ymm(30);
530
+ static constexpr Ymm ymm31 = Ymm(31);
531
+
532
+ static constexpr Zmm zmm0 = Zmm(0);
533
+ static constexpr Zmm zmm1 = Zmm(1);
534
+ static constexpr Zmm zmm2 = Zmm(2);
535
+ static constexpr Zmm zmm3 = Zmm(3);
536
+ static constexpr Zmm zmm4 = Zmm(4);
537
+ static constexpr Zmm zmm5 = Zmm(5);
538
+ static constexpr Zmm zmm6 = Zmm(6);
539
+ static constexpr Zmm zmm7 = Zmm(7);
540
+ static constexpr Zmm zmm8 = Zmm(8);
541
+ static constexpr Zmm zmm9 = Zmm(9);
542
+ static constexpr Zmm zmm10 = Zmm(10);
543
+ static constexpr Zmm zmm11 = Zmm(11);
544
+ static constexpr Zmm zmm12 = Zmm(12);
545
+ static constexpr Zmm zmm13 = Zmm(13);
546
+ static constexpr Zmm zmm14 = Zmm(14);
547
+ static constexpr Zmm zmm15 = Zmm(15);
548
+ static constexpr Zmm zmm16 = Zmm(16);
549
+ static constexpr Zmm zmm17 = Zmm(17);
550
+ static constexpr Zmm zmm18 = Zmm(18);
551
+ static constexpr Zmm zmm19 = Zmm(19);
552
+ static constexpr Zmm zmm20 = Zmm(20);
553
+ static constexpr Zmm zmm21 = Zmm(21);
554
+ static constexpr Zmm zmm22 = Zmm(22);
555
+ static constexpr Zmm zmm23 = Zmm(23);
556
+ static constexpr Zmm zmm24 = Zmm(24);
557
+ static constexpr Zmm zmm25 = Zmm(25);
558
+ static constexpr Zmm zmm26 = Zmm(26);
559
+ static constexpr Zmm zmm27 = Zmm(27);
560
+ static constexpr Zmm zmm28 = Zmm(28);
561
+ static constexpr Zmm zmm29 = Zmm(29);
562
+ static constexpr Zmm zmm30 = Zmm(30);
563
+ static constexpr Zmm zmm31 = Zmm(31);
564
+
565
+ static constexpr Mm mm0 = Mm(0);
566
+ static constexpr Mm mm1 = Mm(1);
567
+ static constexpr Mm mm2 = Mm(2);
568
+ static constexpr Mm mm3 = Mm(3);
569
+ static constexpr Mm mm4 = Mm(4);
570
+ static constexpr Mm mm5 = Mm(5);
571
+ static constexpr Mm mm6 = Mm(6);
572
+ static constexpr Mm mm7 = Mm(7);
573
+
574
+ static constexpr KReg k0 = KReg(0);
575
+ static constexpr KReg k1 = KReg(1);
576
+ static constexpr KReg k2 = KReg(2);
577
+ static constexpr KReg k3 = KReg(3);
578
+ static constexpr KReg k4 = KReg(4);
579
+ static constexpr KReg k5 = KReg(5);
580
+ static constexpr KReg k6 = KReg(6);
581
+ static constexpr KReg k7 = KReg(7);
582
+
583
+ static constexpr SReg no_seg = SReg(SReg::kIdNone);
584
+ static constexpr SReg es = SReg(SReg::kIdEs);
585
+ static constexpr SReg cs = SReg(SReg::kIdCs);
586
+ static constexpr SReg ss = SReg(SReg::kIdSs);
587
+ static constexpr SReg ds = SReg(SReg::kIdDs);
588
+ static constexpr SReg fs = SReg(SReg::kIdFs);
589
+ static constexpr SReg gs = SReg(SReg::kIdGs);
590
+
591
+ static constexpr CReg cr0 = CReg(0);
592
+ static constexpr CReg cr1 = CReg(1);
593
+ static constexpr CReg cr2 = CReg(2);
594
+ static constexpr CReg cr3 = CReg(3);
595
+ static constexpr CReg cr4 = CReg(4);
596
+ static constexpr CReg cr5 = CReg(5);
597
+ static constexpr CReg cr6 = CReg(6);
598
+ static constexpr CReg cr7 = CReg(7);
599
+ static constexpr CReg cr8 = CReg(8);
600
+ static constexpr CReg cr9 = CReg(9);
601
+ static constexpr CReg cr10 = CReg(10);
602
+ static constexpr CReg cr11 = CReg(11);
603
+ static constexpr CReg cr12 = CReg(12);
604
+ static constexpr CReg cr13 = CReg(13);
605
+ static constexpr CReg cr14 = CReg(14);
606
+ static constexpr CReg cr15 = CReg(15);
607
+
608
+ static constexpr DReg dr0 = DReg(0);
609
+ static constexpr DReg dr1 = DReg(1);
610
+ static constexpr DReg dr2 = DReg(2);
611
+ static constexpr DReg dr3 = DReg(3);
612
+ static constexpr DReg dr4 = DReg(4);
613
+ static constexpr DReg dr5 = DReg(5);
614
+ static constexpr DReg dr6 = DReg(6);
615
+ static constexpr DReg dr7 = DReg(7);
616
+ static constexpr DReg dr8 = DReg(8);
617
+ static constexpr DReg dr9 = DReg(9);
618
+ static constexpr DReg dr10 = DReg(10);
619
+ static constexpr DReg dr11 = DReg(11);
620
+ static constexpr DReg dr12 = DReg(12);
621
+ static constexpr DReg dr13 = DReg(13);
622
+ static constexpr DReg dr14 = DReg(14);
623
+ static constexpr DReg dr15 = DReg(15);
624
+
625
+ static constexpr St st0 = St(0);
626
+ static constexpr St st1 = St(1);
627
+ static constexpr St st2 = St(2);
628
+ static constexpr St st3 = St(3);
629
+ static constexpr St st4 = St(4);
630
+ static constexpr St st5 = St(5);
631
+ static constexpr St st6 = St(6);
632
+ static constexpr St st7 = St(7);
633
+
634
+ static constexpr Bnd bnd0 = Bnd(0);
635
+ static constexpr Bnd bnd1 = Bnd(1);
636
+ static constexpr Bnd bnd2 = Bnd(2);
637
+ static constexpr Bnd bnd3 = Bnd(3);
638
+
639
+ static constexpr Tmm tmm0 = Tmm(0);
640
+ static constexpr Tmm tmm1 = Tmm(1);
641
+ static constexpr Tmm tmm2 = Tmm(2);
642
+ static constexpr Tmm tmm3 = Tmm(3);
643
+ static constexpr Tmm tmm4 = Tmm(4);
644
+ static constexpr Tmm tmm5 = Tmm(5);
645
+ static constexpr Tmm tmm6 = Tmm(6);
646
+ static constexpr Tmm tmm7 = Tmm(7);
647
+
648
+ static constexpr Rip rip = Rip(0);
649
+
650
+ #ifndef _DOXYGEN
651
+ } // {regs}
652
+
653
+ // Make `x86::regs` accessible through `x86` namespace as well.
654
+ using namespace regs;
655
+ #endif
656
+
657
+ //! Memory operand specific to X86 and X86_64 architecture.
658
+ class Mem : public BaseMem {
659
+ public:
660
+ //! \name Constants
661
+ //! \{
662
+
663
+ //! Additional bits of operand's signature used by `x86::Mem`.
664
+ enum AdditionalBits : uint32_t {
665
+ // Memory address type (2 bits).
666
+ // |........|........|XX......|........|
667
+ kSignatureMemAddrTypeShift = 14,
668
+ kSignatureMemAddrTypeMask = 0x03u << kSignatureMemAddrTypeShift,
669
+
670
+ // Memory shift amount (2 bits).
671
+ // |........|......XX|........|........|
672
+ kSignatureMemShiftValueShift = 16,
673
+ kSignatureMemShiftValueMask = 0x03u << kSignatureMemShiftValueShift,
674
+
675
+ // Memory segment reg (3 bits).
676
+ // |........|...XXX..|........|........|
677
+ kSignatureMemSegmentShift = 18,
678
+ kSignatureMemSegmentMask = 0x07u << kSignatureMemSegmentShift,
679
+
680
+ // Memory broadcast type (3 bits).
681
+ // |........|XXX.....|........|........|
682
+ kSignatureMemBroadcastShift = 21,
683
+ kSignatureMemBroadcastMask = 0x7u << kSignatureMemBroadcastShift
684
+ };
685
+
686
+ //! Address type.
687
+ enum class AddrType : uint32_t {
688
+ //! Default address type, Assembler will select the best type when necessary.
689
+ kDefault = 0,
690
+ //! Absolute address type.
691
+ kAbs = 1,
692
+ //! Relative address type.
693
+ kRel = 2,
694
+
695
+ //! Maximum value of `AddrType`.
696
+ kMaxValue = kRel
697
+ };
698
+
699
+ //! Memory broadcast type.
700
+ enum class Broadcast : uint32_t {
701
+ //! No broadcast (regular memory operand).
702
+ kNone = 0,
703
+ //! Broadcast {1to2}.
704
+ k1To2 = 1,
705
+ //! Broadcast {1to4}.
706
+ k1To4 = 2,
707
+ //! Broadcast {1to8}.
708
+ k1To8 = 3,
709
+ //! Broadcast {1to16}.
710
+ k1To16 = 4,
711
+ //! Broadcast {1to32}.
712
+ k1To32 = 5,
713
+ //! Broadcast {1to64}.
714
+ k1To64 = 6,
715
+
716
+ //! Maximum value of `Broadcast`.
717
+ kMaxValue = k1To64
718
+ };
719
+
720
+ //! \}
721
+
722
+ //! \name Construction & Destruction
723
+ //! \{
724
+
725
+ //! Creates a default `Mem` operand that points to [0].
726
+ inline constexpr Mem() noexcept
727
+ : BaseMem() {}
728
+
729
+ inline constexpr Mem(const Mem& other) noexcept
730
+ : BaseMem(other) {}
731
+
732
+ inline explicit Mem(Globals::NoInit_) noexcept
733
+ : BaseMem(Globals::NoInit) {}
734
+
735
+ inline constexpr Mem(const Signature& signature, uint32_t baseId, uint32_t indexId, int32_t offset) noexcept
736
+ : BaseMem(signature, baseId, indexId, offset) {}
737
+
738
+ inline constexpr Mem(const Label& base, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
739
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
740
+ Signature::fromMemBaseType(RegType::kLabelTag) |
741
+ Signature::fromSize(size) |
742
+ signature, base.id(), 0, off) {}
743
+
744
+ inline constexpr Mem(const Label& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
745
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
746
+ Signature::fromMemBaseType(RegType::kLabelTag) |
747
+ Signature::fromMemIndexType(index.type()) |
748
+ Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
749
+ Signature::fromSize(size) |
750
+ signature, base.id(), index.id(), off) {}
751
+
752
+ inline constexpr Mem(const BaseReg& base, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
753
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
754
+ Signature::fromMemBaseType(base.type()) |
755
+ Signature::fromSize(size) |
756
+ signature, base.id(), 0, off) {}
757
+
758
+ inline constexpr Mem(const BaseReg& base, const BaseReg& index, uint32_t shift, int32_t off, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
759
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
760
+ Signature::fromMemBaseType(base.type()) |
761
+ Signature::fromMemIndexType(index.type()) |
762
+ Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
763
+ Signature::fromSize(size) |
764
+ signature, base.id(), index.id(), off) {}
765
+
766
+ inline constexpr explicit Mem(uint64_t base, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
767
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
768
+ Signature::fromSize(size) |
769
+ signature, uint32_t(base >> 32), 0, int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
770
+
771
+ inline constexpr Mem(uint64_t base, const BaseReg& index, uint32_t shift = 0, uint32_t size = 0, Signature signature = OperandSignature{0}) noexcept
772
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
773
+ Signature::fromMemIndexType(index.type()) |
774
+ Signature::fromValue<kSignatureMemShiftValueMask>(shift) |
775
+ Signature::fromSize(size) |
776
+ signature, uint32_t(base >> 32), index.id(), int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
777
+
778
+ //! \}
779
+
780
+ //! \name Overloaded Operators
781
+ //! \{
782
+
783
+ inline Mem& operator=(const Mem& other) noexcept = default;
784
+
785
+ //! \}
786
+
787
+ //! \name Clone
788
+ //! \{
789
+
790
+ //! Clones the memory operand.
791
+ inline constexpr Mem clone() const noexcept { return Mem(*this); }
792
+
793
+ //! Creates a new copy of this memory operand adjusted by `off`.
794
+ inline Mem cloneAdjusted(int64_t off) const noexcept {
795
+ Mem result(*this);
796
+ result.addOffset(off);
797
+ return result;
798
+ }
799
+
800
+ inline constexpr Mem cloneBroadcasted(Broadcast b) const noexcept {
801
+ return Mem((_signature & ~Signature{kSignatureMemBroadcastMask}) | Signature::fromValue<kSignatureMemBroadcastMask>(b), _baseId, _data[0], int32_t(_data[1]));
802
+ }
803
+
804
+ //! \}
805
+
806
+ //! \name Base & Index
807
+ //! \{
808
+
809
+ //! Converts memory `baseType` and `baseId` to `x86::Reg` instance.
810
+ //!
811
+ //! The memory must have a valid base register otherwise the result will be wrong.
812
+ inline Reg baseReg() const noexcept { return Reg::fromTypeAndId(baseType(), baseId()); }
813
+
814
+ //! Converts memory `indexType` and `indexId` to `x86::Reg` instance.
815
+ //!
816
+ //! The memory must have a valid index register otherwise the result will be wrong.
817
+ inline Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
818
+
819
+ using BaseMem::setIndex;
820
+
821
+ inline void setIndex(const BaseReg& index, uint32_t shift) noexcept {
822
+ setIndex(index);
823
+ setShift(shift);
824
+ }
825
+
826
+ //! \}
827
+
828
+ //! \name Address Type
829
+ //! \{
830
+
831
+ //! Returns the address type of the memory operand.
832
+ //!
833
+ //! By default, address type of newly created memory operands is always \ref AddrType::kDefault.
834
+ inline constexpr AddrType addrType() const noexcept { return (AddrType)_signature.getField<kSignatureMemAddrTypeMask>(); }
835
+ //! Sets the address type to `addrType`.
836
+ inline void setAddrType(AddrType addrType) noexcept { _signature.setField<kSignatureMemAddrTypeMask>(uint32_t(addrType)); }
837
+ //! Resets the address type to \ref AddrType::kDefault.
838
+ inline void resetAddrType() noexcept { _signature.setField<kSignatureMemAddrTypeMask>(uint32_t(AddrType::kDefault)); }
839
+
840
+ //! Tests whether the address type is \ref AddrType::kAbs.
841
+ inline constexpr bool isAbs() const noexcept { return addrType() == AddrType::kAbs; }
842
+ //! Sets the address type to \ref AddrType::kAbs.
843
+ inline void setAbs() noexcept { setAddrType(AddrType::kAbs); }
844
+
845
+ //! Tests whether the address type is \ref AddrType::kRel.
846
+ inline constexpr bool isRel() const noexcept { return addrType() == AddrType::kRel; }
847
+ //! Sets the address type to \ref AddrType::kRel.
848
+ inline void setRel() noexcept { setAddrType(AddrType::kRel); }
849
+
850
+ //! \}
851
+
852
+ //! \name Segment
853
+ //! \{
854
+
855
+ //! Tests whether the memory operand has a segment override.
856
+ inline constexpr bool hasSegment() const noexcept { return _signature.hasField<kSignatureMemSegmentMask>(); }
857
+ //! Returns the associated segment override as `SReg` operand.
858
+ inline constexpr SReg segment() const noexcept { return SReg(segmentId()); }
859
+ //! Returns segment override register id, see `SReg::Id`.
860
+ inline constexpr uint32_t segmentId() const noexcept { return _signature.getField<kSignatureMemSegmentMask>(); }
861
+
862
+ //! Sets the segment override to `seg`.
863
+ inline void setSegment(const SReg& seg) noexcept { setSegment(seg.id()); }
864
+ //! Sets the segment override to `id`.
865
+ inline void setSegment(uint32_t rId) noexcept { _signature.setField<kSignatureMemSegmentMask>(rId); }
866
+ //! Resets the segment override.
867
+ inline void resetSegment() noexcept { _signature.setField<kSignatureMemSegmentMask>(0); }
868
+
869
+ //! \}
870
+
871
+ //! \name Shift
872
+ //! \{
873
+
874
+ //! Tests whether the memory operand has shift (aka scale) value.
875
+ inline constexpr bool hasShift() const noexcept { return _signature.hasField<kSignatureMemShiftValueMask>(); }
876
+ //! Returns the memory operand's shift (aka scale) value.
877
+ inline constexpr uint32_t shift() const noexcept { return _signature.getField<kSignatureMemShiftValueMask>(); }
878
+ //! Sets the memory operand's shift (aka scale) value.
879
+ inline void setShift(uint32_t shift) noexcept { _signature.setField<kSignatureMemShiftValueMask>(shift); }
880
+ //! Resets the memory operand's shift (aka scale) value to zero.
881
+ inline void resetShift() noexcept { _signature.setField<kSignatureMemShiftValueMask>(0); }
882
+
883
+ //! \}
884
+
885
+ //! \name Broadcast
886
+ //! \{
887
+
888
+ //! Tests whether the memory operand has broadcast {1tox}.
889
+ inline constexpr bool hasBroadcast() const noexcept { return _signature.hasField<kSignatureMemBroadcastMask>(); }
890
+ //! Returns the memory operand's broadcast.
891
+ inline constexpr Broadcast getBroadcast() const noexcept { return (Broadcast)_signature.getField<kSignatureMemBroadcastMask>(); }
892
+ //! Sets the memory operand's broadcast.
893
+ inline void setBroadcast(Broadcast b) noexcept { _signature.setField<kSignatureMemBroadcastMask>(uint32_t(b)); }
894
+ //! Resets the memory operand's broadcast to none.
895
+ inline void resetBroadcast() noexcept { _signature.setField<kSignatureMemBroadcastMask>(0); }
896
+
897
+ //! Returns a new `Mem` without a broadcast (the possible broadcast is cleared).
898
+ inline constexpr Mem _1to1() const noexcept { return cloneBroadcasted(Broadcast::kNone); }
899
+ //! Returns a new `Mem` with {1to2} broadcast (AVX-512).
900
+ inline constexpr Mem _1to2() const noexcept { return cloneBroadcasted(Broadcast::k1To2); }
901
+ //! Returns a new `Mem` with {1to4} broadcast (AVX-512).
902
+ inline constexpr Mem _1to4() const noexcept { return cloneBroadcasted(Broadcast::k1To4); }
903
+ //! Returns a new `Mem` with {1to8} broadcast (AVX-512).
904
+ inline constexpr Mem _1to8() const noexcept { return cloneBroadcasted(Broadcast::k1To8); }
905
+ //! Returns a new `Mem` with {1to16} broadcast (AVX-512).
906
+ inline constexpr Mem _1to16() const noexcept { return cloneBroadcasted(Broadcast::k1To16); }
907
+ //! Returns a new `Mem` with {1to32} broadcast (AVX-512).
908
+ inline constexpr Mem _1to32() const noexcept { return cloneBroadcasted(Broadcast::k1To32); }
909
+ //! Returns a new `Mem` with {1to64} broadcast (AVX-512).
910
+ inline constexpr Mem _1to64() const noexcept { return cloneBroadcasted(Broadcast::k1To64); }
911
+
912
+ //! \}
913
+ };
914
+
915
+ //! Creates `[base.reg + offset]` memory operand.
916
+ static inline constexpr Mem ptr(const Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
917
+ return Mem(base, offset, size);
918
+ }
919
+ //! Creates `[base.reg + (index << shift) + offset]` memory operand (scalar index).
920
+ static inline constexpr Mem ptr(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
921
+ return Mem(base, index, shift, offset, size);
922
+ }
923
+ //! Creates `[base.reg + (index << shift) + offset]` memory operand (vector index).
924
+ static inline constexpr Mem ptr(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
925
+ return Mem(base, index, shift, offset, size);
926
+ }
927
+
928
+ //! Creates `[base + offset]` memory operand.
929
+ static inline constexpr Mem ptr(const Label& base, int32_t offset = 0, uint32_t size = 0) noexcept {
930
+ return Mem(base, offset, size);
931
+ }
932
+ //! Creates `[base + (index << shift) + offset]` memory operand.
933
+ static inline constexpr Mem ptr(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
934
+ return Mem(base, index, shift, offset, size);
935
+ }
936
+ //! Creates `[base + (index << shift) + offset]` memory operand.
937
+ static inline constexpr Mem ptr(const Label& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
938
+ return Mem(base, index, shift, offset, size);
939
+ }
940
+
941
+ //! Creates `[rip + offset]` memory operand.
942
+ static inline constexpr Mem ptr(const Rip& rip_, int32_t offset = 0, uint32_t size = 0) noexcept {
943
+ return Mem(rip_, offset, size);
944
+ }
945
+
946
+ //! Creates `[base]` absolute memory operand.
947
+ static inline constexpr Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
948
+ return Mem(base, size);
949
+ }
950
+ //! Creates `[base + (index.reg << shift)]` absolute memory operand.
951
+ static inline constexpr Mem ptr(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
952
+ return Mem(base, index, shift, size);
953
+ }
954
+ //! Creates `[base + (index.reg << shift)]` absolute memory operand.
955
+ static inline constexpr Mem ptr(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
956
+ return Mem(base, index, shift, size);
957
+ }
958
+
959
+ //! Creates `[base]` absolute memory operand (absolute).
960
+ static inline constexpr Mem ptr_abs(uint64_t base, uint32_t size = 0) noexcept {
961
+ return Mem(base, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
962
+ }
963
+ //! Creates `[base + (index.reg << shift)]` absolute memory operand (absolute).
964
+ static inline constexpr Mem ptr_abs(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
965
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
966
+ }
967
+ //! Creates `[base + (index.reg << shift)]` absolute memory operand (absolute).
968
+ static inline constexpr Mem ptr_abs(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
969
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs));
970
+ }
971
+
972
+ //! Creates `[base]` relative memory operand (relative).
973
+ static inline constexpr Mem ptr_rel(uint64_t base, uint32_t size = 0) noexcept {
974
+ return Mem(base, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
975
+ }
976
+ //! Creates `[base + (index.reg << shift)]` relative memory operand (relative).
977
+ static inline constexpr Mem ptr_rel(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
978
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
979
+ }
980
+ //! Creates `[base + (index.reg << shift)]` relative memory operand (relative).
981
+ static inline constexpr Mem ptr_rel(uint64_t base, const Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
982
+ return Mem(base, index, shift, size, OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel));
983
+ }
984
+
985
+ #define ASMJIT_MEM_PTR(FUNC, SIZE) \
986
+ static constexpr Mem FUNC(const Gp& base, int32_t offset = 0) noexcept { \
987
+ return Mem(base, offset, SIZE); \
988
+ } \
989
+ static constexpr Mem FUNC(const Gp& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
990
+ return Mem(base, index, shift, offset, SIZE); \
991
+ } \
992
+ static constexpr Mem FUNC(const Gp& base, const Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
993
+ return Mem(base, index, shift, offset, SIZE); \
994
+ } \
995
+ static constexpr Mem FUNC(const Label& base, int32_t offset = 0) noexcept { \
996
+ return Mem(base, offset, SIZE); \
997
+ } \
998
+ static constexpr Mem FUNC(const Label& base, const Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
999
+ return Mem(base, index, shift, offset, SIZE); \
1000
+ } \
1001
+ static constexpr Mem FUNC(const Rip& rip_, int32_t offset = 0) noexcept { \
1002
+ return Mem(rip_, offset, SIZE); \
1003
+ } \
1004
+ static constexpr Mem FUNC(uint64_t base) noexcept { \
1005
+ return Mem(base, SIZE); \
1006
+ } \
1007
+ static constexpr Mem FUNC(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
1008
+ return Mem(base, index, shift, SIZE); \
1009
+ } \
1010
+ static constexpr Mem FUNC(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
1011
+ return Mem(base, index, shift, SIZE); \
1012
+ } \
1013
+ \
1014
+ static constexpr Mem FUNC##_abs(uint64_t base) noexcept { \
1015
+ return Mem(base, SIZE, \
1016
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); \
1017
+ } \
1018
+ static constexpr Mem FUNC##_abs(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
1019
+ return Mem(base, index, shift, SIZE, \
1020
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); \
1021
+ } \
1022
+ static constexpr Mem FUNC##_abs(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
1023
+ return Mem(base, index, shift, SIZE, \
1024
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kAbs)); \
1025
+ } \
1026
+ \
1027
+ static constexpr Mem FUNC##_rel(uint64_t base) noexcept { \
1028
+ return Mem(base, SIZE, \
1029
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); \
1030
+ } \
1031
+ static constexpr Mem FUNC##_rel(uint64_t base, const Gp& index, uint32_t shift = 0) noexcept { \
1032
+ return Mem(base, index, shift, SIZE, \
1033
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); \
1034
+ } \
1035
+ static constexpr Mem FUNC##_rel(uint64_t base, const Vec& index, uint32_t shift = 0) noexcept { \
1036
+ return Mem(base, index, shift, SIZE, \
1037
+ OperandSignature::fromValue<Mem::kSignatureMemAddrTypeMask>(Mem::AddrType::kRel)); \
1038
+ }
1039
+
1040
+ // Definition of memory operand constructors that use platform independent naming.
1041
+ ASMJIT_MEM_PTR(ptr_8, 1)
1042
+ ASMJIT_MEM_PTR(ptr_16, 2)
1043
+ ASMJIT_MEM_PTR(ptr_32, 4)
1044
+ ASMJIT_MEM_PTR(ptr_48, 6)
1045
+ ASMJIT_MEM_PTR(ptr_64, 8)
1046
+ ASMJIT_MEM_PTR(ptr_80, 10)
1047
+ ASMJIT_MEM_PTR(ptr_128, 16)
1048
+ ASMJIT_MEM_PTR(ptr_256, 32)
1049
+ ASMJIT_MEM_PTR(ptr_512, 64)
1050
+
1051
+ // Definition of memory operand constructors that use X86-specific convention.
1052
+ ASMJIT_MEM_PTR(byte_ptr, 1)
1053
+ ASMJIT_MEM_PTR(word_ptr, 2)
1054
+ ASMJIT_MEM_PTR(dword_ptr, 4)
1055
+ ASMJIT_MEM_PTR(fword_ptr, 6)
1056
+ ASMJIT_MEM_PTR(qword_ptr, 8)
1057
+ ASMJIT_MEM_PTR(tbyte_ptr, 10)
1058
+ ASMJIT_MEM_PTR(tword_ptr, 10)
1059
+ ASMJIT_MEM_PTR(oword_ptr, 16)
1060
+ ASMJIT_MEM_PTR(dqword_ptr, 16)
1061
+ ASMJIT_MEM_PTR(qqword_ptr, 32)
1062
+ ASMJIT_MEM_PTR(xmmword_ptr, 16)
1063
+ ASMJIT_MEM_PTR(ymmword_ptr, 32)
1064
+ ASMJIT_MEM_PTR(zmmword_ptr, 64)
1065
+
1066
+ #undef ASMJIT_MEM_PTR
1067
+
1068
+ //! \}
1069
+
1070
+ ASMJIT_END_SUB_NAMESPACE
1071
+
1072
+ //! \cond INTERNAL
1073
+ ASMJIT_BEGIN_NAMESPACE
1074
+ ASMJIT_DEFINE_TYPE_ID(x86::Gpb, TypeId::kInt8);
1075
+ ASMJIT_DEFINE_TYPE_ID(x86::Gpw, TypeId::kInt16);
1076
+ ASMJIT_DEFINE_TYPE_ID(x86::Gpd, TypeId::kInt32);
1077
+ ASMJIT_DEFINE_TYPE_ID(x86::Gpq, TypeId::kInt64);
1078
+ ASMJIT_DEFINE_TYPE_ID(x86::Mm , TypeId::kMmx64);
1079
+ ASMJIT_DEFINE_TYPE_ID(x86::Xmm, TypeId::kInt32x4);
1080
+ ASMJIT_DEFINE_TYPE_ID(x86::Ymm, TypeId::kInt32x8);
1081
+ ASMJIT_DEFINE_TYPE_ID(x86::Zmm, TypeId::kInt32x16);
1082
+ ASMJIT_END_NAMESPACE
1083
+ //! \endcond
1084
+
1085
+ #endif // ASMJIT_X86_X86OPERAND_H_INCLUDED