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,947 @@
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
+ // ============================================================================
7
+ // tablegen.js
8
+ //
9
+ // Provides core foundation for generating tables that AsmJit requires. This
10
+ // file should provide everything table generators need in general.
11
+ // ============================================================================
12
+
13
+ "use strict";
14
+
15
+ const VERBOSE = false;
16
+
17
+ // ============================================================================
18
+ // [Imports]
19
+ // ============================================================================
20
+
21
+ const fs = require("fs");
22
+ const hasOwn = Object.prototype.hasOwnProperty;
23
+
24
+ const asmdb = (function() {
25
+ // Try to import a local 'asmdb' package, if available.
26
+ try {
27
+ return require("./asmdb");
28
+ }
29
+ catch (ex) {
30
+ if (ex.code !== "MODULE_NOT_FOUND") {
31
+ console.log(`FATAL ERROR: ${ex.message}`);
32
+ throw ex;
33
+ }
34
+ }
35
+
36
+ // Try to import global 'asmdb' package as local package is not available.
37
+ return require("asmdb");
38
+ })();
39
+ exports.asmdb = asmdb;
40
+
41
+ // ============================================================================
42
+ // [Constants]
43
+ // ============================================================================
44
+
45
+ const kIndent = " ";
46
+ const kJustify = 119;
47
+ const kAsmJitRoot = "..";
48
+
49
+ exports.kIndent = kIndent;
50
+ exports.kJustify = kJustify;
51
+ exports.kAsmJitRoot = kAsmJitRoot;
52
+
53
+ // ============================================================================
54
+ // [Debugging]
55
+ // ============================================================================
56
+
57
+ function DEBUG(msg) {
58
+ if (VERBOSE)
59
+ console.log(msg);
60
+ }
61
+ exports.DEBUG = DEBUG;
62
+
63
+ function WARN(msg) {
64
+ console.log(msg);
65
+ }
66
+ exports.WARN = WARN;
67
+
68
+ function FAIL(msg) {
69
+ console.log(`FATAL ERROR: ${msg}`);
70
+ throw new Error(msg);
71
+ }
72
+ exports.FAIL = FAIL;
73
+
74
+ // ============================================================================
75
+ // [Lang]
76
+ // ============================================================================
77
+
78
+ function nop(x) { return x; }
79
+
80
+ class Lang {
81
+ static merge(a, b) {
82
+ if (a === b)
83
+ return a;
84
+
85
+ for (var k in b) {
86
+ var av = a[k];
87
+ var bv = b[k];
88
+
89
+ if (typeof av === "object" && typeof bv === "object")
90
+ Lang.merge(av, bv);
91
+ else
92
+ a[k] = bv;
93
+ }
94
+
95
+ return a;
96
+ }
97
+
98
+ static deepEq(a, b) {
99
+ if (a === b)
100
+ return true;
101
+
102
+ if (typeof a !== typeof b)
103
+ return false;
104
+
105
+ if (typeof a !== "object")
106
+ return a === b;
107
+
108
+ if (Array.isArray(a) || Array.isArray(b)) {
109
+ if (Array.isArray(a) !== Array.isArray(b))
110
+ return false;
111
+
112
+ const len = a.length;
113
+ if (b.length !== len)
114
+ return false;
115
+
116
+ for (var i = 0; i < len; i++)
117
+ if (!Lang.deepEq(a[i], b[i]))
118
+ return false;
119
+ }
120
+ else {
121
+ if (a === null || b === null)
122
+ return a === b;
123
+
124
+ for (var k in a)
125
+ if (!hasOwn.call(b, k) || !Lang.deepEq(a[k], b[k]))
126
+ return false;
127
+
128
+ for (var k in b)
129
+ if (!hasOwn.call(a, k))
130
+ return false;
131
+ }
132
+
133
+ return true;
134
+ }
135
+
136
+ static deepEqExcept(a, b, except) {
137
+ if (a === b)
138
+ return true;
139
+
140
+ if (typeof a !== "object" || typeof b !== "object" || Array.isArray(a) || Array.isArray(b))
141
+ return Lang.deepEq(a, b);
142
+
143
+ for (var k in a)
144
+ if (!hasOwn.call(except, k) && (!hasOwn.call(b, k) || !Lang.deepEq(a[k], b[k])))
145
+ return false;
146
+
147
+ for (var k in b)
148
+ if (!hasOwn.call(except, k) && !hasOwn.call(a, k))
149
+ return false;
150
+
151
+ return true;
152
+ }
153
+ }
154
+ exports.Lang = Lang;
155
+
156
+ // ============================================================================
157
+ // [StringUtils]
158
+ // ============================================================================
159
+
160
+ class StringUtils {
161
+ static asString(x) { return String(x); }
162
+
163
+ static countOf(s, pattern) {
164
+ if (!pattern)
165
+ FAIL(`Pattern cannot be empty`);
166
+
167
+ var n = 0;
168
+ var pos = 0;
169
+
170
+ while ((pos = s.indexOf(pattern, pos)) >= 0) {
171
+ n++;
172
+ pos += pattern.length;
173
+ }
174
+
175
+ return n;
176
+ }
177
+
178
+ static capitalize(s) {
179
+ s = String(s);
180
+ return !s ? s : s[0].toUpperCase() + s.substr(1);
181
+ }
182
+
183
+ static trimLeft(s) { return s.replace(/^\s+/, ""); }
184
+ static trimRight(s) { return s.replace(/\s+$/, ""); }
185
+
186
+ static upFirst(s) {
187
+ if (!s) return "";
188
+ return s[0].toUpperCase() + s.substr(1);
189
+ }
190
+
191
+ static decToHex(n, nPad) {
192
+ var hex = Number(n < 0 ? 0x100000000 + n : n).toString(16);
193
+ while (nPad > hex.length)
194
+ hex = "0" + hex;
195
+ return "0x" + hex.toUpperCase();
196
+ }
197
+
198
+ static format(array, indent, showIndex, mapFn) {
199
+ if (!mapFn)
200
+ mapFn = StringUtils.asString;
201
+
202
+ var s = "";
203
+ var threshold = 80;
204
+
205
+ if (showIndex === -1)
206
+ s += indent;
207
+
208
+ for (var i = 0; i < array.length; i++) {
209
+ const item = array[i];
210
+ const last = i === array.length - 1;
211
+
212
+ if (showIndex !== -1)
213
+ s += indent;
214
+
215
+ s += mapFn(item);
216
+ if (showIndex > 0) {
217
+ s += `${last ? " " : ","} // #${i}`;
218
+ if (typeof array.refCountOf === "function")
219
+ s += ` [ref=${array.refCountOf(item)}x]`;
220
+ }
221
+ else if (!last) {
222
+ s += ",";
223
+ }
224
+
225
+ if (showIndex === -1) {
226
+ if (s.length >= threshold - 1 && !last) {
227
+ s += "\n" + indent;
228
+ threshold += 80;
229
+ }
230
+ else {
231
+ if (!last) s += " ";
232
+ }
233
+ }
234
+ else {
235
+ if (!last) s += "\n";
236
+ }
237
+ }
238
+
239
+ return s;
240
+ }
241
+
242
+ static makeCxxArray(array, code, indent) {
243
+ if (!indent) indent = kIndent;
244
+ return `${code} = {\n${indent}` + array.join(`,\n${indent}`) + `\n};\n`;
245
+ }
246
+
247
+ static makeCxxArrayWithComment(array, code, indent) {
248
+ if (!indent) indent = kIndent;
249
+ var s = "";
250
+ for (var i = 0; i < array.length; i++) {
251
+ const last = i === array.length - 1;
252
+ s += indent + array[i].data +
253
+ (last ? " // " : ", // ") + (array[i].refs ? "#" + String(i) : "").padEnd(5) + array[i].comment + "\n";
254
+ }
255
+ return `${code} = {\n${s}};\n`;
256
+ }
257
+
258
+ static disclaimer(s) {
259
+ return "// ------------------- Automatically generated, do not edit -------------------\n" +
260
+ s +
261
+ "// ----------------------------------------------------------------------------\n";
262
+ }
263
+
264
+ static indent(s, indentation) {
265
+ var lines = s.split(/\r?\n/g);
266
+ if (indentation) {
267
+ for (var i = 0; i < lines.length; i++) {
268
+ var line = lines[i];
269
+ if (line) lines[i] = indentation + line;
270
+ }
271
+ }
272
+
273
+ return lines.join("\n");
274
+ }
275
+
276
+ static extract(s, start, end) {
277
+ var iStart = s.indexOf(start);
278
+ var iEnd = s.indexOf(end);
279
+
280
+ if (iStart === -1)
281
+ FAIL(`StringUtils.extract(): Couldn't locate start mark '${start}'`);
282
+
283
+ if (iEnd === -1)
284
+ FAIL(`StringUtils.extract(): Couldn't locate end mark '${end}'`);
285
+
286
+ return s.substring(iStart + start.length, iEnd).trim();
287
+ }
288
+
289
+ static inject(s, start, end, code) {
290
+ var iStart = s.indexOf(start);
291
+ var iEnd = s.indexOf(end);
292
+
293
+ if (iStart === -1)
294
+ FAIL(`StringUtils.inject(): Couldn't locate start mark '${start}'`);
295
+
296
+ if (iEnd === -1)
297
+ FAIL(`StringUtils.inject(): Couldn't locate end mark '${end}'`);
298
+
299
+ var nIndent = 0;
300
+ while (iStart > 0 && s[iStart-1] === " ") {
301
+ iStart--;
302
+ nIndent++;
303
+ }
304
+
305
+ if (nIndent) {
306
+ const indentation = " ".repeat(nIndent);
307
+ code = StringUtils.indent(code, indentation) + indentation;
308
+ }
309
+
310
+ return s.substr(0, iStart + start.length + nIndent) + code + s.substr(iEnd);
311
+ }
312
+
313
+ static makePriorityCompare(priorityArray) {
314
+ const map = Object.create(null);
315
+ priorityArray.forEach((str, index) => { map[str] = index; });
316
+
317
+ return function(a, b) {
318
+ const ax = hasOwn.call(map, a) ? map[a] : Infinity;
319
+ const bx = hasOwn.call(map, b) ? map[b] : Infinity;
320
+ return ax != bx ? ax - bx : a < b ? -1 : a > b ? 1 : 0;
321
+ }
322
+ }
323
+ }
324
+ exports.StringUtils = StringUtils;
325
+
326
+ // ============================================================================
327
+ // [ArrayUtils]
328
+ // ============================================================================
329
+
330
+ class ArrayUtils {
331
+ static min(arr, fn) {
332
+ if (!arr.length)
333
+ return null;
334
+
335
+ if (!fn)
336
+ fn = nop;
337
+
338
+ var v = fn(arr[0]);
339
+ for (var i = 1; i < arr.length; i++)
340
+ v = Math.min(v, fn(arr[i]));
341
+ return v;
342
+ }
343
+
344
+ static max(arr, fn) {
345
+ if (!arr.length)
346
+ return null;
347
+
348
+ if (!fn)
349
+ fn = nop;
350
+
351
+ var v = fn(arr[0]);
352
+ for (var i = 1; i < arr.length; i++)
353
+ v = Math.max(v, fn(arr[i]));
354
+ return v;
355
+ }
356
+
357
+ static sorted(obj, cmp) {
358
+ const out = Array.isArray(obj) ? obj.slice() : Object.getOwnPropertyNames(obj);
359
+ out.sort(cmp);
360
+ return out;
361
+ }
362
+
363
+ static deepIndexOf(arr, what) {
364
+ for (var i = 0; i < arr.length; i++)
365
+ if (Lang.deepEq(arr[i], what))
366
+ return i;
367
+ return -1;
368
+ }
369
+ }
370
+ exports.ArrayUtils = ArrayUtils;
371
+
372
+ // ============================================================================
373
+ // [MapUtils]
374
+ // ============================================================================
375
+
376
+ class MapUtils {
377
+ static clone(map) {
378
+ return Object.assign(Object.create(null), map);
379
+ }
380
+
381
+ static arrayToMap(arr, value) {
382
+ if (value === undefined)
383
+ value = true;
384
+
385
+ const out = Object.create(null);
386
+ for (var i = 0; i < arr.length; i++)
387
+ out[arr[i]] = value;
388
+ return out;
389
+ }
390
+
391
+ static equals(a, b) {
392
+ for (var k in a) if (!hasOwn.call(b, k)) return false;
393
+ for (var k in b) if (!hasOwn.call(a, k)) return false;
394
+ return true;
395
+ }
396
+
397
+ static firstOf(map, flags) {
398
+ for (var k in flags)
399
+ if (hasOwn.call(map, k))
400
+ return k;
401
+ return undefined;
402
+ }
403
+
404
+ static anyOf(map, flags) {
405
+ for (var k in flags)
406
+ if (hasOwn.call(map, k))
407
+ return true;
408
+ return false;
409
+ }
410
+
411
+ static add(a, b) {
412
+ for (var k in b)
413
+ a[k] = b[k];
414
+ return a;
415
+ }
416
+
417
+ static and(a, b) {
418
+ const out = Object.create(null);
419
+ for (var k in a)
420
+ if (hasOwn.call(b, k))
421
+ out[k] = true;
422
+ return out;
423
+ }
424
+
425
+ static xor(a, b) {
426
+ const out = Object.create(null);
427
+ for (var k in a) if (!hasOwn.call(b, k)) out[k] = true;
428
+ for (var k in b) if (!hasOwn.call(a, k)) out[k] = true;
429
+ return out;
430
+ }
431
+ };
432
+ exports.MapUtils = MapUtils;
433
+
434
+ // ============================================================================
435
+ // [CxxUtils]
436
+ // ============================================================================
437
+
438
+ class CxxUtils {
439
+ static flags(obj, fn, none) {
440
+ if (none == null)
441
+ none = "0";
442
+
443
+ if (!fn)
444
+ fn = nop;
445
+
446
+ var out = "";
447
+ for (var k in obj) {
448
+ if (obj[k])
449
+ out += (out ? " | " : "") + fn(k);
450
+ }
451
+ return out ? out : none;
452
+ }
453
+
454
+ static struct(...args) {
455
+ return "{ " + args.join(", ") + " }";
456
+ }
457
+ };
458
+ exports.CxxUtils = CxxUtils;
459
+
460
+ // ============================================================================
461
+ // [IndexedString]
462
+ // ============================================================================
463
+
464
+ // IndexedString is mostly used to merge all instruction names into a single
465
+ // string with external index. It's designed mostly for generating C++ tables.
466
+ //
467
+ // Consider the following cases in C++:
468
+ //
469
+ // a) static const char* const* instNames = { "add", "mov", "vpunpcklbw" };
470
+ //
471
+ // b) static const char instNames[] = { "add\0" "mov\0" "vpunpcklbw\0" };
472
+ // static const uint16_t instNameIndex[] = { 0, 4, 8 };
473
+ //
474
+ // The latter (b) has an advantage that it doesn't have to be relocated by the
475
+ // linker, which saves a lot of space in the resulting binary and a lot of CPU
476
+ // cycles (and memory) when the linker loads it. AsmJit supports thousands of
477
+ // instructions so each optimization like this makes it smaller and faster to
478
+ // load.
479
+ class IndexedString {
480
+ constructor() {
481
+ this.map = Object.create(null);
482
+ this.array = [];
483
+ this.size = -1;
484
+ }
485
+
486
+ add(s) {
487
+ this.map[s] = -1;
488
+ }
489
+
490
+ index() {
491
+ const map = this.map;
492
+ const array = this.array;
493
+ const partialMap = Object.create(null);
494
+
495
+ var k, kp;
496
+ var i, len;
497
+
498
+ // Create a map that will contain all keys and partial keys.
499
+ for (k in map) {
500
+ if (!k) {
501
+ partialMap[k] = k;
502
+ }
503
+ else {
504
+ for (i = 0, len = k.length; i < len; i++) {
505
+ kp = k.substr(i);
506
+ if (!hasOwn.call(partialMap, kp) || partialMap[kp].length < len)
507
+ partialMap[kp] = k;
508
+ }
509
+ }
510
+ }
511
+
512
+ // Create an array that will only contain keys that are needed.
513
+ for (k in map)
514
+ if (partialMap[k] === k)
515
+ array.push(k);
516
+ array.sort();
517
+
518
+ // Create valid offsets to the `array`.
519
+ var offMap = Object.create(null);
520
+ var offset = 0;
521
+
522
+ for (i = 0, len = array.length; i < len; i++) {
523
+ k = array[i];
524
+
525
+ offMap[k] = offset;
526
+ offset += k.length + 1;
527
+ }
528
+ this.size = offset;
529
+
530
+ // Assign valid offsets to `map`.
531
+ for (kp in map) {
532
+ k = partialMap[kp];
533
+ map[kp] = offMap[k] + k.length - kp.length;
534
+ }
535
+ }
536
+
537
+ format(indent, justify) {
538
+ if (this.size === -1)
539
+ FAIL(`IndexedString.format(): not indexed yet, call index()`);
540
+
541
+ const array = this.array;
542
+ if (!justify) justify = 0;
543
+
544
+ var i;
545
+ var s = "";
546
+ var line = "";
547
+
548
+ for (i = 0; i < array.length; i++) {
549
+ const item = "\"" + array[i] + ((i !== array.length - 1) ? "\\0\"" : "\";");
550
+ const newl = line + (line ? " " : indent) + item;
551
+
552
+ if (newl.length <= justify) {
553
+ line = newl;
554
+ continue;
555
+ }
556
+ else {
557
+ s += line + "\n";
558
+ line = indent + item;
559
+ }
560
+ }
561
+
562
+ return s + line;
563
+ }
564
+
565
+ getSize() {
566
+ if (this.size === -1)
567
+ FAIL(`IndexedString.getSize(): Not indexed yet, call index()`);
568
+ return this.size;
569
+ }
570
+
571
+ getIndex(k) {
572
+ if (this.size === -1)
573
+ FAIL(`IndexedString.getIndex(): Not indexed yet, call index()`);
574
+
575
+ if (!hasOwn.call(this.map, k))
576
+ FAIL(`IndexedString.getIndex(): Key '${k}' not found.`);
577
+
578
+ return this.map[k];
579
+ }
580
+ }
581
+ exports.IndexedString = IndexedString;
582
+
583
+ // ============================================================================
584
+ // [IndexedArray]
585
+ // ============================================================================
586
+
587
+ // IndexedArray is an Array replacement that allows to index each item inserted
588
+ // to it. Its main purpose is to avoid data duplication, if an item passed to
589
+ // `addIndexed()` is already within the Array then it's not inserted and the
590
+ // existing index is returned instead.
591
+ function IndexedArray_keyOf(item) {
592
+ return typeof item === "string" ? item : JSON.stringify(item);
593
+ }
594
+
595
+ class IndexedArray extends Array {
596
+ constructor() {
597
+ super();
598
+ this._index = Object.create(null);
599
+ }
600
+
601
+ refCountOf(item) {
602
+ const key = IndexedArray_keyOf(item);
603
+ const idx = this._index[key];
604
+
605
+ return idx !== undefined ? idx.refCount : 0;
606
+ }
607
+
608
+ addIndexed(item) {
609
+ const key = IndexedArray_keyOf(item);
610
+ var idx = this._index[key];
611
+
612
+ if (idx !== undefined) {
613
+ idx.refCount++;
614
+ return idx.data;
615
+ }
616
+
617
+ idx = this.length;
618
+ this._index[key] = {
619
+ data: idx,
620
+ refCount: 1
621
+ };
622
+ this.push(item);
623
+ return idx;
624
+ }
625
+ }
626
+ exports.IndexedArray = IndexedArray;
627
+
628
+ // ============================================================================
629
+ // [Task]
630
+ // ============================================================================
631
+
632
+ // A base runnable task that can access the TableGen through `this.ctx`.
633
+ class Task {
634
+ constructor(name, deps) {
635
+ this.ctx = null;
636
+ this.name = name || "";
637
+ this.deps = deps || [];
638
+ }
639
+
640
+ inject(key, str, size) {
641
+ this.ctx.inject(key, str, size);
642
+ return this;
643
+ }
644
+
645
+ run() {
646
+ FAIL("Task.run(): Must be reimplemented");
647
+ }
648
+ }
649
+ exports.Task = Task;
650
+
651
+ // ============================================================================
652
+ // [TableGen]
653
+ // ============================================================================
654
+
655
+ // Main context used to load, generate, and store instruction tables. The idea
656
+ // is to be extensible, so it stores 'Task's to be executed with minimal deps
657
+ // management.
658
+ class TableGen {
659
+ constructor(arch) {
660
+ this.arch = arch;
661
+ this.files = Object.create(null);
662
+ this.tableSizes = Object.create(null);
663
+
664
+ this.tasks = [];
665
+ this.taskMap = Object.create(null);
666
+
667
+ this.insts = [];
668
+ this.instMap = Object.create(null);
669
+
670
+ this.aliases = [];
671
+ this.aliasMem = Object.create(null);
672
+ }
673
+
674
+ // --------------------------------------------------------------------------
675
+ // [File Management]
676
+ // --------------------------------------------------------------------------
677
+
678
+ load(fileList) {
679
+ for (var i = 0; i < fileList.length; i++) {
680
+ const file = fileList[i];
681
+ const path = kAsmJitRoot + "/" + file;
682
+ const data = fs.readFileSync(path, "utf8").replace(/\r\n/g, "\n");
683
+
684
+ this.files[file] = {
685
+ prev: data,
686
+ data: data
687
+ };
688
+ }
689
+ return this;
690
+ }
691
+
692
+ save() {
693
+ for (var file in this.files) {
694
+ const obj = this.files[file];
695
+ if (obj.data !== obj.prev) {
696
+ const path = kAsmJitRoot + "/" + file;
697
+ console.log(`MODIFIED '${file}'`);
698
+
699
+ fs.writeFileSync(path + ".backup", obj.prev, "utf8");
700
+ fs.writeFileSync(path, obj.data, "utf8");
701
+ }
702
+ }
703
+ }
704
+
705
+ dataOfFile(file) {
706
+ const obj = this.files[file];
707
+ if (!obj)
708
+ FAIL(`TableGen.dataOfFile(): File '${file}' not loaded`);
709
+ return obj.data;
710
+ }
711
+
712
+ inject(key, str, size) {
713
+ const begin = "// ${" + key + ":Begin}\n";
714
+ const end = "// ${" + key + ":End}\n";
715
+
716
+ var done = false;
717
+ for (var file in this.files) {
718
+ const obj = this.files[file];
719
+ const data = obj.data;
720
+
721
+ if (data.indexOf(begin) !== -1) {
722
+ obj.data = StringUtils.inject(data, begin, end, str);
723
+ done = true;
724
+ break;
725
+ }
726
+ }
727
+
728
+ if (!done)
729
+ FAIL(`TableGen.inject(): Cannot find '${key}'`);
730
+
731
+ if (size)
732
+ this.tableSizes[key] = size;
733
+
734
+ return this;
735
+ }
736
+
737
+ // --------------------------------------------------------------------------
738
+ // [Task Management]
739
+ // --------------------------------------------------------------------------
740
+
741
+ addTask(task) {
742
+ if (!task.name)
743
+ FAIL(`TableGen.addModule(): Module must have a name`);
744
+
745
+ if (this.taskMap[task.name])
746
+ FAIL(`TableGen.addModule(): Module '${task.name}' already added`);
747
+
748
+ task.deps.forEach((dependency) => {
749
+ if (!this.taskMap[dependency])
750
+ FAIL(`TableGen.addModule(): Dependency '${dependency}' of module '${task.name}' doesn't exist`);
751
+ });
752
+
753
+ this.tasks.push(task);
754
+ this.taskMap[task.name] = task;
755
+
756
+ task.ctx = this;
757
+ return this;
758
+ }
759
+
760
+ runTasks() {
761
+ const tasks = this.tasks;
762
+ const tasksDone = Object.create(null);
763
+
764
+ var pending = tasks.length;
765
+ while (pending) {
766
+ const oldPending = pending;
767
+ const arrPending = [];
768
+
769
+ for (var i = 0; i < tasks.length; i++) {
770
+ const task = tasks[i];
771
+ if (tasksDone[task.name])
772
+ continue;
773
+
774
+ if (task.deps.every((dependency) => { return tasksDone[dependency] === true; })) {
775
+ task.run();
776
+ tasksDone[task.name] = true;
777
+ pending--;
778
+ }
779
+ else {
780
+ arrPending.push(task.name);
781
+ }
782
+ }
783
+
784
+ if (oldPending === pending)
785
+ throw Error(`TableGen.runModules(): Modules '${arrPending.join("|")}' stuck (cyclic dependency?)`);
786
+ }
787
+ }
788
+
789
+ // --------------------------------------------------------------------------
790
+ // [Instruction Management]
791
+ // --------------------------------------------------------------------------
792
+
793
+ addInst(inst) {
794
+ if (this.instMap[inst.name])
795
+ FAIL(`TableGen.addInst(): Instruction '${inst.name}' already added`);
796
+
797
+ inst.id = this.insts.length;
798
+ this.insts.push(inst);
799
+ this.instMap[inst.name] = inst;
800
+
801
+ return this;
802
+ }
803
+
804
+ addAlias(alias, name) {
805
+ this.aliases.push(alias);
806
+ this.aliasMap[alias] = name;
807
+
808
+ return this;
809
+ }
810
+
811
+ // --------------------------------------------------------------------------
812
+ // [Run]
813
+ // --------------------------------------------------------------------------
814
+
815
+ run() {
816
+ this.onBeforeRun();
817
+ this.runTasks();
818
+ this.onAfterRun();
819
+ }
820
+
821
+ // --------------------------------------------------------------------------
822
+ // [Other]
823
+ // --------------------------------------------------------------------------
824
+
825
+ dumpTableSizes() {
826
+ const sizes = this.tableSizes;
827
+
828
+ var pad = 26;
829
+ var total = 0;
830
+
831
+ for (var name in sizes) {
832
+ const size = sizes[name];
833
+ total += size;
834
+ console.log(("Size of " + name).padEnd(pad) + ": " + size);
835
+ }
836
+
837
+ console.log("Size of all tables".padEnd(pad) + ": " + total);
838
+ }
839
+
840
+ // --------------------------------------------------------------------------
841
+ // [Hooks]
842
+ // --------------------------------------------------------------------------
843
+
844
+ onBeforeRun() {}
845
+ onAfterRun() {}
846
+ }
847
+ exports.TableGen = TableGen;
848
+
849
+ // ============================================================================
850
+ // [IdEnum]
851
+ // ============================================================================
852
+
853
+ class IdEnum extends Task {
854
+ constructor(name, deps) {
855
+ super(name || "IdEnum", deps);
856
+ }
857
+
858
+ comment(name) {
859
+ FAIL("IdEnum.comment(): Must be reimplemented");
860
+ }
861
+
862
+ run() {
863
+ const insts = this.ctx.insts;
864
+
865
+ var s = "";
866
+ for (var i = 0; i < insts.length; i++) {
867
+ const inst = insts[i];
868
+
869
+ var line = "kId" + inst.enum + (i ? "" : " = 0") + ",";
870
+ var text = this.comment(inst);
871
+
872
+ if (text)
873
+ line = line.padEnd(37) + "//!< " + text;
874
+
875
+ s += line + "\n";
876
+ }
877
+ s += "_kIdCount\n";
878
+
879
+ return this.ctx.inject("InstId", s);
880
+ }
881
+ }
882
+ exports.IdEnum = IdEnum;
883
+
884
+ // ============================================================================
885
+ // [NameTable]
886
+ // ============================================================================
887
+
888
+ class NameTable extends Task {
889
+ constructor(name, deps) {
890
+ super(name || "NameTable", deps);
891
+ }
892
+
893
+ run() {
894
+ const arch = this.ctx.arch;
895
+ const none = "Inst::kIdNone";
896
+
897
+ const insts = this.ctx.insts;
898
+ const instNames = new IndexedString();
899
+
900
+ const instFirst = new Array(26);
901
+ const instLast = new Array(26);
902
+
903
+ var maxLength = 0;
904
+ for (var i = 0; i < insts.length; i++) {
905
+ const inst = insts[i];
906
+ instNames.add(inst.displayName);
907
+ maxLength = Math.max(maxLength, inst.displayName.length);
908
+ }
909
+ instNames.index();
910
+
911
+ for (var i = 0; i < insts.length; i++) {
912
+ const inst = insts[i];
913
+ const name = inst.displayName;
914
+ const nameIndex = instNames.getIndex(name);
915
+
916
+ const index = name.charCodeAt(0) - 'a'.charCodeAt(0);
917
+ if (index < 0 || index >= 26)
918
+ FAIL(`TableGen.generateNameData(): Invalid lookup character '${name[0]}' of '${name}'`);
919
+
920
+ inst.nameIndex = nameIndex;
921
+ if (instFirst[index] === undefined)
922
+ instFirst[index] = `Inst::kId${inst.enum}`;
923
+ instLast[index] = `Inst::kId${inst.enum}`;
924
+ }
925
+
926
+ var s = "";
927
+ s += `const char InstDB::_nameData[] =\n${instNames.format(kIndent, kJustify)}\n`;
928
+ s += `\n`;
929
+ s += `const InstDB::InstNameIndex InstDB::instNameIndex[26] = {\n`;
930
+ for (var i = 0; i < instFirst.length; i++) {
931
+ const firstId = instFirst[i] || none;
932
+ const lastId = instLast[i] || none;
933
+
934
+ s += ` { ${String(firstId).padEnd(22)}, ${String(lastId).padEnd(22)} + 1 }`;
935
+ if (i !== 26 - 1)
936
+ s += `,`;
937
+ s += `\n`;
938
+ }
939
+ s += `};\n`;
940
+
941
+ this.ctx.inject("NameLimits",
942
+ StringUtils.disclaimer(`enum : uint32_t { kMaxNameSize = ${maxLength} };\n`));
943
+
944
+ return this.ctx.inject("NameData", StringUtils.disclaimer(s), instNames.getSize() + 26 * 4);
945
+ }
946
+ }
947
+ exports.NameTable = NameTable;