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,619 @@
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_X86)
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 "../core/radefs_p.h"
15
+ #include "../x86/x86emithelper_p.h"
16
+ #include "../x86/x86emitter.h"
17
+ #include "../x86/x86formatter_p.h"
18
+ #include "../x86/x86instapi_p.h"
19
+
20
+ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
21
+
22
+ // x86::EmitHelper - Utilities
23
+ // ===========================
24
+
25
+ static inline uint32_t getXmmMovInst(const FuncFrame& frame) {
26
+ bool avx = frame.isAvxEnabled();
27
+ bool aligned = frame.hasAlignedVecSR();
28
+
29
+ return aligned ? (avx ? Inst::kIdVmovaps : Inst::kIdMovaps)
30
+ : (avx ? Inst::kIdVmovups : Inst::kIdMovups);
31
+ }
32
+
33
+ //! Converts `size` to a 'kmov?' instruction.
34
+ static inline uint32_t kmovInstFromSize(uint32_t size) noexcept {
35
+ switch (size) {
36
+ case 1: return Inst::kIdKmovb;
37
+ case 2: return Inst::kIdKmovw;
38
+ case 4: return Inst::kIdKmovd;
39
+ case 8: return Inst::kIdKmovq;
40
+ default: return Inst::kIdNone;
41
+ }
42
+ }
43
+
44
+ static inline uint32_t makeCastOp(TypeId dst, TypeId src) noexcept {
45
+ return (uint32_t(dst) << 8) | uint32_t(src);
46
+ }
47
+
48
+ // x86::EmitHelper - Emit Reg Move
49
+ // ===============================
50
+
51
+ ASMJIT_FAVOR_SIZE Error EmitHelper::emitRegMove(
52
+ const Operand_& dst_,
53
+ const Operand_& src_, TypeId typeId, const char* comment) {
54
+
55
+ // Invalid or abstract TypeIds are not allowed.
56
+ ASMJIT_ASSERT(TypeUtils::isValid(typeId) && !TypeUtils::isAbstract(typeId));
57
+
58
+ Operand dst(dst_);
59
+ Operand src(src_);
60
+
61
+ InstId instId = Inst::kIdNone;
62
+ uint32_t memFlags = 0;
63
+ uint32_t overrideMemSize = 0;
64
+
65
+ enum MemFlags : uint32_t {
66
+ kDstMem = 0x1,
67
+ kSrcMem = 0x2
68
+ };
69
+
70
+ // Detect memory operands and patch them to have the same size as the register. BaseCompiler always sets memory size
71
+ // of allocs and spills, so it shouldn't be really necessary, however, after this function was separated from Compiler
72
+ // it's better to make sure that the size is always specified, as we can use 'movzx' and 'movsx' that rely on it.
73
+ if (dst.isMem()) { memFlags |= kDstMem; dst.as<Mem>().setSize(src.size()); }
74
+ if (src.isMem()) { memFlags |= kSrcMem; src.as<Mem>().setSize(dst.size()); }
75
+
76
+ switch (typeId) {
77
+ case TypeId::kInt8:
78
+ case TypeId::kUInt8:
79
+ case TypeId::kInt16:
80
+ case TypeId::kUInt16:
81
+ // Special case - 'movzx' load.
82
+ if (memFlags & kSrcMem) {
83
+ instId = Inst::kIdMovzx;
84
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
85
+ break;
86
+ }
87
+
88
+ if (!memFlags) {
89
+ // Change both destination and source registers to GPD (safer, no dependencies).
90
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
91
+ src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
92
+ }
93
+ ASMJIT_FALLTHROUGH;
94
+
95
+ case TypeId::kInt32:
96
+ case TypeId::kUInt32:
97
+ case TypeId::kInt64:
98
+ case TypeId::kUInt64:
99
+ instId = Inst::kIdMov;
100
+ break;
101
+
102
+ case TypeId::kMmx32:
103
+ instId = Inst::kIdMovd;
104
+ if (memFlags) break;
105
+ ASMJIT_FALLTHROUGH;
106
+
107
+ case TypeId::kMmx64 : instId = Inst::kIdMovq ; break;
108
+ case TypeId::kMask8 : instId = Inst::kIdKmovb; break;
109
+ case TypeId::kMask16: instId = Inst::kIdKmovw; break;
110
+ case TypeId::kMask32: instId = Inst::kIdKmovd; break;
111
+ case TypeId::kMask64: instId = Inst::kIdKmovq; break;
112
+
113
+ default: {
114
+ TypeId scalarTypeId = TypeUtils::scalarOf(typeId);
115
+ if (TypeUtils::isVec32(typeId) && memFlags) {
116
+ overrideMemSize = 4;
117
+ if (scalarTypeId == TypeId::kFloat32)
118
+ instId = _avxEnabled ? Inst::kIdVmovss : Inst::kIdMovss;
119
+ else
120
+ instId = _avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
121
+ break;
122
+ }
123
+
124
+ if (TypeUtils::isVec64(typeId) && memFlags) {
125
+ overrideMemSize = 8;
126
+ if (scalarTypeId == TypeId::kFloat64)
127
+ instId = _avxEnabled ? Inst::kIdVmovsd : Inst::kIdMovsd;
128
+ else
129
+ instId = _avxEnabled ? Inst::kIdVmovq : Inst::kIdMovq;
130
+ break;
131
+ }
132
+
133
+ if (scalarTypeId == TypeId::kFloat32)
134
+ instId = _avxEnabled ? Inst::kIdVmovaps : Inst::kIdMovaps;
135
+ else if (scalarTypeId == TypeId::kFloat64)
136
+ instId = _avxEnabled ? Inst::kIdVmovapd : Inst::kIdMovapd;
137
+ else if (!_avx512Enabled)
138
+ instId = _avxEnabled ? Inst::kIdVmovdqa : Inst::kIdMovdqa;
139
+ else
140
+ instId = Inst::kIdVmovdqa32;
141
+ break;
142
+ }
143
+ }
144
+
145
+ if (!instId)
146
+ return DebugUtils::errored(kErrorInvalidState);
147
+
148
+ if (overrideMemSize) {
149
+ if (dst.isMem()) dst.as<Mem>().setSize(overrideMemSize);
150
+ if (src.isMem()) src.as<Mem>().setSize(overrideMemSize);
151
+ }
152
+
153
+ _emitter->setInlineComment(comment);
154
+ return _emitter->emit(instId, dst, src);
155
+ }
156
+
157
+ // x86::EmitHelper - Emit Arg Move
158
+ // ===============================
159
+
160
+ ASMJIT_FAVOR_SIZE Error EmitHelper::emitArgMove(
161
+ const BaseReg& dst_, TypeId dstTypeId,
162
+ const Operand_& src_, TypeId srcTypeId, const char* comment) {
163
+
164
+ // Deduce optional `dstTypeId`, which may be `TypeId::kVoid` in some cases.
165
+ if (dstTypeId == TypeId::kVoid) {
166
+ const ArchTraits& archTraits = ArchTraits::byArch(_emitter->arch());
167
+ dstTypeId = archTraits.regTypeToTypeId(dst_.type());
168
+ }
169
+
170
+ // Invalid or abstract TypeIds are not allowed.
171
+ ASMJIT_ASSERT(TypeUtils::isValid(dstTypeId) && !TypeUtils::isAbstract(dstTypeId));
172
+ ASMJIT_ASSERT(TypeUtils::isValid(srcTypeId) && !TypeUtils::isAbstract(srcTypeId));
173
+
174
+ Reg dst(dst_.as<Reg>());
175
+ Operand src(src_);
176
+
177
+ uint32_t dstSize = TypeUtils::sizeOf(dstTypeId);
178
+ uint32_t srcSize = TypeUtils::sizeOf(srcTypeId);
179
+
180
+ InstId instId = Inst::kIdNone;
181
+
182
+ // Not a real loop, just 'break' is nicer than 'goto'.
183
+ for (;;) {
184
+ if (TypeUtils::isInt(dstTypeId)) {
185
+ if (TypeUtils::isInt(srcTypeId)) {
186
+ instId = Inst::kIdMovsx;
187
+ uint32_t castOp = makeCastOp(dstTypeId, srcTypeId);
188
+
189
+ // Sign extend by using 'movsx'.
190
+ if (castOp == makeCastOp(TypeId::kInt16, TypeId::kInt8 ) ||
191
+ castOp == makeCastOp(TypeId::kInt32, TypeId::kInt8 ) ||
192
+ castOp == makeCastOp(TypeId::kInt32, TypeId::kInt16) ||
193
+ castOp == makeCastOp(TypeId::kInt64, TypeId::kInt8 ) ||
194
+ castOp == makeCastOp(TypeId::kInt64, TypeId::kInt16))
195
+ break;
196
+
197
+ // Sign extend by using 'movsxd'.
198
+ instId = Inst::kIdMovsxd;
199
+ if (castOp == makeCastOp(TypeId::kInt64, TypeId::kInt32))
200
+ break;
201
+ }
202
+
203
+ if (TypeUtils::isInt(srcTypeId) || src_.isMem()) {
204
+ // Zero extend by using 'movzx' or 'mov'.
205
+ if (dstSize <= 4 && srcSize < 4) {
206
+ instId = Inst::kIdMovzx;
207
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
208
+ }
209
+ else {
210
+ // We should have caught all possibilities where `srcSize` is less than 4, so we don't have to worry
211
+ // about 'movzx' anymore. Minimum size is enough to determine if we want 32-bit or 64-bit move.
212
+ instId = Inst::kIdMov;
213
+ srcSize = Support::min(srcSize, dstSize);
214
+
215
+ dst.setSignature(srcSize == 4 ? Reg::signatureOfT<RegType::kX86_Gpd>()
216
+ : Reg::signatureOfT<RegType::kX86_Gpq>());
217
+ if (src.isReg())
218
+ src.setSignature(dst.signature());
219
+ }
220
+ break;
221
+ }
222
+
223
+ // NOTE: The previous branch caught all memory sources, from here it's always register to register conversion,
224
+ // so catch the remaining cases.
225
+ srcSize = Support::min(srcSize, dstSize);
226
+
227
+ if (TypeUtils::isMmx(srcTypeId)) {
228
+ // 64-bit move.
229
+ instId = Inst::kIdMovq;
230
+ if (srcSize == 8)
231
+ break;
232
+
233
+ // 32-bit move.
234
+ instId = Inst::kIdMovd;
235
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
236
+ break;
237
+ }
238
+
239
+ if (TypeUtils::isMask(srcTypeId)) {
240
+ instId = kmovInstFromSize(srcSize);
241
+ dst.setSignature(srcSize <= 4 ? Reg::signatureOfT<RegType::kX86_Gpd>()
242
+ : Reg::signatureOfT<RegType::kX86_Gpq>());
243
+ break;
244
+ }
245
+
246
+ if (TypeUtils::isVec(srcTypeId)) {
247
+ // 64-bit move.
248
+ instId = _avxEnabled ? Inst::kIdVmovq : Inst::kIdMovq;
249
+ if (srcSize == 8)
250
+ break;
251
+
252
+ // 32-bit move.
253
+ instId = _avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
254
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
255
+ break;
256
+ }
257
+ }
258
+
259
+ if (TypeUtils::isMmx(dstTypeId)) {
260
+ instId = Inst::kIdMovq;
261
+ srcSize = Support::min(srcSize, dstSize);
262
+
263
+ if (TypeUtils::isInt(srcTypeId) || src.isMem()) {
264
+ // 64-bit move.
265
+ if (srcSize == 8)
266
+ break;
267
+
268
+ // 32-bit move.
269
+ instId = Inst::kIdMovd;
270
+ if (src.isReg())
271
+ src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
272
+ break;
273
+ }
274
+
275
+ if (TypeUtils::isMmx(srcTypeId))
276
+ break;
277
+
278
+ // This will hurt if AVX is enabled.
279
+ instId = Inst::kIdMovdq2q;
280
+ if (TypeUtils::isVec(srcTypeId))
281
+ break;
282
+ }
283
+
284
+ if (TypeUtils::isMask(dstTypeId)) {
285
+ srcSize = Support::min(srcSize, dstSize);
286
+
287
+ if (TypeUtils::isInt(srcTypeId) || TypeUtils::isMask(srcTypeId) || src.isMem()) {
288
+ instId = kmovInstFromSize(srcSize);
289
+ if (Reg::isGp(src) && srcSize <= 4)
290
+ src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
291
+ break;
292
+ }
293
+ }
294
+
295
+ if (TypeUtils::isVec(dstTypeId)) {
296
+ // By default set destination to XMM, will be set to YMM|ZMM if needed.
297
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Xmm>());
298
+
299
+ // This will hurt if AVX is enabled.
300
+ if (Reg::isMm(src)) {
301
+ // 64-bit move.
302
+ instId = Inst::kIdMovq2dq;
303
+ break;
304
+ }
305
+
306
+ // Argument conversion.
307
+ TypeId dstScalarId = TypeUtils::scalarOf(dstTypeId);
308
+ TypeId srcScalarId = TypeUtils::scalarOf(srcTypeId);
309
+
310
+ if (dstScalarId == TypeId::kFloat32 && srcScalarId == TypeId::kFloat64) {
311
+ srcSize = Support::min(dstSize * 2, srcSize);
312
+ dstSize = srcSize / 2;
313
+
314
+ if (srcSize <= 8)
315
+ instId = _avxEnabled ? Inst::kIdVcvtss2sd : Inst::kIdCvtss2sd;
316
+ else
317
+ instId = _avxEnabled ? Inst::kIdVcvtps2pd : Inst::kIdCvtps2pd;
318
+
319
+ if (dstSize == 32)
320
+ dst.setSignature(Reg::signatureOfT<RegType::kX86_Ymm>());
321
+ if (src.isReg())
322
+ src.setSignature(Reg::signatureOfVecBySize(srcSize));
323
+ break;
324
+ }
325
+
326
+ if (dstScalarId == TypeId::kFloat64 && srcScalarId == TypeId::kFloat32) {
327
+ srcSize = Support::min(dstSize, srcSize * 2) / 2;
328
+ dstSize = srcSize * 2;
329
+
330
+ if (srcSize <= 4)
331
+ instId = _avxEnabled ? Inst::kIdVcvtsd2ss : Inst::kIdCvtsd2ss;
332
+ else
333
+ instId = _avxEnabled ? Inst::kIdVcvtpd2ps : Inst::kIdCvtpd2ps;
334
+
335
+ dst.setSignature(Reg::signatureOfVecBySize(dstSize));
336
+ if (src.isReg() && srcSize >= 32)
337
+ src.setSignature(Reg::signatureOfT<RegType::kX86_Ymm>());
338
+ break;
339
+ }
340
+
341
+ srcSize = Support::min(srcSize, dstSize);
342
+ if (Reg::isGp(src) || src.isMem()) {
343
+ // 32-bit move.
344
+ if (srcSize <= 4) {
345
+ instId = _avxEnabled ? Inst::kIdVmovd : Inst::kIdMovd;
346
+ if (src.isReg())
347
+ src.setSignature(Reg::signatureOfT<RegType::kX86_Gpd>());
348
+ break;
349
+ }
350
+
351
+ // 64-bit move.
352
+ if (srcSize == 8) {
353
+ instId = _avxEnabled ? Inst::kIdVmovq : Inst::kIdMovq;
354
+ break;
355
+ }
356
+ }
357
+
358
+ if (Reg::isVec(src) || src.isMem()) {
359
+ instId = _avxEnabled ? Inst::kIdVmovaps : Inst::kIdMovaps;
360
+
361
+ if (src.isMem() && srcSize < _emitter->environment().stackAlignment())
362
+ instId = _avxEnabled ? Inst::kIdVmovups : Inst::kIdMovups;
363
+
364
+ OperandSignature signature = Reg::signatureOfVecBySize(srcSize);
365
+ dst.setSignature(signature);
366
+ if (src.isReg())
367
+ src.setSignature(signature);
368
+ break;
369
+ }
370
+ }
371
+
372
+ return DebugUtils::errored(kErrorInvalidState);
373
+ }
374
+
375
+ if (src.isMem())
376
+ src.as<Mem>().setSize(srcSize);
377
+
378
+ _emitter->setInlineComment(comment);
379
+ return _emitter->emit(instId, dst, src);
380
+ }
381
+
382
+ Error EmitHelper::emitRegSwap(
383
+ const BaseReg& a,
384
+ const BaseReg& b, const char* comment) {
385
+
386
+ if (a.isGp() && b.isGp()) {
387
+ _emitter->setInlineComment(comment);
388
+ return _emitter->emit(Inst::kIdXchg, a, b);
389
+ }
390
+ else
391
+ return DebugUtils::errored(kErrorInvalidState);
392
+ }
393
+
394
+ // x86::EmitHelper - Emit Prolog & Epilog
395
+ // ======================================
396
+
397
+ static inline void X86Internal_setupSaveRestoreInfo(RegGroup group, const FuncFrame& frame, Reg& xReg, uint32_t& xInst, uint32_t& xSize) noexcept {
398
+ switch (group) {
399
+ case RegGroup::kVec:
400
+ xReg = xmm(0);
401
+ xInst = getXmmMovInst(frame);
402
+ xSize = xReg.size();
403
+ break;
404
+ case RegGroup::kX86_K:
405
+ xReg = k(0);
406
+ xInst = Inst::kIdKmovq;
407
+ xSize = xReg.size();
408
+ break;
409
+ case RegGroup::kX86_MM:
410
+ xReg = mm(0);
411
+ xInst = Inst::kIdMovq;
412
+ xSize = xReg.size();
413
+ break;
414
+ default:
415
+ break;
416
+ }
417
+ }
418
+
419
+ ASMJIT_FAVOR_SIZE Error EmitHelper::emitProlog(const FuncFrame& frame) {
420
+ Emitter* emitter = _emitter->as<Emitter>();
421
+ uint32_t gpSaved = frame.savedRegs(RegGroup::kGp);
422
+
423
+ Gp zsp = emitter->zsp(); // ESP|RSP register.
424
+ Gp zbp = emitter->zbp(); // EBP|RBP register.
425
+ Gp gpReg = zsp; // General purpose register (temporary).
426
+ Gp saReg = zsp; // Stack-arguments base pointer.
427
+
428
+ // Emit: 'push zbp'
429
+ // 'mov zbp, zsp'.
430
+ if (frame.hasPreservedFP()) {
431
+ gpSaved &= ~Support::bitMask(Gp::kIdBp);
432
+ ASMJIT_PROPAGATE(emitter->push(zbp));
433
+ ASMJIT_PROPAGATE(emitter->mov(zbp, zsp));
434
+ }
435
+
436
+ // Emit: 'push gp' sequence.
437
+ {
438
+ Support::BitWordIterator<RegMask> it(gpSaved);
439
+ while (it.hasNext()) {
440
+ gpReg.setId(it.next());
441
+ ASMJIT_PROPAGATE(emitter->push(gpReg));
442
+ }
443
+ }
444
+
445
+ // Emit: 'mov saReg, zsp'.
446
+ uint32_t saRegId = frame.saRegId();
447
+ if (saRegId != BaseReg::kIdBad && saRegId != Gp::kIdSp) {
448
+ saReg.setId(saRegId);
449
+ if (frame.hasPreservedFP()) {
450
+ if (saRegId != Gp::kIdBp)
451
+ ASMJIT_PROPAGATE(emitter->mov(saReg, zbp));
452
+ }
453
+ else {
454
+ ASMJIT_PROPAGATE(emitter->mov(saReg, zsp));
455
+ }
456
+ }
457
+
458
+ // Emit: 'and zsp, StackAlignment'.
459
+ if (frame.hasDynamicAlignment()) {
460
+ ASMJIT_PROPAGATE(emitter->and_(zsp, -int32_t(frame.finalStackAlignment())));
461
+ }
462
+
463
+ // Emit: 'sub zsp, StackAdjustment'.
464
+ if (frame.hasStackAdjustment()) {
465
+ ASMJIT_PROPAGATE(emitter->sub(zsp, frame.stackAdjustment()));
466
+ }
467
+
468
+ // Emit: 'mov [zsp + DAOffset], saReg'.
469
+ if (frame.hasDynamicAlignment() && frame.hasDAOffset()) {
470
+ Mem saMem = ptr(zsp, int32_t(frame.daOffset()));
471
+ ASMJIT_PROPAGATE(emitter->mov(saMem, saReg));
472
+ }
473
+
474
+ // Emit 'movxxx [zsp + X], {[x|y|z]mm, k}'.
475
+ {
476
+ Reg xReg;
477
+ Mem xBase = ptr(zsp, int32_t(frame.extraRegSaveOffset()));
478
+
479
+ uint32_t xInst;
480
+ uint32_t xSize;
481
+
482
+ for (RegGroup group : Support::EnumValues<RegGroup, RegGroup(1), RegGroup::kMaxVirt>{}) {
483
+ Support::BitWordIterator<RegMask> it(frame.savedRegs(group));
484
+ if (it.hasNext()) {
485
+ X86Internal_setupSaveRestoreInfo(group, frame, xReg, xInst, xSize);
486
+ do {
487
+ xReg.setId(it.next());
488
+ ASMJIT_PROPAGATE(emitter->emit(xInst, xBase, xReg));
489
+ xBase.addOffsetLo32(int32_t(xSize));
490
+ } while (it.hasNext());
491
+ }
492
+ }
493
+ }
494
+
495
+ return kErrorOk;
496
+ }
497
+
498
+ ASMJIT_FAVOR_SIZE Error EmitHelper::emitEpilog(const FuncFrame& frame) {
499
+ Emitter* emitter = _emitter->as<Emitter>();
500
+
501
+ uint32_t i;
502
+ uint32_t regId;
503
+
504
+ uint32_t registerSize = emitter->registerSize();
505
+ uint32_t gpSaved = frame.savedRegs(RegGroup::kGp);
506
+
507
+ Gp zsp = emitter->zsp(); // ESP|RSP register.
508
+ Gp zbp = emitter->zbp(); // EBP|RBP register.
509
+ Gp gpReg = emitter->zsp(); // General purpose register (temporary).
510
+
511
+ // Don't emit 'pop zbp' in the pop sequence, this case is handled separately.
512
+ if (frame.hasPreservedFP())
513
+ gpSaved &= ~Support::bitMask(Gp::kIdBp);
514
+
515
+ // Emit 'movxxx {[x|y|z]mm, k}, [zsp + X]'.
516
+ {
517
+ Reg xReg;
518
+ Mem xBase = ptr(zsp, int32_t(frame.extraRegSaveOffset()));
519
+
520
+ uint32_t xInst;
521
+ uint32_t xSize;
522
+
523
+ for (RegGroup group : Support::EnumValues<RegGroup, RegGroup(1), RegGroup::kMaxVirt>{}) {
524
+ Support::BitWordIterator<RegMask> it(frame.savedRegs(group));
525
+ if (it.hasNext()) {
526
+ X86Internal_setupSaveRestoreInfo(group, frame, xReg, xInst, xSize);
527
+ do {
528
+ xReg.setId(it.next());
529
+ ASMJIT_PROPAGATE(emitter->emit(xInst, xReg, xBase));
530
+ xBase.addOffsetLo32(int32_t(xSize));
531
+ } while (it.hasNext());
532
+ }
533
+ }
534
+ }
535
+
536
+ // Emit 'emms' and/or 'vzeroupper'.
537
+ if (frame.hasMmxCleanup()) ASMJIT_PROPAGATE(emitter->emms());
538
+ if (frame.hasAvxCleanup()) ASMJIT_PROPAGATE(emitter->vzeroupper());
539
+
540
+ if (frame.hasPreservedFP()) {
541
+ // Emit 'mov zsp, zbp' or 'lea zsp, [zbp - x]'
542
+ int32_t count = int32_t(frame.pushPopSaveSize() - registerSize);
543
+ if (!count)
544
+ ASMJIT_PROPAGATE(emitter->mov(zsp, zbp));
545
+ else
546
+ ASMJIT_PROPAGATE(emitter->lea(zsp, ptr(zbp, -count)));
547
+ }
548
+ else {
549
+ if (frame.hasDynamicAlignment() && frame.hasDAOffset()) {
550
+ // Emit 'mov zsp, [zsp + DsaSlot]'.
551
+ Mem saMem = ptr(zsp, int32_t(frame.daOffset()));
552
+ ASMJIT_PROPAGATE(emitter->mov(zsp, saMem));
553
+ }
554
+ else if (frame.hasStackAdjustment()) {
555
+ // Emit 'add zsp, StackAdjustment'.
556
+ ASMJIT_PROPAGATE(emitter->add(zsp, int32_t(frame.stackAdjustment())));
557
+ }
558
+ }
559
+
560
+ // Emit 'pop gp' sequence.
561
+ if (gpSaved) {
562
+ i = gpSaved;
563
+ regId = 16;
564
+
565
+ do {
566
+ regId--;
567
+ if (i & 0x8000) {
568
+ gpReg.setId(regId);
569
+ ASMJIT_PROPAGATE(emitter->pop(gpReg));
570
+ }
571
+ i <<= 1;
572
+ } while (regId != 0);
573
+ }
574
+
575
+ // Emit 'pop zbp'.
576
+ if (frame.hasPreservedFP())
577
+ ASMJIT_PROPAGATE(emitter->pop(zbp));
578
+
579
+ // Emit 'ret' or 'ret x'.
580
+ if (frame.hasCalleeStackCleanup())
581
+ ASMJIT_PROPAGATE(emitter->emit(Inst::kIdRet, int(frame.calleeStackCleanup())));
582
+ else
583
+ ASMJIT_PROPAGATE(emitter->emit(Inst::kIdRet));
584
+
585
+ return kErrorOk;
586
+ }
587
+
588
+ static Error ASMJIT_CDECL Emitter_emitProlog(BaseEmitter* emitter, const FuncFrame& frame) {
589
+ EmitHelper emitHelper(emitter, frame.isAvxEnabled(), frame.isAvx512Enabled());
590
+ return emitHelper.emitProlog(frame);
591
+ }
592
+
593
+ static Error ASMJIT_CDECL Emitter_emitEpilog(BaseEmitter* emitter, const FuncFrame& frame) {
594
+ EmitHelper emitHelper(emitter, frame.isAvxEnabled(), frame.isAvx512Enabled());
595
+ return emitHelper.emitEpilog(frame);
596
+ }
597
+
598
+ static Error ASMJIT_CDECL Emitter_emitArgsAssignment(BaseEmitter* emitter, const FuncFrame& frame, const FuncArgsAssignment& args) {
599
+ EmitHelper emitHelper(emitter, frame.isAvxEnabled(), frame.isAvx512Enabled());
600
+ return emitHelper.emitArgsAssignment(frame, args);
601
+ }
602
+
603
+ void assignEmitterFuncs(BaseEmitter* emitter) {
604
+ emitter->_funcs.emitProlog = Emitter_emitProlog;
605
+ emitter->_funcs.emitEpilog = Emitter_emitEpilog;
606
+ emitter->_funcs.emitArgsAssignment = Emitter_emitArgsAssignment;
607
+
608
+ #ifndef ASMJIT_NO_LOGGING
609
+ emitter->_funcs.formatInstruction = FormatterInternal::formatInstruction;
610
+ #endif
611
+
612
+ #ifndef ASMJIT_NO_VALIDATION
613
+ emitter->_funcs.validate = InstInternal::validate;
614
+ #endif
615
+ }
616
+
617
+ ASMJIT_END_SUB_NAMESPACE
618
+
619
+ #endif // !ASMJIT_NO_X86
@@ -0,0 +1,60 @@
1
+ // This file is part of AsmJit project <https://asmjit.com>
2
+ //
3
+ // See asmjit.h or LICENSE.md for license and copyright information
4
+ // SPDX-License-Identifier: Zlib
5
+
6
+ #ifndef ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED
7
+ #define ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED
8
+
9
+ #include "../core/api-config.h"
10
+
11
+ #include "../core/emithelper_p.h"
12
+ #include "../core/func.h"
13
+ #include "../x86/x86emitter.h"
14
+ #include "../x86/x86operand.h"
15
+
16
+ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
17
+
18
+ //! \cond INTERNAL
19
+ //! \addtogroup asmjit_x86
20
+ //! \{
21
+
22
+ static inline RegType vecTypeIdToRegType(TypeId typeId) noexcept {
23
+ return uint32_t(typeId) <= uint32_t(TypeId::_kVec128End) ? RegType::kX86_Xmm :
24
+ uint32_t(typeId) <= uint32_t(TypeId::_kVec256End) ? RegType::kX86_Ymm : RegType::kX86_Zmm;
25
+ }
26
+
27
+ class EmitHelper : public BaseEmitHelper {
28
+ public:
29
+ bool _avxEnabled;
30
+ bool _avx512Enabled;
31
+
32
+ inline explicit EmitHelper(BaseEmitter* emitter = nullptr, bool avxEnabled = false, bool avx512Enabled = false) noexcept
33
+ : BaseEmitHelper(emitter),
34
+ _avxEnabled(avxEnabled || avx512Enabled),
35
+ _avx512Enabled(avx512Enabled) {}
36
+
37
+ Error emitRegMove(
38
+ const Operand_& dst_,
39
+ const Operand_& src_, TypeId typeId, const char* comment = nullptr) override;
40
+
41
+ Error emitArgMove(
42
+ const BaseReg& dst_, TypeId dstTypeId,
43
+ const Operand_& src_, TypeId srcTypeId, const char* comment = nullptr) override;
44
+
45
+ Error emitRegSwap(
46
+ const BaseReg& a,
47
+ const BaseReg& b, const char* comment = nullptr) override;
48
+
49
+ Error emitProlog(const FuncFrame& frame);
50
+ Error emitEpilog(const FuncFrame& frame);
51
+ };
52
+
53
+ void assignEmitterFuncs(BaseEmitter* emitter);
54
+
55
+ //! \}
56
+ //! \endcond
57
+
58
+ ASMJIT_END_SUB_NAMESPACE
59
+
60
+ #endif // ASMJIT_X86_X86EMITHELPER_P_H_INCLUDED