asmjit 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/Rakefile +5 -3
  4. data/asmjit.gemspec +1 -3
  5. data/ext/asmjit/asmjit/.editorconfig +10 -0
  6. data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
  7. data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
  8. data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
  9. data/ext/asmjit/asmjit/.gitignore +6 -0
  10. data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
  11. data/ext/asmjit/asmjit/LICENSE.md +17 -0
  12. data/ext/asmjit/asmjit/README.md +69 -0
  13. data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
  14. data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
  15. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
  16. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
  17. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
  18. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
  19. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
  20. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
  21. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
  22. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
  23. data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
  24. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
  25. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
  26. data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
  27. data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
  28. data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
  29. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
  30. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
  31. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
  32. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
  33. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
  34. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
  35. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
  36. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
  37. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
  38. data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
  39. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
  40. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
  41. data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
  42. data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
  43. data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
  44. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
  45. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
  46. data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
  47. data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
  48. data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
  49. data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
  50. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
  51. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
  52. data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
  53. data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
  54. data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
  55. data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
  56. data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
  57. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
  58. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
  59. data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
  60. data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
  61. data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
  62. data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
  63. data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
  64. data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
  65. data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
  66. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
  67. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
  68. data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
  69. data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
  70. data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
  71. data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
  72. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
  73. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
  74. data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
  75. data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
  76. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
  77. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
  78. data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
  79. data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
  80. data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
  81. data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
  82. data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
  83. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
  84. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
  85. data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
  86. data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
  87. data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
  88. data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
  89. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
  90. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
  91. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
  92. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
  93. data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
  94. data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
  95. data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
  96. data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
  97. data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
  98. data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
  99. data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
  100. data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
  101. data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
  102. data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
  103. data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
  104. data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
  105. data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
  106. data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
  107. data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
  108. data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
  109. data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
  110. data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
  111. data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
  112. data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
  113. data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
  114. data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
  115. data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
  116. data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
  117. data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
  118. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
  119. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
  120. data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
  121. data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
  122. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
  123. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
  124. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
  125. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
  126. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
  127. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
  128. data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
  129. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
  130. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
  131. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
  132. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
  133. data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
  134. data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
  135. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
  136. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
  137. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
  138. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
  139. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
  140. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
  141. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
  142. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
  143. data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
  144. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
  145. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
  146. data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
  147. data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
  148. data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
  149. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
  150. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
  151. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
  152. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
  153. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
  154. data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
  155. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
  156. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
  157. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
  158. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
  159. data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
  160. data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
  161. data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
  162. data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
  163. data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
  164. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
  165. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
  166. data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
  167. data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
  168. data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
  169. data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
  170. data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
  171. data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
  172. data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
  173. data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
  174. data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
  175. data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
  176. data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
  177. data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
  178. data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
  179. data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
  180. data/ext/asmjit/asmjit/test/broken.cpp +312 -0
  181. data/ext/asmjit/asmjit/test/broken.h +148 -0
  182. data/ext/asmjit/asmjit/test/cmdline.h +61 -0
  183. data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
  184. data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
  185. data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
  186. data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
  187. data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
  188. data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
  189. data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
  190. data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
  191. data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
  192. data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
  193. data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
  194. data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
  195. data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
  196. data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
  197. data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
  198. data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
  199. data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
  200. data/ext/asmjit/asmjit.cc +167 -30
  201. data/ext/asmjit/extconf.rb +9 -9
  202. data/lib/asmjit/version.rb +1 -1
  203. data/lib/asmjit.rb +14 -4
  204. metadata +198 -17
