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,84 @@
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/osutils.h"
8
+ #include "../core/support.h"
9
+
10
+ #if defined(_WIN32)
11
+ #include <atomic>
12
+ #elif defined(__APPLE__)
13
+ #include <mach/mach_time.h>
14
+ #else
15
+ #include <time.h>
16
+ #include <unistd.h>
17
+ #endif
18
+
19
+ ASMJIT_BEGIN_NAMESPACE
20
+
21
+ uint32_t OSUtils::getTickCount() noexcept {
22
+ #if defined(_WIN32)
23
+ enum HiResStatus : uint32_t {
24
+ kHiResUnknown = 0,
25
+ kHiResAvailable = 1,
26
+ kHiResNotAvailable = 2
27
+ };
28
+
29
+ static std::atomic<uint32_t> _hiResStatus(kHiResUnknown);
30
+ static volatile double _hiResFreq(0);
31
+
32
+ uint32_t status = _hiResStatus.load();
33
+ LARGE_INTEGER now, qpf;
34
+
35
+ if (status != kHiResNotAvailable && ::QueryPerformanceCounter(&now)) {
36
+ double freq = _hiResFreq;
37
+ if (status == kHiResUnknown) {
38
+ // Detects the availability of high resolution counter.
39
+ if (::QueryPerformanceFrequency(&qpf)) {
40
+ freq = double(qpf.QuadPart) / 1000.0;
41
+ _hiResFreq = freq;
42
+ _hiResStatus.compare_exchange_strong(status, kHiResAvailable);
43
+ status = kHiResAvailable;
44
+ }
45
+ else {
46
+ // High resolution not available.
47
+ _hiResStatus.compare_exchange_strong(status, kHiResNotAvailable);
48
+ }
49
+ }
50
+
51
+ if (status == kHiResAvailable)
52
+ return uint32_t(uint64_t(int64_t(double(now.QuadPart) / freq)) & 0xFFFFFFFFu);
53
+ }
54
+
55
+ // Bail to `GetTickCount()` if we cannot use high resolution.
56
+ return ::GetTickCount();
57
+ #elif defined(__APPLE__)
58
+ // See Apple's QA1398.
59
+ static mach_timebase_info_data_t _machTime;
60
+
61
+ uint32_t denom = _machTime.denom;
62
+ if (ASMJIT_UNLIKELY(!denom)) {
63
+ if (mach_timebase_info(&_machTime) != KERN_SUCCESS || !(denom = _machTime.denom))
64
+ return 0;
65
+ }
66
+
67
+ // `mach_absolute_time()` returns nanoseconds, we want milliseconds.
68
+ uint64_t t = mach_absolute_time() / 1000000u;
69
+ t = (t * _machTime.numer) / _machTime.denom;
70
+ return uint32_t(t & 0xFFFFFFFFu);
71
+ #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
72
+ struct timespec ts;
73
+ if (ASMJIT_UNLIKELY(clock_gettime(CLOCK_MONOTONIC, &ts) != 0))
74
+ return 0;
75
+
76
+ uint64_t t = (uint64_t(ts.tv_sec ) * 1000u) + (uint64_t(ts.tv_nsec) / 1000000u);
77
+ return uint32_t(t & 0xFFFFFFFFu);
78
+ #else
79
+ #pragma message("asmjit::OSUtils::getTickCount() doesn't have implementation for the target OS.")
80
+ return 0;
81
+ #endif
82
+ }
83
+
84
+ ASMJIT_END_NAMESPACE
@@ -0,0 +1,61 @@
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_OSUTILS_H_INCLUDED
7
+ #define ASMJIT_CORE_OSUTILS_H_INCLUDED
8
+
9
+ #include "../core/globals.h"
10
+
11
+ ASMJIT_BEGIN_NAMESPACE
12
+
13
+ //! \addtogroup asmjit_utilities
14
+ //! \{
15
+
16
+ //! Operating system utilities.
17
+ namespace OSUtils {
18
+ //! Gets the current CPU tick count, used for benchmarking (1ms resolution).
19
+ ASMJIT_API uint32_t getTickCount() noexcept;
20
+ };
21
+
22
+
23
+ //! \cond INTERNAL
24
+ //! Lock.
25
+ //!
26
+ //! Lock is internal, it cannot be used outside of AsmJit, however, its internal
27
+ //! layout is exposed as it's used by some other classes, which are public.
28
+ class Lock {
29
+ public:
30
+ ASMJIT_NONCOPYABLE(Lock)
31
+
32
+ #if defined(_WIN32)
33
+ #pragma pack(push, 8)
34
+ struct ASMJIT_MAY_ALIAS Handle {
35
+ void* DebugInfo;
36
+ long LockCount;
37
+ long RecursionCount;
38
+ void* OwningThread;
39
+ void* LockSemaphore;
40
+ unsigned long* SpinCount;
41
+ };
42
+ Handle _handle;
43
+ #pragma pack(pop)
44
+ #elif !defined(__EMSCRIPTEN__)
45
+ typedef pthread_mutex_t Handle;
46
+ Handle _handle;
47
+ #endif
48
+
49
+ ASMJIT_FORCE_INLINE Lock() noexcept;
50
+ ASMJIT_FORCE_INLINE ~Lock() noexcept;
51
+
52
+ ASMJIT_FORCE_INLINE void lock() noexcept;
53
+ ASMJIT_FORCE_INLINE void unlock() noexcept;
54
+ };
55
+ //! \endcond
56
+
57
+ //! \}
58
+
59
+ ASMJIT_END_NAMESPACE
60
+
61
+ #endif // ASMJIT_CORE_OSUTILS_H_INCLUDED
@@ -0,0 +1,68 @@
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_OSUTILS_P_H_INCLUDED
7
+ #define ASMJIT_CORE_OSUTILS_P_H_INCLUDED
8
+
9
+ #include "../core/osutils.h"
10
+
11
+ ASMJIT_BEGIN_NAMESPACE
12
+
13
+ //! \cond INTERNAL
14
+ //! \addtogroup asmjit_utilities
15
+ //! \{
16
+
17
+ #if defined(_WIN32)
18
+
19
+ // Windows implementation.
20
+ static_assert(sizeof(Lock::Handle) == sizeof(CRITICAL_SECTION), "asmjit::Lock::Handle layout must match CRITICAL_SECTION");
21
+ static_assert(alignof(Lock::Handle) == alignof(CRITICAL_SECTION), "asmjit::Lock::Handle alignment must match CRITICAL_SECTION");
22
+
23
+ ASMJIT_FORCE_INLINE Lock::Lock() noexcept { InitializeCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
24
+ ASMJIT_FORCE_INLINE Lock::~Lock() noexcept { DeleteCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
25
+ ASMJIT_FORCE_INLINE void Lock::lock() noexcept { EnterCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
26
+ ASMJIT_FORCE_INLINE void Lock::unlock() noexcept { LeaveCriticalSection(reinterpret_cast<CRITICAL_SECTION*>(&_handle)); }
27
+
28
+ #elif !defined(__EMSCRIPTEN__)
29
+
30
+ // PThread implementation.
31
+ #ifdef PTHREAD_MUTEX_INITIALIZER
32
+ ASMJIT_FORCE_INLINE Lock::Lock() noexcept : _handle(PTHREAD_MUTEX_INITIALIZER) {}
33
+ #else
34
+ ASMJIT_FORCE_INLINE Lock::Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
35
+ #endif
36
+ ASMJIT_FORCE_INLINE Lock::~Lock() noexcept { pthread_mutex_destroy(&_handle); }
37
+ ASMJIT_FORCE_INLINE void Lock::lock() noexcept { pthread_mutex_lock(&_handle); }
38
+ ASMJIT_FORCE_INLINE void Lock::unlock() noexcept { pthread_mutex_unlock(&_handle); }
39
+
40
+ #else
41
+
42
+ // Dummy implementation - Emscripten or other unsupported platform.
43
+ ASMJIT_FORCE_INLINE Lock::Lock() noexcept {}
44
+ ASMJIT_FORCE_INLINE Lock::~Lock() noexcept {}
45
+ ASMJIT_FORCE_INLINE void Lock::lock() noexcept {}
46
+ ASMJIT_FORCE_INLINE void Lock::unlock() noexcept {}
47
+
48
+ #endif
49
+
50
+ //! Scoped lock.
51
+ class LockGuard {
52
+ public:
53
+ ASMJIT_NONCOPYABLE(LockGuard)
54
+
55
+ Lock& _target;
56
+
57
+ inline LockGuard(Lock& target) noexcept
58
+ : _target(target) { _target.lock(); }
59
+ inline ~LockGuard() noexcept { _target.unlock(); }
60
+ };
61
+
62
+ //! \}
63
+ //! \endcond
64
+
65
+ ASMJIT_END_NAMESPACE
66
+
67
+ #endif // ASMJIT_CORE_OSUTILS_P_H_INCLUDED
68
+
@@ -0,0 +1,418 @@
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_RAASSIGNMENT_P_H_INCLUDED
7
+ #define ASMJIT_CORE_RAASSIGNMENT_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
+ //! Holds the current register assignment.
21
+ //!
22
+ //! Has two purposes:
23
+ //!
24
+ //! 1. Holds register assignment of a local register allocator (see \ref RALocalAllocator).
25
+ //! 2. Holds register assignment of the entry of basic blocks (see \ref RABlock).
26
+ class RAAssignment {
27
+ public:
28
+ ASMJIT_NONCOPYABLE(RAAssignment)
29
+
30
+ enum Ids : uint32_t {
31
+ kPhysNone = 0xFF,
32
+ kWorkNone = RAWorkReg::kIdNone
33
+ };
34
+
35
+ enum DirtyBit : uint32_t {
36
+ kClean = 0,
37
+ kDirty = 1
38
+ };
39
+
40
+ struct Layout {
41
+ //! Index of architecture registers per group.
42
+ RARegIndex physIndex;
43
+ //! Count of architecture registers per group.
44
+ RARegCount physCount;
45
+ //! Count of physical registers of all groups.
46
+ uint32_t physTotal;
47
+ //! Count of work registers.
48
+ uint32_t workCount;
49
+ //! WorkRegs data (vector).
50
+ const RAWorkRegs* workRegs;
51
+
52
+ inline void reset() noexcept {
53
+ physIndex.reset();
54
+ physCount.reset();
55
+ physTotal = 0;
56
+ workCount = 0;
57
+ workRegs = nullptr;
58
+ }
59
+ };
60
+
61
+ struct PhysToWorkMap {
62
+ //! Assigned registers (each bit represents one physical reg).
63
+ RARegMask assigned;
64
+ //! Dirty registers (spill slot out of sync or no spill slot).
65
+ RARegMask dirty;
66
+ //! PhysReg to WorkReg mapping.
67
+ uint32_t workIds[1 /* ... */];
68
+
69
+ static inline size_t sizeOf(size_t count) noexcept {
70
+ return sizeof(PhysToWorkMap) - sizeof(uint32_t) + count * sizeof(uint32_t);
71
+ }
72
+
73
+ inline void reset(size_t count) noexcept {
74
+ assigned.reset();
75
+ dirty.reset();
76
+
77
+ for (size_t i = 0; i < count; i++)
78
+ workIds[i] = kWorkNone;
79
+ }
80
+
81
+ inline void copyFrom(const PhysToWorkMap* other, size_t count) noexcept {
82
+ size_t size = sizeOf(count);
83
+ memcpy(this, other, size);
84
+ }
85
+
86
+ inline void unassign(RegGroup group, uint32_t physId, uint32_t indexInWorkIds) noexcept {
87
+ assigned.clear(group, Support::bitMask(physId));
88
+ dirty.clear(group, Support::bitMask(physId));
89
+ workIds[indexInWorkIds] = kWorkNone;
90
+ }
91
+ };
92
+
93
+ struct WorkToPhysMap {
94
+ //! WorkReg to PhysReg mapping
95
+ uint8_t physIds[1 /* ... */];
96
+
97
+ static inline size_t sizeOf(size_t count) noexcept {
98
+ return size_t(count) * sizeof(uint8_t);
99
+ }
100
+
101
+ inline void reset(size_t count) noexcept {
102
+ for (size_t i = 0; i < count; i++)
103
+ physIds[i] = kPhysNone;
104
+ }
105
+
106
+ inline void copyFrom(const WorkToPhysMap* other, size_t count) noexcept {
107
+ size_t size = sizeOf(count);
108
+ if (ASMJIT_LIKELY(size))
109
+ memcpy(this, other, size);
110
+ }
111
+ };
112
+
113
+ //! \name Members
114
+ //! \{
115
+
116
+ //! Physical registers layout.
117
+ Layout _layout;
118
+ //! WorkReg to PhysReg mapping.
119
+ WorkToPhysMap* _workToPhysMap;
120
+ //! PhysReg to WorkReg mapping and assigned/dirty bits.
121
+ PhysToWorkMap* _physToWorkMap;
122
+ //! Optimization to translate PhysRegs to WorkRegs faster.
123
+ Support::Array<uint32_t*, Globals::kNumVirtGroups> _physToWorkIds;
124
+
125
+ //! \}
126
+
127
+ //! \name Construction & Destruction
128
+ //! \{
129
+
130
+ inline RAAssignment() noexcept {
131
+ _layout.reset();
132
+ resetMaps();
133
+ }
134
+
135
+ ASMJIT_FORCE_INLINE void initLayout(const RARegCount& physCount, const RAWorkRegs& workRegs) noexcept {
136
+ // Layout must be initialized before data.
137
+ ASMJIT_ASSERT(_physToWorkMap == nullptr);
138
+ ASMJIT_ASSERT(_workToPhysMap == nullptr);
139
+
140
+ _layout.physIndex.buildIndexes(physCount);
141
+ _layout.physCount = physCount;
142
+ _layout.physTotal = uint32_t(_layout.physIndex[RegGroup::kMaxVirt]) +
143
+ uint32_t(_layout.physCount[RegGroup::kMaxVirt]) ;
144
+ _layout.workCount = workRegs.size();
145
+ _layout.workRegs = &workRegs;
146
+ }
147
+
148
+ ASMJIT_FORCE_INLINE void initMaps(PhysToWorkMap* physToWorkMap, WorkToPhysMap* workToPhysMap) noexcept {
149
+ _physToWorkMap = physToWorkMap;
150
+ _workToPhysMap = workToPhysMap;
151
+ for (RegGroup group : RegGroupVirtValues{})
152
+ _physToWorkIds[group] = physToWorkMap->workIds + _layout.physIndex.get(group);
153
+ }
154
+
155
+ ASMJIT_FORCE_INLINE void resetMaps() noexcept {
156
+ _physToWorkMap = nullptr;
157
+ _workToPhysMap = nullptr;
158
+ _physToWorkIds.fill(nullptr);
159
+ }
160
+
161
+ //! \}
162
+
163
+ //! \name Accessors
164
+ //! \{
165
+
166
+ inline PhysToWorkMap* physToWorkMap() const noexcept { return _physToWorkMap; }
167
+ inline WorkToPhysMap* workToPhysMap() const noexcept { return _workToPhysMap; }
168
+
169
+ inline RARegMask& assigned() noexcept { return _physToWorkMap->assigned; }
170
+ inline const RARegMask& assigned() const noexcept { return _physToWorkMap->assigned; }
171
+ inline uint32_t assigned(RegGroup group) const noexcept { return _physToWorkMap->assigned[group]; }
172
+
173
+ inline RARegMask& dirty() noexcept { return _physToWorkMap->dirty; }
174
+ inline const RARegMask& dirty() const noexcept { return _physToWorkMap->dirty; }
175
+ inline RegMask dirty(RegGroup group) const noexcept { return _physToWorkMap->dirty[group]; }
176
+
177
+ inline uint32_t workToPhysId(RegGroup group, uint32_t workId) const noexcept {
178
+ DebugUtils::unused(group);
179
+ ASMJIT_ASSERT(workId != kWorkNone);
180
+ ASMJIT_ASSERT(workId < _layout.workCount);
181
+ return _workToPhysMap->physIds[workId];
182
+ }
183
+
184
+ inline uint32_t physToWorkId(RegGroup group, uint32_t physId) const noexcept {
185
+ ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
186
+ return _physToWorkIds[group][physId];
187
+ }
188
+
189
+ inline bool isPhysAssigned(RegGroup group, uint32_t physId) const noexcept {
190
+ ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
191
+ return Support::bitTest(_physToWorkMap->assigned[group], physId);
192
+ }
193
+
194
+ inline bool isPhysDirty(RegGroup group, uint32_t physId) const noexcept {
195
+ ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
196
+ return Support::bitTest(_physToWorkMap->dirty[group], physId);
197
+ }
198
+
199
+ //! \}
200
+
201
+ //! \name Assignment
202
+ //!
203
+ //! These are low-level allocation helpers that are used to update the current mappings between physical and
204
+ //! virt/work registers and also to update masks that represent allocated and dirty registers. These functions
205
+ //! don't emit any code; they are only used to update and keep all mappings in sync.
206
+ //!
207
+ //! \{
208
+
209
+ //! Assign [VirtReg/WorkReg] to a physical register.
210
+ inline void assign(RegGroup group, uint32_t workId, uint32_t physId, bool dirty) noexcept {
211
+ ASMJIT_ASSERT(workToPhysId(group, workId) == kPhysNone);
212
+ ASMJIT_ASSERT(physToWorkId(group, physId) == kWorkNone);
213
+ ASMJIT_ASSERT(!isPhysAssigned(group, physId));
214
+ ASMJIT_ASSERT(!isPhysDirty(group, physId));
215
+
216
+ _workToPhysMap->physIds[workId] = uint8_t(physId);
217
+ _physToWorkIds[group][physId] = workId;
218
+
219
+ RegMask regMask = Support::bitMask(physId);
220
+ _physToWorkMap->assigned[group] |= regMask;
221
+ _physToWorkMap->dirty[group] |= regMask & Support::bitMaskFromBool<RegMask>(dirty);
222
+
223
+ verify();
224
+ }
225
+
226
+ //! Reassign [VirtReg/WorkReg] to `dstPhysId` from `srcPhysId`.
227
+ inline void reassign(RegGroup group, uint32_t workId, uint32_t dstPhysId, uint32_t srcPhysId) noexcept {
228
+ ASMJIT_ASSERT(dstPhysId != srcPhysId);
229
+ ASMJIT_ASSERT(workToPhysId(group, workId) == srcPhysId);
230
+ ASMJIT_ASSERT(physToWorkId(group, srcPhysId) == workId);
231
+ ASMJIT_ASSERT(isPhysAssigned(group, srcPhysId) == true);
232
+ ASMJIT_ASSERT(isPhysAssigned(group, dstPhysId) == false);
233
+
234
+ _workToPhysMap->physIds[workId] = uint8_t(dstPhysId);
235
+ _physToWorkIds[group][srcPhysId] = kWorkNone;
236
+ _physToWorkIds[group][dstPhysId] = workId;
237
+
238
+ RegMask srcMask = Support::bitMask(srcPhysId);
239
+ RegMask dstMask = Support::bitMask(dstPhysId);
240
+
241
+ bool dirty = (_physToWorkMap->dirty[group] & srcMask) != 0;
242
+ RegMask regMask = dstMask | srcMask;
243
+
244
+ _physToWorkMap->assigned[group] ^= regMask;
245
+ _physToWorkMap->dirty[group] ^= regMask & Support::bitMaskFromBool<RegMask>(dirty);
246
+
247
+ verify();
248
+ }
249
+
250
+ inline void swap(RegGroup group, uint32_t aWorkId, uint32_t aPhysId, uint32_t bWorkId, uint32_t bPhysId) noexcept {
251
+ ASMJIT_ASSERT(aPhysId != bPhysId);
252
+ ASMJIT_ASSERT(workToPhysId(group, aWorkId) == aPhysId);
253
+ ASMJIT_ASSERT(workToPhysId(group, bWorkId) == bPhysId);
254
+ ASMJIT_ASSERT(physToWorkId(group, aPhysId) == aWorkId);
255
+ ASMJIT_ASSERT(physToWorkId(group, bPhysId) == bWorkId);
256
+ ASMJIT_ASSERT(isPhysAssigned(group, aPhysId));
257
+ ASMJIT_ASSERT(isPhysAssigned(group, bPhysId));
258
+
259
+ _workToPhysMap->physIds[aWorkId] = uint8_t(bPhysId);
260
+ _workToPhysMap->physIds[bWorkId] = uint8_t(aPhysId);
261
+ _physToWorkIds[group][aPhysId] = bWorkId;
262
+ _physToWorkIds[group][bPhysId] = aWorkId;
263
+
264
+ RegMask aMask = Support::bitMask(aPhysId);
265
+ RegMask bMask = Support::bitMask(bPhysId);
266
+ RegMask flipMask = Support::bitMaskFromBool<RegMask>(((_physToWorkMap->dirty[group] & aMask) != 0) ^ ((_physToWorkMap->dirty[group] & bMask) != 0));
267
+ RegMask regMask = aMask | bMask;
268
+ _physToWorkMap->dirty[group] ^= regMask & flipMask;
269
+
270
+ verify();
271
+ }
272
+
273
+ //! Unassign [VirtReg/WorkReg] from a physical register.
274
+ inline void unassign(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
275
+ ASMJIT_ASSERT(physId < Globals::kMaxPhysRegs);
276
+ ASMJIT_ASSERT(workToPhysId(group, workId) == physId);
277
+ ASMJIT_ASSERT(physToWorkId(group, physId) == workId);
278
+ ASMJIT_ASSERT(isPhysAssigned(group, physId));
279
+
280
+ _workToPhysMap->physIds[workId] = kPhysNone;
281
+ _physToWorkIds[group][physId] = kWorkNone;
282
+
283
+ RegMask regMask = Support::bitMask(physId);
284
+ _physToWorkMap->assigned[group] &= ~regMask;
285
+ _physToWorkMap->dirty[group] &= ~regMask;
286
+
287
+ verify();
288
+ }
289
+
290
+ inline void makeClean(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
291
+ DebugUtils::unused(workId);
292
+ RegMask regMask = Support::bitMask(physId);
293
+ _physToWorkMap->dirty[group] &= ~regMask;
294
+ }
295
+
296
+ inline void makeDirty(RegGroup group, uint32_t workId, uint32_t physId) noexcept {
297
+ DebugUtils::unused(workId);
298
+ RegMask regMask = Support::bitMask(physId);
299
+ _physToWorkMap->dirty[group] |= regMask;
300
+ }
301
+
302
+ //! \}
303
+
304
+ //! \name Utilities
305
+ //! \{
306
+
307
+ ASMJIT_FORCE_INLINE void swap(RAAssignment& other) noexcept {
308
+ std::swap(_workToPhysMap, other._workToPhysMap);
309
+ std::swap(_physToWorkMap, other._physToWorkMap);
310
+ _physToWorkIds.swap(other._physToWorkIds);
311
+ }
312
+
313
+ inline void assignWorkIdsFromPhysIds() noexcept {
314
+ memset(_workToPhysMap, uint8_t(BaseReg::kIdBad), WorkToPhysMap::sizeOf(_layout.workCount));
315
+
316
+ for (RegGroup group : RegGroupVirtValues{}) {
317
+ uint32_t physBaseIndex = _layout.physIndex[group];
318
+ Support::BitWordIterator<RegMask> it(_physToWorkMap->assigned[group]);
319
+
320
+ while (it.hasNext()) {
321
+ uint32_t physId = it.next();
322
+ uint32_t workId = _physToWorkMap->workIds[physBaseIndex + physId];
323
+
324
+ ASMJIT_ASSERT(workId != kWorkNone);
325
+ _workToPhysMap->physIds[workId] = uint8_t(physId);
326
+ }
327
+ }
328
+ }
329
+
330
+ inline void copyFrom(const PhysToWorkMap* physToWorkMap) noexcept {
331
+ memcpy(_physToWorkMap, physToWorkMap, PhysToWorkMap::sizeOf(_layout.physTotal));
332
+ assignWorkIdsFromPhysIds();
333
+ }
334
+
335
+ inline void copyFrom(const PhysToWorkMap* physToWorkMap, const WorkToPhysMap* workToPhysMap) noexcept {
336
+ memcpy(_physToWorkMap, physToWorkMap, PhysToWorkMap::sizeOf(_layout.physTotal));
337
+ memcpy(_workToPhysMap, workToPhysMap, WorkToPhysMap::sizeOf(_layout.workCount));
338
+ }
339
+
340
+ inline void copyFrom(const RAAssignment& other) noexcept {
341
+ copyFrom(other.physToWorkMap(), other.workToPhysMap());
342
+ }
343
+
344
+ // Not really useful outside of debugging.
345
+ bool equals(const RAAssignment& other) const noexcept {
346
+ // Layout should always match.
347
+ if (_layout.physIndex != other._layout.physIndex ||
348
+ _layout.physCount != other._layout.physCount ||
349
+ _layout.physTotal != other._layout.physTotal ||
350
+ _layout.workCount != other._layout.workCount ||
351
+ _layout.workRegs != other._layout.workRegs)
352
+ return false;
353
+
354
+ uint32_t physTotal = _layout.physTotal;
355
+ uint32_t workCount = _layout.workCount;
356
+
357
+ for (uint32_t physId = 0; physId < physTotal; physId++) {
358
+ uint32_t thisWorkId = _physToWorkMap->workIds[physId];
359
+ uint32_t otherWorkId = other._physToWorkMap->workIds[physId];
360
+ if (thisWorkId != otherWorkId)
361
+ return false;
362
+ }
363
+
364
+ for (uint32_t workId = 0; workId < workCount; workId++) {
365
+ uint32_t thisPhysId = _workToPhysMap->physIds[workId];
366
+ uint32_t otherPhysId = other._workToPhysMap->physIds[workId];
367
+ if (thisPhysId != otherPhysId)
368
+ return false;
369
+ }
370
+
371
+ if (_physToWorkMap->assigned != other._physToWorkMap->assigned ||
372
+ _physToWorkMap->dirty != other._physToWorkMap->dirty )
373
+ return false;
374
+
375
+ return true;
376
+ }
377
+
378
+ #if defined(ASMJIT_BUILD_DEBUG)
379
+ ASMJIT_NOINLINE void verify() noexcept {
380
+ // Verify WorkToPhysMap.
381
+ {
382
+ for (uint32_t workId = 0; workId < _layout.workCount; workId++) {
383
+ uint32_t physId = _workToPhysMap->physIds[workId];
384
+ if (physId != kPhysNone) {
385
+ const RAWorkReg* workReg = _layout.workRegs->at(workId);
386
+ RegGroup group = workReg->group();
387
+ ASMJIT_ASSERT(_physToWorkIds[group][physId] == workId);
388
+ }
389
+ }
390
+ }
391
+
392
+ // Verify PhysToWorkMap.
393
+ {
394
+ for (RegGroup group : RegGroupVirtValues{}) {
395
+ uint32_t physCount = _layout.physCount[group];
396
+ for (uint32_t physId = 0; physId < physCount; physId++) {
397
+ uint32_t workId = _physToWorkIds[group][physId];
398
+ if (workId != kWorkNone) {
399
+ ASMJIT_ASSERT(_workToPhysMap->physIds[workId] == physId);
400
+ }
401
+ }
402
+ }
403
+ }
404
+ }
405
+ #else
406
+ inline void verify() noexcept {}
407
+ #endif
408
+
409
+ //! \}
410
+ };
411
+
412
+ //! \}
413
+ //! \endcond
414
+
415
+ ASMJIT_END_NAMESPACE
416
+
417
+ #endif // !ASMJIT_NO_COMPILER
418
+ #endif // ASMJIT_CORE_RAASSIGNMENT_P_H_INCLUDED