asmjit 0.2.0 → 0.2.2
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/Rakefile +5 -3
- data/asmjit.gemspec +1 -3
- 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 +167 -30
- data/ext/asmjit/extconf.rb +9 -9
- data/lib/asmjit/version.rb +1 -1
- data/lib/asmjit.rb +14 -4
- metadata +198 -17
@@ -0,0 +1,889 @@
|
|
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_BUILDER
|
8
|
+
|
9
|
+
#include "../core/builder.h"
|
10
|
+
#include "../core/emitterutils_p.h"
|
11
|
+
#include "../core/errorhandler.h"
|
12
|
+
#include "../core/formatter.h"
|
13
|
+
#include "../core/logger.h"
|
14
|
+
#include "../core/support.h"
|
15
|
+
|
16
|
+
ASMJIT_BEGIN_NAMESPACE
|
17
|
+
|
18
|
+
// PostponedErrorHandler (Internal)
|
19
|
+
// ================================
|
20
|
+
|
21
|
+
//! Postponed error handler that never throws. Used as a temporal error handler
|
22
|
+
//! to run passes. If error occurs, the caller is notified and will call the
|
23
|
+
//! real error handler, that can throw.
|
24
|
+
class PostponedErrorHandler : public ErrorHandler {
|
25
|
+
public:
|
26
|
+
void handleError(Error err, const char* message, BaseEmitter* origin) override {
|
27
|
+
DebugUtils::unused(err, origin);
|
28
|
+
_message.assign(message);
|
29
|
+
}
|
30
|
+
|
31
|
+
StringTmp<128> _message;
|
32
|
+
};
|
33
|
+
|
34
|
+
// BaseBuilder - Utilities
|
35
|
+
// =======================
|
36
|
+
|
37
|
+
static void BaseBuilder_deletePasses(BaseBuilder* self) noexcept {
|
38
|
+
for (Pass* pass : self->_passes)
|
39
|
+
pass->~Pass();
|
40
|
+
self->_passes.reset();
|
41
|
+
}
|
42
|
+
|
43
|
+
// BaseBuilder - Construction & Destruction
|
44
|
+
// ========================================
|
45
|
+
|
46
|
+
BaseBuilder::BaseBuilder() noexcept
|
47
|
+
: BaseEmitter(EmitterType::kBuilder),
|
48
|
+
_codeZone(32768 - Zone::kBlockOverhead),
|
49
|
+
_dataZone(16384 - Zone::kBlockOverhead),
|
50
|
+
_passZone(65536 - Zone::kBlockOverhead),
|
51
|
+
_allocator(&_codeZone) {}
|
52
|
+
|
53
|
+
BaseBuilder::~BaseBuilder() noexcept {
|
54
|
+
BaseBuilder_deletePasses(this);
|
55
|
+
}
|
56
|
+
|
57
|
+
// BaseBuilder - Node Management
|
58
|
+
// =============================
|
59
|
+
|
60
|
+
Error BaseBuilder::newInstNode(InstNode** out, InstId instId, InstOptions instOptions, uint32_t opCount) {
|
61
|
+
uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
|
62
|
+
ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity);
|
63
|
+
|
64
|
+
InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
|
65
|
+
if (ASMJIT_UNLIKELY(!node))
|
66
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
67
|
+
|
68
|
+
*out = new(node) InstNode(this, instId, instOptions, opCount, opCapacity);
|
69
|
+
return kErrorOk;
|
70
|
+
}
|
71
|
+
|
72
|
+
|
73
|
+
Error BaseBuilder::newLabelNode(LabelNode** out) {
|
74
|
+
*out = nullptr;
|
75
|
+
|
76
|
+
ASMJIT_PROPAGATE(_newNodeT<LabelNode>(out));
|
77
|
+
return registerLabelNode(*out);
|
78
|
+
}
|
79
|
+
|
80
|
+
Error BaseBuilder::newAlignNode(AlignNode** out, AlignMode alignMode, uint32_t alignment) {
|
81
|
+
*out = nullptr;
|
82
|
+
return _newNodeT<AlignNode>(out, alignMode, alignment);
|
83
|
+
}
|
84
|
+
|
85
|
+
Error BaseBuilder::newEmbedDataNode(EmbedDataNode** out, TypeId typeId, const void* data, size_t itemCount, size_t repeatCount) {
|
86
|
+
*out = nullptr;
|
87
|
+
|
88
|
+
uint32_t deabstractDelta = TypeUtils::deabstractDeltaOfSize(registerSize());
|
89
|
+
TypeId finalTypeId = TypeUtils::deabstract(typeId, deabstractDelta);
|
90
|
+
|
91
|
+
if (ASMJIT_UNLIKELY(!TypeUtils::isValid(finalTypeId)))
|
92
|
+
return reportError(DebugUtils::errored(kErrorInvalidArgument));
|
93
|
+
|
94
|
+
uint32_t typeSize = TypeUtils::sizeOf(finalTypeId);
|
95
|
+
Support::FastUInt8 of = 0;
|
96
|
+
|
97
|
+
size_t dataSize = Support::mulOverflow(itemCount, size_t(typeSize), &of);
|
98
|
+
if (ASMJIT_UNLIKELY(of))
|
99
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
100
|
+
|
101
|
+
EmbedDataNode* node;
|
102
|
+
ASMJIT_PROPAGATE(_newNodeT<EmbedDataNode>(&node));
|
103
|
+
|
104
|
+
node->_embed._typeId = typeId;
|
105
|
+
node->_embed._typeSize = uint8_t(typeSize);
|
106
|
+
node->_itemCount = itemCount;
|
107
|
+
node->_repeatCount = repeatCount;
|
108
|
+
|
109
|
+
uint8_t* dstData = node->_inlineData;
|
110
|
+
if (dataSize > EmbedDataNode::kInlineBufferSize) {
|
111
|
+
dstData = static_cast<uint8_t*>(_dataZone.alloc(dataSize, 8));
|
112
|
+
if (ASMJIT_UNLIKELY(!dstData))
|
113
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
114
|
+
node->_externalData = dstData;
|
115
|
+
}
|
116
|
+
|
117
|
+
if (data)
|
118
|
+
memcpy(dstData, data, dataSize);
|
119
|
+
|
120
|
+
*out = node;
|
121
|
+
return kErrorOk;
|
122
|
+
}
|
123
|
+
|
124
|
+
Error BaseBuilder::newConstPoolNode(ConstPoolNode** out) {
|
125
|
+
*out = nullptr;
|
126
|
+
|
127
|
+
ASMJIT_PROPAGATE(_newNodeT<ConstPoolNode>(out));
|
128
|
+
return registerLabelNode(*out);
|
129
|
+
}
|
130
|
+
|
131
|
+
Error BaseBuilder::newCommentNode(CommentNode** out, const char* data, size_t size) {
|
132
|
+
*out = nullptr;
|
133
|
+
|
134
|
+
if (data) {
|
135
|
+
if (size == SIZE_MAX)
|
136
|
+
size = strlen(data);
|
137
|
+
|
138
|
+
if (size > 0) {
|
139
|
+
data = static_cast<char*>(_dataZone.dup(data, size, true));
|
140
|
+
if (ASMJIT_UNLIKELY(!data))
|
141
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
return _newNodeT<CommentNode>(out, data);
|
146
|
+
}
|
147
|
+
|
148
|
+
BaseNode* BaseBuilder::addNode(BaseNode* node) noexcept {
|
149
|
+
ASMJIT_ASSERT(!node->_prev);
|
150
|
+
ASMJIT_ASSERT(!node->_next);
|
151
|
+
ASMJIT_ASSERT(!node->isActive());
|
152
|
+
|
153
|
+
if (!_cursor) {
|
154
|
+
if (!_firstNode) {
|
155
|
+
_firstNode = node;
|
156
|
+
_lastNode = node;
|
157
|
+
}
|
158
|
+
else {
|
159
|
+
node->_next = _firstNode;
|
160
|
+
_firstNode->_prev = node;
|
161
|
+
_firstNode = node;
|
162
|
+
}
|
163
|
+
}
|
164
|
+
else {
|
165
|
+
BaseNode* prev = _cursor;
|
166
|
+
BaseNode* next = _cursor->next();
|
167
|
+
|
168
|
+
node->_prev = prev;
|
169
|
+
node->_next = next;
|
170
|
+
|
171
|
+
prev->_next = node;
|
172
|
+
if (next)
|
173
|
+
next->_prev = node;
|
174
|
+
else
|
175
|
+
_lastNode = node;
|
176
|
+
}
|
177
|
+
|
178
|
+
node->addFlags(NodeFlags::kIsActive);
|
179
|
+
if (node->isSection())
|
180
|
+
_dirtySectionLinks = true;
|
181
|
+
|
182
|
+
_cursor = node;
|
183
|
+
return node;
|
184
|
+
}
|
185
|
+
|
186
|
+
BaseNode* BaseBuilder::addAfter(BaseNode* node, BaseNode* ref) noexcept {
|
187
|
+
ASMJIT_ASSERT(!node->_prev);
|
188
|
+
ASMJIT_ASSERT(!node->_next);
|
189
|
+
|
190
|
+
BaseNode* prev = ref;
|
191
|
+
BaseNode* next = ref->next();
|
192
|
+
|
193
|
+
node->_prev = prev;
|
194
|
+
node->_next = next;
|
195
|
+
|
196
|
+
node->addFlags(NodeFlags::kIsActive);
|
197
|
+
if (node->isSection())
|
198
|
+
_dirtySectionLinks = true;
|
199
|
+
|
200
|
+
prev->_next = node;
|
201
|
+
if (next)
|
202
|
+
next->_prev = node;
|
203
|
+
else
|
204
|
+
_lastNode = node;
|
205
|
+
|
206
|
+
return node;
|
207
|
+
}
|
208
|
+
|
209
|
+
BaseNode* BaseBuilder::addBefore(BaseNode* node, BaseNode* ref) noexcept {
|
210
|
+
ASMJIT_ASSERT(!node->_prev);
|
211
|
+
ASMJIT_ASSERT(!node->_next);
|
212
|
+
ASMJIT_ASSERT(!node->isActive());
|
213
|
+
ASMJIT_ASSERT(ref->isActive());
|
214
|
+
|
215
|
+
BaseNode* prev = ref->prev();
|
216
|
+
BaseNode* next = ref;
|
217
|
+
|
218
|
+
node->_prev = prev;
|
219
|
+
node->_next = next;
|
220
|
+
|
221
|
+
node->addFlags(NodeFlags::kIsActive);
|
222
|
+
if (node->isSection())
|
223
|
+
_dirtySectionLinks = true;
|
224
|
+
|
225
|
+
next->_prev = node;
|
226
|
+
if (prev)
|
227
|
+
prev->_next = node;
|
228
|
+
else
|
229
|
+
_firstNode = node;
|
230
|
+
|
231
|
+
return node;
|
232
|
+
}
|
233
|
+
|
234
|
+
BaseNode* BaseBuilder::removeNode(BaseNode* node) noexcept {
|
235
|
+
if (!node->isActive())
|
236
|
+
return node;
|
237
|
+
|
238
|
+
BaseNode* prev = node->prev();
|
239
|
+
BaseNode* next = node->next();
|
240
|
+
|
241
|
+
if (_firstNode == node)
|
242
|
+
_firstNode = next;
|
243
|
+
else
|
244
|
+
prev->_next = next;
|
245
|
+
|
246
|
+
if (_lastNode == node)
|
247
|
+
_lastNode = prev;
|
248
|
+
else
|
249
|
+
next->_prev = prev;
|
250
|
+
|
251
|
+
node->_prev = nullptr;
|
252
|
+
node->_next = nullptr;
|
253
|
+
node->clearFlags(NodeFlags::kIsActive);
|
254
|
+
if (node->isSection())
|
255
|
+
_dirtySectionLinks = true;
|
256
|
+
|
257
|
+
if (_cursor == node)
|
258
|
+
_cursor = prev;
|
259
|
+
|
260
|
+
return node;
|
261
|
+
}
|
262
|
+
|
263
|
+
void BaseBuilder::removeNodes(BaseNode* first, BaseNode* last) noexcept {
|
264
|
+
if (first == last) {
|
265
|
+
removeNode(first);
|
266
|
+
return;
|
267
|
+
}
|
268
|
+
|
269
|
+
if (!first->isActive())
|
270
|
+
return;
|
271
|
+
|
272
|
+
BaseNode* prev = first->prev();
|
273
|
+
BaseNode* next = last->next();
|
274
|
+
|
275
|
+
if (_firstNode == first)
|
276
|
+
_firstNode = next;
|
277
|
+
else
|
278
|
+
prev->_next = next;
|
279
|
+
|
280
|
+
if (_lastNode == last)
|
281
|
+
_lastNode = prev;
|
282
|
+
else
|
283
|
+
next->_prev = prev;
|
284
|
+
|
285
|
+
BaseNode* node = first;
|
286
|
+
uint32_t didRemoveSection = false;
|
287
|
+
|
288
|
+
for (;;) {
|
289
|
+
next = node->next();
|
290
|
+
ASMJIT_ASSERT(next != nullptr);
|
291
|
+
|
292
|
+
node->_prev = nullptr;
|
293
|
+
node->_next = nullptr;
|
294
|
+
node->clearFlags(NodeFlags::kIsActive);
|
295
|
+
didRemoveSection |= uint32_t(node->isSection());
|
296
|
+
|
297
|
+
if (_cursor == node)
|
298
|
+
_cursor = prev;
|
299
|
+
|
300
|
+
if (node == last)
|
301
|
+
break;
|
302
|
+
node = next;
|
303
|
+
}
|
304
|
+
|
305
|
+
if (didRemoveSection)
|
306
|
+
_dirtySectionLinks = true;
|
307
|
+
}
|
308
|
+
|
309
|
+
BaseNode* BaseBuilder::setCursor(BaseNode* node) noexcept {
|
310
|
+
BaseNode* old = _cursor;
|
311
|
+
_cursor = node;
|
312
|
+
return old;
|
313
|
+
}
|
314
|
+
|
315
|
+
// BaseBuilder - Sections
|
316
|
+
// ======================
|
317
|
+
|
318
|
+
Error BaseBuilder::sectionNodeOf(SectionNode** out, uint32_t sectionId) {
|
319
|
+
*out = nullptr;
|
320
|
+
|
321
|
+
if (ASMJIT_UNLIKELY(!_code))
|
322
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
323
|
+
|
324
|
+
if (ASMJIT_UNLIKELY(!_code->isSectionValid(sectionId)))
|
325
|
+
return reportError(DebugUtils::errored(kErrorInvalidSection));
|
326
|
+
|
327
|
+
if (sectionId >= _sectionNodes.size()) {
|
328
|
+
Error err = _sectionNodes.reserve(&_allocator, sectionId + 1);
|
329
|
+
if (ASMJIT_UNLIKELY(err != kErrorOk))
|
330
|
+
return reportError(err);
|
331
|
+
}
|
332
|
+
|
333
|
+
SectionNode* node = nullptr;
|
334
|
+
if (sectionId < _sectionNodes.size())
|
335
|
+
node = _sectionNodes[sectionId];
|
336
|
+
|
337
|
+
if (!node) {
|
338
|
+
ASMJIT_PROPAGATE(_newNodeT<SectionNode>(&node, sectionId));
|
339
|
+
|
340
|
+
// We have already reserved enough space, this cannot fail now.
|
341
|
+
if (sectionId >= _sectionNodes.size())
|
342
|
+
_sectionNodes.resize(&_allocator, sectionId + 1);
|
343
|
+
|
344
|
+
_sectionNodes[sectionId] = node;
|
345
|
+
}
|
346
|
+
|
347
|
+
*out = node;
|
348
|
+
return kErrorOk;
|
349
|
+
}
|
350
|
+
|
351
|
+
Error BaseBuilder::section(Section* section) {
|
352
|
+
SectionNode* node;
|
353
|
+
ASMJIT_PROPAGATE(sectionNodeOf(&node, section->id()));
|
354
|
+
ASMJIT_ASSUME(node != nullptr);
|
355
|
+
|
356
|
+
if (!node->isActive()) {
|
357
|
+
// Insert the section at the end if it was not part of the code.
|
358
|
+
addAfter(node, lastNode());
|
359
|
+
_cursor = node;
|
360
|
+
}
|
361
|
+
else {
|
362
|
+
// This is a bit tricky. We cache section links to make sure that
|
363
|
+
// switching sections doesn't involve traversal in linked-list unless
|
364
|
+
// the position of the section has changed.
|
365
|
+
if (hasDirtySectionLinks())
|
366
|
+
updateSectionLinks();
|
367
|
+
|
368
|
+
if (node->_nextSection)
|
369
|
+
_cursor = node->_nextSection->_prev;
|
370
|
+
else
|
371
|
+
_cursor = _lastNode;
|
372
|
+
}
|
373
|
+
|
374
|
+
return kErrorOk;
|
375
|
+
}
|
376
|
+
|
377
|
+
void BaseBuilder::updateSectionLinks() noexcept {
|
378
|
+
if (!_dirtySectionLinks)
|
379
|
+
return;
|
380
|
+
|
381
|
+
BaseNode* node_ = _firstNode;
|
382
|
+
SectionNode* currentSection = nullptr;
|
383
|
+
|
384
|
+
while (node_) {
|
385
|
+
if (node_->isSection()) {
|
386
|
+
if (currentSection)
|
387
|
+
currentSection->_nextSection = node_->as<SectionNode>();
|
388
|
+
currentSection = node_->as<SectionNode>();
|
389
|
+
}
|
390
|
+
node_ = node_->next();
|
391
|
+
}
|
392
|
+
|
393
|
+
if (currentSection)
|
394
|
+
currentSection->_nextSection = nullptr;
|
395
|
+
|
396
|
+
_dirtySectionLinks = false;
|
397
|
+
}
|
398
|
+
|
399
|
+
// BaseBuilder - Labels
|
400
|
+
// ====================
|
401
|
+
|
402
|
+
Error BaseBuilder::labelNodeOf(LabelNode** out, uint32_t labelId) {
|
403
|
+
*out = nullptr;
|
404
|
+
|
405
|
+
if (ASMJIT_UNLIKELY(!_code))
|
406
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
407
|
+
|
408
|
+
uint32_t index = labelId;
|
409
|
+
if (ASMJIT_UNLIKELY(index >= _code->labelCount()))
|
410
|
+
return DebugUtils::errored(kErrorInvalidLabel);
|
411
|
+
|
412
|
+
if (index >= _labelNodes.size())
|
413
|
+
ASMJIT_PROPAGATE(_labelNodes.resize(&_allocator, index + 1));
|
414
|
+
|
415
|
+
LabelNode* node = _labelNodes[index];
|
416
|
+
if (!node) {
|
417
|
+
ASMJIT_PROPAGATE(_newNodeT<LabelNode>(&node, labelId));
|
418
|
+
_labelNodes[index] = node;
|
419
|
+
}
|
420
|
+
|
421
|
+
*out = node;
|
422
|
+
return kErrorOk;
|
423
|
+
}
|
424
|
+
|
425
|
+
Error BaseBuilder::registerLabelNode(LabelNode* node) {
|
426
|
+
if (ASMJIT_UNLIKELY(!_code))
|
427
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
428
|
+
|
429
|
+
LabelEntry* le;
|
430
|
+
ASMJIT_PROPAGATE(_code->newLabelEntry(&le));
|
431
|
+
uint32_t labelId = le->id();
|
432
|
+
|
433
|
+
// We just added one label so it must be true.
|
434
|
+
ASMJIT_ASSERT(_labelNodes.size() < labelId + 1);
|
435
|
+
ASMJIT_PROPAGATE(_labelNodes.resize(&_allocator, labelId + 1));
|
436
|
+
|
437
|
+
_labelNodes[labelId] = node;
|
438
|
+
node->_labelId = labelId;
|
439
|
+
|
440
|
+
return kErrorOk;
|
441
|
+
}
|
442
|
+
|
443
|
+
static Error BaseBuilder_newLabelInternal(BaseBuilder* self, uint32_t labelId) {
|
444
|
+
ASMJIT_ASSERT(self->_labelNodes.size() < labelId + 1);
|
445
|
+
|
446
|
+
uint32_t growBy = labelId - self->_labelNodes.size();
|
447
|
+
Error err = self->_labelNodes.willGrow(&self->_allocator, growBy);
|
448
|
+
|
449
|
+
if (ASMJIT_UNLIKELY(err))
|
450
|
+
return self->reportError(err);
|
451
|
+
|
452
|
+
LabelNode* node;
|
453
|
+
ASMJIT_PROPAGATE(self->_newNodeT<LabelNode>(&node, labelId));
|
454
|
+
|
455
|
+
self->_labelNodes.resize(&self->_allocator, labelId + 1);
|
456
|
+
self->_labelNodes[labelId] = node;
|
457
|
+
node->_labelId = labelId;
|
458
|
+
return kErrorOk;
|
459
|
+
}
|
460
|
+
|
461
|
+
Label BaseBuilder::newLabel() {
|
462
|
+
uint32_t labelId = Globals::kInvalidId;
|
463
|
+
LabelEntry* le;
|
464
|
+
|
465
|
+
if (_code &&
|
466
|
+
_code->newLabelEntry(&le) == kErrorOk &&
|
467
|
+
BaseBuilder_newLabelInternal(this, le->id()) == kErrorOk) {
|
468
|
+
labelId = le->id();
|
469
|
+
}
|
470
|
+
|
471
|
+
return Label(labelId);
|
472
|
+
}
|
473
|
+
|
474
|
+
Label BaseBuilder::newNamedLabel(const char* name, size_t nameSize, LabelType type, uint32_t parentId) {
|
475
|
+
uint32_t labelId = Globals::kInvalidId;
|
476
|
+
LabelEntry* le;
|
477
|
+
|
478
|
+
if (_code &&
|
479
|
+
_code->newNamedLabelEntry(&le, name, nameSize, type, parentId) == kErrorOk &&
|
480
|
+
BaseBuilder_newLabelInternal(this, le->id()) == kErrorOk) {
|
481
|
+
labelId = le->id();
|
482
|
+
}
|
483
|
+
|
484
|
+
return Label(labelId);
|
485
|
+
}
|
486
|
+
|
487
|
+
Error BaseBuilder::bind(const Label& label) {
|
488
|
+
LabelNode* node;
|
489
|
+
ASMJIT_PROPAGATE(labelNodeOf(&node, label));
|
490
|
+
|
491
|
+
addNode(node);
|
492
|
+
return kErrorOk;
|
493
|
+
}
|
494
|
+
|
495
|
+
// BaseBuilder - Passes
|
496
|
+
// ====================
|
497
|
+
|
498
|
+
ASMJIT_FAVOR_SIZE Pass* BaseBuilder::passByName(const char* name) const noexcept {
|
499
|
+
for (Pass* pass : _passes)
|
500
|
+
if (strcmp(pass->name(), name) == 0)
|
501
|
+
return pass;
|
502
|
+
return nullptr;
|
503
|
+
}
|
504
|
+
|
505
|
+
ASMJIT_FAVOR_SIZE Error BaseBuilder::addPass(Pass* pass) noexcept {
|
506
|
+
if (ASMJIT_UNLIKELY(!_code))
|
507
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
508
|
+
|
509
|
+
if (ASMJIT_UNLIKELY(pass == nullptr)) {
|
510
|
+
// Since this is directly called by `addPassT()` we treat `null` argument
|
511
|
+
// as out-of-memory condition. Otherwise it would be API misuse.
|
512
|
+
return DebugUtils::errored(kErrorOutOfMemory);
|
513
|
+
}
|
514
|
+
else if (ASMJIT_UNLIKELY(pass->_cb)) {
|
515
|
+
// Kinda weird, but okay...
|
516
|
+
if (pass->_cb == this)
|
517
|
+
return kErrorOk;
|
518
|
+
return DebugUtils::errored(kErrorInvalidState);
|
519
|
+
}
|
520
|
+
|
521
|
+
ASMJIT_PROPAGATE(_passes.append(&_allocator, pass));
|
522
|
+
pass->_cb = this;
|
523
|
+
return kErrorOk;
|
524
|
+
}
|
525
|
+
|
526
|
+
ASMJIT_FAVOR_SIZE Error BaseBuilder::deletePass(Pass* pass) noexcept {
|
527
|
+
if (ASMJIT_UNLIKELY(!_code))
|
528
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
529
|
+
|
530
|
+
if (ASMJIT_UNLIKELY(pass == nullptr))
|
531
|
+
return DebugUtils::errored(kErrorInvalidArgument);
|
532
|
+
|
533
|
+
if (pass->_cb != nullptr) {
|
534
|
+
if (pass->_cb != this)
|
535
|
+
return DebugUtils::errored(kErrorInvalidState);
|
536
|
+
|
537
|
+
uint32_t index = _passes.indexOf(pass);
|
538
|
+
ASMJIT_ASSERT(index != Globals::kNotFound);
|
539
|
+
|
540
|
+
pass->_cb = nullptr;
|
541
|
+
_passes.removeAt(index);
|
542
|
+
}
|
543
|
+
|
544
|
+
pass->~Pass();
|
545
|
+
return kErrorOk;
|
546
|
+
}
|
547
|
+
|
548
|
+
Error BaseBuilder::runPasses() {
|
549
|
+
if (ASMJIT_UNLIKELY(!_code))
|
550
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
551
|
+
|
552
|
+
if (_passes.empty())
|
553
|
+
return kErrorOk;
|
554
|
+
|
555
|
+
ErrorHandler* prev = errorHandler();
|
556
|
+
PostponedErrorHandler postponed;
|
557
|
+
|
558
|
+
Error err = kErrorOk;
|
559
|
+
setErrorHandler(&postponed);
|
560
|
+
|
561
|
+
for (Pass* pass : _passes) {
|
562
|
+
_passZone.reset();
|
563
|
+
err = pass->run(&_passZone, _logger);
|
564
|
+
if (err)
|
565
|
+
break;
|
566
|
+
}
|
567
|
+
_passZone.reset();
|
568
|
+
setErrorHandler(prev);
|
569
|
+
|
570
|
+
if (ASMJIT_UNLIKELY(err))
|
571
|
+
return reportError(err, !postponed._message.empty() ? postponed._message.data() : nullptr);
|
572
|
+
|
573
|
+
return kErrorOk;
|
574
|
+
}
|
575
|
+
|
576
|
+
// BaseBuilder - Emit
|
577
|
+
// ==================
|
578
|
+
|
579
|
+
Error BaseBuilder::_emit(InstId instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_* opExt) {
|
580
|
+
uint32_t opCount = EmitterUtils::opCountFromEmitArgs(o0, o1, o2, opExt);
|
581
|
+
InstOptions options = instOptions() | forcedInstOptions();
|
582
|
+
|
583
|
+
if (Support::test(options, InstOptions::kReserved)) {
|
584
|
+
if (ASMJIT_UNLIKELY(!_code))
|
585
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
586
|
+
|
587
|
+
#ifndef ASMJIT_NO_VALIDATION
|
588
|
+
// Strict validation.
|
589
|
+
if (hasDiagnosticOption(DiagnosticOptions::kValidateIntermediate)) {
|
590
|
+
Operand_ opArray[Globals::kMaxOpCount];
|
591
|
+
EmitterUtils::opArrayFromEmitArgs(opArray, o0, o1, o2, opExt);
|
592
|
+
|
593
|
+
ValidationFlags validationFlags = isCompiler() ? ValidationFlags::kEnableVirtRegs : ValidationFlags::kNone;
|
594
|
+
Error err = _funcs.validate(arch(), BaseInst(instId, options, _extraReg), opArray, opCount, validationFlags);
|
595
|
+
|
596
|
+
if (ASMJIT_UNLIKELY(err)) {
|
597
|
+
resetInstOptions();
|
598
|
+
resetExtraReg();
|
599
|
+
resetInlineComment();
|
600
|
+
return reportError(err);
|
601
|
+
}
|
602
|
+
}
|
603
|
+
#endif
|
604
|
+
|
605
|
+
// Clear instruction options that should never be part of a regular instruction.
|
606
|
+
options &= ~InstOptions::kReserved;
|
607
|
+
}
|
608
|
+
|
609
|
+
uint32_t opCapacity = InstNode::capacityOfOpCount(opCount);
|
610
|
+
ASMJIT_ASSERT(opCapacity >= InstNode::kBaseOpCapacity);
|
611
|
+
|
612
|
+
InstNode* node = _allocator.allocT<InstNode>(InstNode::nodeSizeOfOpCapacity(opCapacity));
|
613
|
+
const char* comment = inlineComment();
|
614
|
+
|
615
|
+
resetInstOptions();
|
616
|
+
resetInlineComment();
|
617
|
+
|
618
|
+
if (ASMJIT_UNLIKELY(!node)) {
|
619
|
+
resetExtraReg();
|
620
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
621
|
+
}
|
622
|
+
|
623
|
+
node = new(node) InstNode(this, instId, options, opCount, opCapacity);
|
624
|
+
node->setExtraReg(extraReg());
|
625
|
+
node->setOp(0, o0);
|
626
|
+
node->setOp(1, o1);
|
627
|
+
node->setOp(2, o2);
|
628
|
+
for (uint32_t i = 3; i < opCount; i++)
|
629
|
+
node->setOp(i, opExt[i - 3]);
|
630
|
+
node->resetOpRange(opCount, opCapacity);
|
631
|
+
|
632
|
+
if (comment)
|
633
|
+
node->setInlineComment(static_cast<char*>(_dataZone.dup(comment, strlen(comment), true)));
|
634
|
+
|
635
|
+
addNode(node);
|
636
|
+
resetExtraReg();
|
637
|
+
return kErrorOk;
|
638
|
+
}
|
639
|
+
|
640
|
+
// BaseBuilder - Align
|
641
|
+
// ===================
|
642
|
+
|
643
|
+
Error BaseBuilder::align(AlignMode alignMode, uint32_t alignment) {
|
644
|
+
if (ASMJIT_UNLIKELY(!_code))
|
645
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
646
|
+
|
647
|
+
AlignNode* node;
|
648
|
+
ASMJIT_PROPAGATE(newAlignNode(&node, alignMode, alignment));
|
649
|
+
ASMJIT_ASSUME(node != nullptr);
|
650
|
+
|
651
|
+
addNode(node);
|
652
|
+
return kErrorOk;
|
653
|
+
}
|
654
|
+
|
655
|
+
// BaseBuilder - Embed
|
656
|
+
// ===================
|
657
|
+
|
658
|
+
Error BaseBuilder::embed(const void* data, size_t dataSize) {
|
659
|
+
if (ASMJIT_UNLIKELY(!_code))
|
660
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
661
|
+
|
662
|
+
EmbedDataNode* node;
|
663
|
+
ASMJIT_PROPAGATE(newEmbedDataNode(&node, TypeId::kUInt8, data, dataSize));
|
664
|
+
ASMJIT_ASSUME(node != nullptr);
|
665
|
+
|
666
|
+
addNode(node);
|
667
|
+
return kErrorOk;
|
668
|
+
}
|
669
|
+
|
670
|
+
Error BaseBuilder::embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t itemRepeat) {
|
671
|
+
if (ASMJIT_UNLIKELY(!_code))
|
672
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
673
|
+
|
674
|
+
EmbedDataNode* node;
|
675
|
+
ASMJIT_PROPAGATE(newEmbedDataNode(&node, typeId, data, itemCount, itemRepeat));
|
676
|
+
ASMJIT_ASSUME(node != nullptr);
|
677
|
+
|
678
|
+
addNode(node);
|
679
|
+
return kErrorOk;
|
680
|
+
}
|
681
|
+
|
682
|
+
Error BaseBuilder::embedConstPool(const Label& label, const ConstPool& pool) {
|
683
|
+
if (ASMJIT_UNLIKELY(!_code))
|
684
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
685
|
+
|
686
|
+
if (!isLabelValid(label))
|
687
|
+
return reportError(DebugUtils::errored(kErrorInvalidLabel));
|
688
|
+
|
689
|
+
ASMJIT_PROPAGATE(align(AlignMode::kData, uint32_t(pool.alignment())));
|
690
|
+
ASMJIT_PROPAGATE(bind(label));
|
691
|
+
|
692
|
+
EmbedDataNode* node;
|
693
|
+
ASMJIT_PROPAGATE(newEmbedDataNode(&node, TypeId::kUInt8, nullptr, pool.size()));
|
694
|
+
ASMJIT_ASSUME(node != nullptr);
|
695
|
+
|
696
|
+
pool.fill(node->data());
|
697
|
+
addNode(node);
|
698
|
+
return kErrorOk;
|
699
|
+
}
|
700
|
+
|
701
|
+
// BaseBuilder - EmbedLabel & EmbedLabelDelta
|
702
|
+
// ==========================================
|
703
|
+
//
|
704
|
+
// If dataSize is zero it means that the size is the same as target register width, however,
|
705
|
+
// if it's provided we really want to validate whether it's within the possible range.
|
706
|
+
|
707
|
+
static inline bool BaseBuilder_checkDataSize(size_t dataSize) noexcept {
|
708
|
+
return !dataSize || (Support::isPowerOf2(dataSize) && dataSize <= 8);
|
709
|
+
}
|
710
|
+
|
711
|
+
Error BaseBuilder::embedLabel(const Label& label, size_t dataSize) {
|
712
|
+
if (ASMJIT_UNLIKELY(!_code))
|
713
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
714
|
+
|
715
|
+
if (!BaseBuilder_checkDataSize(dataSize))
|
716
|
+
return reportError(DebugUtils::errored(kErrorInvalidArgument));
|
717
|
+
|
718
|
+
EmbedLabelNode* node;
|
719
|
+
ASMJIT_PROPAGATE(_newNodeT<EmbedLabelNode>(&node, label.id(), uint32_t(dataSize)));
|
720
|
+
|
721
|
+
addNode(node);
|
722
|
+
return kErrorOk;
|
723
|
+
}
|
724
|
+
|
725
|
+
Error BaseBuilder::embedLabelDelta(const Label& label, const Label& base, size_t dataSize) {
|
726
|
+
if (ASMJIT_UNLIKELY(!_code))
|
727
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
728
|
+
|
729
|
+
if (!BaseBuilder_checkDataSize(dataSize))
|
730
|
+
return reportError(DebugUtils::errored(kErrorInvalidArgument));
|
731
|
+
|
732
|
+
EmbedLabelDeltaNode* node;
|
733
|
+
ASMJIT_PROPAGATE(_newNodeT<EmbedLabelDeltaNode>(&node, label.id(), base.id(), uint32_t(dataSize)));
|
734
|
+
|
735
|
+
addNode(node);
|
736
|
+
return kErrorOk;
|
737
|
+
}
|
738
|
+
|
739
|
+
// BaseBuilder - Comment
|
740
|
+
// =====================
|
741
|
+
|
742
|
+
Error BaseBuilder::comment(const char* data, size_t size) {
|
743
|
+
if (ASMJIT_UNLIKELY(!_code))
|
744
|
+
return DebugUtils::errored(kErrorNotInitialized);
|
745
|
+
|
746
|
+
CommentNode* node;
|
747
|
+
ASMJIT_PROPAGATE(newCommentNode(&node, data, size));
|
748
|
+
ASMJIT_ASSUME(node != nullptr);
|
749
|
+
|
750
|
+
addNode(node);
|
751
|
+
return kErrorOk;
|
752
|
+
}
|
753
|
+
|
754
|
+
// BaseBuilder - SerializeTo
|
755
|
+
// =========================
|
756
|
+
|
757
|
+
Error BaseBuilder::serializeTo(BaseEmitter* dst) {
|
758
|
+
Error err = kErrorOk;
|
759
|
+
BaseNode* node_ = _firstNode;
|
760
|
+
|
761
|
+
Operand_ opArray[Globals::kMaxOpCount];
|
762
|
+
|
763
|
+
do {
|
764
|
+
dst->setInlineComment(node_->inlineComment());
|
765
|
+
|
766
|
+
if (node_->isInst()) {
|
767
|
+
InstNode* node = node_->as<InstNode>();
|
768
|
+
|
769
|
+
// NOTE: Inlined to remove one additional call per instruction.
|
770
|
+
dst->setInstOptions(node->options());
|
771
|
+
dst->setExtraReg(node->extraReg());
|
772
|
+
|
773
|
+
const Operand_* op = node->operands();
|
774
|
+
const Operand_* opExt = EmitterUtils::noExt;
|
775
|
+
|
776
|
+
uint32_t opCount = node->opCount();
|
777
|
+
if (opCount > 3) {
|
778
|
+
uint32_t i = 4;
|
779
|
+
opArray[3] = op[3];
|
780
|
+
|
781
|
+
while (i < opCount) {
|
782
|
+
opArray[i].copyFrom(op[i]);
|
783
|
+
i++;
|
784
|
+
}
|
785
|
+
while (i < Globals::kMaxOpCount) {
|
786
|
+
opArray[i].reset();
|
787
|
+
i++;
|
788
|
+
}
|
789
|
+
opExt = opArray + 3;
|
790
|
+
}
|
791
|
+
|
792
|
+
err = dst->_emit(node->id(), op[0], op[1], op[2], opExt);
|
793
|
+
}
|
794
|
+
else if (node_->isLabel()) {
|
795
|
+
if (node_->isConstPool()) {
|
796
|
+
ConstPoolNode* node = node_->as<ConstPoolNode>();
|
797
|
+
err = dst->embedConstPool(node->label(), node->constPool());
|
798
|
+
}
|
799
|
+
else {
|
800
|
+
LabelNode* node = node_->as<LabelNode>();
|
801
|
+
err = dst->bind(node->label());
|
802
|
+
}
|
803
|
+
}
|
804
|
+
else if (node_->isAlign()) {
|
805
|
+
AlignNode* node = node_->as<AlignNode>();
|
806
|
+
err = dst->align(node->alignMode(), node->alignment());
|
807
|
+
}
|
808
|
+
else if (node_->isEmbedData()) {
|
809
|
+
EmbedDataNode* node = node_->as<EmbedDataNode>();
|
810
|
+
err = dst->embedDataArray(node->typeId(), node->data(), node->itemCount(), node->repeatCount());
|
811
|
+
}
|
812
|
+
else if (node_->isEmbedLabel()) {
|
813
|
+
EmbedLabelNode* node = node_->as<EmbedLabelNode>();
|
814
|
+
err = dst->embedLabel(node->label(), node->dataSize());
|
815
|
+
}
|
816
|
+
else if (node_->isEmbedLabelDelta()) {
|
817
|
+
EmbedLabelDeltaNode* node = node_->as<EmbedLabelDeltaNode>();
|
818
|
+
err = dst->embedLabelDelta(node->label(), node->baseLabel(), node->dataSize());
|
819
|
+
}
|
820
|
+
else if (node_->isSection()) {
|
821
|
+
SectionNode* node = node_->as<SectionNode>();
|
822
|
+
err = dst->section(_code->sectionById(node->id()));
|
823
|
+
}
|
824
|
+
else if (node_->isComment()) {
|
825
|
+
CommentNode* node = node_->as<CommentNode>();
|
826
|
+
err = dst->comment(node->inlineComment());
|
827
|
+
}
|
828
|
+
|
829
|
+
if (err) break;
|
830
|
+
node_ = node_->next();
|
831
|
+
} while (node_);
|
832
|
+
|
833
|
+
return err;
|
834
|
+
}
|
835
|
+
|
836
|
+
// BaseBuilder - Events
|
837
|
+
// ====================
|
838
|
+
|
839
|
+
Error BaseBuilder::onAttach(CodeHolder* code) noexcept {
|
840
|
+
ASMJIT_PROPAGATE(Base::onAttach(code));
|
841
|
+
|
842
|
+
SectionNode* initialSection;
|
843
|
+
Error err = sectionNodeOf(&initialSection, 0);
|
844
|
+
|
845
|
+
if (!err)
|
846
|
+
err = _passes.willGrow(&_allocator, 8);
|
847
|
+
|
848
|
+
if (ASMJIT_UNLIKELY(err)) {
|
849
|
+
onDetach(code);
|
850
|
+
return err;
|
851
|
+
}
|
852
|
+
|
853
|
+
ASMJIT_ASSUME(initialSection != nullptr);
|
854
|
+
_cursor = initialSection;
|
855
|
+
_firstNode = initialSection;
|
856
|
+
_lastNode = initialSection;
|
857
|
+
initialSection->setFlags(NodeFlags::kIsActive);
|
858
|
+
|
859
|
+
return kErrorOk;
|
860
|
+
}
|
861
|
+
|
862
|
+
Error BaseBuilder::onDetach(CodeHolder* code) noexcept {
|
863
|
+
BaseBuilder_deletePasses(this);
|
864
|
+
_sectionNodes.reset();
|
865
|
+
_labelNodes.reset();
|
866
|
+
|
867
|
+
_allocator.reset(&_codeZone);
|
868
|
+
_codeZone.reset();
|
869
|
+
_dataZone.reset();
|
870
|
+
_passZone.reset();
|
871
|
+
|
872
|
+
_nodeFlags = NodeFlags::kNone;
|
873
|
+
_cursor = nullptr;
|
874
|
+
_firstNode = nullptr;
|
875
|
+
_lastNode = nullptr;
|
876
|
+
|
877
|
+
return Base::onDetach(code);
|
878
|
+
}
|
879
|
+
|
880
|
+
// Pass - Construction & Destruction
|
881
|
+
// =================================
|
882
|
+
|
883
|
+
Pass::Pass(const char* name) noexcept
|
884
|
+
: _name(name) {}
|
885
|
+
Pass::~Pass() noexcept {}
|
886
|
+
|
887
|
+
ASMJIT_END_NAMESPACE
|
888
|
+
|
889
|
+
#endif // !ASMJIT_NO_BUILDER
|