@@ -0,0 +1,464 @@
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
+ #include "../core/api-build_p.h"
7
+ #if !defined(ASMJIT_NO_AARCH64)
8
+
9
+ #include "../core/formatter.h"
10
+ #include "../core/funcargscontext_p.h"
11
+ #include "../core/string.h"
12
+ #include "../core/support.h"
13
+ #include "../core/type.h"
14
+ #include "../arm/a64emithelper_p.h"
15
+ #include "../arm/a64formatter_p.h"
16
+ #include "../arm/a64instapi_p.h"
17
+ #include "../arm/a64operand.h"
18
+
19
+ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
20
+
21
+ // a64::EmitHelper - Emit Operations
22
+ // =================================
23
+
24
+ ASMJIT_FAVOR_SIZE Error EmitHelper::emitRegMove(
25
+ const Operand_& dst_,
26
+ const Operand_& src_, TypeId typeId, const char* comment) {
27
+
28
+ Emitter* emitter = _emitter->as<Emitter>();
29
+
30
+ // Invalid or abstract TypeIds are not allowed.
31
+ ASMJIT_ASSERT(TypeUtils::isValid(typeId) && !TypeUtils::isAbstract(typeId));
32
+
33
+ emitter->setInlineComment(comment);
34
+
35
+ if (dst_.isReg() && src_.isMem()) {
36
+ Reg dst(dst_.as<Reg>());
37
+ Mem src(src_.as<Mem>());
38
+
39
+ switch (typeId) {
40
+ case TypeId::kInt8:
41
+ case TypeId::kUInt8:
42
+ return emitter->ldrb(dst.as<Gp>(), src);
43
+
44
+ case TypeId::kInt16:
45
+ case TypeId::kUInt16:
46
+ return emitter->ldrh(dst.as<Gp>(), src);
47
+
48
+ case TypeId::kInt32:
49
+ case TypeId::kUInt32:
50
+ return emitter->ldr(dst.as<Gp>().w(), src);
51
+
52
+ case TypeId::kInt64:
53
+ case TypeId::kUInt64:
54
+ return emitter->ldr(dst.as<Gp>().x(), src);
55
+
56
+ default: {
57
+ if (TypeUtils::isFloat32(typeId) || TypeUtils::isVec32(typeId))
58
+ return emitter->ldr(dst.as<Vec>().s(), src);
59
+
60
+ if (TypeUtils::isFloat64(typeId) || TypeUtils::isVec64(typeId))
61
+ return emitter->ldr(dst.as<Vec>().d(), src);
62
+
63
+ if (TypeUtils::isVec128(typeId))
64
+ return emitter->ldr(dst.as<Vec>().q(), src);
65
+
66
+ break;
67
+ }
68
+ }
69
+ }
70
+
71
+ if (dst_.isMem() && src_.isReg()) {
72
+ Mem dst(dst_.as<Mem>());
73
+ Reg src(src_.as<Reg>());
74
+
75
+ switch (typeId) {
76
+ case TypeId::kInt8:
77
+ case TypeId::kUInt8:
78
+ return emitter->strb(src.as<Gp>(), dst);
79
+
80
+ case TypeId::kInt16:
81
+ case TypeId::kUInt16:
82
+ return emitter->strh(src.as<Gp>(), dst);
83
+
84
+ case TypeId::kInt32:
85
+ case TypeId::kUInt32:
86
+ return emitter->str(src.as<Gp>().w(), dst);
87
+
88
+ case TypeId::kInt64:
89
+ case TypeId::kUInt64:
90
+ return emitter->str(src.as<Gp>().x(), dst);
91
+
92
+ default: {
93
+ if (TypeUtils::isFloat32(typeId) || TypeUtils::isVec32(typeId))
94
+ return emitter->str(src.as<Vec>().s(), dst);
95
+
96
+ if (TypeUtils::isFloat64(typeId) || TypeUtils::isVec64(typeId))
97
+ return emitter->str(src.as<Vec>().d(), dst);
98
+
99
+ if (TypeUtils::isVec128(typeId))
100
+ return emitter->str(src.as<Vec>().q(), dst);
101
+
102
+ break;
103
+ }
104
+ }
105
+ }
106
+
107
+ if (dst_.isReg() && src_.isReg()) {
108
+ Reg dst(dst_.as<Reg>());
109
+ Reg src(src_.as<Reg>());
110
+
111
+ switch (typeId) {
112
+ case TypeId::kInt8:
113
+ case TypeId::kUInt8:
114
+ case TypeId::kInt16:
115
+ case TypeId::kUInt16:
116
+ case TypeId::kInt32:
117
+ case TypeId::kUInt32:
118
+ case TypeId::kInt64:
119
+ case TypeId::kUInt64:
120
+ return emitter->mov(dst.as<Gp>().x(), src.as<Gp>().x());
121
+
122
+ default: {
123
+ if (TypeUtils::isFloat32(typeId) || TypeUtils::isVec32(typeId))
124
+ return emitter->fmov(dst.as<Vec>().s(), src.as<Vec>().s());
125
+
126
+ if (TypeUtils::isFloat64(typeId) || TypeUtils::isVec64(typeId))
127
+ return emitter->mov(dst.as<Vec>().b8(), src.as<Vec>().b8());
128
+
129
+ if (TypeUtils::isVec128(typeId))
130
+ return emitter->mov(dst.as<Vec>().b16(), src.as<Vec>().b16());
131
+
132
+ break;
133
+ }
134
+ }
135
+ }
136
+
137
+ emitter->setInlineComment(nullptr);
138
+ return DebugUtils::errored(kErrorInvalidState);
139
+ }
140
+
141
+ Error EmitHelper::emitRegSwap(
142
+ const BaseReg& a,
143
+ const BaseReg& b, const char* comment) {
144
+
145
+ DebugUtils::unused(a, b, comment);
146
+ return DebugUtils::errored(kErrorInvalidState);
147
+ }
148
+
149
+ // TODO: [ARM] EmitArgMove is unfinished.
150
+ Error EmitHelper::emitArgMove(
151
+ const BaseReg& dst_, TypeId dstTypeId,
152
+ const Operand_& src_, TypeId srcTypeId, const char* comment) {
153
+
154
+ // Deduce optional `dstTypeId`, which may be `TypeId::kVoid` in some cases.
155
+ if (dstTypeId == TypeId::kVoid) {
156
+ const ArchTraits& archTraits = ArchTraits::byArch(_emitter->arch());
157
+ dstTypeId = archTraits.regTypeToTypeId(dst_.type());
158
+ }
159
+
160
+ // Invalid or abstract TypeIds are not allowed.
161
+ ASMJIT_ASSERT(TypeUtils::isValid(dstTypeId) && !TypeUtils::isAbstract(dstTypeId));
162
+ ASMJIT_ASSERT(TypeUtils::isValid(srcTypeId) && !TypeUtils::isAbstract(srcTypeId));
163
+
164
+ Reg dst(dst_.as<Reg>());
165
+ Operand src(src_);
166
+
167
+ uint32_t dstSize = TypeUtils::sizeOf(dstTypeId);
168
+ uint32_t srcSize = TypeUtils::sizeOf(srcTypeId);
169
+
170
+ if (TypeUtils::isInt(dstTypeId)) {
171
+ if (TypeUtils::isInt(srcTypeId)) {
172
+ uint32_t x = dstSize == 8;
173
+
174
+ dst.setSignature(OperandSignature{x ? uint32_t(GpX::kSignature) : uint32_t(GpW::kSignature)});
175
+ _emitter->setInlineComment(comment);
176
+
177
+ if (src.isReg()) {
178
+ src.setSignature(dst.signature());
179
+ return _emitter->emit(Inst::kIdMov, dst, src);
180
+ }
181
+ else if (src.isMem()) {
182
+ InstId instId = Inst::kIdNone;
183
+ switch (srcTypeId) {
184
+ case TypeId::kInt8: instId = Inst::kIdLdrsb; break;
185
+ case TypeId::kUInt8: instId = Inst::kIdLdrb; break;
186
+ case TypeId::kInt16: instId = Inst::kIdLdrsh; break;
187
+ case TypeId::kUInt16: instId = Inst::kIdLdrh; break;
188
+ case TypeId::kInt32: instId = x ? Inst::kIdLdrsw : Inst::kIdLdr; break;
189
+ case TypeId::kUInt32: instId = Inst::kIdLdr; x = 0; break;
190
+ case TypeId::kInt64: instId = Inst::kIdLdr; break;
191
+ case TypeId::kUInt64: instId = Inst::kIdLdr; break;
192
+ default:
193
+ return DebugUtils::errored(kErrorInvalidState);
194
+ }
195
+ return _emitter->emit(instId, dst, src);
196
+ }
197
+ }
198
+ }
199
+
200
+ if (TypeUtils::isFloat(dstTypeId) || TypeUtils::isVec(dstTypeId)) {
201
+ if (TypeUtils::isFloat(srcTypeId) || TypeUtils::isVec(srcTypeId)) {
202
+ switch (srcSize) {
203
+ case 2: dst.as<Vec>().setSignature(OperandSignature{VecH::kSignature}); break;
204
+ case 4: dst.as<Vec>().setSignature(OperandSignature{VecS::kSignature}); break;
205
+ case 8: dst.as<Vec>().setSignature(OperandSignature{VecD::kSignature}); break;
206
+ case 16: dst.as<Vec>().setSignature(OperandSignature{VecV::kSignature}); break;
207
+ default:
208
+ return DebugUtils::errored(kErrorInvalidState);
209
+ }
210
+
211
+ _emitter->setInlineComment(comment);
212
+
213
+ if (src.isReg()) {
214
+ InstId instId = srcSize <= 4 ? Inst::kIdFmov_v : Inst::kIdMov_v;
215
+ src.setSignature(dst.signature());
216
+ return _emitter->emit(instId, dst, src);
217
+ }
218
+ else if (src.isMem()) {
219
+ return _emitter->emit(Inst::kIdLdr_v, dst, src);
220
+ }
221
+ }
222
+ }
223
+
224
+ return DebugUtils::errored(kErrorInvalidState);
225
+ }
226
+
227
+ // a64::EmitHelper - Emit Prolog & Epilog
228
+ // ======================================
229
+
230
+ struct LoadStoreInstructions {
231
+ InstId singleInstId;
232
+ InstId pairInstId;
233
+ };
234
+
235
+ struct PrologEpilogInfo {
236
+ struct RegPair {
237
+ uint8_t ids[2];
238
+ uint16_t offset;
239
+ };
240
+
241
+ struct GroupData {
242
+ RegPair pairs[16];
243
+ uint32_t pairCount;
244
+ };
245
+
246
+ Support::Array<GroupData, 2> groups;
247
+ uint32_t sizeTotal;
248
+
249
+ Error init(const FuncFrame& frame) noexcept {
250
+ uint32_t offset = 0;
251
+
252
+ for (RegGroup group : Support::EnumValues<RegGroup, RegGroup::kGp, RegGroup::kVec>{}) {
253
+ GroupData& data = groups[group];
254
+
255
+ uint32_t n = 0;
256
+ uint32_t pairCount = 0;
257
+ RegPair* pairs = data.pairs;
258
+
259
+ uint32_t slotSize = frame.saveRestoreRegSize(group);
260
+ uint32_t savedRegs = frame.savedRegs(group);
261
+
262
+ if (group == RegGroup::kGp && frame.hasPreservedFP()) {
263
+ // Must be at the beginning of the push/pop sequence.
264
+ ASMJIT_ASSERT(pairCount == 0);
265
+
266
+ pairs[0].offset = uint16_t(offset);
267
+ pairs[0].ids[0] = Gp::kIdFp;
268
+ pairs[0].ids[1] = Gp::kIdLr;
269
+ offset += slotSize * 2;
270
+ pairCount++;
271
+
272
+ savedRegs &= ~Support::bitMask(Gp::kIdFp, Gp::kIdLr);
273
+ }
274
+
275
+ Support::BitWordIterator<uint32_t> it(savedRegs);
276
+ while (it.hasNext()) {
277
+ pairs[pairCount].ids[n] = uint8_t(it.next());
278
+
279
+ if (++n == 2) {
280
+ pairs[pairCount].offset = uint16_t(offset);
281
+ offset += slotSize * 2;
282
+
283
+ n = 0;
284
+ pairCount++;
285
+ }
286
+ }
287
+
288
+ if (n == 1) {
289
+ pairs[pairCount].ids[1] = uint8_t(BaseReg::kIdBad);
290
+ pairs[pairCount].offset = uint16_t(offset);
291
+ offset += slotSize * 2;
292
+ pairCount++;
293
+ }
294
+
295
+ data.pairCount = pairCount;
296
+ }
297
+
298
+ sizeTotal = offset;
299
+ return kErrorOk;
300
+ }
301
+ };
302
+
303
+ ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
304
+ Emitter* emitter = _emitter->as<Emitter>();
305
+
306
+ PrologEpilogInfo pei;
307
+ ASMJIT_PROPAGATE(pei.init(frame));
308
+
309
+ static const Support::Array<Reg, 2> groupRegs = {{ x0, d0 }};
310
+ static const Support::Array<LoadStoreInstructions, 2> groupInsts = {{
311
+ { Inst::kIdStr , Inst::kIdStp },
312
+ { Inst::kIdStr_v, Inst::kIdStp_v }
313
+ }};
314
+
315
+ uint32_t adjustInitialOffset = pei.sizeTotal;
316
+
317
+ for (RegGroup group : Support::EnumValues<RegGroup, RegGroup::kGp, RegGroup::kVec>{}) {
318
+ const PrologEpilogInfo::GroupData& data = pei.groups[group];
319
+ uint32_t pairCount = data.pairCount;
320
+
321
+ Reg regs[2] = { groupRegs[group], groupRegs[group] };
322
+ Mem mem = ptr(sp);
323
+
324
+ const LoadStoreInstructions& insts = groupInsts[group];
325
+ for (uint32_t i = 0; i < pairCount; i++) {
326
+ const PrologEpilogInfo::RegPair& pair = data.pairs[i];
327
+
328
+ regs[0].setId(pair.ids[0]);
329
+ regs[1].setId(pair.ids[1]);
330
+ mem.setOffsetLo32(pair.offset);
331
+
332
+ if (pair.offset == 0 && adjustInitialOffset) {
333
+ mem.setOffset(-int(adjustInitialOffset));
334
+ mem.makePreIndex();
335
+ }
336
+
337
+ if (pair.ids[1] == BaseReg::kIdBad)
338
+ ASMJIT_PROPAGATE(emitter->emit(insts.singleInstId, regs[0], mem));
339
+ else
340
+ ASMJIT_PROPAGATE(emitter->emit(insts.pairInstId, regs[0], regs[1], mem));
341
+
342
+ mem.resetToFixedOffset();
343
+
344
+ if (i == 0 && frame.hasPreservedFP()) {
345
+ ASMJIT_PROPAGATE(emitter->mov(x29, sp));
346
+ }
347
+ }
348
+ }
349
+
350
+ if (frame.hasStackAdjustment()) {
351
+ uint32_t adj = frame.stackAdjustment();
352
+ if (adj <= 0xFFFu) {
353
+ ASMJIT_PROPAGATE(emitter->sub(sp, sp, adj));
354
+ }
355
+ else if (adj <= 0xFFFFFFu) {
356
+ // TODO: [ARM] Prolog - we must touch the pages otherwise it's undefined.
357
+ ASMJIT_PROPAGATE(emitter->sub(sp, sp, adj & 0x000FFFu));
358
+ ASMJIT_PROPAGATE(emitter->sub(sp, sp, adj & 0xFFF000u));
359
+ }
360
+ else {
361
+ return DebugUtils::errored(kErrorInvalidState);
362
+ }
363
+ }
364
+
365
+ return kErrorOk;
366
+ }
367
+
368
+ // TODO: [ARM] Emit epilog.
369
+ ASMJIT_FAVOR_SIZE Error EmitHelper::emitEpilog(const FuncFrame& frame) {
370
+ Emitter* emitter = _emitter->as<Emitter>();
371
+
372
+ PrologEpilogInfo pei;
373
+ ASMJIT_PROPAGATE(pei.init(frame));
374
+
375
+ static const Support::Array<Reg, 2> groupRegs = {{ x0, d0 }};
376
+ static const Support::Array<LoadStoreInstructions, 2> groupInsts = {{
377
+ { Inst::kIdLdr , Inst::kIdLdp },
378
+ { Inst::kIdLdr_v, Inst::kIdLdp_v }
379
+ }};
380
+
381
+ uint32_t adjustInitialOffset = pei.sizeTotal;
382
+
383
+ if (frame.hasStackAdjustment()) {
384
+ uint32_t adj = frame.stackAdjustment();
385
+ if (adj <= 0xFFFu) {
386
+ ASMJIT_PROPAGATE(emitter->add(sp, sp, adj));
387
+ }
388
+ else if (adj <= 0xFFFFFFu) {
389
+ ASMJIT_PROPAGATE(emitter->add(sp, sp, adj & 0x000FFFu));
390
+ ASMJIT_PROPAGATE(emitter->add(sp, sp, adj & 0xFFF000u));
391
+ }
392
+ else {
393
+ return DebugUtils::errored(kErrorInvalidState);
394
+ }
395
+ }
396
+
397
+ for (int g = 1; g >= 0; g--) {
398
+ RegGroup group = RegGroup(g);
399
+ const PrologEpilogInfo::GroupData& data = pei.groups[group];
400
+ uint32_t pairCount = data.pairCount;
401
+
402
+ Reg regs[2] = { groupRegs[group], groupRegs[group] };
403
+ Mem mem = ptr(sp);
404
+
405
+ const LoadStoreInstructions& insts = groupInsts[group];
406
+
407
+ for (int i = int(pairCount) - 1; i >= 0; i--) {
408
+ const PrologEpilogInfo::RegPair& pair = data.pairs[i];
409
+
410
+ regs[0].setId(pair.ids[0]);
411
+ regs[1].setId(pair.ids[1]);
412
+ mem.setOffsetLo32(pair.offset);
413
+
414
+ if (pair.offset == 0 && adjustInitialOffset) {
415
+ mem.setOffset(int(adjustInitialOffset));
416
+ mem.makePostIndex();
417
+ }
418
+
419
+ if (pair.ids[1] == BaseReg::kIdBad)
420
+ ASMJIT_PROPAGATE(emitter->emit(insts.singleInstId, regs[0], mem));
421
+ else
422
+ ASMJIT_PROPAGATE(emitter->emit(insts.pairInstId, regs[0], regs[1], mem));
423
+
424
+ mem.resetToFixedOffset();
425
+ }
426
+ }
427
+
428
+ ASMJIT_PROPAGATE(emitter->ret(x30));
429
+
430
+ return kErrorOk;
431
+ }
432
+
433
+ static Error ASMJIT_CDECL Emitter_emitProlog(BaseEmitter* emitter, const FuncFrame& frame) {
434
+ EmitHelper emitHelper(emitter);
435
+ return emitHelper.emitProlog(frame);
436
+ }
437
+
438
+ static Error ASMJIT_CDECL Emitter_emitEpilog(BaseEmitter* emitter, const FuncFrame& frame) {
439
+ EmitHelper emitHelper(emitter);
440
+ return emitHelper.emitEpilog(frame);
441
+ }
442
+
443
+ static Error ASMJIT_CDECL Emitter_emitArgsAssignment(BaseEmitter* emitter, const FuncFrame& frame, const FuncArgsAssignment& args) {
444
+ EmitHelper emitHelper(emitter);
445
+ return emitHelper.emitArgsAssignment(frame, args);
446
+ }
447
+
448
+ void assignEmitterFuncs(BaseEmitter* emitter) {
449
+ emitter->_funcs.emitProlog = Emitter_emitProlog;
450
+ emitter->_funcs.emitEpilog = Emitter_emitEpilog;
451
+ emitter->_funcs.emitArgsAssignment = Emitter_emitArgsAssignment;
452
+
453
+ #ifndef ASMJIT_NO_LOGGING
454
+ emitter->_funcs.formatInstruction = FormatterInternal::formatInstruction;
455
+ #endif
456
+
457
+ #ifndef ASMJIT_NO_VALIDATION
458
+ emitter->_funcs.validate = InstInternal::validate;
459
+ #endif
460
+ }
461
+
462
+ ASMJIT_END_SUB_NAMESPACE
463
+
464
+ #endif // !ASMJIT_NO_AARCH64
@@ -0,0 +1,50 @@
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_ARMEMITHELPER_P_H_INCLUDED
7
+ #define ASMJIT_ARM_ARMEMITHELPER_P_H_INCLUDED
8
+
9
+ #include "../core/api-config.h"
10
+
11
+ #include "../core/emithelper_p.h"
12
+ #include "../core/func.h"
13
+ #include "../arm/a64emitter.h"
14
+ #include "../arm/a64operand.h"
15
+
16
+ ASMJIT_BEGIN_SUB_NAMESPACE(a64)
17
+
18
+ //! \cond INTERNAL
19
+ //! \addtogroup asmjit_a64
20
+ //! \{
21
+
22
+ class EmitHelper : public BaseEmitHelper {
23
+ public:
24
+ inline explicit EmitHelper(BaseEmitter* emitter = nullptr) noexcept
25
+ : BaseEmitHelper(emitter) {}
26
+
27
+ Error emitRegMove(
28
+ const Operand_& dst_,
29
+ const Operand_& src_, TypeId typeId, const char* comment = nullptr) override;
30
+
31
+ Error emitRegSwap(
32
+ const BaseReg& a,
33
+ const BaseReg& b, const char* comment = nullptr) override;
34
+
35
+ Error emitArgMove(
36
+ const BaseReg& dst_, TypeId dstTypeId,
37
+ const Operand_& src_, TypeId srcTypeId, const char* comment = nullptr) override;
38
+
39
+ Error emitProlog(const FuncFrame& frame);
40
+ Error emitEpilog(const FuncFrame& frame);
41
+ };
42
+
43
+ void assignEmitterFuncs(BaseEmitter* emitter);
44
+
45
+ //! \}
46
+ //! \endcond
47
+
48
+ ASMJIT_END_SUB_NAMESPACE
49
+
50
+ #endif // ASMJIT_ARM_ARMEMITHELPER_P_H_INCLUDED