asmjit 0.2.0 → 0.2.2

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 (204) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/Rakefile +5 -3
  4. data/asmjit.gemspec +1 -3
  5. data/ext/asmjit/asmjit/.editorconfig +10 -0
  6. data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
  7. data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
  8. data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
  9. data/ext/asmjit/asmjit/.gitignore +6 -0
  10. data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
  11. data/ext/asmjit/asmjit/LICENSE.md +17 -0
  12. data/ext/asmjit/asmjit/README.md +69 -0
  13. data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
  14. data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
  15. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
  16. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
  17. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
  18. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
  19. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
  20. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
  21. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
  22. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
  23. data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
  24. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
  25. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
  26. data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
  27. data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
  28. data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
  29. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
  30. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
  31. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
  32. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
  33. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
  34. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
  35. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
  36. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
  37. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
  38. data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
  39. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
  40. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
  41. data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
  42. data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
  43. data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
  44. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
  45. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
  46. data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
  47. data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
  48. data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
  49. data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
  50. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
  51. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
  52. data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
  53. data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
  54. data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
  55. data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
  56. data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
  57. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
  58. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
  59. data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
  60. data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
  61. data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
  62. data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
  63. data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
  64. data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
  65. data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
  66. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
  67. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
  68. data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
  69. data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
  70. data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
  71. data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
  72. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
  73. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
  74. data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
  75. data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
  76. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
  77. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
  78. data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
  79. data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
  80. data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
  81. data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
  82. data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
  83. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
  84. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
  85. data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
  86. data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
  87. data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
  88. data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
  89. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
  90. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
  91. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
  92. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
  93. data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
  94. data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
  95. data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
  96. data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
  97. data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
  98. data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
  99. data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
  100. data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
  101. data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
  102. data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
  103. data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
  104. data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
  105. data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
  106. data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
  107. data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
  108. data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
  109. data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
  110. data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
  111. data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
  112. data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
  113. data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
  114. data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
  115. data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
  116. data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
  117. data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
  118. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
  119. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
  120. data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
  121. data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
  122. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
  123. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
  124. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
  125. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
  126. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
  127. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
  128. data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
  129. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
  130. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
  131. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
  132. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
  133. data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
  134. data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
  135. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
  136. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
  137. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
  138. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
  139. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
  140. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
  141. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
  142. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
  143. data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
  144. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
  145. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
  146. data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
  147. data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
  148. data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
  149. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
  150. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
  151. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
  152. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
  153. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
  154. data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
  155. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
  156. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
  157. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
  158. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
  159. data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
  160. data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
  161. data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
  162. data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
  163. data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
  164. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
  165. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
  166. data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
  167. data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
  168. data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
  169. data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
  170. data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
  171. data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
  172. data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
  173. data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
  174. data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
  175. data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
  176. data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
  177. data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
  178. data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
  179. data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
  180. data/ext/asmjit/asmjit/test/broken.cpp +312 -0
  181. data/ext/asmjit/asmjit/test/broken.h +148 -0
  182. data/ext/asmjit/asmjit/test/cmdline.h +61 -0
  183. data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
  184. data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
  185. data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
  186. data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
  187. data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
  188. data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
  189. data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
  190. data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
  191. data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
  192. data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
  193. data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
  194. data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
  195. data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
  196. data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
  197. data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
  198. data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
  199. data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
  200. data/ext/asmjit/asmjit.cc +167 -30
  201. data/ext/asmjit/extconf.rb +9 -9
  202. data/lib/asmjit/version.rb +1 -1
  203. data/lib/asmjit.rb +14 -4
  204. metadata +198 -17
