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