asmjit 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,621 @@
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_ARM_ARMOPERAND_H_INCLUDED
7
+ #define ASMJIT_ARM_ARMOPERAND_H_INCLUDED
8
+
9
+ #include "../core/archtraits.h"
10
+ #include "../core/operand.h"
11
+ #include "../core/type.h"
12
+ #include "../arm/armglobals.h"
13
+
14
+ ASMJIT_BEGIN_SUB_NAMESPACE(arm)
15
+
16
+ //! \addtogroup asmjit_arm
17
+ //! \{
18
+
19
+ class Reg;
20
+ class Mem;
21
+
22
+ class Gp;
23
+ class GpW;
24
+ class GpX;
25
+
26
+ class Vec;
27
+ class VecB;
28
+ class VecH;
29
+ class VecS;
30
+ class VecD;
31
+ class VecV;
32
+
33
+ //! Register traits (ARM/AArch64).
34
+ //!
35
+ //! Register traits contains information about a particular register type. It's used by asmjit to setup register
36
+ //! information on-the-fly and to populate tables that contain register information (this way it's possible to
37
+ //! change register types and groups without having to reorder these tables).
38
+ template<RegType kRegType>
39
+ struct RegTraits : public BaseRegTraits {};
40
+
41
+ //! \cond
42
+ // <--------------------+-----+-------------------------+------------------------+---+---+------------------+
43
+ // | Reg | Reg-Type | Reg-Group |Sz |Cnt| TypeId |
44
+ // <--------------------+-----+-------------------------+------------------------+---+---+------------------+
45
+ ASMJIT_DEFINE_REG_TRAITS(GpW , RegType::kARM_GpW , RegGroup::kGp , 4 , 32, TypeId::kInt32 );
46
+ ASMJIT_DEFINE_REG_TRAITS(GpX , RegType::kARM_GpX , RegGroup::kGp , 8 , 32, TypeId::kInt64 );
47
+ ASMJIT_DEFINE_REG_TRAITS(VecB , RegType::kARM_VecB , RegGroup::kVec , 1 , 32, TypeId::kVoid );
48
+ ASMJIT_DEFINE_REG_TRAITS(VecH , RegType::kARM_VecH , RegGroup::kVec , 2 , 32, TypeId::kVoid );
49
+ ASMJIT_DEFINE_REG_TRAITS(VecS , RegType::kARM_VecS , RegGroup::kVec , 4 , 32, TypeId::kInt32x1 );
50
+ ASMJIT_DEFINE_REG_TRAITS(VecD , RegType::kARM_VecD , RegGroup::kVec , 8 , 32, TypeId::kInt32x2 );
51
+ ASMJIT_DEFINE_REG_TRAITS(VecV , RegType::kARM_VecV , RegGroup::kVec , 16, 32, TypeId::kInt32x4 );
52
+ //! \endcond
53
+
54
+ //! Register (ARM).
55
+ class Reg : public BaseReg {
56
+ public:
57
+ ASMJIT_DEFINE_ABSTRACT_REG(Reg, BaseReg)
58
+
59
+ //! Gets whether the register is a `R|W` register (32-bit).
60
+ inline constexpr bool isGpW() const noexcept { return baseSignature() == RegTraits<RegType::kARM_GpW>::kSignature; }
61
+ //! Gets whether the register is an `X` register (64-bit).
62
+ inline constexpr bool isGpX() const noexcept { return baseSignature() == RegTraits<RegType::kARM_GpX>::kSignature; }
63
+ //! Gets whether the register is a VEC-B register (8-bit).
64
+ inline constexpr bool isVecB() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecB>::kSignature; }
65
+ //! Gets whether the register is a VEC-H register (16-bit).
66
+ inline constexpr bool isVecH() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecH>::kSignature; }
67
+ //! Gets whether the register is a VEC-S register (32-bit).
68
+ inline constexpr bool isVecS() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecS>::kSignature; }
69
+ //! Gets whether the register is a VEC-D register (64-bit).
70
+ inline constexpr bool isVecD() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecD>::kSignature; }
71
+ //! Gets whether the register is a VEC-Q register (128-bit).
72
+ inline constexpr bool isVecQ() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecV>::kSignature; }
73
+
74
+ //! Gets whether the register is either VEC-D (64-bit) or VEC-Q (128-bit).
75
+ inline constexpr bool isVecDOrQ() const noexcept { return uint32_t(type()) - uint32_t(RegType::kARM_VecD) <= 1u; }
76
+
77
+ //! Gets whether the register is a VEC-V register (128-bit).
78
+ inline constexpr bool isVecV() const noexcept { return baseSignature() == RegTraits<RegType::kARM_VecV>::kSignature; }
79
+
80
+ template<RegType kRegType>
81
+ inline void setRegT(uint32_t id) noexcept {
82
+ setSignature(RegTraits<kRegType>::kSignature);
83
+ setId(id);
84
+ }
85
+
86
+ inline void setTypeAndId(RegType type, uint32_t id) noexcept {
87
+ setSignature(signatureOf(type));
88
+ setId(id);
89
+ }
90
+
91
+ static inline RegGroup groupOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kAArch64).regTypeToGroup(type); }
92
+ static inline TypeId typeIdOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kAArch64).regTypeToTypeId(type); }
93
+ static inline OperandSignature signatureOf(RegType type) noexcept { return ArchTraits::byArch(Arch::kAArch64).regTypeToSignature(type); }
94
+
95
+ template<RegType kRegType>
96
+ static inline RegGroup groupOfT() noexcept { return RegTraits<kRegType>::kGroup; }
97
+
98
+ template<RegType kRegType>
99
+ static inline TypeId typeIdOfT() noexcept { return RegTraits<kRegType>::kTypeId; }
100
+
101
+ template<RegType kRegType>
102
+ static inline OperandSignature signatureOfT() noexcept { return RegTraits<kRegType>::kSignature; }
103
+
104
+ static inline bool isGpW(const Operand_& op) noexcept { return op.as<Reg>().isGpW(); }
105
+ static inline bool isGpX(const Operand_& op) noexcept { return op.as<Reg>().isGpX(); }
106
+ static inline bool isVecB(const Operand_& op) noexcept { return op.as<Reg>().isVecB(); }
107
+ static inline bool isVecH(const Operand_& op) noexcept { return op.as<Reg>().isVecH(); }
108
+ static inline bool isVecS(const Operand_& op) noexcept { return op.as<Reg>().isVecS(); }
109
+ static inline bool isVecD(const Operand_& op) noexcept { return op.as<Reg>().isVecD(); }
110
+ static inline bool isVecQ(const Operand_& op) noexcept { return op.as<Reg>().isVecQ(); }
111
+ static inline bool isVecV(const Operand_& op) noexcept { return op.as<Reg>().isVecV(); }
112
+
113
+ static inline bool isGpW(const Operand_& op, uint32_t id) noexcept { return isGpW(op) & (op.id() == id); }
114
+ static inline bool isGpX(const Operand_& op, uint32_t id) noexcept { return isGpX(op) & (op.id() == id); }
115
+ static inline bool isVecB(const Operand_& op, uint32_t id) noexcept { return isVecB(op) & (op.id() == id); }
116
+ static inline bool isVecH(const Operand_& op, uint32_t id) noexcept { return isVecH(op) & (op.id() == id); }
117
+ static inline bool isVecS(const Operand_& op, uint32_t id) noexcept { return isVecS(op) & (op.id() == id); }
118
+ static inline bool isVecD(const Operand_& op, uint32_t id) noexcept { return isVecD(op) & (op.id() == id); }
119
+ static inline bool isVecQ(const Operand_& op, uint32_t id) noexcept { return isVecQ(op) & (op.id() == id); }
120
+ static inline bool isVecV(const Operand_& op, uint32_t id) noexcept { return isVecV(op) & (op.id() == id); }
121
+ };
122
+
123
+ //! General purpose register (ARM).
124
+ class Gp : public Reg {
125
+ public:
126
+ ASMJIT_DEFINE_ABSTRACT_REG(Gp, Reg)
127
+
128
+ //! Special register id.
129
+ enum Id : uint32_t {
130
+ //! Register that depends on OS, could be used as TLS offset.
131
+ kIdOs = 18,
132
+ //! Frame pointer.
133
+ kIdFp = 29,
134
+ //! Link register.
135
+ kIdLr = 30,
136
+ //! Stack register id.
137
+ kIdSp = 31,
138
+ //! Zero register id.
139
+ //!
140
+ //! Although zero register has the same id as stack register it has a special treatment, because we need to be
141
+ //! able to distinguish between these two at API level. Some intructions were designed to be used with SP and
142
+ //! some other with ZR - so we need a way to distinguish these two to make sure we emit the right thing.
143
+ //!
144
+ //! The number 63 is not random, when you perform `id & 31` you would always get 31 for both SP and ZR inputs,
145
+ //! which is the identifier used by AArch64 ISA to encode either SP or ZR depending on the instruction.
146
+ kIdZr = 63
147
+ };
148
+
149
+ inline constexpr bool isZR() const noexcept { return id() == kIdZr; }
150
+ inline constexpr bool isSP() const noexcept { return id() == kIdSp; }
151
+
152
+ //! Cast this register to a 32-bit R|W.
153
+ inline GpW w() const noexcept;
154
+ //! Cast this register to a 64-bit X.
155
+ inline GpX x() const noexcept;
156
+ };
157
+
158
+ //! Vector register (ARM).
159
+ class Vec : public Reg {
160
+ public:
161
+ ASMJIT_DEFINE_ABSTRACT_REG(Vec, Reg)
162
+
163
+ //! Additional signature bits used by arm::Vec.
164
+ enum AdditionalBits : uint32_t {
165
+ // Register element type (3 bits).
166
+ // |........|........|.XXX....|........|
167
+ kSignatureRegElementTypeShift = 12,
168
+ kSignatureRegElementTypeMask = 0x07 << kSignatureRegElementTypeShift,
169
+
170
+ // Register has element index (1 bit).
171
+ // |........|........|X.......|........|
172
+ kSignatureRegElementFlagShift = 15,
173
+ kSignatureRegElementFlagMask = 0x01 << kSignatureRegElementFlagShift,
174
+
175
+ // Register element index (4 bits).
176
+ // |........|....XXXX|........|........|
177
+ kSignatureRegElementIndexShift = 16,
178
+ kSignatureRegElementIndexMask = 0x0F << kSignatureRegElementIndexShift
179
+ };
180
+
181
+ //! Element type.
182
+ enum ElementType : uint32_t {
183
+ //! No element type specified.
184
+ kElementTypeNone = 0,
185
+ //! Byte elements (B8 or B16).
186
+ kElementTypeB,
187
+ //! Halfword elements (H4 or H8).
188
+ kElementTypeH,
189
+ //! Singleword elements (S2 or S4).
190
+ kElementTypeS,
191
+ //! Doubleword elements (D2).
192
+ kElementTypeD,
193
+ //! Byte elements grouped by 4 bytes (B4).
194
+ //!
195
+ //! \note This element-type is only used by few instructions.
196
+ kElementTypeB4,
197
+ //! Halfword elements grouped by 2 halfwords (H2).
198
+ //!
199
+ //! \note This element-type is only used by few instructions.
200
+ kElementTypeH2,
201
+
202
+ //! Count of element types.
203
+ kElementTypeCount
204
+ };
205
+
206
+ //! \cond
207
+ //! Shortcuts.
208
+ enum SignatureReg : uint32_t {
209
+ kSignatureElementB = kElementTypeB << kSignatureRegElementTypeShift,
210
+ kSignatureElementH = kElementTypeH << kSignatureRegElementTypeShift,
211
+ kSignatureElementS = kElementTypeS << kSignatureRegElementTypeShift,
212
+ kSignatureElementD = kElementTypeD << kSignatureRegElementTypeShift,
213
+ kSignatureElementB4 = kElementTypeB4 << kSignatureRegElementTypeShift,
214
+ kSignatureElementH2 = kElementTypeH2 << kSignatureRegElementTypeShift
215
+ };
216
+ //! \endcond
217
+
218
+ //! Returns whether the register has associated an element type.
219
+ inline constexpr bool hasElementType() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask>(); }
220
+ //! Returns whether the register has element index (it's an element index access).
221
+ inline constexpr bool hasElementIndex() const noexcept { return _signature.hasField<kSignatureRegElementFlagMask>(); }
222
+ //! Returns whether the reggister has element type or element index (or both).
223
+ inline constexpr bool hasElementTypeOrIndex() const noexcept { return _signature.hasField<kSignatureRegElementTypeMask | kSignatureRegElementFlagMask>(); }
224
+
225
+ //! Returns element type of the register.
226
+ inline constexpr uint32_t elementType() const noexcept { return _signature.getField<kSignatureRegElementTypeMask>(); }
227
+ //! Sets element type of the register to `elementType`.
228
+ inline void setElementType(uint32_t elementType) noexcept { _signature.setField<kSignatureRegElementTypeMask>(elementType); }
229
+ //! Resets element type to none.
230
+ inline void resetElementType() noexcept { _signature.setField<kSignatureRegElementTypeMask>(0); }
231
+
232
+ //! Returns element index of the register.
233
+ inline constexpr uint32_t elementIndex() const noexcept { return _signature.getField<kSignatureRegElementIndexMask>(); }
234
+ //! Sets element index of the register to `elementType`.
235
+ inline void setElementIndex(uint32_t elementIndex) noexcept {
236
+ _signature |= kSignatureRegElementFlagMask;
237
+ _signature.setField<kSignatureRegElementIndexMask>(elementIndex);
238
+ }
239
+ //! Resets element index of the register.
240
+ inline void resetElementIndex() noexcept {
241
+ _signature &= ~(kSignatureRegElementFlagMask | kSignatureRegElementIndexMask);
242
+ }
243
+
244
+ inline constexpr bool isVecB8() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementB); }
245
+ inline constexpr bool isVecH4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementH); }
246
+ inline constexpr bool isVecS2() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature | kSignatureElementS); }
247
+ inline constexpr bool isVecD1() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecD>::kSignature); }
248
+
249
+ inline constexpr bool isVecB16() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementB); }
250
+ inline constexpr bool isVecH8() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementH); }
251
+ inline constexpr bool isVecS4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementS); }
252
+ inline constexpr bool isVecD2() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementD); }
253
+ inline constexpr bool isVecB4x4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementB4); }
254
+ inline constexpr bool isVecH2x4() const noexcept { return _signature.subset(kBaseSignatureMask | kSignatureRegElementTypeMask) == (RegTraits<RegType::kARM_VecV>::kSignature | kSignatureElementH2); }
255
+
256
+ //! Creates a cloned register with element access.
257
+ inline Vec at(uint32_t elementIndex) const noexcept {
258
+ return Vec((signature() & ~kSignatureRegElementIndexMask) | (elementIndex << kSignatureRegElementIndexShift) | kSignatureRegElementFlagMask, id());
259
+ }
260
+
261
+ //! Cast this register to an 8-bit B register (scalar).
262
+ inline VecB b() const noexcept;
263
+ //! Cast this register to a 16-bit H register (scalar).
264
+ inline VecH h() const noexcept;
265
+ //! Cast this register to a 32-bit S register (scalar).
266
+ inline VecS s() const noexcept;
267
+ //! Cast this register to a 64-bit D register (scalar).
268
+ inline VecD d() const noexcept;
269
+ //! Cast this register to a 128-bit Q register (scalar).
270
+ inline VecV q() const noexcept;
271
+ //! Cast this register to a 128-bit V register.
272
+ inline VecV v() const noexcept;
273
+
274
+ //! Cast this register to a 128-bit V.B[elementIndex] register.
275
+ inline VecV b(uint32_t elementIndex) const noexcept;
276
+ //! Cast this register to a 128-bit V.H[elementIndex] register.
277
+ inline VecV h(uint32_t elementIndex) const noexcept;
278
+ //! Cast this register to a 128-bit V.S[elementIndex] register.
279
+ inline VecV s(uint32_t elementIndex) const noexcept;
280
+ //! Cast this register to a 128-bit V.D[elementIndex] register.
281
+ inline VecV d(uint32_t elementIndex) const noexcept;
282
+ //! Cast this register to a 128-bit V.H2[elementIndex] register.
283
+ inline VecV h2(uint32_t elementIndex) const noexcept;
284
+ //! Cast this register to a 128-bit V.B4[elementIndex] register.
285
+ inline VecV b4(uint32_t elementIndex) const noexcept;
286
+
287
+ //! Cast this register to V.8B.
288
+ inline VecD b8() const noexcept;
289
+ //! Cast this register to V.16B.
290
+ inline VecV b16() const noexcept;
291
+ //! Cast this register to V.2H.
292
+ inline VecS h2() const noexcept;
293
+ //! Cast this register to V.4H.
294
+ inline VecD h4() const noexcept;
295
+ //! Cast this register to V.8H.
296
+ inline VecV h8() const noexcept;
297
+ //! Cast this register to V.2S.
298
+ inline VecD s2() const noexcept;
299
+ //! Cast this register to V.4S.
300
+ inline VecV s4() const noexcept;
301
+ //! Cast this register to V.2D.
302
+ inline VecV d2() const noexcept;
303
+
304
+ static inline constexpr OperandSignature _makeElementAccessSignature(uint32_t elementType, uint32_t elementIndex) noexcept {
305
+ return OperandSignature{
306
+ uint32_t(RegTraits<RegType::kARM_VecV>::kSignature) |
307
+ uint32_t(kSignatureRegElementFlagMask) |
308
+ uint32_t(elementType << kSignatureRegElementTypeShift) |
309
+ uint32_t(elementIndex << kSignatureRegElementIndexShift)};
310
+ }
311
+ };
312
+
313
+ //! 32-bit GPW (AArch64) and/or GPR (ARM/AArch32) register.
314
+ class GpW : public Gp { ASMJIT_DEFINE_FINAL_REG(GpW, Gp, RegTraits<RegType::kARM_GpW>) };
315
+ //! 64-bit GPX (AArch64) register.
316
+ class GpX : public Gp { ASMJIT_DEFINE_FINAL_REG(GpX, Gp, RegTraits<RegType::kARM_GpX>) };
317
+
318
+ //! 8-bit view (S) of VFP/SIMD register.
319
+ class VecB : public Vec { ASMJIT_DEFINE_FINAL_REG(VecB, Vec, RegTraits<RegType::kARM_VecB>) };
320
+ //! 16-bit view (S) of VFP/SIMD register.
321
+ class VecH : public Vec { ASMJIT_DEFINE_FINAL_REG(VecH, Vec, RegTraits<RegType::kARM_VecH>) };
322
+ //! 32-bit view (S) of VFP/SIMD register.
323
+ class VecS : public Vec { ASMJIT_DEFINE_FINAL_REG(VecS, Vec, RegTraits<RegType::kARM_VecS>) };
324
+ //! 64-bit view (D) of VFP/SIMD register.
325
+ class VecD : public Vec { ASMJIT_DEFINE_FINAL_REG(VecD, Vec, RegTraits<RegType::kARM_VecD>) };
326
+ //! 128-bit vector register (Q or V).
327
+ class VecV : public Vec { ASMJIT_DEFINE_FINAL_REG(VecV, Vec, RegTraits<RegType::kARM_VecV>) };
328
+
329
+ inline GpW Gp::w() const noexcept { return GpW(id()); }
330
+ inline GpX Gp::x() const noexcept { return GpX(id()); }
331
+
332
+ inline VecB Vec::b() const noexcept { return VecB(id()); }
333
+ inline VecH Vec::h() const noexcept { return VecH(id()); }
334
+ inline VecS Vec::s() const noexcept { return VecS(id()); }
335
+ inline VecD Vec::d() const noexcept { return VecD(id()); }
336
+ inline VecV Vec::q() const noexcept { return VecV(id()); }
337
+ inline VecV Vec::v() const noexcept { return VecV(id()); }
338
+
339
+ inline VecV Vec::b(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeB, elementIndex), id()); }
340
+ inline VecV Vec::h(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeH, elementIndex), id()); }
341
+ inline VecV Vec::s(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeS, elementIndex), id()); }
342
+ inline VecV Vec::d(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeD, elementIndex), id()); }
343
+ inline VecV Vec::h2(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeH2, elementIndex), id()); }
344
+ inline VecV Vec::b4(uint32_t elementIndex) const noexcept { return VecV(_makeElementAccessSignature(kElementTypeB4, elementIndex), id()); }
345
+
346
+ inline VecD Vec::b8() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementB}, id()); }
347
+ inline VecS Vec::h2() const noexcept { return VecS(OperandSignature{VecS::kSignature | kSignatureElementH}, id()); }
348
+ inline VecD Vec::h4() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementH}, id()); }
349
+ inline VecD Vec::s2() const noexcept { return VecD(OperandSignature{VecD::kSignature | kSignatureElementS}, id()); }
350
+ inline VecV Vec::b16() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementB}, id()); }
351
+ inline VecV Vec::h8() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementH}, id()); }
352
+ inline VecV Vec::s4() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementS}, id()); }
353
+ inline VecV Vec::d2() const noexcept { return VecV(OperandSignature{VecV::kSignature | kSignatureElementD}, id()); }
354
+
355
+ #ifndef _DOXYGEN
356
+ namespace regs {
357
+ #endif
358
+
359
+ //! Creates a 32-bit W register operand (ARM/AArch64).
360
+ static inline constexpr GpW w(uint32_t id) noexcept { return GpW(id); }
361
+ //! Creates a 64-bit X register operand (AArch64).
362
+ static inline constexpr GpX x(uint32_t id) noexcept { return GpX(id); }
363
+ //! Creates a 32-bit S register operand (ARM/AArch64).
364
+ static inline constexpr VecS s(uint32_t id) noexcept { return VecS(id); }
365
+ //! Creates a 64-bit D register operand (ARM/AArch64).
366
+ static inline constexpr VecD d(uint32_t id) noexcept { return VecD(id); }
367
+ //! Creates a 1282-bit V register operand (ARM/AArch64).
368
+ static inline constexpr VecV v(uint32_t id) noexcept { return VecV(id); }
369
+
370
+ #ifndef _DOXYGEN
371
+ } // {regs}
372
+
373
+ // Make `arm::regs` accessible through `arm` namespace as well.
374
+ using namespace regs;
375
+ #endif
376
+
377
+ //! Memory operand (ARM).
378
+ class Mem : public BaseMem {
379
+ public:
380
+ //! \cond INTERNAL
381
+ //! Additional bits of operand's signature used by `arm::Mem`.
382
+ enum AdditionalBits : uint32_t {
383
+ // Index shift value (5 bits).
384
+ // |........|.....XXX|XX......|........|
385
+ kSignatureMemShiftValueShift = 14,
386
+ kSignatureMemShiftValueMask = 0x1Fu << kSignatureMemShiftValueShift,
387
+
388
+ // Shift operation type (4 bits).
389
+ // |........|XXXX....|........|........|
390
+ kSignatureMemPredicateShift = 20,
391
+ kSignatureMemPredicateMask = 0x0Fu << kSignatureMemPredicateShift
392
+ };
393
+ //! \endcond
394
+
395
+ //! Memory offset mode.
396
+ //!
397
+ //! Additional constants that can be used with the `predicate`.
398
+ enum OffsetMode : uint32_t {
399
+ //! Pre-index "[BASE, #Offset {, <shift>}]!" with write-back.
400
+ kOffsetPreIndex = 0xE,
401
+ //! Post-index "[BASE], #Offset {, <shift>}" with write-back.
402
+ kOffsetPostIndex = 0xF
403
+ };
404
+
405
+ //! \name Construction & Destruction
406
+ //! \{
407
+
408
+ //! Construct a default `Mem` operand, that points to [0].
409
+ inline constexpr Mem() noexcept
410
+ : BaseMem() {}
411
+
412
+ inline constexpr Mem(const Mem& other) noexcept
413
+ : BaseMem(other) {}
414
+
415
+ inline explicit Mem(Globals::NoInit_) noexcept
416
+ : BaseMem(Globals::NoInit) {}
417
+
418
+ inline constexpr Mem(const Signature& signature, uint32_t baseId, uint32_t indexId, int32_t offset) noexcept
419
+ : BaseMem(signature, baseId, indexId, offset) {}
420
+
421
+ inline constexpr explicit Mem(const Label& base, int32_t off = 0, Signature signature = Signature{0}) noexcept
422
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
423
+ Signature::fromMemBaseType(RegType::kLabelTag) |
424
+ signature, base.id(), 0, off) {}
425
+
426
+ inline constexpr explicit Mem(const BaseReg& base, int32_t off = 0, Signature signature = Signature{0}) noexcept
427
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
428
+ Signature::fromMemBaseType(base.type()) |
429
+ signature, base.id(), 0, off) {}
430
+
431
+ inline constexpr Mem(const BaseReg& base, const BaseReg& index, Signature signature = Signature{0}) noexcept
432
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
433
+ Signature::fromMemBaseType(base.type()) |
434
+ Signature::fromMemIndexType(index.type()) |
435
+ signature, base.id(), index.id(), 0) {}
436
+
437
+ inline constexpr Mem(const BaseReg& base, const BaseReg& index, const Shift& shift, Signature signature = Signature{0}) noexcept
438
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
439
+ Signature::fromMemBaseType(base.type()) |
440
+ Signature::fromMemIndexType(index.type()) |
441
+ Signature::fromValue<kSignatureMemPredicateMask>(uint32_t(shift.op())) |
442
+ Signature::fromValue<kSignatureMemShiftValueMask>(shift.value()) |
443
+ signature, base.id(), index.id(), 0) {}
444
+
445
+ inline constexpr Mem(uint64_t base, Signature signature = Signature{0}) noexcept
446
+ : BaseMem(Signature::fromOpType(OperandType::kMem) |
447
+ signature, uint32_t(base >> 32), 0, int32_t(uint32_t(base & 0xFFFFFFFFu))) {}
448
+
449
+ //! \}
450
+
451
+ //! \name Overloaded Operators
452
+ //! \{
453
+
454
+ inline Mem& operator=(const Mem& other) noexcept = default;
455
+
456
+ //! \}
457
+
458
+ //! \name Clone
459
+ //! \{
460
+
461
+ //! Clones the memory operand.
462
+ inline constexpr Mem clone() const noexcept { return Mem(*this); }
463
+
464
+ //! Gets new memory operand adjusted by `off`.
465
+ inline Mem cloneAdjusted(int64_t off) const noexcept {
466
+ Mem result(*this);
467
+ result.addOffset(off);
468
+ return result;
469
+ }
470
+
471
+ //! Clones the memory operand and makes it pre-index.
472
+ inline Mem pre() const noexcept {
473
+ Mem result(*this);
474
+ result.setPredicate(kOffsetPreIndex);
475
+ return result;
476
+ }
477
+
478
+ //! Clones the memory operand, applies a given offset `off` and makes it pre-index.
479
+ inline Mem pre(int64_t off) const noexcept {
480
+ Mem result(*this);
481
+ result.setPredicate(kOffsetPreIndex);
482
+ result.addOffset(off);
483
+ return result;
484
+ }
485
+
486
+ //! Clones the memory operand and makes it post-index.
487
+ inline Mem post() const noexcept {
488
+ Mem result(*this);
489
+ result.setPredicate(kOffsetPreIndex);
490
+ return result;
491
+ }
492
+
493
+ //! Clones the memory operand, applies a given offset `off` and makes it post-index.
494
+ inline Mem post(int64_t off) const noexcept {
495
+ Mem result(*this);
496
+ result.setPredicate(kOffsetPostIndex);
497
+ result.addOffset(off);
498
+ return result;
499
+ }
500
+
501
+ //! \}
502
+
503
+ //! \name Base & Index
504
+ //! \{
505
+
506
+ //! Converts memory `baseType` and `baseId` to `arm::Reg` instance.
507
+ //!
508
+ //! The memory must have a valid base register otherwise the result will be wrong.
509
+ inline Reg baseReg() const noexcept { return Reg::fromTypeAndId(baseType(), baseId()); }
510
+
511
+ //! Converts memory `indexType` and `indexId` to `arm::Reg` instance.
512
+ //!
513
+ //! The memory must have a valid index register otherwise the result will be wrong.
514
+ inline Reg indexReg() const noexcept { return Reg::fromTypeAndId(indexType(), indexId()); }
515
+
516
+ using BaseMem::setIndex;
517
+
518
+ inline void setIndex(const BaseReg& index, uint32_t shift) noexcept {
519
+ setIndex(index);
520
+ setShift(shift);
521
+ }
522
+
523
+ //! \}
524
+
525
+ //! \name ARM Specific Features
526
+ //! \{
527
+
528
+ //! Gets whether the memory operand has shift (aka scale) constant.
529
+ inline constexpr bool hasShift() const noexcept { return _signature.hasField<kSignatureMemShiftValueMask>(); }
530
+ //! Gets the memory operand's shift (aka scale) constant.
531
+ inline constexpr uint32_t shift() const noexcept { return _signature.getField<kSignatureMemShiftValueMask>(); }
532
+ //! Sets the memory operand's shift (aka scale) constant.
533
+ inline void setShift(uint32_t shift) noexcept { _signature.setField<kSignatureMemShiftValueMask>(shift); }
534
+ //! Resets the memory operand's shift (aka scale) constant to zero.
535
+ inline void resetShift() noexcept { _signature.setField<kSignatureMemShiftValueMask>(0); }
536
+
537
+ //! Gets memory predicate (shift mode or offset mode), see \ref ShiftOp and \ref OffsetMode.
538
+ inline constexpr uint32_t predicate() const noexcept { return _signature.getField<kSignatureMemPredicateMask>(); }
539
+ //! Sets memory predicate to `predicate`, see `Mem::ShiftOp`.
540
+ inline void setPredicate(uint32_t predicate) noexcept { _signature.setField<kSignatureMemPredicateMask>(predicate); }
541
+ //! Resets shift mode to LSL (default).
542
+ inline void resetPredicate() noexcept { _signature.setField<kSignatureMemPredicateMask>(0); }
543
+
544
+ inline constexpr bool isFixedOffset() const noexcept { return predicate() < kOffsetPreIndex; }
545
+ inline constexpr bool isPreOrPost() const noexcept { return predicate() >= kOffsetPreIndex; }
546
+ inline constexpr bool isPreIndex() const noexcept { return predicate() == kOffsetPreIndex; }
547
+ inline constexpr bool isPostIndex() const noexcept { return predicate() == kOffsetPostIndex; }
548
+
549
+ inline void resetToFixedOffset() noexcept { resetPredicate(); }
550
+ inline void makePreIndex() noexcept { setPredicate(kOffsetPreIndex); }
551
+ inline void makePostIndex() noexcept { setPredicate(kOffsetPostIndex); }
552
+
553
+ //! \}
554
+ };
555
+
556
+ //! Creates `[base.reg, offset]` memory operand (offset mode).
557
+ static inline constexpr Mem ptr(const Gp& base, int32_t offset = 0) noexcept {
558
+ return Mem(base, offset);
559
+ }
560
+
561
+ //! Creates `[base.reg, offset]!` memory operand (pre-index mode).
562
+ static inline constexpr Mem ptr_pre(const Gp& base, int32_t offset = 0) noexcept {
563
+ return Mem(base, offset, OperandSignature::fromValue<Mem::kSignatureMemPredicateMask>(Mem::kOffsetPreIndex));
564
+ }
565
+
566
+ //! Creates `[base.reg], offset` memory operand (post-index mode).
567
+ static inline constexpr Mem ptr_post(const Gp& base, int32_t offset = 0) noexcept {
568
+ return Mem(base, offset, OperandSignature::fromValue<Mem::kSignatureMemPredicateMask>(Mem::kOffsetPostIndex));
569
+ }
570
+
571
+ //! Creates `[base.reg, index]` memory operand.
572
+ static inline constexpr Mem ptr(const Gp& base, const Gp& index) noexcept {
573
+ return Mem(base, index);
574
+ }
575
+
576
+ //! Creates `[base.reg], index` memory operand (post-index mode).
577
+ static inline constexpr Mem ptr_post(const Gp& base, const Gp& index) noexcept {
578
+ return Mem(base, index, OperandSignature::fromValue<Mem::kSignatureMemPredicateMask>(Mem::kOffsetPostIndex));
579
+ }
580
+
581
+ //! Creates `[base.reg, index, SHIFT_OP #shift]` memory operand.
582
+ static inline constexpr Mem ptr(const Gp& base, const Gp& index, const Shift& shift) noexcept {
583
+ return Mem(base, index, shift);
584
+ }
585
+
586
+ //! Creates `[base + offset]` memory operand.
587
+ static inline constexpr Mem ptr(const Label& base, int32_t offset = 0) noexcept {
588
+ return Mem(base, offset);
589
+ }
590
+
591
+ // TODO: [ARM] PC + offset address.
592
+ #if 0
593
+ //! Creates `[PC + offset]` (relative) memory operand.
594
+ static inline constexpr Mem ptr(const PC& pc, int32_t offset = 0) noexcept {
595
+ return Mem(pc, offset);
596
+ }
597
+ #endif
598
+
599
+ //! Creates `[base]` absolute memory operand.
600
+ //!
601
+ //! \note The concept of absolute memory operands doesn't exist on ARM, the ISA only provides PC relative addressing.
602
+ //! Absolute memory operands can only be used if it's known that the PC relative offset is encodable and that it
603
+ //! would be within the limits. Absolute address is also often output from disassemblers, so AsmJit support it so it
604
+ //! can assemble it back.
605
+ static inline constexpr Mem ptr(uint64_t base) noexcept { return Mem(base); }
606
+
607
+ //! \}
608
+
609
+ ASMJIT_END_SUB_NAMESPACE
610
+
611
+ //! \cond INTERNAL
612
+ ASMJIT_BEGIN_NAMESPACE
613
+ ASMJIT_DEFINE_TYPE_ID(arm::GpW, TypeId::kInt32);
614
+ ASMJIT_DEFINE_TYPE_ID(arm::GpX, TypeId::kInt64);
615
+ ASMJIT_DEFINE_TYPE_ID(arm::VecS, TypeId::kFloat32x1);
616
+ ASMJIT_DEFINE_TYPE_ID(arm::VecD, TypeId::kFloat64x1);
617
+ ASMJIT_DEFINE_TYPE_ID(arm::VecV, TypeId::kInt32x4);
618
+ ASMJIT_END_NAMESPACE
619
+ //! \endcond
620
+
621
+ #endif // ASMJIT_ARM_ARMOPERAND_H_INCLUDED
@@ -0,0 +1,62 @@
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_ARM_H_INCLUDED
7
+ #define ASMJIT_ARM_H_INCLUDED
8
+
9
+ //! \addtogroup asmjit_arm
10
+ //!
11
+ //! ### Namespaces
12
+ //!
13
+ //! - \ref arm - arm namespace provides common functionality for both AArch32 and AArch64 backends.
14
+ //! - \ref a64 - a64 namespace provides support for AArch64 architecture. In addition it includes
15
+ //! \ref arm namespace, so you can only use a single namespace when targeting AArch64 architecture.
16
+ //!
17
+ //! ### Emitters
18
+ //!
19
+ //! - AArch64
20
+ //! - \ref a64::Assembler - AArch64 assembler (must read, provides examples).
21
+ //! - \ref a64::Builder - AArch64 builder.
22
+ //! - \ref a64::Compiler - AArch64 compiler.
23
+ //! - \ref a64::Emitter - AArch64 emitter (abstract).
24
+ //!
25
+ //! ### Supported Instructions
26
+ //!
27
+ //! - AArch64:
28
+ //! - Emitters:
29
+ //! - \ref a64::EmitterExplicitT - Provides all instructions that use explicit operands, provides also
30
+ //! utility functions. The member functions provided are part of all AArch64 emitters.
31
+ //! - Instruction representation:
32
+ //! - \ref a64::Inst::Id - instruction identifiers.
33
+ //!
34
+ //! ### Register Operands
35
+ //!
36
+ //! - \ref arm::Reg - Base class for any AArch32/AArch64 register.
37
+ //! - \ref arm::Gp - General purpose register:
38
+ //! - \ref arm::GpW - 32-bit register.
39
+ //! - \ref arm::GpX - 64-bit register.
40
+ //! - \ref arm::Vec - Vector (SIMD) register:
41
+ //! - \ref arm::VecB - 8-bit SIMD register (AArch64 only).
42
+ //! - \ref arm::VecH - 16-bit SIMD register (AArch64 only).
43
+ //! - \ref arm::VecS - 32-bit SIMD register.
44
+ //! - \ref arm::VecD - 64-bit SIMD register.
45
+ //! - \ref arm::VecV - 128-bit SIMD register.
46
+ //!
47
+ //! ### Memory Operands
48
+ //!
49
+ //! - \ref arm::Mem - AArch32/AArch64 memory operand that provides support for all ARM addressing features
50
+ //! including base, index, pre/post increment, and ARM-specific shift addressing and index extending.
51
+ //!
52
+ //! ### Other
53
+ //!
54
+ //! - \ref arm::Shift - Shift operation and value (both AArch32 and AArch64).
55
+ //! - \ref arm::DataType - Data type that is part of an instruction in AArch32 mode.
56
+ //! - \ref a64::Utils - Utilities that can help during code generation for AArch64.
57
+
58
+ #include "./core.h"
59
+ #include "./arm/armglobals.h"
60
+ #include "./arm/armoperand.h"
61
+
62
+ #endif // ASMJIT_ARM_H_INCLUDED