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,173 @@
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_COMPILERDEFS_H_INCLUDED
7
+ #define ASMJIT_CORE_COMPILERDEFS_H_INCLUDED
8
+
9
+ #include "../core/api-config.h"
10
+ #include "../core/operand.h"
11
+ #include "../core/type.h"
12
+ #include "../core/zonestring.h"
13
+
14
+ ASMJIT_BEGIN_NAMESPACE
15
+
16
+ class RAWorkReg;
17
+
18
+ //! \addtogroup asmjit_compiler
19
+ //! \{
20
+
21
+ //! Virtual register data, managed by \ref BaseCompiler.
22
+ class VirtReg {
23
+ public:
24
+ ASMJIT_NONCOPYABLE(VirtReg)
25
+
26
+ //! \name Members
27
+ //! \{
28
+
29
+ //! Virtual register signature.
30
+ OperandSignature _signature {};
31
+ //! Virtual register id.
32
+ uint32_t _id = 0;
33
+ //! Virtual register size (can be smaller than `_signature._size`).
34
+ uint32_t _virtSize = 0;
35
+ //! Virtual register alignment (for spilling).
36
+ uint8_t _alignment = 0;
37
+ //! Type-id.
38
+ TypeId _typeId = TypeId::kVoid;
39
+ //! Virtual register weight for alloc/spill decisions.
40
+ uint8_t _weight = 1;
41
+ //! True if this is a fixed register, never reallocated.
42
+ uint8_t _isFixed : 1;
43
+ //! True if the virtual register is only used as a stack (never accessed as register).
44
+ uint8_t _isStack : 1;
45
+ //! True if this virtual register has assigned stack offset (can be only valid after register allocation pass).
46
+ uint8_t _hasStackSlot : 1;
47
+ uint8_t _reservedBits : 5;
48
+
49
+ //! Stack offset assigned by the register allocator relative to stack pointer (can be negative as well).
50
+ int32_t _stackOffset = 0;
51
+
52
+ //! Reserved for future use (padding).
53
+ uint32_t _reservedU32 = 0;
54
+
55
+ //! Virtual register name (user provided or automatically generated).
56
+ ZoneString<16> _name {};
57
+
58
+ // The following members are used exclusively by RAPass. They are initialized when the VirtReg is created to
59
+ // null pointers and then changed during RAPass execution. RAPass sets them back to NULL before it returns.
60
+
61
+ //! Reference to `RAWorkReg`, used during register allocation.
62
+ RAWorkReg* _workReg = nullptr;
63
+
64
+ //! \}
65
+
66
+ //! \name Construction & Destruction
67
+ //! \{
68
+
69
+ inline VirtReg(OperandSignature signature, uint32_t id, uint32_t virtSize, uint32_t alignment, TypeId typeId) noexcept
70
+ : _signature(signature),
71
+ _id(id),
72
+ _virtSize(virtSize),
73
+ _alignment(uint8_t(alignment)),
74
+ _typeId(typeId),
75
+ _isFixed(false),
76
+ _isStack(false),
77
+ _hasStackSlot(false),
78
+ _reservedBits(0),
79
+ _stackOffset(0),
80
+ _reservedU32(0) {}
81
+
82
+ //! \}
83
+
84
+ //! \name Accessors
85
+ //! \{
86
+
87
+ //! Returns the virtual register id.
88
+ inline uint32_t id() const noexcept { return _id; }
89
+
90
+ //! Returns the virtual register name.
91
+ inline const char* name() const noexcept { return _name.data(); }
92
+ //! Returns the size of the virtual register name.
93
+ inline uint32_t nameSize() const noexcept { return _name.size(); }
94
+
95
+ //! Returns a register signature of this virtual register.
96
+ inline OperandSignature signature() const noexcept { return _signature; }
97
+ //! Returns a virtual register type (maps to the physical register type as well).
98
+ inline RegType type() const noexcept { return _signature.regType(); }
99
+ //! Returns a virtual register group (maps to the physical register group as well).
100
+ inline RegGroup group() const noexcept { return _signature.regGroup(); }
101
+
102
+ //! Returns a real size of the register this virtual register maps to.
103
+ //!
104
+ //! For example if this is a 128-bit SIMD register used for a scalar single precision floating point value then
105
+ //! its virtSize would be 4, however, the `regSize` would still say 16 (128-bits), because it's the smallest size
106
+ //! of that register type.
107
+ inline uint32_t regSize() const noexcept { return _signature.size(); }
108
+
109
+ //! Returns the virtual register size.
110
+ //!
111
+ //! The virtual register size describes how many bytes the virtual register needs to store its content. It can be
112
+ //! smaller than the physical register size, see `regSize()`.
113
+ inline uint32_t virtSize() const noexcept { return _virtSize; }
114
+
115
+ //! Returns the virtual register alignment.
116
+ inline uint32_t alignment() const noexcept { return _alignment; }
117
+
118
+ //! Returns the virtual register type id.
119
+ inline TypeId typeId() const noexcept { return _typeId; }
120
+
121
+ //! Returns the virtual register weight - the register allocator can use it as explicit hint for alloc/spill
122
+ //! decisions.
123
+ inline uint32_t weight() const noexcept { return _weight; }
124
+ //! Sets the virtual register weight (0 to 255) - the register allocator can use it as explicit hint for
125
+ //! alloc/spill decisions and initial bin-packing.
126
+ inline void setWeight(uint32_t weight) noexcept { _weight = uint8_t(weight); }
127
+
128
+ //! Returns whether the virtual register is always allocated to a fixed physical register (and never reallocated).
129
+ //!
130
+ //! \note This is only used for special purposes and it's mostly internal.
131
+ inline bool isFixed() const noexcept { return bool(_isFixed); }
132
+
133
+ //! Tests whether the virtual register is in fact a stack that only uses the virtual register id.
134
+ //!
135
+ //! \note It's an error if a stack is accessed as a register.
136
+ inline bool isStack() const noexcept { return bool(_isStack); }
137
+
138
+ //! Tests whether this virtual register (or stack) has assigned a stack offset.
139
+ //!
140
+ //! If this is a virtual register that was never allocated on stack, it would return false, otherwise if
141
+ //! it's a virtual register that was spilled or explicitly allocated stack, the return value would be true.
142
+ inline bool hasStackSlot() const noexcept { return bool(_hasStackSlot); }
143
+
144
+ //! Assigns a stack offset of this virtual register to `stackOffset` and sets `_hasStackSlot` to true.
145
+ inline void assignStackSlot(int32_t stackOffset) noexcept {
146
+ _hasStackSlot = 1;
147
+ _stackOffset = stackOffset;
148
+ }
149
+
150
+ //! Returns a stack offset associated with a virtual register or explicit stack allocation.
151
+ //!
152
+ //! \note Always verify that the stack offset has been assigned by calling \ref hasStackSlot(). The return
153
+ //! value will be zero when the stack offset was not assigned.
154
+ inline int32_t stackOffset() const noexcept { return _stackOffset; }
155
+
156
+ //! Tests whether the virtual register has an associated `RAWorkReg` at the moment.
157
+ inline bool hasWorkReg() const noexcept { return _workReg != nullptr; }
158
+ //! Returns an associated RAWorkReg with this virtual register (only valid during register allocation).
159
+ inline RAWorkReg* workReg() const noexcept { return _workReg; }
160
+ //! Associates a RAWorkReg with this virtual register (used by register allocator).
161
+ inline void setWorkReg(RAWorkReg* workReg) noexcept { _workReg = workReg; }
162
+ //! Reset the RAWorkReg association (used by register allocator).
163
+ inline void resetWorkReg() noexcept { _workReg = nullptr; }
164
+
165
+ //! \}
166
+ };
167
+
168
+ //! \}
169
+
170
+ ASMJIT_END_NAMESPACE
171
+
172
+ #endif // ASMJIT_CORE_COMPILERDEFS_H_INCLUDED
173
+
@@ -0,0 +1,363 @@
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/constpool.h"
8
+ #include "../core/support.h"
9
+
10
+ ASMJIT_BEGIN_NAMESPACE
11
+
12
+ // ConstPool - Construction & Destruction
13
+ // ======================================
14
+
15
+ ConstPool::ConstPool(Zone* zone) noexcept { reset(zone); }
16
+ ConstPool::~ConstPool() noexcept {}
17
+
18
+ // ConstPool - Reset
19
+ // =================
20
+
21
+ void ConstPool::reset(Zone* zone) noexcept {
22
+ _zone = zone;
23
+
24
+ size_t dataSize = 1;
25
+ for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) {
26
+ _tree[i].reset();
27
+ _tree[i].setDataSize(dataSize);
28
+ _gaps[i] = nullptr;
29
+ dataSize <<= 1;
30
+ }
31
+
32
+ _gapPool = nullptr;
33
+ _size = 0;
34
+ _alignment = 0;
35
+ _minItemSize = 0;
36
+ }
37
+
38
+ // ConstPool - Operations
39
+ // ======================
40
+
41
+ static inline ConstPool::Gap* ConstPool_allocGap(ConstPool* self) noexcept {
42
+ ConstPool::Gap* gap = self->_gapPool;
43
+ if (!gap)
44
+ return self->_zone->allocT<ConstPool::Gap>();
45
+
46
+ self->_gapPool = gap->_next;
47
+ return gap;
48
+ }
49
+
50
+ static inline void ConstPool_freeGap(ConstPool* self, ConstPool::Gap* gap) noexcept {
51
+ gap->_next = self->_gapPool;
52
+ self->_gapPool = gap;
53
+ }
54
+
55
+ static void ConstPool_addGap(ConstPool* self, size_t offset, size_t size) noexcept {
56
+ ASMJIT_ASSERT(size > 0);
57
+
58
+ while (size > 0) {
59
+ size_t gapIndex;
60
+ size_t gapSize;
61
+
62
+ if (size >= 32 && Support::isAligned<size_t>(offset, 32)) {
63
+ gapIndex = ConstPool::kIndex32;
64
+ gapSize = 32;
65
+ }
66
+ else if (size >= 16 && Support::isAligned<size_t>(offset, 16)) {
67
+ gapIndex = ConstPool::kIndex16;
68
+ gapSize = 16;
69
+ }
70
+ else if (size >= 8 && Support::isAligned<size_t>(offset, 8)) {
71
+ gapIndex = ConstPool::kIndex8;
72
+ gapSize = 8;
73
+ }
74
+ else if (size >= 4 && Support::isAligned<size_t>(offset, 4)) {
75
+ gapIndex = ConstPool::kIndex4;
76
+ gapSize = 4;
77
+ }
78
+ else if (size >= 2 && Support::isAligned<size_t>(offset, 2)) {
79
+ gapIndex = ConstPool::kIndex2;
80
+ gapSize = 2;
81
+ }
82
+ else {
83
+ gapIndex = ConstPool::kIndex1;
84
+ gapSize = 1;
85
+ }
86
+
87
+ // We don't have to check for errors here, if this failed nothing really happened (just the gap won't be
88
+ // visible) and it will fail again at place where the same check would generate `kErrorOutOfMemory` error.
89
+ ConstPool::Gap* gap = ConstPool_allocGap(self);
90
+ if (!gap)
91
+ return;
92
+
93
+ gap->_next = self->_gaps[gapIndex];
94
+ self->_gaps[gapIndex] = gap;
95
+
96
+ gap->_offset = offset;
97
+ gap->_size = gapSize;
98
+
99
+ offset += gapSize;
100
+ size -= gapSize;
101
+ }
102
+ }
103
+
104
+ Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept {
105
+ size_t treeIndex;
106
+
107
+ if (size == 64)
108
+ treeIndex = kIndex64;
109
+ else if (size == 32)
110
+ treeIndex = kIndex32;
111
+ else if (size == 16)
112
+ treeIndex = kIndex16;
113
+ else if (size == 8)
114
+ treeIndex = kIndex8;
115
+ else if (size == 4)
116
+ treeIndex = kIndex4;
117
+ else if (size == 2)
118
+ treeIndex = kIndex2;
119
+ else if (size == 1)
120
+ treeIndex = kIndex1;
121
+ else
122
+ return DebugUtils::errored(kErrorInvalidArgument);
123
+
124
+ ConstPool::Node* node = _tree[treeIndex].get(data);
125
+ if (node) {
126
+ dstOffset = node->_offset;
127
+ return kErrorOk;
128
+ }
129
+
130
+ // Before incrementing the current offset try if there is a gap that can be used for the requested data.
131
+ size_t offset = ~size_t(0);
132
+ size_t gapIndex = treeIndex;
133
+
134
+ while (gapIndex != kIndexCount - 1) {
135
+ ConstPool::Gap* gap = _gaps[treeIndex];
136
+
137
+ // Check if there is a gap.
138
+ if (gap) {
139
+ size_t gapOffset = gap->_offset;
140
+ size_t gapSize = gap->_size;
141
+
142
+ // Destroy the gap for now.
143
+ _gaps[treeIndex] = gap->_next;
144
+ ConstPool_freeGap(this, gap);
145
+
146
+ offset = gapOffset;
147
+ ASMJIT_ASSERT(Support::isAligned<size_t>(offset, size));
148
+
149
+ gapSize -= size;
150
+ if (gapSize > 0)
151
+ ConstPool_addGap(this, gapOffset, gapSize);
152
+ }
153
+
154
+ gapIndex++;
155
+ }
156
+
157
+ if (offset == ~size_t(0)) {
158
+ // Get how many bytes have to be skipped so the address is aligned accordingly to the 'size'.
159
+ size_t diff = Support::alignUpDiff<size_t>(_size, size);
160
+
161
+ if (diff != 0) {
162
+ ConstPool_addGap(this, _size, diff);
163
+ _size += diff;
164
+ }
165
+
166
+ offset = _size;
167
+ _size += size;
168
+ }
169
+
170
+ // Add the initial node to the right index.
171
+ node = ConstPool::Tree::_newNode(_zone, data, size, offset, false);
172
+ if (ASMJIT_UNLIKELY(!node))
173
+ return DebugUtils::errored(kErrorOutOfMemory);
174
+
175
+ _tree[treeIndex].insert(node);
176
+ _alignment = Support::max<size_t>(_alignment, size);
177
+
178
+ dstOffset = offset;
179
+
180
+ // Now create a bunch of shared constants that are based on the data pattern. We stop at size 4,
181
+ // it probably doesn't make sense to split constants down to 1 byte.
182
+ size_t pCount = 1;
183
+ size_t smallerSize = size;
184
+
185
+ while (smallerSize > 4) {
186
+ pCount <<= 1;
187
+ smallerSize >>= 1;
188
+
189
+ ASMJIT_ASSERT(treeIndex != 0);
190
+ treeIndex--;
191
+
192
+ const uint8_t* pData = static_cast<const uint8_t*>(data);
193
+ for (size_t i = 0; i < pCount; i++, pData += smallerSize) {
194
+ node = _tree[treeIndex].get(pData);
195
+ if (node) continue;
196
+
197
+ node = ConstPool::Tree::_newNode(_zone, pData, smallerSize, offset + (i * smallerSize), true);
198
+ _tree[treeIndex].insert(node);
199
+ }
200
+ }
201
+
202
+ if (_minItemSize == 0)
203
+ _minItemSize = size;
204
+ else
205
+ _minItemSize = Support::min(_minItemSize, size);
206
+
207
+ return kErrorOk;
208
+ }
209
+
210
+ // ConstPool - Reset
211
+ // =================
212
+
213
+ struct ConstPoolFill {
214
+ inline ConstPoolFill(uint8_t* dst, size_t dataSize) noexcept :
215
+ _dst(dst),
216
+ _dataSize(dataSize) {}
217
+
218
+ inline void operator()(const ConstPool::Node* node) noexcept {
219
+ if (!node->_shared)
220
+ memcpy(_dst + node->_offset, node->data(), _dataSize);
221
+ }
222
+
223
+ uint8_t* _dst;
224
+ size_t _dataSize;
225
+ };
226
+
227
+ void ConstPool::fill(void* dst) const noexcept {
228
+ // Clears possible gaps, asmjit should never emit garbage to the output.
229
+ memset(dst, 0, _size);
230
+
231
+ ConstPoolFill filler(static_cast<uint8_t*>(dst), 1);
232
+ for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) {
233
+ _tree[i].forEach(filler);
234
+ filler._dataSize <<= 1;
235
+ }
236
+ }
237
+
238
+ // ConstPool - Tests
239
+ // =================
240
+
241
+ #if defined(ASMJIT_TEST)
242
+ UNIT(const_pool) {
243
+ Zone zone(32384 - Zone::kBlockOverhead);
244
+ ConstPool pool(&zone);
245
+
246
+ uint32_t i;
247
+ uint32_t kCount = BrokenAPI::hasArg("--quick") ? 1000 : 1000000;
248
+
249
+ INFO("Adding %u constants to the pool", kCount);
250
+ {
251
+ size_t prevOffset;
252
+ size_t curOffset;
253
+ uint64_t c = 0x0101010101010101u;
254
+
255
+ EXPECT(pool.add(&c, 8, prevOffset) == kErrorOk);
256
+ EXPECT(prevOffset == 0);
257
+
258
+ for (i = 1; i < kCount; i++) {
259
+ c++;
260
+ EXPECT(pool.add(&c, 8, curOffset) == kErrorOk);
261
+ EXPECT(prevOffset + 8 == curOffset);
262
+ EXPECT(pool.size() == (i + 1) * 8);
263
+ prevOffset = curOffset;
264
+ }
265
+
266
+ EXPECT(pool.alignment() == 8);
267
+ }
268
+
269
+ INFO("Retrieving %u constants from the pool", kCount);
270
+ {
271
+ uint64_t c = 0x0101010101010101u;
272
+
273
+ for (i = 0; i < kCount; i++) {
274
+ size_t offset;
275
+ EXPECT(pool.add(&c, 8, offset) == kErrorOk);
276
+ EXPECT(offset == i * 8);
277
+ c++;
278
+ }
279
+ }
280
+
281
+ INFO("Checking if the constants were split into 4-byte patterns");
282
+ {
283
+ uint32_t c = 0x01010101;
284
+ for (i = 0; i < kCount; i++) {
285
+ size_t offset;
286
+ EXPECT(pool.add(&c, 4, offset) == kErrorOk);
287
+ EXPECT(offset == i * 8);
288
+ c++;
289
+ }
290
+ }
291
+
292
+ INFO("Adding 2 byte constant to misalign the current offset");
293
+ {
294
+ uint16_t c = 0xFFFF;
295
+ size_t offset;
296
+
297
+ EXPECT(pool.add(&c, 2, offset) == kErrorOk);
298
+ EXPECT(offset == kCount * 8);
299
+ EXPECT(pool.alignment() == 8);
300
+ }
301
+
302
+ INFO("Adding 8 byte constant to check if pool gets aligned again");
303
+ {
304
+ uint64_t c = 0xFFFFFFFFFFFFFFFFu;
305
+ size_t offset;
306
+
307
+ EXPECT(pool.add(&c, 8, offset) == kErrorOk);
308
+ EXPECT(offset == kCount * 8 + 8);
309
+ }
310
+
311
+ INFO("Adding 2 byte constant to verify the gap is filled");
312
+ {
313
+ uint16_t c = 0xFFFE;
314
+ size_t offset;
315
+
316
+ EXPECT(pool.add(&c, 2, offset) == kErrorOk);
317
+ EXPECT(offset == kCount * 8 + 2);
318
+ EXPECT(pool.alignment() == 8);
319
+ }
320
+
321
+ INFO("Checking reset functionality");
322
+ {
323
+ pool.reset(&zone);
324
+ zone.reset();
325
+
326
+ EXPECT(pool.size() == 0);
327
+ EXPECT(pool.alignment() == 0);
328
+ }
329
+
330
+ INFO("Checking pool alignment when combined constants are added");
331
+ {
332
+ uint8_t bytes[32] = { 0 };
333
+ size_t offset;
334
+
335
+ pool.add(bytes, 1, offset);
336
+ EXPECT(pool.size() == 1);
337
+ EXPECT(pool.alignment() == 1);
338
+ EXPECT(offset == 0);
339
+
340
+ pool.add(bytes, 2, offset);
341
+ EXPECT(pool.size() == 4);
342
+ EXPECT(pool.alignment() == 2);
343
+ EXPECT(offset == 2);
344
+
345
+ pool.add(bytes, 4, offset);
346
+ EXPECT(pool.size() == 8);
347
+ EXPECT(pool.alignment() == 4);
348
+ EXPECT(offset == 4);
349
+
350
+ pool.add(bytes, 4, offset);
351
+ EXPECT(pool.size() == 8);
352
+ EXPECT(pool.alignment() == 4);
353
+ EXPECT(offset == 4);
354
+
355
+ pool.add(bytes, 32, offset);
356
+ EXPECT(pool.size() == 64);
357
+ EXPECT(pool.alignment() == 32);
358
+ EXPECT(offset == 32);
359
+ }
360
+ }
361
+ #endif
362
+
363
+ ASMJIT_END_NAMESPACE