asmjit 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/Rakefile +5 -3
  4. data/asmjit.gemspec +1 -3
  5. data/ext/asmjit/asmjit/.editorconfig +10 -0
  6. data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
  7. data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
  8. data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
  9. data/ext/asmjit/asmjit/.gitignore +6 -0
  10. data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
  11. data/ext/asmjit/asmjit/LICENSE.md +17 -0
  12. data/ext/asmjit/asmjit/README.md +69 -0
  13. data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
  14. data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
  15. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
  16. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
  17. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
  18. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
  19. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
  20. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
  21. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
  22. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
  23. data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
  24. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
  25. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
  26. data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
  27. data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
  28. data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
  29. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
  30. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
  31. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
  32. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
  33. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
  34. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
  35. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
  36. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
  37. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
  38. data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
  39. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
  40. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
  41. data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
  42. data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
  43. data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
  44. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
  45. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
  46. data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
  47. data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
  48. data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
  49. data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
  50. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
  51. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
  52. data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
  53. data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
  54. data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
  55. data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
  56. data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
  57. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
  58. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
  59. data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
  60. data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
  61. data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
  62. data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
  63. data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
  64. data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
  65. data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
  66. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
  67. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
  68. data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
  69. data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
  70. data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
  71. data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
  72. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
  73. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
  74. data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
  75. data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
  76. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
  77. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
  78. data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
  79. data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
  80. data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
  81. data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
  82. data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
  83. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
  84. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
  85. data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
  86. data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
  87. data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
  88. data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
  89. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
  90. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
  91. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
  92. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
  93. data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
  94. data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
  95. data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
  96. data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
  97. data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
  98. data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
  99. data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
  100. data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
  101. data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
  102. data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
  103. data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
  104. data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
  105. data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
  106. data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
  107. data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
  108. data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
  109. data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
  110. data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
  111. data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
  112. data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
  113. data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
  114. data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
  115. data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
  116. data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
  117. data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
  118. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
  119. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
  120. data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
  121. data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
  122. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
  123. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
  124. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
  125. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
  126. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
  127. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
  128. data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
  129. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
  130. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
  131. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
  132. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
  133. data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
  134. data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
  135. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
  136. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
  137. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
  138. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
  139. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
  140. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
  141. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
  142. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
  143. data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
  144. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
  145. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
  146. data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
  147. data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
  148. data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
  149. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
  150. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
  151. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
  152. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
  153. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
  154. data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
  155. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
  156. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
  157. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
  158. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
  159. data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
  160. data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
  161. data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
  162. data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
  163. data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
  164. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
  165. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
  166. data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
  167. data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
  168. data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
  169. data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
  170. data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
  171. data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
  172. data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
  173. data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
  174. data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
  175. data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
  176. data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
  177. data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
  178. data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
  179. data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
  180. data/ext/asmjit/asmjit/test/broken.cpp +312 -0
  181. data/ext/asmjit/asmjit/test/broken.h +148 -0
  182. data/ext/asmjit/asmjit/test/cmdline.h +61 -0
  183. data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
  184. data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
  185. data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
  186. data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
  187. data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
  188. data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
  189. data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
  190. data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
  191. data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
  192. data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
  193. data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
  194. data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
  195. data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
  196. data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
  197. data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
  198. data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
  199. data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
  200. data/ext/asmjit/asmjit.cc +167 -30
  201. data/ext/asmjit/extconf.rb +9 -9
  202. data/lib/asmjit/version.rb +1 -1
  203. data/lib/asmjit.rb +14 -4
  204. metadata +198 -17
@@ -0,0 +1,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;