asmjit 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/asmjit.gemspec +1 -1
- data/ext/asmjit/asmjit/.editorconfig +10 -0
- data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
- data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
- data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
- data/ext/asmjit/asmjit/.gitignore +6 -0
- data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
- data/ext/asmjit/asmjit/LICENSE.md +17 -0
- data/ext/asmjit/asmjit/README.md +69 -0
- data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
- data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
- data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
- data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
- data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
- data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
- data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
- data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
- data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
- data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
- data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
- data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
- data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
- data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
- data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
- data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
- data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
- data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
- data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
- data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
- data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
- data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
- data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
- data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
- data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
- data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
- data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
- data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
- data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
- data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
- data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
- data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
- data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
- data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
- data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
- data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
- data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
- data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
- data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
- data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
- data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
- data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
- data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
- data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
- data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
- data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
- data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
- data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
- data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
- data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
- data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
- data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
- data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
- data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
- data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
- data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
- data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
- data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
- data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
- data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
- data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
- data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
- data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
- data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
- data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
- data/ext/asmjit/asmjit/test/broken.cpp +312 -0
- data/ext/asmjit/asmjit/test/broken.h +148 -0
- data/ext/asmjit/asmjit/test/cmdline.h +61 -0
- data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
- data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
- data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
- data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
- data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
- data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
- data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
- data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
- data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
- data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
- data/ext/asmjit/asmjit.cc +18 -0
- data/lib/asmjit/version.rb +1 -1
- 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;
|