@@ -0,0 +1,184 @@
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
+ #ifndef ASMJIT_NO_COMPILER
8
+
9
+ #include "../core/rastack_p.h"
10
+ #include "../core/support.h"
11
+
12
+ ASMJIT_BEGIN_NAMESPACE
13
+
14
+ // RAStackAllocator - Slots
15
+ // ========================
16
+
17
+ RAStackSlot* RAStackAllocator::newSlot(uint32_t baseRegId, uint32_t size, uint32_t alignment, uint32_t flags) noexcept {
18
+ if (ASMJIT_UNLIKELY(_slots.willGrow(allocator(), 1) != kErrorOk))
19
+ return nullptr;
20
+
21
+ RAStackSlot* slot = allocator()->allocT<RAStackSlot>();
22
+ if (ASMJIT_UNLIKELY(!slot))
23
+ return nullptr;
24
+
25
+ slot->_baseRegId = uint8_t(baseRegId);
26
+ slot->_alignment = uint8_t(Support::max<uint32_t>(alignment, 1));
27
+ slot->_flags = uint16_t(flags);
28
+ slot->_useCount = 0;
29
+ slot->_size = size;
30
+
31
+ slot->_weight = 0;
32
+ slot->_offset = 0;
33
+
34
+ _alignment = Support::max<uint32_t>(_alignment, alignment);
35
+ _slots.appendUnsafe(slot);
36
+ return slot;
37
+ }
38
+
39
+ // RAStackAllocator - Utilities
40
+ // ============================
41
+
42
+ struct RAStackGap {
43
+ inline RAStackGap() noexcept
44
+ : offset(0),
45
+ size(0) {}
46
+
47
+ inline RAStackGap(uint32_t offset, uint32_t size) noexcept
48
+ : offset(offset),
49
+ size(size) {}
50
+
51
+ inline RAStackGap(const RAStackGap& other) noexcept
52
+ : offset(other.offset),
53
+ size(other.size) {}
54
+
55
+ uint32_t offset;
56
+ uint32_t size;
57
+ };
58
+
59
+ Error RAStackAllocator::calculateStackFrame() noexcept {
60
+ // Base weight added to all registers regardless of their size and alignment.
61
+ uint32_t kBaseRegWeight = 16;
62
+
63
+ // STEP 1:
64
+ //
65
+ // Update usage based on the size of the slot. We boost smaller slots in a way that 32-bit register has higher
66
+ // priority than a 128-bit register, however, if one 128-bit register is used 4 times more than some other 32-bit
67
+ // register it will overweight it.
68
+ for (RAStackSlot* slot : _slots) {
69
+ uint32_t alignment = slot->alignment();
70
+ ASMJIT_ASSERT(alignment > 0);
71
+
72
+ uint32_t power = Support::min<uint32_t>(Support::ctz(alignment), 6);
73
+ uint64_t weight;
74
+
75
+ if (slot->isRegHome())
76
+ weight = kBaseRegWeight + (uint64_t(slot->useCount()) * (7 - power));
77
+ else
78
+ weight = power;
79
+
80
+ // If overflown, which has less chance of winning a lottery, just use max possible weight. In such case it
81
+ // probably doesn't matter at all.
82
+ if (weight > 0xFFFFFFFFu)
83
+ weight = 0xFFFFFFFFu;
84
+
85
+ slot->setWeight(uint32_t(weight));
86
+ }
87
+
88
+ // STEP 2:
89
+ //
90
+ // Sort stack slots based on their newly calculated weight (in descending order).
91
+ _slots.sort([](const RAStackSlot* a, const RAStackSlot* b) noexcept {
92
+ return a->weight() > b->weight() ? 1 :
93
+ a->weight() == b->weight() ? 0 : -1;
94
+ });
95
+
96
+ // STEP 3:
97
+ //
98
+ // Calculate offset of each slot. We start from the slot that has the highest weight and advance to slots with
99
+ // lower weight. It could look that offsets start from the first slot in our list and then simply increase, but
100
+ // it's not always the case as we also try to fill all gaps introduced by the fact that slots are sorted by
101
+ // weight and not by size & alignment, so when we need to align some slot we distribute the gap caused by the
102
+ // alignment to `gaps`.
103
+ uint32_t offset = 0;
104
+ ZoneVector<RAStackGap> gaps[kSizeCount - 1];
105
+
106
+ for (RAStackSlot* slot : _slots) {
107
+ if (slot->isStackArg())
108
+ continue;
109
+
110
+ uint32_t slotAlignment = slot->alignment();
111
+ uint32_t alignedOffset = Support::alignUp(offset, slotAlignment);
112
+
113
+ // Try to find a slot within gaps first, before advancing the `offset`.
114
+ bool foundGap = false;
115
+ uint32_t gapSize = 0;
116
+ uint32_t gapOffset = 0;
117
+
118
+ {
119
+ uint32_t slotSize = slot->size();
120
+ if (slotSize < (1u << uint32_t(ASMJIT_ARRAY_SIZE(gaps)))) {
121
+ // Iterate from the lowest to the highest possible.
122
+ uint32_t index = Support::ctz(slotSize);
123
+ do {
124
+ if (!gaps[index].empty()) {
125
+ RAStackGap gap = gaps[index].pop();
126
+
127
+ ASMJIT_ASSERT(Support::isAligned(gap.offset, slotAlignment));
128
+ slot->setOffset(int32_t(gap.offset));
129
+
130
+ gapSize = gap.size - slotSize;
131
+ gapOffset = gap.offset - slotSize;
132
+
133
+ foundGap = true;
134
+ break;
135
+ }
136
+ } while (++index < uint32_t(ASMJIT_ARRAY_SIZE(gaps)));
137
+ }
138
+ }
139
+
140
+ // No gap found, we may create a new one(s) if the current offset is not aligned.
141
+ if (!foundGap && offset != alignedOffset) {
142
+ gapSize = alignedOffset - offset;
143
+ gapOffset = alignedOffset;
144
+
145
+ offset = alignedOffset;
146
+ }
147
+
148
+ // True if we have found a gap and not filled all of it or we aligned the current offset.
149
+ if (gapSize) {
150
+ uint32_t gapEnd = gapSize + gapOffset;
151
+ while (gapOffset < gapEnd) {
152
+ uint32_t index = Support::ctz(gapOffset);
153
+ uint32_t slotSize = 1u << index;
154
+
155
+ // Weird case, better to bail...
156
+ if (gapEnd - gapOffset < slotSize)
157
+ break;
158
+
159
+ ASMJIT_PROPAGATE(gaps[index].append(allocator(), RAStackGap(gapOffset, slotSize)));
160
+ gapOffset += slotSize;
161
+ }
162
+ }
163
+
164
+ if (!foundGap) {
165
+ ASMJIT_ASSERT(Support::isAligned(offset, slotAlignment));
166
+ slot->setOffset(int32_t(offset));
167
+ offset += slot->size();
168
+ }
169
+ }
170
+
171
+ _stackSize = Support::alignUp(offset, _alignment);
172
+ return kErrorOk;
173
+ }
174
+
175
+ Error RAStackAllocator::adjustSlotOffsets(int32_t offset) noexcept {
176
+ for (RAStackSlot* slot : _slots)
177
+ if (!slot->isStackArg())
178
+ slot->_offset += offset;
179
+ return kErrorOk;
180
+ }
181
+
182
+ ASMJIT_END_NAMESPACE
183
+
184
+ #endif // !ASMJIT_NO_COMPILER
@@ -0,0 +1,171 @@
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_RASTACK_P_H_INCLUDED
7
+ #define ASMJIT_CORE_RASTACK_P_H_INCLUDED
8
+
9
+ #include "../core/api-config.h"
10
+ #ifndef ASMJIT_NO_COMPILER
11
+
12
+ #include "../core/radefs_p.h"
13
+
14
+ ASMJIT_BEGIN_NAMESPACE
15
+
16
+ //! \cond INTERNAL
17
+ //! \addtogroup asmjit_ra
18
+ //! \{
19
+
20
+ //! Stack slot.
21
+ struct RAStackSlot {
22
+ //! Stack slot flags.
23
+ //!
24
+ //! TODO: kFlagStackArg is not used by the current implementation, do we need to keep it?
25
+ enum Flags : uint16_t {
26
+ //! Stack slot is register home slot.
27
+ kFlagRegHome = 0x0001u,
28
+ //! Stack slot position matches argument passed via stack.
29
+ kFlagStackArg = 0x0002u
30
+ };
31
+
32
+ enum ArgIndex : uint32_t {
33
+ kNoArgIndex = 0xFF
34
+ };
35
+
36
+ //! \name Members
37
+ //! \{
38
+
39
+ //! Base register used to address the stack.
40
+ uint8_t _baseRegId;
41
+ //! Minimum alignment required by the slot.
42
+ uint8_t _alignment;
43
+ //! Reserved for future use.
44
+ uint16_t _flags;
45
+ //! Size of memory required by the slot.
46
+ uint32_t _size;
47
+
48
+ //! Usage counter (one unit equals one memory access).
49
+ uint32_t _useCount;
50
+ //! Weight of the slot, calculated by \ref RAStackAllocator::calculateStackFrame().
51
+ uint32_t _weight;
52
+ //! Stack offset, calculated by \ref RAStackAllocator::calculateStackFrame().
53
+ int32_t _offset;
54
+
55
+ //! \}
56
+
57
+ //! \name Accessors
58
+ //! \{
59
+
60
+ inline uint32_t baseRegId() const noexcept { return _baseRegId; }
61
+ inline void setBaseRegId(uint32_t id) noexcept { _baseRegId = uint8_t(id); }
62
+
63
+ inline uint32_t size() const noexcept { return _size; }
64
+ inline uint32_t alignment() const noexcept { return _alignment; }
65
+
66
+ inline uint32_t flags() const noexcept { return _flags; }
67
+ inline bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
68
+ inline void addFlags(uint32_t flags) noexcept { _flags = uint16_t(_flags | flags); }
69
+
70
+ inline bool isRegHome() const noexcept { return hasFlag(kFlagRegHome); }
71
+ inline bool isStackArg() const noexcept { return hasFlag(kFlagStackArg); }
72
+
73
+ inline uint32_t useCount() const noexcept { return _useCount; }
74
+ inline void addUseCount(uint32_t n = 1) noexcept { _useCount += n; }
75
+
76
+ inline uint32_t weight() const noexcept { return _weight; }
77
+ inline void setWeight(uint32_t weight) noexcept { _weight = weight; }
78
+
79
+ inline int32_t offset() const noexcept { return _offset; }
80
+ inline void setOffset(int32_t offset) noexcept { _offset = offset; }
81
+
82
+ //! \}
83
+ };
84
+
85
+ typedef ZoneVector<RAStackSlot*> RAStackSlots;
86
+
87
+ //! Stack allocator.
88
+ class RAStackAllocator {
89
+ public:
90
+ ASMJIT_NONCOPYABLE(RAStackAllocator)
91
+
92
+ enum Size : uint32_t {
93
+ kSize1 = 0,
94
+ kSize2 = 1,
95
+ kSize4 = 2,
96
+ kSize8 = 3,
97
+ kSize16 = 4,
98
+ kSize32 = 5,
99
+ kSize64 = 6,
100
+ kSizeCount = 7
101
+ };
102
+
103
+ //! \name Members
104
+ //! \{
105
+
106
+ //! Allocator used to allocate internal data.
107
+ ZoneAllocator* _allocator;
108
+ //! Count of bytes used by all slots.
109
+ uint32_t _bytesUsed;
110
+ //! Calculated stack size (can be a bit greater than `_bytesUsed`).
111
+ uint32_t _stackSize;
112
+ //! Minimum stack alignment.
113
+ uint32_t _alignment;
114
+ //! Stack slots vector.
115
+ RAStackSlots _slots;
116
+
117
+ //! \}
118
+
119
+ //! \name Construction & Destruction
120
+ //! \{
121
+
122
+ inline RAStackAllocator() noexcept
123
+ : _allocator(nullptr),
124
+ _bytesUsed(0),
125
+ _stackSize(0),
126
+ _alignment(1),
127
+ _slots() {}
128
+
129
+ inline void reset(ZoneAllocator* allocator) noexcept {
130
+ _allocator = allocator;
131
+ _bytesUsed = 0;
132
+ _stackSize = 0;
133
+ _alignment = 1;
134
+ _slots.reset();
135
+ }
136
+
137
+ //! \}
138
+
139
+ //! \name Accessors
140
+ //! \{
141
+
142
+ inline ZoneAllocator* allocator() const noexcept { return _allocator; }
143
+
144
+ inline uint32_t bytesUsed() const noexcept { return _bytesUsed; }
145
+ inline uint32_t stackSize() const noexcept { return _stackSize; }
146
+ inline uint32_t alignment() const noexcept { return _alignment; }
147
+
148
+ inline RAStackSlots& slots() noexcept { return _slots; }
149
+ inline const RAStackSlots& slots() const noexcept { return _slots; }
150
+ inline uint32_t slotCount() const noexcept { return _slots.size(); }
151
+
152
+ //! \}
153
+
154
+ //! \name Utilities
155
+ //! \{
156
+
157
+ RAStackSlot* newSlot(uint32_t baseRegId, uint32_t size, uint32_t alignment, uint32_t flags = 0) noexcept;
158
+
159
+ Error calculateStackFrame() noexcept;
160
+ Error adjustSlotOffsets(int32_t offset) noexcept;
161
+
162
+ //! \}
163
+ };
164
+
165
+ //! \}
166
+ //! \endcond
167
+
168
+ ASMJIT_END_NAMESPACE
169
+
170
+ #endif // !ASMJIT_NO_COMPILER
171
+ #endif // ASMJIT_CORE_RASTACK_P_H_INCLUDED