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,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