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.
- 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,582 @@
|
|
|
1
|
+
// This file is part of AsmJit project <https://asmjit.com>
|
|
2
|
+
//
|
|
3
|
+
// See asmjit.h or LICENSE.md for license and copyright information
|
|
4
|
+
// SPDX-License-Identifier: Zlib
|
|
5
|
+
|
|
6
|
+
#include "../core/api-build_p.h"
|
|
7
|
+
#ifndef ASMJIT_NO_COMPILER
|
|
8
|
+
|
|
9
|
+
#include "../core/assembler.h"
|
|
10
|
+
#include "../core/compiler.h"
|
|
11
|
+
#include "../core/cpuinfo.h"
|
|
12
|
+
#include "../core/logger.h"
|
|
13
|
+
#include "../core/rapass_p.h"
|
|
14
|
+
#include "../core/rastack_p.h"
|
|
15
|
+
#include "../core/support.h"
|
|
16
|
+
#include "../core/type.h"
|
|
17
|
+
|
|
18
|
+
ASMJIT_BEGIN_NAMESPACE
|
|
19
|
+
|
|
20
|
+
// GlobalConstPoolPass
|
|
21
|
+
// ===================
|
|
22
|
+
|
|
23
|
+
class GlobalConstPoolPass : public Pass {
|
|
24
|
+
public:
|
|
25
|
+
typedef Pass Base;
|
|
26
|
+
public:
|
|
27
|
+
ASMJIT_NONCOPYABLE(GlobalConstPoolPass)
|
|
28
|
+
|
|
29
|
+
GlobalConstPoolPass() noexcept : Pass("GlobalConstPoolPass") {}
|
|
30
|
+
|
|
31
|
+
Error run(Zone* zone, Logger* logger) override {
|
|
32
|
+
DebugUtils::unused(zone, logger);
|
|
33
|
+
|
|
34
|
+
// Flush the global constant pool.
|
|
35
|
+
BaseCompiler* compiler = static_cast<BaseCompiler*>(_cb);
|
|
36
|
+
ConstPoolNode* globalConstPool = compiler->_constPools[uint32_t(ConstPoolScope::kGlobal)];
|
|
37
|
+
|
|
38
|
+
if (globalConstPool) {
|
|
39
|
+
compiler->addAfter(globalConstPool, compiler->lastNode());
|
|
40
|
+
compiler->_constPools[uint32_t(ConstPoolScope::kGlobal)] = nullptr;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return kErrorOk;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// BaseCompiler - Construction & Destruction
|
|
48
|
+
// =========================================
|
|
49
|
+
|
|
50
|
+
BaseCompiler::BaseCompiler() noexcept
|
|
51
|
+
: BaseBuilder(),
|
|
52
|
+
_func(nullptr),
|
|
53
|
+
_vRegZone(4096 - Zone::kBlockOverhead),
|
|
54
|
+
_vRegArray(),
|
|
55
|
+
_constPools { nullptr, nullptr } {
|
|
56
|
+
_emitterType = EmitterType::kCompiler;
|
|
57
|
+
_validationFlags = ValidationFlags::kEnableVirtRegs;
|
|
58
|
+
}
|
|
59
|
+
BaseCompiler::~BaseCompiler() noexcept {}
|
|
60
|
+
|
|
61
|
+
// BaseCompiler - Function Management
|
|
62
|
+
// ==================================
|
|
63
|
+
|
|
64
|
+
Error BaseCompiler::newFuncNode(FuncNode** out, const FuncSignature& signature) {
|
|
65
|
+
*out = nullptr;
|
|
66
|
+
|
|
67
|
+
// Create FuncNode together with all the required surrounding nodes.
|
|
68
|
+
FuncNode* funcNode;
|
|
69
|
+
ASMJIT_PROPAGATE(_newNodeT<FuncNode>(&funcNode));
|
|
70
|
+
ASMJIT_PROPAGATE(newLabelNode(&funcNode->_exitNode));
|
|
71
|
+
ASMJIT_PROPAGATE(_newNodeT<SentinelNode>(&funcNode->_end, SentinelType::kFuncEnd));
|
|
72
|
+
|
|
73
|
+
// Initialize the function's detail info.
|
|
74
|
+
Error err = funcNode->detail().init(signature, environment());
|
|
75
|
+
if (ASMJIT_UNLIKELY(err))
|
|
76
|
+
return reportError(err);
|
|
77
|
+
|
|
78
|
+
// If the Target guarantees greater stack alignment than required by the calling convention
|
|
79
|
+
// then override it as we can prevent having to perform dynamic stack alignment
|
|
80
|
+
uint32_t environmentStackAlignment = _environment.stackAlignment();
|
|
81
|
+
|
|
82
|
+
if (funcNode->_funcDetail._callConv.naturalStackAlignment() < environmentStackAlignment)
|
|
83
|
+
funcNode->_funcDetail._callConv.setNaturalStackAlignment(environmentStackAlignment);
|
|
84
|
+
|
|
85
|
+
// Initialize the function frame.
|
|
86
|
+
err = funcNode->_frame.init(funcNode->_funcDetail);
|
|
87
|
+
if (ASMJIT_UNLIKELY(err))
|
|
88
|
+
return reportError(err);
|
|
89
|
+
|
|
90
|
+
// Allocate space for function arguments.
|
|
91
|
+
funcNode->_args = nullptr;
|
|
92
|
+
if (funcNode->argCount() != 0) {
|
|
93
|
+
funcNode->_args = _allocator.allocT<FuncNode::ArgPack>(funcNode->argCount() * sizeof(FuncNode::ArgPack));
|
|
94
|
+
if (ASMJIT_UNLIKELY(!funcNode->_args))
|
|
95
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
|
96
|
+
memset(funcNode->_args, 0, funcNode->argCount() * sizeof(FuncNode::ArgPack));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
ASMJIT_PROPAGATE(registerLabelNode(funcNode));
|
|
100
|
+
|
|
101
|
+
*out = funcNode;
|
|
102
|
+
return kErrorOk;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
Error BaseCompiler::addFuncNode(FuncNode** out, const FuncSignature& signature) {
|
|
106
|
+
ASMJIT_PROPAGATE(newFuncNode(out, signature));
|
|
107
|
+
ASMJIT_ASSUME(*out != nullptr);
|
|
108
|
+
|
|
109
|
+
addFunc(*out);
|
|
110
|
+
return kErrorOk;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
Error BaseCompiler::newFuncRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) {
|
|
114
|
+
uint32_t opCount = !o1.isNone() ? 2u : !o0.isNone() ? 1u : 0u;
|
|
115
|
+
FuncRetNode* node;
|
|
116
|
+
|
|
117
|
+
ASMJIT_PROPAGATE(_newNodeT<FuncRetNode>(&node));
|
|
118
|
+
ASMJIT_ASSUME(node != nullptr);
|
|
119
|
+
|
|
120
|
+
node->setOpCount(opCount);
|
|
121
|
+
node->setOp(0, o0);
|
|
122
|
+
node->setOp(1, o1);
|
|
123
|
+
node->resetOpRange(2, node->opCapacity());
|
|
124
|
+
|
|
125
|
+
*out = node;
|
|
126
|
+
return kErrorOk;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
Error BaseCompiler::addFuncRetNode(FuncRetNode** out, const Operand_& o0, const Operand_& o1) {
|
|
130
|
+
ASMJIT_PROPAGATE(newFuncRetNode(out, o0, o1));
|
|
131
|
+
addNode(*out);
|
|
132
|
+
return kErrorOk;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
FuncNode* BaseCompiler::addFunc(FuncNode* func) {
|
|
136
|
+
_func = func;
|
|
137
|
+
|
|
138
|
+
addNode(func); // Function node.
|
|
139
|
+
BaseNode* prev = cursor(); // {CURSOR}.
|
|
140
|
+
addNode(func->exitNode()); // Function exit label.
|
|
141
|
+
addNode(func->endNode()); // Function end sentinel.
|
|
142
|
+
|
|
143
|
+
_setCursor(prev);
|
|
144
|
+
return func;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
Error BaseCompiler::endFunc() {
|
|
148
|
+
FuncNode* func = _func;
|
|
149
|
+
|
|
150
|
+
if (ASMJIT_UNLIKELY(!func))
|
|
151
|
+
return reportError(DebugUtils::errored(kErrorInvalidState));
|
|
152
|
+
|
|
153
|
+
// Add the local constant pool at the end of the function (if exists).
|
|
154
|
+
ConstPoolNode* localConstPool = _constPools[uint32_t(ConstPoolScope::kLocal)];
|
|
155
|
+
if (localConstPool) {
|
|
156
|
+
setCursor(func->endNode()->prev());
|
|
157
|
+
addNode(localConstPool);
|
|
158
|
+
_constPools[uint32_t(ConstPoolScope::kLocal)] = nullptr;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Mark as finished.
|
|
162
|
+
_func = nullptr;
|
|
163
|
+
|
|
164
|
+
SentinelNode* end = func->endNode();
|
|
165
|
+
setCursor(end);
|
|
166
|
+
|
|
167
|
+
return kErrorOk;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// BaseCompiler - Function Invocation
|
|
171
|
+
// ==================================
|
|
172
|
+
|
|
173
|
+
Error BaseCompiler::newInvokeNode(InvokeNode** out, InstId instId, const Operand_& o0, const FuncSignature& signature) {
|
|
174
|
+
InvokeNode* node;
|
|
175
|
+
ASMJIT_PROPAGATE(_newNodeT<InvokeNode>(&node, instId, InstOptions::kNone));
|
|
176
|
+
|
|
177
|
+
node->setOpCount(1);
|
|
178
|
+
node->setOp(0, o0);
|
|
179
|
+
node->resetOpRange(1, node->opCapacity());
|
|
180
|
+
|
|
181
|
+
Error err = node->detail().init(signature, environment());
|
|
182
|
+
if (ASMJIT_UNLIKELY(err))
|
|
183
|
+
return reportError(err);
|
|
184
|
+
|
|
185
|
+
// Skip the allocation if there are no arguments.
|
|
186
|
+
uint32_t argCount = signature.argCount();
|
|
187
|
+
if (argCount) {
|
|
188
|
+
node->_args = static_cast<InvokeNode::OperandPack*>(_allocator.alloc(argCount * sizeof(InvokeNode::OperandPack)));
|
|
189
|
+
if (!node->_args)
|
|
190
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
|
191
|
+
memset(node->_args, 0, argCount * sizeof(InvokeNode::OperandPack));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
*out = node;
|
|
195
|
+
return kErrorOk;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
Error BaseCompiler::addInvokeNode(InvokeNode** out, InstId instId, const Operand_& o0, const FuncSignature& signature) {
|
|
199
|
+
ASMJIT_PROPAGATE(newInvokeNode(out, instId, o0, signature));
|
|
200
|
+
addNode(*out);
|
|
201
|
+
return kErrorOk;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// BaseCompiler - Virtual Registers
|
|
205
|
+
// ================================
|
|
206
|
+
|
|
207
|
+
static void BaseCompiler_assignGenericName(BaseCompiler* self, VirtReg* vReg) {
|
|
208
|
+
uint32_t index = unsigned(Operand::virtIdToIndex(vReg->_id));
|
|
209
|
+
|
|
210
|
+
char buf[64];
|
|
211
|
+
int size = snprintf(buf, ASMJIT_ARRAY_SIZE(buf), "%%%u", unsigned(index));
|
|
212
|
+
|
|
213
|
+
ASMJIT_ASSERT(size > 0 && size < int(ASMJIT_ARRAY_SIZE(buf)));
|
|
214
|
+
vReg->_name.setData(&self->_dataZone, buf, unsigned(size));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
Error BaseCompiler::newVirtReg(VirtReg** out, TypeId typeId, OperandSignature signature, const char* name) {
|
|
218
|
+
*out = nullptr;
|
|
219
|
+
uint32_t index = _vRegArray.size();
|
|
220
|
+
|
|
221
|
+
if (ASMJIT_UNLIKELY(index >= uint32_t(Operand::kVirtIdCount)))
|
|
222
|
+
return reportError(DebugUtils::errored(kErrorTooManyVirtRegs));
|
|
223
|
+
|
|
224
|
+
if (ASMJIT_UNLIKELY(_vRegArray.willGrow(&_allocator) != kErrorOk))
|
|
225
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
|
226
|
+
|
|
227
|
+
VirtReg* vReg = _vRegZone.allocZeroedT<VirtReg>();
|
|
228
|
+
if (ASMJIT_UNLIKELY(!vReg))
|
|
229
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
|
230
|
+
|
|
231
|
+
uint32_t size = TypeUtils::sizeOf(typeId);
|
|
232
|
+
uint32_t alignment = Support::min<uint32_t>(size, 64);
|
|
233
|
+
|
|
234
|
+
vReg = new(vReg) VirtReg(signature, Operand::indexToVirtId(index), size, alignment, typeId);
|
|
235
|
+
|
|
236
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
237
|
+
if (name && name[0] != '\0')
|
|
238
|
+
vReg->_name.setData(&_dataZone, name, SIZE_MAX);
|
|
239
|
+
else
|
|
240
|
+
BaseCompiler_assignGenericName(this, vReg);
|
|
241
|
+
#else
|
|
242
|
+
DebugUtils::unused(name);
|
|
243
|
+
#endif
|
|
244
|
+
|
|
245
|
+
_vRegArray.appendUnsafe(vReg);
|
|
246
|
+
*out = vReg;
|
|
247
|
+
|
|
248
|
+
return kErrorOk;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
Error BaseCompiler::_newReg(BaseReg* out, TypeId typeId, const char* name) {
|
|
252
|
+
OperandSignature regSignature;
|
|
253
|
+
out->reset();
|
|
254
|
+
|
|
255
|
+
Error err = ArchUtils::typeIdToRegSignature(arch(), typeId, &typeId, ®Signature);
|
|
256
|
+
if (ASMJIT_UNLIKELY(err))
|
|
257
|
+
return reportError(err);
|
|
258
|
+
|
|
259
|
+
VirtReg* vReg;
|
|
260
|
+
ASMJIT_PROPAGATE(newVirtReg(&vReg, typeId, regSignature, name));
|
|
261
|
+
ASMJIT_ASSUME(vReg != nullptr);
|
|
262
|
+
|
|
263
|
+
out->_initReg(regSignature, vReg->id());
|
|
264
|
+
return kErrorOk;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
Error BaseCompiler::_newRegFmt(BaseReg* out, TypeId typeId, const char* fmt, ...) {
|
|
268
|
+
va_list ap;
|
|
269
|
+
StringTmp<256> sb;
|
|
270
|
+
|
|
271
|
+
va_start(ap, fmt);
|
|
272
|
+
sb.appendVFormat(fmt, ap);
|
|
273
|
+
va_end(ap);
|
|
274
|
+
|
|
275
|
+
return _newReg(out, typeId, sb.data());
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
Error BaseCompiler::_newReg(BaseReg* out, const BaseReg& ref, const char* name) {
|
|
279
|
+
out->reset();
|
|
280
|
+
|
|
281
|
+
OperandSignature regSignature;
|
|
282
|
+
TypeId typeId;
|
|
283
|
+
|
|
284
|
+
if (isVirtRegValid(ref)) {
|
|
285
|
+
VirtReg* vRef = virtRegByReg(ref);
|
|
286
|
+
typeId = vRef->typeId();
|
|
287
|
+
|
|
288
|
+
// NOTE: It's possible to cast one register type to another if it's the same register group. However, VirtReg
|
|
289
|
+
// always contains the TypeId that was used to create the register. This means that in some cases we may end
|
|
290
|
+
// up having different size of `ref` and `vRef`. In such case we adjust the TypeId to match the `ref` register
|
|
291
|
+
// type instead of the original register type, which should be the expected behavior.
|
|
292
|
+
uint32_t typeSize = TypeUtils::sizeOf(typeId);
|
|
293
|
+
uint32_t refSize = ref.size();
|
|
294
|
+
|
|
295
|
+
if (typeSize != refSize) {
|
|
296
|
+
if (TypeUtils::isInt(typeId)) {
|
|
297
|
+
// GP register - change TypeId to match `ref`, but keep sign of `vRef`.
|
|
298
|
+
switch (refSize) {
|
|
299
|
+
case 1: typeId = TypeId(uint32_t(TypeId::kInt8 ) | (uint32_t(typeId) & 1)); break;
|
|
300
|
+
case 2: typeId = TypeId(uint32_t(TypeId::kInt16) | (uint32_t(typeId) & 1)); break;
|
|
301
|
+
case 4: typeId = TypeId(uint32_t(TypeId::kInt32) | (uint32_t(typeId) & 1)); break;
|
|
302
|
+
case 8: typeId = TypeId(uint32_t(TypeId::kInt64) | (uint32_t(typeId) & 1)); break;
|
|
303
|
+
default: typeId = TypeId::kVoid; break;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
else if (TypeUtils::isMmx(typeId)) {
|
|
307
|
+
// MMX register - always use 64-bit.
|
|
308
|
+
typeId = TypeId::kMmx64;
|
|
309
|
+
}
|
|
310
|
+
else if (TypeUtils::isMask(typeId)) {
|
|
311
|
+
// Mask register - change TypeId to match `ref` size.
|
|
312
|
+
switch (refSize) {
|
|
313
|
+
case 1: typeId = TypeId::kMask8; break;
|
|
314
|
+
case 2: typeId = TypeId::kMask16; break;
|
|
315
|
+
case 4: typeId = TypeId::kMask32; break;
|
|
316
|
+
case 8: typeId = TypeId::kMask64; break;
|
|
317
|
+
default: typeId = TypeId::kVoid; break;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
// Vector register - change TypeId to match `ref` size, keep vector metadata.
|
|
322
|
+
TypeId scalarTypeId = TypeUtils::scalarOf(typeId);
|
|
323
|
+
switch (refSize) {
|
|
324
|
+
case 16: typeId = TypeUtils::scalarToVector(scalarTypeId, TypeId::_kVec128Start); break;
|
|
325
|
+
case 32: typeId = TypeUtils::scalarToVector(scalarTypeId, TypeId::_kVec256Start); break;
|
|
326
|
+
case 64: typeId = TypeUtils::scalarToVector(scalarTypeId, TypeId::_kVec512Start); break;
|
|
327
|
+
default: typeId = TypeId::kVoid; break;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (typeId == TypeId::kVoid)
|
|
332
|
+
return reportError(DebugUtils::errored(kErrorInvalidState));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
typeId = ArchTraits::byArch(arch()).regTypeToTypeId(ref.type());
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
Error err = ArchUtils::typeIdToRegSignature(arch(), typeId, &typeId, ®Signature);
|
|
340
|
+
if (ASMJIT_UNLIKELY(err))
|
|
341
|
+
return reportError(err);
|
|
342
|
+
|
|
343
|
+
VirtReg* vReg;
|
|
344
|
+
ASMJIT_PROPAGATE(newVirtReg(&vReg, typeId, regSignature, name));
|
|
345
|
+
ASMJIT_ASSUME(vReg != nullptr);
|
|
346
|
+
|
|
347
|
+
out->_initReg(regSignature, vReg->id());
|
|
348
|
+
return kErrorOk;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
Error BaseCompiler::_newRegFmt(BaseReg* out, const BaseReg& ref, const char* fmt, ...) {
|
|
352
|
+
va_list ap;
|
|
353
|
+
StringTmp<256> sb;
|
|
354
|
+
|
|
355
|
+
va_start(ap, fmt);
|
|
356
|
+
sb.appendVFormat(fmt, ap);
|
|
357
|
+
va_end(ap);
|
|
358
|
+
|
|
359
|
+
return _newReg(out, ref, sb.data());
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
Error BaseCompiler::_newStack(BaseMem* out, uint32_t size, uint32_t alignment, const char* name) {
|
|
363
|
+
out->reset();
|
|
364
|
+
|
|
365
|
+
if (size == 0)
|
|
366
|
+
return reportError(DebugUtils::errored(kErrorInvalidArgument));
|
|
367
|
+
|
|
368
|
+
if (alignment == 0)
|
|
369
|
+
alignment = 1;
|
|
370
|
+
|
|
371
|
+
if (!Support::isPowerOf2(alignment))
|
|
372
|
+
return reportError(DebugUtils::errored(kErrorInvalidArgument));
|
|
373
|
+
|
|
374
|
+
if (alignment > 64)
|
|
375
|
+
alignment = 64;
|
|
376
|
+
|
|
377
|
+
VirtReg* vReg;
|
|
378
|
+
ASMJIT_PROPAGATE(newVirtReg(&vReg, TypeId::kVoid, OperandSignature{0}, name));
|
|
379
|
+
ASMJIT_ASSUME(vReg != nullptr);
|
|
380
|
+
|
|
381
|
+
vReg->_virtSize = size;
|
|
382
|
+
vReg->_isStack = true;
|
|
383
|
+
vReg->_alignment = uint8_t(alignment);
|
|
384
|
+
|
|
385
|
+
// Set the memory operand to GPD/GPQ and its id to VirtReg.
|
|
386
|
+
*out = BaseMem(OperandSignature::fromOpType(OperandType::kMem) |
|
|
387
|
+
OperandSignature::fromMemBaseType(_gpSignature.regType()) |
|
|
388
|
+
OperandSignature::fromBits(OperandSignature::kMemRegHomeFlag),
|
|
389
|
+
vReg->id(), 0, 0);
|
|
390
|
+
return kErrorOk;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
Error BaseCompiler::setStackSize(uint32_t virtId, uint32_t newSize, uint32_t newAlignment) {
|
|
394
|
+
if (!isVirtIdValid(virtId))
|
|
395
|
+
return DebugUtils::errored(kErrorInvalidVirtId);
|
|
396
|
+
|
|
397
|
+
if (newAlignment && !Support::isPowerOf2(newAlignment))
|
|
398
|
+
return reportError(DebugUtils::errored(kErrorInvalidArgument));
|
|
399
|
+
|
|
400
|
+
if (newAlignment > 64)
|
|
401
|
+
newAlignment = 64;
|
|
402
|
+
|
|
403
|
+
VirtReg* vReg = virtRegById(virtId);
|
|
404
|
+
if (newSize)
|
|
405
|
+
vReg->_virtSize = newSize;
|
|
406
|
+
|
|
407
|
+
if (newAlignment)
|
|
408
|
+
vReg->_alignment = uint8_t(newAlignment);
|
|
409
|
+
|
|
410
|
+
// This is required if the RAPass is already running. There is a chance that a stack-slot has been already
|
|
411
|
+
// allocated and in that case it has to be updated as well, otherwise we would allocate wrong amount of memory.
|
|
412
|
+
RAWorkReg* workReg = vReg->_workReg;
|
|
413
|
+
if (workReg && workReg->_stackSlot) {
|
|
414
|
+
workReg->_stackSlot->_size = vReg->_virtSize;
|
|
415
|
+
workReg->_stackSlot->_alignment = vReg->_alignment;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return kErrorOk;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
Error BaseCompiler::_newConst(BaseMem* out, ConstPoolScope scope, const void* data, size_t size) {
|
|
422
|
+
out->reset();
|
|
423
|
+
|
|
424
|
+
if (uint32_t(scope) > 1)
|
|
425
|
+
return reportError(DebugUtils::errored(kErrorInvalidArgument));
|
|
426
|
+
|
|
427
|
+
if (!_constPools[uint32_t(scope)])
|
|
428
|
+
ASMJIT_PROPAGATE(newConstPoolNode(&_constPools[uint32_t(scope)]));
|
|
429
|
+
|
|
430
|
+
ConstPoolNode* pool = _constPools[uint32_t(scope)];
|
|
431
|
+
size_t off;
|
|
432
|
+
Error err = pool->add(data, size, off);
|
|
433
|
+
|
|
434
|
+
if (ASMJIT_UNLIKELY(err))
|
|
435
|
+
return reportError(err);
|
|
436
|
+
|
|
437
|
+
*out = BaseMem(OperandSignature::fromOpType(OperandType::kMem) |
|
|
438
|
+
OperandSignature::fromMemBaseType(RegType::kLabelTag) |
|
|
439
|
+
OperandSignature::fromSize(uint32_t(size)),
|
|
440
|
+
pool->labelId(), 0, int32_t(off));
|
|
441
|
+
return kErrorOk;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
void BaseCompiler::rename(const BaseReg& reg, const char* fmt, ...) {
|
|
445
|
+
if (!reg.isVirtReg()) return;
|
|
446
|
+
|
|
447
|
+
VirtReg* vReg = virtRegById(reg.id());
|
|
448
|
+
if (!vReg) return;
|
|
449
|
+
|
|
450
|
+
if (fmt && fmt[0] != '\0') {
|
|
451
|
+
char buf[128];
|
|
452
|
+
va_list ap;
|
|
453
|
+
|
|
454
|
+
va_start(ap, fmt);
|
|
455
|
+
vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
|
|
456
|
+
va_end(ap);
|
|
457
|
+
|
|
458
|
+
vReg->_name.setData(&_dataZone, buf, SIZE_MAX);
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
BaseCompiler_assignGenericName(this, vReg);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// BaseCompiler - Jump Annotations
|
|
466
|
+
// ===============================
|
|
467
|
+
|
|
468
|
+
Error BaseCompiler::newJumpNode(JumpNode** out, InstId instId, InstOptions instOptions, const Operand_& o0, JumpAnnotation* annotation) {
|
|
469
|
+
JumpNode* node = _allocator.allocT<JumpNode>();
|
|
470
|
+
uint32_t opCount = 1;
|
|
471
|
+
|
|
472
|
+
*out = node;
|
|
473
|
+
if (ASMJIT_UNLIKELY(!node))
|
|
474
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
|
475
|
+
|
|
476
|
+
node = new(node) JumpNode(this, instId, instOptions, opCount, annotation);
|
|
477
|
+
node->setOp(0, o0);
|
|
478
|
+
node->resetOpRange(opCount, JumpNode::kBaseOpCapacity);
|
|
479
|
+
|
|
480
|
+
return kErrorOk;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
Error BaseCompiler::emitAnnotatedJump(InstId instId, const Operand_& o0, JumpAnnotation* annotation) {
|
|
484
|
+
InstOptions options = instOptions() | forcedInstOptions();
|
|
485
|
+
RegOnly extra = extraReg();
|
|
486
|
+
const char* comment = inlineComment();
|
|
487
|
+
|
|
488
|
+
resetInstOptions();
|
|
489
|
+
resetInlineComment();
|
|
490
|
+
resetExtraReg();
|
|
491
|
+
|
|
492
|
+
JumpNode* node;
|
|
493
|
+
ASMJIT_PROPAGATE(newJumpNode(&node, instId, options, o0, annotation));
|
|
494
|
+
|
|
495
|
+
node->setExtraReg(extra);
|
|
496
|
+
if (comment)
|
|
497
|
+
node->setInlineComment(static_cast<char*>(_dataZone.dup(comment, strlen(comment), true)));
|
|
498
|
+
|
|
499
|
+
addNode(node);
|
|
500
|
+
return kErrorOk;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
JumpAnnotation* BaseCompiler::newJumpAnnotation() {
|
|
504
|
+
if (_jumpAnnotations.grow(&_allocator, 1) != kErrorOk) {
|
|
505
|
+
reportError(DebugUtils::errored(kErrorOutOfMemory));
|
|
506
|
+
return nullptr;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
uint32_t id = _jumpAnnotations.size();
|
|
510
|
+
JumpAnnotation* jumpAnnotation = _allocator.newT<JumpAnnotation>(this, id);
|
|
511
|
+
|
|
512
|
+
if (!jumpAnnotation) {
|
|
513
|
+
reportError(DebugUtils::errored(kErrorOutOfMemory));
|
|
514
|
+
return nullptr;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
_jumpAnnotations.appendUnsafe(jumpAnnotation);
|
|
518
|
+
return jumpAnnotation;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// BaseCompiler - Events
|
|
522
|
+
// =====================
|
|
523
|
+
|
|
524
|
+
Error BaseCompiler::onAttach(CodeHolder* code) noexcept {
|
|
525
|
+
ASMJIT_PROPAGATE(Base::onAttach(code));
|
|
526
|
+
|
|
527
|
+
const ArchTraits& archTraits = ArchTraits::byArch(code->arch());
|
|
528
|
+
RegType nativeRegType = Environment::is32Bit(code->arch()) ? RegType::kGp32 : RegType::kGp64;
|
|
529
|
+
_gpSignature = archTraits.regTypeToSignature(nativeRegType);
|
|
530
|
+
|
|
531
|
+
Error err = addPassT<GlobalConstPoolPass>();
|
|
532
|
+
if (ASMJIT_UNLIKELY(err)) {
|
|
533
|
+
onDetach(code);
|
|
534
|
+
return err;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
return kErrorOk;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
Error BaseCompiler::onDetach(CodeHolder* code) noexcept {
|
|
541
|
+
_func = nullptr;
|
|
542
|
+
_constPools[uint32_t(ConstPoolScope::kLocal)] = nullptr;
|
|
543
|
+
_constPools[uint32_t(ConstPoolScope::kGlobal)] = nullptr;
|
|
544
|
+
|
|
545
|
+
_vRegArray.reset();
|
|
546
|
+
_vRegZone.reset();
|
|
547
|
+
|
|
548
|
+
return Base::onDetach(code);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// FuncPass - Construction & Destruction
|
|
552
|
+
// =====================================
|
|
553
|
+
|
|
554
|
+
FuncPass::FuncPass(const char* name) noexcept
|
|
555
|
+
: Pass(name) {}
|
|
556
|
+
|
|
557
|
+
// FuncPass - Run
|
|
558
|
+
// ==============
|
|
559
|
+
|
|
560
|
+
Error FuncPass::run(Zone* zone, Logger* logger) {
|
|
561
|
+
BaseNode* node = cb()->firstNode();
|
|
562
|
+
if (!node) return kErrorOk;
|
|
563
|
+
|
|
564
|
+
do {
|
|
565
|
+
if (node->type() == NodeType::kFunc) {
|
|
566
|
+
FuncNode* func = node->as<FuncNode>();
|
|
567
|
+
node = func->endNode();
|
|
568
|
+
ASMJIT_PROPAGATE(runOnFunction(zone, logger, func));
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Find a function by skipping all nodes that are not `NodeType::kFunc`.
|
|
572
|
+
do {
|
|
573
|
+
node = node->next();
|
|
574
|
+
} while (node && node->type() != NodeType::kFunc);
|
|
575
|
+
} while (node);
|
|
576
|
+
|
|
577
|
+
return kErrorOk;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
ASMJIT_END_NAMESPACE
|
|
581
|
+
|
|
582
|
+
#endif // !ASMJIT_NO_COMPILER
|