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