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