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,293 @@
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
+ #include "../core/funcargscontext_p.h"
8
+
9
+ ASMJIT_BEGIN_NAMESPACE
10
+
11
+ //! \cond INTERNAL
12
+ //! \addtogroup asmjit_core
13
+ //! \{
14
+
15
+ FuncArgsContext::FuncArgsContext() noexcept {
16
+ for (RegGroup group : RegGroupVirtValues{})
17
+ _workData[size_t(group)].reset();
18
+ }
19
+
20
+ ASMJIT_FAVOR_SIZE Error FuncArgsContext::initWorkData(const FuncFrame& frame, const FuncArgsAssignment& args, const RAConstraints* constraints) noexcept {
21
+ Arch arch = frame.arch();
22
+ const FuncDetail& func = *args.funcDetail();
23
+
24
+ _archTraits = &ArchTraits::byArch(arch);
25
+ _constraints = constraints;
26
+ _arch = arch;
27
+
28
+ // Initialize `_archRegs`.
29
+ for (RegGroup group : RegGroupVirtValues{})
30
+ _workData[group]._archRegs = _constraints->availableRegs(group);
31
+
32
+ if (frame.hasPreservedFP())
33
+ _workData[size_t(RegGroup::kGp)]._archRegs &= ~Support::bitMask(archTraits().fpRegId());
34
+
35
+ // Extract information from all function arguments/assignments and build Var[] array.
36
+ uint32_t varId = 0;
37
+ for (uint32_t argIndex = 0; argIndex < Globals::kMaxFuncArgs; argIndex++) {
38
+ for (uint32_t valueIndex = 0; valueIndex < Globals::kMaxValuePack; valueIndex++) {
39
+ const FuncValue& dst_ = args.arg(argIndex, valueIndex);
40
+ if (!dst_.isAssigned())
41
+ continue;
42
+
43
+ const FuncValue& src_ = func.arg(argIndex, valueIndex);
44
+ if (ASMJIT_UNLIKELY(!src_.isAssigned()))
45
+ return DebugUtils::errored(kErrorInvalidState);
46
+
47
+ Var& var = _vars[varId];
48
+ var.init(src_, dst_);
49
+
50
+ FuncValue& src = var.cur;
51
+ FuncValue& dst = var.out;
52
+
53
+ RegGroup dstGroup = RegGroup::kMaxValue;
54
+ uint32_t dstId = BaseReg::kIdBad;
55
+ WorkData* dstWd = nullptr;
56
+
57
+ // Not supported.
58
+ if (src.isIndirect())
59
+ return DebugUtils::errored(kErrorInvalidAssignment);
60
+
61
+ if (dst.isReg()) {
62
+ RegType dstType = dst.regType();
63
+ if (ASMJIT_UNLIKELY(!archTraits().hasRegType(dstType)))
64
+ return DebugUtils::errored(kErrorInvalidRegType);
65
+
66
+ // Copy TypeId from source if the destination doesn't have it. The RA used by BaseCompiler would never
67
+ // leave TypeId undefined, but users of FuncAPI can just assign phys regs without specifying the type.
68
+ if (!dst.hasTypeId())
69
+ dst.setTypeId(archTraits().regTypeToTypeId(dst.regType()));
70
+
71
+ dstGroup = archTraits().regTypeToGroup(dstType);
72
+ if (ASMJIT_UNLIKELY(dstGroup > RegGroup::kMaxVirt))
73
+ return DebugUtils::errored(kErrorInvalidRegGroup);
74
+
75
+ dstWd = &_workData[dstGroup];
76
+ dstId = dst.regId();
77
+ if (ASMJIT_UNLIKELY(dstId >= 32 || !Support::bitTest(dstWd->archRegs(), dstId)))
78
+ return DebugUtils::errored(kErrorInvalidPhysId);
79
+
80
+ if (ASMJIT_UNLIKELY(Support::bitTest(dstWd->dstRegs(), dstId)))
81
+ return DebugUtils::errored(kErrorOverlappedRegs);
82
+
83
+ dstWd->_dstRegs |= Support::bitMask(dstId);
84
+ dstWd->_dstShuf |= Support::bitMask(dstId);
85
+ dstWd->_usedRegs |= Support::bitMask(dstId);
86
+ }
87
+ else {
88
+ if (!dst.hasTypeId())
89
+ dst.setTypeId(src.typeId());
90
+
91
+ OperandSignature signature = getSuitableRegForMemToMemMove(arch, dst.typeId(), src.typeId());
92
+ if (ASMJIT_UNLIKELY(!signature.isValid()))
93
+ return DebugUtils::errored(kErrorInvalidState);
94
+ _stackDstMask = uint8_t(_stackDstMask | Support::bitMask(signature.regGroup()));
95
+ }
96
+
97
+ if (src.isReg()) {
98
+ uint32_t srcId = src.regId();
99
+ RegGroup srcGroup = archTraits().regTypeToGroup(src.regType());
100
+
101
+ if (dstGroup == srcGroup) {
102
+ ASMJIT_ASSERT(dstWd != nullptr);
103
+ dstWd->assign(varId, srcId);
104
+
105
+ // The best case, register is allocated where it is expected to be.
106
+ if (dstId == srcId)
107
+ var.markDone();
108
+ }
109
+ else {
110
+ if (ASMJIT_UNLIKELY(srcGroup > RegGroup::kMaxVirt))
111
+ return DebugUtils::errored(kErrorInvalidState);
112
+
113
+ WorkData& srcData = _workData[size_t(srcGroup)];
114
+ srcData.assign(varId, srcId);
115
+ }
116
+ }
117
+ else {
118
+ if (dstWd)
119
+ dstWd->_numStackArgs++;
120
+ _hasStackSrc = true;
121
+ }
122
+
123
+ varId++;
124
+ }
125
+ }
126
+
127
+ // Initialize WorkData::workRegs.
128
+ for (RegGroup group : RegGroupVirtValues{}) {
129
+ _workData[group]._workRegs =
130
+ (_workData[group].archRegs() & (frame.dirtyRegs(group) | ~frame.preservedRegs(group))) | _workData[group].dstRegs() | _workData[group].assignedRegs();
131
+ }
132
+
133
+ // Create a variable that represents `SARegId` if necessary.
134
+ bool saRegRequired = _hasStackSrc && frame.hasDynamicAlignment() && !frame.hasPreservedFP();
135
+
136
+ WorkData& gpRegs = _workData[RegGroup::kGp];
137
+ uint32_t saCurRegId = frame.saRegId();
138
+ uint32_t saOutRegId = args.saRegId();
139
+
140
+ if (saCurRegId != BaseReg::kIdBad) {
141
+ // Check if the provided `SARegId` doesn't collide with input registers.
142
+ if (ASMJIT_UNLIKELY(gpRegs.isAssigned(saCurRegId)))
143
+ return DebugUtils::errored(kErrorOverlappedRegs);
144
+ }
145
+
146
+ if (saOutRegId != BaseReg::kIdBad) {
147
+ // Check if the provided `SARegId` doesn't collide with argument assignments.
148
+ if (ASMJIT_UNLIKELY(Support::bitTest(gpRegs.dstRegs(), saOutRegId)))
149
+ return DebugUtils::errored(kErrorOverlappedRegs);
150
+ saRegRequired = true;
151
+ }
152
+
153
+ if (saRegRequired) {
154
+ TypeId ptrTypeId = Environment::is32Bit(arch) ? TypeId::kUInt32 : TypeId::kUInt64;
155
+ RegType ptrRegType = Environment::is32Bit(arch) ? RegType::kGp32 : RegType::kGp64;
156
+
157
+ _saVarId = uint8_t(varId);
158
+ _hasPreservedFP = frame.hasPreservedFP();
159
+
160
+ Var& var = _vars[varId];
161
+ var.reset();
162
+
163
+ if (saCurRegId == BaseReg::kIdBad) {
164
+ if (saOutRegId != BaseReg::kIdBad && !gpRegs.isAssigned(saOutRegId)) {
165
+ saCurRegId = saOutRegId;
166
+ }
167
+ else {
168
+ RegMask availableRegs = gpRegs.availableRegs();
169
+ if (!availableRegs)
170
+ availableRegs = gpRegs.archRegs() & ~gpRegs.workRegs();
171
+
172
+ if (ASMJIT_UNLIKELY(!availableRegs))
173
+ return DebugUtils::errored(kErrorNoMorePhysRegs);
174
+
175
+ saCurRegId = Support::ctz(availableRegs);
176
+ }
177
+ }
178
+
179
+ var.cur.initReg(ptrRegType, saCurRegId, ptrTypeId);
180
+ gpRegs.assign(varId, saCurRegId);
181
+ gpRegs._workRegs |= Support::bitMask(saCurRegId);
182
+
183
+ if (saOutRegId != BaseReg::kIdBad) {
184
+ var.out.initReg(ptrRegType, saOutRegId, ptrTypeId);
185
+ gpRegs._dstRegs |= Support::bitMask(saOutRegId);
186
+ gpRegs._workRegs |= Support::bitMask(saOutRegId);
187
+ }
188
+ else {
189
+ var.markDone();
190
+ }
191
+
192
+ varId++;
193
+ }
194
+
195
+ _varCount = varId;
196
+
197
+ // Detect register swaps.
198
+ for (varId = 0; varId < _varCount; varId++) {
199
+ Var& var = _vars[varId];
200
+ if (var.cur.isReg() && var.out.isReg()) {
201
+ uint32_t srcId = var.cur.regId();
202
+ uint32_t dstId = var.out.regId();
203
+
204
+ RegGroup group = archTraits().regTypeToGroup(var.cur.regType());
205
+ if (group != archTraits().regTypeToGroup(var.out.regType()))
206
+ continue;
207
+
208
+ WorkData& wd = _workData[group];
209
+ if (wd.isAssigned(dstId)) {
210
+ Var& other = _vars[wd._physToVarId[dstId]];
211
+ if (archTraits().regTypeToGroup(other.out.regType()) == group && other.out.regId() == srcId) {
212
+ wd._numSwaps++;
213
+ _regSwapsMask = uint8_t(_regSwapsMask | Support::bitMask(group));
214
+ }
215
+ }
216
+ }
217
+ }
218
+
219
+ return kErrorOk;
220
+ }
221
+
222
+ ASMJIT_FAVOR_SIZE Error FuncArgsContext::markDstRegsDirty(FuncFrame& frame) noexcept {
223
+ for (RegGroup group : RegGroupVirtValues{}) {
224
+ WorkData& wd = _workData[group];
225
+ uint32_t regs = wd.usedRegs() | wd._dstShuf;
226
+
227
+ wd._workRegs |= regs;
228
+ frame.addDirtyRegs(group, regs);
229
+ }
230
+
231
+ return kErrorOk;
232
+ }
233
+
234
+ ASMJIT_FAVOR_SIZE Error FuncArgsContext::markScratchRegs(FuncFrame& frame) noexcept {
235
+ uint32_t groupMask = 0;
236
+
237
+ // Handle stack to stack moves.
238
+ groupMask |= _stackDstMask;
239
+
240
+ // Handle register swaps.
241
+ groupMask |= _regSwapsMask & ~Support::bitMask(RegGroup::kGp);
242
+
243
+ if (!groupMask)
244
+ return kErrorOk;
245
+
246
+ // Selects one dirty register per affected group that can be used as a scratch register.
247
+ for (RegGroup group : RegGroupVirtValues{}) {
248
+ if (Support::bitTest(groupMask, group)) {
249
+ WorkData& wd = _workData[group];
250
+
251
+ // Initially, pick some clobbered or dirty register.
252
+ RegMask workRegs = wd.workRegs();
253
+ RegMask regs = workRegs & ~(wd.usedRegs() | wd._dstShuf);
254
+
255
+ // If that didn't work out pick some register which is not in 'used'.
256
+ if (!regs)
257
+ regs = workRegs & ~wd.usedRegs();
258
+
259
+ // If that didn't work out pick any other register that is allocable.
260
+ // This last resort case will, however, result in marking one more
261
+ // register dirty.
262
+ if (!regs)
263
+ regs = wd.archRegs() & ~workRegs;
264
+
265
+ // If that didn't work out we will have to use XORs instead of MOVs.
266
+ if (!regs)
267
+ continue;
268
+
269
+ RegMask regMask = Support::blsi(regs);
270
+ wd._workRegs |= regMask;
271
+ frame.addDirtyRegs(group, regMask);
272
+ }
273
+ }
274
+
275
+ return kErrorOk;
276
+ }
277
+
278
+ ASMJIT_FAVOR_SIZE Error FuncArgsContext::markStackArgsReg(FuncFrame& frame) noexcept {
279
+ if (_saVarId != kVarIdNone) {
280
+ const Var& var = _vars[_saVarId];
281
+ frame.setSARegId(var.cur.regId());
282
+ }
283
+ else if (frame.hasPreservedFP()) {
284
+ frame.setSARegId(archTraits().fpRegId());
285
+ }
286
+
287
+ return kErrorOk;
288
+ }
289
+
290
+ //! \}
291
+ //! \endcond
292
+
293
+ ASMJIT_END_NAMESPACE
@@ -0,0 +1,199 @@
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_CORE_FUNCARGSCONTEXT_P_H_INCLUDED
7
+ #define ASMJIT_CORE_FUNCARGSCONTEXT_P_H_INCLUDED
8
+
9
+ #include "../core/archtraits.h"
10
+ #include "../core/environment.h"
11
+ #include "../core/func.h"
12
+ #include "../core/operand.h"
13
+ #include "../core/radefs_p.h"
14
+ #include "../core/support.h"
15
+
16
+ ASMJIT_BEGIN_NAMESPACE
17
+
18
+ //! \cond INTERNAL
19
+ //! \addtogroup asmjit_core
20
+ //! \{
21
+
22
+ static inline OperandSignature getSuitableRegForMemToMemMove(Arch arch, TypeId dstTypeId, TypeId srcTypeId) noexcept {
23
+ const ArchTraits& archTraits = ArchTraits::byArch(arch);
24
+
25
+ uint32_t dstSize = TypeUtils::sizeOf(dstTypeId);
26
+ uint32_t srcSize = TypeUtils::sizeOf(srcTypeId);
27
+ uint32_t maxSize = Support::max<uint32_t>(dstSize, srcSize);
28
+ uint32_t regSize = Environment::registerSizeFromArch(arch);
29
+
30
+ OperandSignature signature{0};
31
+ if (maxSize <= regSize || (TypeUtils::isInt(dstTypeId) && TypeUtils::isInt(srcTypeId)))
32
+ signature = maxSize <= 4 ? archTraits.regTypeToSignature(RegType::kGp32)
33
+ : archTraits.regTypeToSignature(RegType::kGp64);
34
+ else if (maxSize <= 8 && archTraits.hasRegType(RegType::kVec64))
35
+ signature = archTraits.regTypeToSignature(RegType::kVec64);
36
+ else if (maxSize <= 16 && archTraits.hasRegType(RegType::kVec128))
37
+ signature = archTraits.regTypeToSignature(RegType::kVec128);
38
+ else if (maxSize <= 32 && archTraits.hasRegType(RegType::kVec256))
39
+ signature = archTraits.regTypeToSignature(RegType::kVec256);
40
+ else if (maxSize <= 64 && archTraits.hasRegType(RegType::kVec512))
41
+ signature = archTraits.regTypeToSignature(RegType::kVec512);
42
+
43
+ return signature;
44
+ }
45
+
46
+ class FuncArgsContext {
47
+ public:
48
+ enum VarId : uint32_t {
49
+ kVarIdNone = 0xFF
50
+ };
51
+
52
+ //! Contains information about a single argument or SA register that may need shuffling.
53
+ struct Var {
54
+ FuncValue cur;
55
+ FuncValue out;
56
+
57
+ inline void init(const FuncValue& cur_, const FuncValue& out_) noexcept {
58
+ cur = cur_;
59
+ out = out_;
60
+ }
61
+
62
+ //! Reset the value to its unassigned state.
63
+ inline void reset() noexcept {
64
+ cur.reset();
65
+ out.reset();
66
+ }
67
+
68
+ inline bool isDone() const noexcept { return cur.isDone(); }
69
+ inline void markDone() noexcept { cur.addFlags(FuncValue::kFlagIsDone); }
70
+ };
71
+
72
+ struct WorkData {
73
+ //! All allocable registers provided by the architecture.
74
+ RegMask _archRegs;
75
+ //! All registers that can be used by the shuffler.
76
+ RegMask _workRegs;
77
+ //! Registers used by the shuffler (all).
78
+ RegMask _usedRegs;
79
+ //! Assigned registers.
80
+ RegMask _assignedRegs;
81
+ //! Destination registers assigned to arguments or SA.
82
+ RegMask _dstRegs;
83
+ //! Destination registers that require shuffling.
84
+ RegMask _dstShuf;
85
+ //! Number of register swaps.
86
+ uint8_t _numSwaps;
87
+ //! Number of stack loads.
88
+ uint8_t _numStackArgs;
89
+ //! Reserved (only used as padding).
90
+ uint8_t _reserved[6];
91
+ //! Physical ID to variable ID mapping.
92
+ uint8_t _physToVarId[32];
93
+
94
+ inline void reset() noexcept {
95
+ _archRegs = 0;
96
+ _workRegs = 0;
97
+ _usedRegs = 0;
98
+ _assignedRegs = 0;
99
+ _dstRegs = 0;
100
+ _dstShuf = 0;
101
+ _numSwaps = 0;
102
+ _numStackArgs = 0;
103
+ memset(_reserved, 0, sizeof(_reserved));
104
+ memset(_physToVarId, kVarIdNone, 32);
105
+ }
106
+
107
+ inline bool isAssigned(uint32_t regId) const noexcept {
108
+ ASMJIT_ASSERT(regId < 32);
109
+ return Support::bitTest(_assignedRegs, regId);
110
+ }
111
+
112
+ inline void assign(uint32_t varId, uint32_t regId) noexcept {
113
+ ASMJIT_ASSERT(!isAssigned(regId));
114
+ ASMJIT_ASSERT(_physToVarId[regId] == kVarIdNone);
115
+
116
+ _physToVarId[regId] = uint8_t(varId);
117
+ _assignedRegs ^= Support::bitMask(regId);
118
+ }
119
+
120
+ inline void reassign(uint32_t varId, uint32_t newId, uint32_t oldId) noexcept {
121
+ ASMJIT_ASSERT( isAssigned(oldId));
122
+ ASMJIT_ASSERT(!isAssigned(newId));
123
+ ASMJIT_ASSERT(_physToVarId[oldId] == varId);
124
+ ASMJIT_ASSERT(_physToVarId[newId] == kVarIdNone);
125
+
126
+ _physToVarId[oldId] = uint8_t(kVarIdNone);
127
+ _physToVarId[newId] = uint8_t(varId);
128
+ _assignedRegs ^= Support::bitMask(newId) ^ Support::bitMask(oldId);
129
+ }
130
+
131
+ inline void swap(uint32_t aVarId, uint32_t aRegId, uint32_t bVarId, uint32_t bRegId) noexcept {
132
+ ASMJIT_ASSERT(isAssigned(aRegId));
133
+ ASMJIT_ASSERT(isAssigned(bRegId));
134
+ ASMJIT_ASSERT(_physToVarId[aRegId] == aVarId);
135
+ ASMJIT_ASSERT(_physToVarId[bRegId] == bVarId);
136
+
137
+ _physToVarId[aRegId] = uint8_t(bVarId);
138
+ _physToVarId[bRegId] = uint8_t(aVarId);
139
+ }
140
+
141
+ inline void unassign(uint32_t varId, uint32_t regId) noexcept {
142
+ ASMJIT_ASSERT(isAssigned(regId));
143
+ ASMJIT_ASSERT(_physToVarId[regId] == varId);
144
+
145
+ DebugUtils::unused(varId);
146
+ _physToVarId[regId] = uint8_t(kVarIdNone);
147
+ _assignedRegs ^= Support::bitMask(regId);
148
+ }
149
+
150
+ inline RegMask archRegs() const noexcept { return _archRegs; }
151
+ inline RegMask workRegs() const noexcept { return _workRegs; }
152
+ inline RegMask usedRegs() const noexcept { return _usedRegs; }
153
+ inline RegMask assignedRegs() const noexcept { return _assignedRegs; }
154
+ inline RegMask dstRegs() const noexcept { return _dstRegs; }
155
+ inline RegMask availableRegs() const noexcept { return _workRegs & ~_assignedRegs; }
156
+ };
157
+
158
+ //! Architecture traits.
159
+ const ArchTraits* _archTraits = nullptr;
160
+ //! Architecture constraints.
161
+ const RAConstraints* _constraints = nullptr;
162
+ //! Target architecture.
163
+ Arch _arch = Arch::kUnknown;
164
+ //! Has arguments passed via stack (SRC).
165
+ bool _hasStackSrc = false;
166
+ //! Has preserved frame-pointer (FP).
167
+ bool _hasPreservedFP = false;
168
+ //! Has arguments assigned to stack (DST).
169
+ uint8_t _stackDstMask = 0;
170
+ //! Register swap groups (bit-mask).
171
+ uint8_t _regSwapsMask = 0;
172
+ uint8_t _saVarId = kVarIdNone;
173
+ uint32_t _varCount = 0;
174
+ Support::Array<WorkData, Globals::kNumVirtGroups> _workData;
175
+ Var _vars[Globals::kMaxFuncArgs * Globals::kMaxValuePack + 1];
176
+
177
+ FuncArgsContext() noexcept;
178
+
179
+ inline const ArchTraits& archTraits() const noexcept { return *_archTraits; }
180
+ inline Arch arch() const noexcept { return _arch; }
181
+
182
+ inline uint32_t varCount() const noexcept { return _varCount; }
183
+ inline size_t indexOf(const Var* var) const noexcept { return (size_t)(var - _vars); }
184
+
185
+ inline Var& var(size_t varId) noexcept { return _vars[varId]; }
186
+ inline const Var& var(size_t varId) const noexcept { return _vars[varId]; }
187
+
188
+ Error initWorkData(const FuncFrame& frame, const FuncArgsAssignment& args, const RAConstraints* constraints) noexcept;
189
+ Error markScratchRegs(FuncFrame& frame) noexcept;
190
+ Error markDstRegsDirty(FuncFrame& frame) noexcept;
191
+ Error markStackArgsReg(FuncFrame& frame) noexcept;
192
+ };
193
+
194
+ //! \}
195
+ //! \endcond
196
+
197
+ ASMJIT_END_NAMESPACE
198
+
199
+ #endif // ASMJIT_CORE_FUNCARGSCONTEXT_P_H_INCLUDED
@@ -0,0 +1,133 @@
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
+ #include "../core/globals.h"
8
+ #include "../core/support.h"
9
+
10
+ ASMJIT_BEGIN_NAMESPACE
11
+
12
+ // DebugUtils - Error As String
13
+ // ============================
14
+
15
+ ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept {
16
+ #ifndef ASMJIT_NO_TEXT
17
+ // @EnumStringBegin{"enum": "ErrorCode", "output": "sError", "strip": "kError"}@
18
+ static const char sErrorString[] =
19
+ "Ok\0"
20
+ "OutOfMemory\0"
21
+ "InvalidArgument\0"
22
+ "InvalidState\0"
23
+ "InvalidArch\0"
24
+ "NotInitialized\0"
25
+ "AlreadyInitialized\0"
26
+ "FeatureNotEnabled\0"
27
+ "TooManyHandles\0"
28
+ "TooLarge\0"
29
+ "NoCodeGenerated\0"
30
+ "InvalidDirective\0"
31
+ "InvalidLabel\0"
32
+ "TooManyLabels\0"
33
+ "LabelAlreadyBound\0"
34
+ "LabelAlreadyDefined\0"
35
+ "LabelNameTooLong\0"
36
+ "InvalidLabelName\0"
37
+ "InvalidParentLabel\0"
38
+ "InvalidSection\0"
39
+ "TooManySections\0"
40
+ "InvalidSectionName\0"
41
+ "TooManyRelocations\0"
42
+ "InvalidRelocEntry\0"
43
+ "RelocOffsetOutOfRange\0"
44
+ "InvalidAssignment\0"
45
+ "InvalidInstruction\0"
46
+ "InvalidRegType\0"
47
+ "InvalidRegGroup\0"
48
+ "InvalidPhysId\0"
49
+ "InvalidVirtId\0"
50
+ "InvalidElementIndex\0"
51
+ "InvalidPrefixCombination\0"
52
+ "InvalidLockPrefix\0"
53
+ "InvalidXAcquirePrefix\0"
54
+ "InvalidXReleasePrefix\0"
55
+ "InvalidRepPrefix\0"
56
+ "InvalidRexPrefix\0"
57
+ "InvalidExtraReg\0"
58
+ "InvalidKMaskUse\0"
59
+ "InvalidKZeroUse\0"
60
+ "InvalidBroadcast\0"
61
+ "InvalidEROrSAE\0"
62
+ "InvalidAddress\0"
63
+ "InvalidAddressIndex\0"
64
+ "InvalidAddressScale\0"
65
+ "InvalidAddress64Bit\0"
66
+ "InvalidAddress64BitZeroExtension\0"
67
+ "InvalidDisplacement\0"
68
+ "InvalidSegment\0"
69
+ "InvalidImmediate\0"
70
+ "InvalidOperandSize\0"
71
+ "AmbiguousOperandSize\0"
72
+ "OperandSizeMismatch\0"
73
+ "InvalidOption\0"
74
+ "OptionAlreadyDefined\0"
75
+ "InvalidTypeId\0"
76
+ "InvalidUseOfGpbHi\0"
77
+ "InvalidUseOfGpq\0"
78
+ "InvalidUseOfF80\0"
79
+ "NotConsecutiveRegs\0"
80
+ "ConsecutiveRegsAllocation\0"
81
+ "IllegalVirtReg\0"
82
+ "TooManyVirtRegs\0"
83
+ "NoMorePhysRegs\0"
84
+ "OverlappedRegs\0"
85
+ "OverlappingStackRegWithRegArg\0"
86
+ "ExpressionLabelNotBound\0"
87
+ "ExpressionOverflow\0"
88
+ "FailedToOpenAnonymousMemory\0"
89
+ "<Unknown>\0";
90
+
91
+ static const uint16_t sErrorIndex[] = {
92
+ 0, 3, 15, 31, 44, 56, 71, 90, 108, 123, 132, 148, 165, 178, 192, 210, 230,
93
+ 247, 264, 283, 298, 314, 333, 352, 370, 392, 410, 429, 444, 460, 474, 488,
94
+ 508, 533, 551, 573, 595, 612, 629, 645, 661, 677, 694, 709, 724, 744, 764,
95
+ 784, 817, 837, 852, 869, 888, 909, 929, 943, 964, 978, 996, 1012, 1028, 1047,
96
+ 1073, 1088, 1104, 1119, 1134, 1164, 1188, 1207, 1235
97
+ };
98
+ // @EnumStringEnd@
99
+
100
+ return sErrorString + sErrorIndex[Support::min<Error>(err, kErrorCount)];
101
+ #else
102
+ DebugUtils::unused(err);
103
+ static const char noMessage[] = "";
104
+ return noMessage;
105
+ #endif
106
+ }
107
+
108
+ // DebugUtils - Debug Output
109
+ // =========================
110
+
111
+ ASMJIT_FAVOR_SIZE void DebugUtils::debugOutput(const char* str) noexcept {
112
+ #if defined(_WIN32)
113
+ ::OutputDebugStringA(str);
114
+ #else
115
+ ::fputs(str, stderr);
116
+ #endif
117
+ }
118
+
119
+ // DebugUtils - Fatal Errors
120
+ // =========================
121
+
122
+ ASMJIT_FAVOR_SIZE void DebugUtils::assertionFailed(const char* file, int line, const char* msg) noexcept {
123
+ char str[1024];
124
+
125
+ snprintf(str, 1024,
126
+ "[asmjit] Assertion failed at %s (line %d):\n"
127
+ "[asmjit] %s\n", file, line, msg);
128
+
129
+ debugOutput(str);
130
+ ::abort();
131
+ }
132
+
133
+ ASMJIT_END_NAMESPACE