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,406 @@
|
|
|
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
|
+
#include "../core/assembler.h"
|
|
8
|
+
#include "../core/codewriter_p.h"
|
|
9
|
+
#include "../core/constpool.h"
|
|
10
|
+
#include "../core/emitterutils_p.h"
|
|
11
|
+
#include "../core/formatter.h"
|
|
12
|
+
#include "../core/logger.h"
|
|
13
|
+
#include "../core/support.h"
|
|
14
|
+
|
|
15
|
+
ASMJIT_BEGIN_NAMESPACE
|
|
16
|
+
|
|
17
|
+
// BaseAssembler - Construction & Destruction
|
|
18
|
+
// ==========================================
|
|
19
|
+
|
|
20
|
+
BaseAssembler::BaseAssembler() noexcept
|
|
21
|
+
: BaseEmitter(EmitterType::kAssembler) {}
|
|
22
|
+
|
|
23
|
+
BaseAssembler::~BaseAssembler() noexcept {}
|
|
24
|
+
|
|
25
|
+
// BaseAssembler - Buffer Management
|
|
26
|
+
// =================================
|
|
27
|
+
|
|
28
|
+
Error BaseAssembler::setOffset(size_t offset) {
|
|
29
|
+
if (ASMJIT_UNLIKELY(!_code))
|
|
30
|
+
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
|
31
|
+
|
|
32
|
+
size_t size = Support::max<size_t>(_section->bufferSize(), this->offset());
|
|
33
|
+
if (ASMJIT_UNLIKELY(offset > size))
|
|
34
|
+
return reportError(DebugUtils::errored(kErrorInvalidArgument));
|
|
35
|
+
|
|
36
|
+
_bufferPtr = _bufferData + offset;
|
|
37
|
+
return kErrorOk;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// BaseAssembler - Section Management
|
|
41
|
+
// ==================================
|
|
42
|
+
|
|
43
|
+
static void BaseAssembler_initSection(BaseAssembler* self, Section* section) noexcept {
|
|
44
|
+
uint8_t* p = section->_buffer._data;
|
|
45
|
+
|
|
46
|
+
self->_section = section;
|
|
47
|
+
self->_bufferData = p;
|
|
48
|
+
self->_bufferPtr = p + section->_buffer._size;
|
|
49
|
+
self->_bufferEnd = p + section->_buffer._capacity;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
Error BaseAssembler::section(Section* section) {
|
|
53
|
+
if (ASMJIT_UNLIKELY(!_code))
|
|
54
|
+
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
|
55
|
+
|
|
56
|
+
if (!_code->isSectionValid(section->id()) || _code->_sections[section->id()] != section)
|
|
57
|
+
return reportError(DebugUtils::errored(kErrorInvalidSection));
|
|
58
|
+
|
|
59
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
60
|
+
if (_logger)
|
|
61
|
+
_logger->logf(".section %s {#%u}\n", section->name(), section->id());
|
|
62
|
+
#endif
|
|
63
|
+
|
|
64
|
+
BaseAssembler_initSection(this, section);
|
|
65
|
+
return kErrorOk;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// BaseAssembler - Label Management
|
|
69
|
+
// ================================
|
|
70
|
+
|
|
71
|
+
Label BaseAssembler::newLabel() {
|
|
72
|
+
uint32_t labelId = Globals::kInvalidId;
|
|
73
|
+
if (ASMJIT_LIKELY(_code)) {
|
|
74
|
+
LabelEntry* le;
|
|
75
|
+
Error err = _code->newLabelEntry(&le);
|
|
76
|
+
if (ASMJIT_UNLIKELY(err))
|
|
77
|
+
reportError(err);
|
|
78
|
+
else
|
|
79
|
+
labelId = le->id();
|
|
80
|
+
}
|
|
81
|
+
return Label(labelId);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
Label BaseAssembler::newNamedLabel(const char* name, size_t nameSize, LabelType type, uint32_t parentId) {
|
|
85
|
+
uint32_t labelId = Globals::kInvalidId;
|
|
86
|
+
if (ASMJIT_LIKELY(_code)) {
|
|
87
|
+
LabelEntry* le;
|
|
88
|
+
Error err = _code->newNamedLabelEntry(&le, name, nameSize, type, parentId);
|
|
89
|
+
if (ASMJIT_UNLIKELY(err))
|
|
90
|
+
reportError(err);
|
|
91
|
+
else
|
|
92
|
+
labelId = le->id();
|
|
93
|
+
}
|
|
94
|
+
return Label(labelId);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
Error BaseAssembler::bind(const Label& label) {
|
|
98
|
+
if (ASMJIT_UNLIKELY(!_code))
|
|
99
|
+
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
|
100
|
+
|
|
101
|
+
Error err = _code->bindLabel(label, _section->id(), offset());
|
|
102
|
+
|
|
103
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
104
|
+
if (_logger)
|
|
105
|
+
EmitterUtils::logLabelBound(this, label);
|
|
106
|
+
#endif
|
|
107
|
+
|
|
108
|
+
resetInlineComment();
|
|
109
|
+
if (err)
|
|
110
|
+
return reportError(err);
|
|
111
|
+
|
|
112
|
+
return kErrorOk;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// BaseAssembler - Embed
|
|
116
|
+
// =====================
|
|
117
|
+
|
|
118
|
+
Error BaseAssembler::embed(const void* data, size_t dataSize) {
|
|
119
|
+
if (ASMJIT_UNLIKELY(!_code))
|
|
120
|
+
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
|
121
|
+
|
|
122
|
+
if (dataSize == 0)
|
|
123
|
+
return kErrorOk;
|
|
124
|
+
|
|
125
|
+
CodeWriter writer(this);
|
|
126
|
+
ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize));
|
|
127
|
+
|
|
128
|
+
writer.emitData(data, dataSize);
|
|
129
|
+
writer.done(this);
|
|
130
|
+
|
|
131
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
132
|
+
if (_logger) {
|
|
133
|
+
StringTmp<512> sb;
|
|
134
|
+
Formatter::formatData(sb, _logger->flags(), arch(), TypeId::kUInt8, data, dataSize, 1);
|
|
135
|
+
sb.append('\n');
|
|
136
|
+
_logger->log(sb);
|
|
137
|
+
}
|
|
138
|
+
#endif
|
|
139
|
+
|
|
140
|
+
return kErrorOk;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
Error BaseAssembler::embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount) {
|
|
144
|
+
uint32_t deabstractDelta = TypeUtils::deabstractDeltaOfSize(registerSize());
|
|
145
|
+
TypeId finalTypeId = TypeUtils::deabstract(typeId, deabstractDelta);
|
|
146
|
+
|
|
147
|
+
if (ASMJIT_UNLIKELY(!TypeUtils::isValid(finalTypeId)))
|
|
148
|
+
return reportError(DebugUtils::errored(kErrorInvalidArgument));
|
|
149
|
+
|
|
150
|
+
if (itemCount == 0 || repeatCount == 0)
|
|
151
|
+
return kErrorOk;
|
|
152
|
+
|
|
153
|
+
uint32_t typeSize = TypeUtils::sizeOf(finalTypeId);
|
|
154
|
+
Support::FastUInt8 of = 0;
|
|
155
|
+
|
|
156
|
+
size_t dataSize = Support::mulOverflow(itemCount, size_t(typeSize), &of);
|
|
157
|
+
size_t totalSize = Support::mulOverflow(dataSize, repeatCount, &of);
|
|
158
|
+
|
|
159
|
+
if (ASMJIT_UNLIKELY(of))
|
|
160
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
|
161
|
+
|
|
162
|
+
CodeWriter writer(this);
|
|
163
|
+
ASMJIT_PROPAGATE(writer.ensureSpace(this, totalSize));
|
|
164
|
+
|
|
165
|
+
for (size_t i = 0; i < repeatCount; i++)
|
|
166
|
+
writer.emitData(data, dataSize);
|
|
167
|
+
|
|
168
|
+
writer.done(this);
|
|
169
|
+
|
|
170
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
171
|
+
if (_logger) {
|
|
172
|
+
StringTmp<512> sb;
|
|
173
|
+
Formatter::formatData(sb, _logger->flags(), arch(), typeId, data, itemCount, repeatCount);
|
|
174
|
+
sb.append('\n');
|
|
175
|
+
_logger->log(sb);
|
|
176
|
+
}
|
|
177
|
+
#endif
|
|
178
|
+
|
|
179
|
+
return kErrorOk;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
183
|
+
static const TypeId dataTypeIdBySize[9] = {
|
|
184
|
+
TypeId::kVoid, // [0] (invalid)
|
|
185
|
+
TypeId::kUInt8, // [1] (uint8_t)
|
|
186
|
+
TypeId::kUInt16, // [2] (uint16_t)
|
|
187
|
+
TypeId::kVoid, // [3] (invalid)
|
|
188
|
+
TypeId::kUInt32, // [4] (uint32_t)
|
|
189
|
+
TypeId::kVoid, // [5] (invalid)
|
|
190
|
+
TypeId::kVoid, // [6] (invalid)
|
|
191
|
+
TypeId::kVoid, // [7] (invalid)
|
|
192
|
+
TypeId::kUInt64 // [8] (uint64_t)
|
|
193
|
+
};
|
|
194
|
+
#endif
|
|
195
|
+
|
|
196
|
+
Error BaseAssembler::embedConstPool(const Label& label, const ConstPool& pool) {
|
|
197
|
+
if (ASMJIT_UNLIKELY(!_code))
|
|
198
|
+
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
|
199
|
+
|
|
200
|
+
if (ASMJIT_UNLIKELY(!isLabelValid(label)))
|
|
201
|
+
return reportError(DebugUtils::errored(kErrorInvalidLabel));
|
|
202
|
+
|
|
203
|
+
ASMJIT_PROPAGATE(align(AlignMode::kData, uint32_t(pool.alignment())));
|
|
204
|
+
ASMJIT_PROPAGATE(bind(label));
|
|
205
|
+
|
|
206
|
+
size_t size = pool.size();
|
|
207
|
+
if (!size)
|
|
208
|
+
return kErrorOk;
|
|
209
|
+
|
|
210
|
+
CodeWriter writer(this);
|
|
211
|
+
ASMJIT_PROPAGATE(writer.ensureSpace(this, size));
|
|
212
|
+
|
|
213
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
214
|
+
uint8_t* data = writer.cursor();
|
|
215
|
+
#endif
|
|
216
|
+
|
|
217
|
+
pool.fill(writer.cursor());
|
|
218
|
+
writer.advance(size);
|
|
219
|
+
writer.done(this);
|
|
220
|
+
|
|
221
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
222
|
+
if (_logger) {
|
|
223
|
+
uint32_t dataSizeLog2 = Support::min<uint32_t>(Support::ctz(pool.minItemSize()), 3);
|
|
224
|
+
uint32_t dataSize = 1 << dataSizeLog2;
|
|
225
|
+
|
|
226
|
+
StringTmp<512> sb;
|
|
227
|
+
Formatter::formatData(sb, _logger->flags(), arch(), dataTypeIdBySize[dataSize], data, size >> dataSizeLog2);
|
|
228
|
+
sb.append('\n');
|
|
229
|
+
_logger->log(sb);
|
|
230
|
+
}
|
|
231
|
+
#endif
|
|
232
|
+
|
|
233
|
+
return kErrorOk;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
Error BaseAssembler::embedLabel(const Label& label, size_t dataSize) {
|
|
237
|
+
if (ASMJIT_UNLIKELY(!_code))
|
|
238
|
+
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
|
239
|
+
|
|
240
|
+
ASMJIT_ASSERT(_code != nullptr);
|
|
241
|
+
RelocEntry* re;
|
|
242
|
+
LabelEntry* le = _code->labelEntry(label);
|
|
243
|
+
|
|
244
|
+
if (ASMJIT_UNLIKELY(!le))
|
|
245
|
+
return reportError(DebugUtils::errored(kErrorInvalidLabel));
|
|
246
|
+
|
|
247
|
+
if (dataSize == 0)
|
|
248
|
+
dataSize = registerSize();
|
|
249
|
+
|
|
250
|
+
if (ASMJIT_UNLIKELY(!Support::isPowerOf2(dataSize) || dataSize > 8))
|
|
251
|
+
return reportError(DebugUtils::errored(kErrorInvalidOperandSize));
|
|
252
|
+
|
|
253
|
+
CodeWriter writer(this);
|
|
254
|
+
ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize));
|
|
255
|
+
|
|
256
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
257
|
+
if (_logger) {
|
|
258
|
+
StringTmp<256> sb;
|
|
259
|
+
sb.append('.');
|
|
260
|
+
Formatter::formatDataType(sb, _logger->flags(), arch(), dataTypeIdBySize[dataSize]);
|
|
261
|
+
sb.append(' ');
|
|
262
|
+
Formatter::formatLabel(sb, FormatFlags::kNone, this, label.id());
|
|
263
|
+
sb.append('\n');
|
|
264
|
+
_logger->log(sb);
|
|
265
|
+
}
|
|
266
|
+
#endif
|
|
267
|
+
|
|
268
|
+
Error err = _code->newRelocEntry(&re, RelocType::kRelToAbs);
|
|
269
|
+
if (ASMJIT_UNLIKELY(err))
|
|
270
|
+
return reportError(err);
|
|
271
|
+
|
|
272
|
+
re->_sourceSectionId = _section->id();
|
|
273
|
+
re->_sourceOffset = offset();
|
|
274
|
+
re->_format.resetToSimpleValue(OffsetType::kUnsignedOffset, dataSize);
|
|
275
|
+
|
|
276
|
+
if (le->isBound()) {
|
|
277
|
+
re->_targetSectionId = le->section()->id();
|
|
278
|
+
re->_payload = le->offset();
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
OffsetFormat of;
|
|
282
|
+
of.resetToSimpleValue(OffsetType::kUnsignedOffset, dataSize);
|
|
283
|
+
|
|
284
|
+
LabelLink* link = _code->newLabelLink(le, _section->id(), offset(), 0, of);
|
|
285
|
+
if (ASMJIT_UNLIKELY(!link))
|
|
286
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
|
287
|
+
|
|
288
|
+
link->relocId = re->id();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Emit dummy DWORD/QWORD depending on the data size.
|
|
292
|
+
writer.emitZeros(dataSize);
|
|
293
|
+
writer.done(this);
|
|
294
|
+
|
|
295
|
+
return kErrorOk;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size_t dataSize) {
|
|
299
|
+
if (ASMJIT_UNLIKELY(!_code))
|
|
300
|
+
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
|
301
|
+
|
|
302
|
+
LabelEntry* labelEntry = _code->labelEntry(label);
|
|
303
|
+
LabelEntry* baseEntry = _code->labelEntry(base);
|
|
304
|
+
|
|
305
|
+
if (ASMJIT_UNLIKELY(!labelEntry || !baseEntry))
|
|
306
|
+
return reportError(DebugUtils::errored(kErrorInvalidLabel));
|
|
307
|
+
|
|
308
|
+
if (dataSize == 0)
|
|
309
|
+
dataSize = registerSize();
|
|
310
|
+
|
|
311
|
+
if (ASMJIT_UNLIKELY(!Support::isPowerOf2(dataSize) || dataSize > 8))
|
|
312
|
+
return reportError(DebugUtils::errored(kErrorInvalidOperandSize));
|
|
313
|
+
|
|
314
|
+
CodeWriter writer(this);
|
|
315
|
+
ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize));
|
|
316
|
+
|
|
317
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
318
|
+
if (_logger) {
|
|
319
|
+
StringTmp<256> sb;
|
|
320
|
+
sb.append('.');
|
|
321
|
+
Formatter::formatDataType(sb, _logger->flags(), arch(), dataTypeIdBySize[dataSize]);
|
|
322
|
+
sb.append(" (");
|
|
323
|
+
Formatter::formatLabel(sb, FormatFlags::kNone, this, label.id());
|
|
324
|
+
sb.append(" - ");
|
|
325
|
+
Formatter::formatLabel(sb, FormatFlags::kNone, this, base.id());
|
|
326
|
+
sb.append(")\n");
|
|
327
|
+
_logger->log(sb);
|
|
328
|
+
}
|
|
329
|
+
#endif
|
|
330
|
+
|
|
331
|
+
// If both labels are bound within the same section it means the delta can be calculated now.
|
|
332
|
+
if (labelEntry->isBound() && baseEntry->isBound() && labelEntry->section() == baseEntry->section()) {
|
|
333
|
+
uint64_t delta = labelEntry->offset() - baseEntry->offset();
|
|
334
|
+
writer.emitValueLE(delta, dataSize);
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
RelocEntry* re;
|
|
338
|
+
Error err = _code->newRelocEntry(&re, RelocType::kExpression);
|
|
339
|
+
if (ASMJIT_UNLIKELY(err))
|
|
340
|
+
return reportError(err);
|
|
341
|
+
|
|
342
|
+
Expression* exp = _code->_zone.newT<Expression>();
|
|
343
|
+
if (ASMJIT_UNLIKELY(!exp))
|
|
344
|
+
return reportError(DebugUtils::errored(kErrorOutOfMemory));
|
|
345
|
+
|
|
346
|
+
exp->reset();
|
|
347
|
+
exp->opType = ExpressionOpType::kSub;
|
|
348
|
+
exp->setValueAsLabel(0, labelEntry);
|
|
349
|
+
exp->setValueAsLabel(1, baseEntry);
|
|
350
|
+
|
|
351
|
+
re->_format.resetToSimpleValue(OffsetType::kSignedOffset, dataSize);
|
|
352
|
+
re->_sourceSectionId = _section->id();
|
|
353
|
+
re->_sourceOffset = offset();
|
|
354
|
+
re->_payload = (uint64_t)(uintptr_t)exp;
|
|
355
|
+
|
|
356
|
+
writer.emitZeros(dataSize);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
writer.done(this);
|
|
360
|
+
return kErrorOk;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// BaseAssembler - Comment
|
|
364
|
+
// =======================
|
|
365
|
+
|
|
366
|
+
Error BaseAssembler::comment(const char* data, size_t size) {
|
|
367
|
+
if (!hasEmitterFlag(EmitterFlags::kLogComments)) {
|
|
368
|
+
if (!hasEmitterFlag(EmitterFlags::kAttached))
|
|
369
|
+
return reportError(DebugUtils::errored(kErrorNotInitialized));
|
|
370
|
+
return kErrorOk;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
#ifndef ASMJIT_NO_LOGGING
|
|
374
|
+
// Logger cannot be NULL if `EmitterFlags::kLogComments` is set.
|
|
375
|
+
ASMJIT_ASSERT(_logger != nullptr);
|
|
376
|
+
|
|
377
|
+
_logger->log(data, size);
|
|
378
|
+
_logger->log("\n", 1);
|
|
379
|
+
return kErrorOk;
|
|
380
|
+
#else
|
|
381
|
+
DebugUtils::unused(data, size);
|
|
382
|
+
return kErrorOk;
|
|
383
|
+
#endif
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// BaseAssembler - Events
|
|
387
|
+
// ======================
|
|
388
|
+
|
|
389
|
+
Error BaseAssembler::onAttach(CodeHolder* code) noexcept {
|
|
390
|
+
ASMJIT_PROPAGATE(Base::onAttach(code));
|
|
391
|
+
|
|
392
|
+
// Attach to the end of the .text section.
|
|
393
|
+
BaseAssembler_initSection(this, code->_sections[0]);
|
|
394
|
+
|
|
395
|
+
return kErrorOk;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
Error BaseAssembler::onDetach(CodeHolder* code) noexcept {
|
|
399
|
+
_section = nullptr;
|
|
400
|
+
_bufferData = nullptr;
|
|
401
|
+
_bufferEnd = nullptr;
|
|
402
|
+
_bufferPtr = nullptr;
|
|
403
|
+
return Base::onDetach(code);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
ASMJIT_END_NAMESPACE
|
|
@@ -0,0 +1,129 @@
|
|
|
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
|
+
#ifndef ASMJIT_CORE_ASSEMBLER_H_INCLUDED
|
|
7
|
+
#define ASMJIT_CORE_ASSEMBLER_H_INCLUDED
|
|
8
|
+
|
|
9
|
+
#include "../core/codeholder.h"
|
|
10
|
+
#include "../core/emitter.h"
|
|
11
|
+
#include "../core/operand.h"
|
|
12
|
+
|
|
13
|
+
ASMJIT_BEGIN_NAMESPACE
|
|
14
|
+
|
|
15
|
+
//! \addtogroup asmjit_assembler
|
|
16
|
+
//! \{
|
|
17
|
+
|
|
18
|
+
//! Base assembler.
|
|
19
|
+
//!
|
|
20
|
+
//! This is a base class that provides interface used by architecture specific
|
|
21
|
+
//! assembler implementations. Assembler doesn't hold any data, instead it's
|
|
22
|
+
//! attached to \ref CodeHolder, which provides all the data that Assembler
|
|
23
|
+
//! needs and which can be altered by it.
|
|
24
|
+
//!
|
|
25
|
+
//! Check out architecture specific assemblers for more details and examples:
|
|
26
|
+
//!
|
|
27
|
+
//! - \ref x86::Assembler - X86/X64 assembler implementation.
|
|
28
|
+
class ASMJIT_VIRTAPI BaseAssembler : public BaseEmitter {
|
|
29
|
+
public:
|
|
30
|
+
ASMJIT_NONCOPYABLE(BaseAssembler)
|
|
31
|
+
typedef BaseEmitter Base;
|
|
32
|
+
|
|
33
|
+
//! Current section where the assembling happens.
|
|
34
|
+
Section* _section = nullptr;
|
|
35
|
+
//! Start of the CodeBuffer of the current section.
|
|
36
|
+
uint8_t* _bufferData = nullptr;
|
|
37
|
+
//! End (first invalid byte) of the current section.
|
|
38
|
+
uint8_t* _bufferEnd = nullptr;
|
|
39
|
+
//! Pointer in the CodeBuffer of the current section.
|
|
40
|
+
uint8_t* _bufferPtr = nullptr;
|
|
41
|
+
|
|
42
|
+
//! \name Construction & Destruction
|
|
43
|
+
//! \{
|
|
44
|
+
|
|
45
|
+
//! Creates a new `BaseAssembler` instance.
|
|
46
|
+
ASMJIT_API BaseAssembler() noexcept;
|
|
47
|
+
//! Destroys the `BaseAssembler` instance.
|
|
48
|
+
ASMJIT_API virtual ~BaseAssembler() noexcept;
|
|
49
|
+
|
|
50
|
+
//! \}
|
|
51
|
+
|
|
52
|
+
//! \name Code-Buffer Management
|
|
53
|
+
//! \{
|
|
54
|
+
|
|
55
|
+
//! Returns the capacity of the current CodeBuffer.
|
|
56
|
+
inline size_t bufferCapacity() const noexcept { return (size_t)(_bufferEnd - _bufferData); }
|
|
57
|
+
//! Returns the number of remaining bytes in the current CodeBuffer.
|
|
58
|
+
inline size_t remainingSpace() const noexcept { return (size_t)(_bufferEnd - _bufferPtr); }
|
|
59
|
+
|
|
60
|
+
//! Returns the current position in the CodeBuffer.
|
|
61
|
+
inline size_t offset() const noexcept { return (size_t)(_bufferPtr - _bufferData); }
|
|
62
|
+
|
|
63
|
+
//! Sets the current position in the CodeBuffer to `offset`.
|
|
64
|
+
//!
|
|
65
|
+
//! \note The `offset` cannot be greater than buffer size even if it's
|
|
66
|
+
//! within the buffer's capacity.
|
|
67
|
+
ASMJIT_API Error setOffset(size_t offset);
|
|
68
|
+
|
|
69
|
+
//! Returns the start of the CodeBuffer in the current section.
|
|
70
|
+
inline uint8_t* bufferData() const noexcept { return _bufferData; }
|
|
71
|
+
//! Returns the end (first invalid byte) in the current section.
|
|
72
|
+
inline uint8_t* bufferEnd() const noexcept { return _bufferEnd; }
|
|
73
|
+
//! Returns the current pointer in the CodeBuffer in the current section.
|
|
74
|
+
inline uint8_t* bufferPtr() const noexcept { return _bufferPtr; }
|
|
75
|
+
|
|
76
|
+
//! \}
|
|
77
|
+
|
|
78
|
+
//! \name Section Management
|
|
79
|
+
//! \{
|
|
80
|
+
|
|
81
|
+
//! Returns the current section.
|
|
82
|
+
inline Section* currentSection() const noexcept { return _section; }
|
|
83
|
+
|
|
84
|
+
ASMJIT_API Error section(Section* section) override;
|
|
85
|
+
|
|
86
|
+
//! \}
|
|
87
|
+
|
|
88
|
+
//! \name Label Management
|
|
89
|
+
//! \{
|
|
90
|
+
|
|
91
|
+
ASMJIT_API Label newLabel() override;
|
|
92
|
+
ASMJIT_API Label newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, LabelType type = LabelType::kGlobal, uint32_t parentId = Globals::kInvalidId) override;
|
|
93
|
+
ASMJIT_API Error bind(const Label& label) override;
|
|
94
|
+
|
|
95
|
+
//! \}
|
|
96
|
+
|
|
97
|
+
//! \name Embed
|
|
98
|
+
//! \{
|
|
99
|
+
|
|
100
|
+
ASMJIT_API Error embed(const void* data, size_t dataSize) override;
|
|
101
|
+
ASMJIT_API Error embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1) override;
|
|
102
|
+
ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override;
|
|
103
|
+
|
|
104
|
+
ASMJIT_API Error embedLabel(const Label& label, size_t dataSize = 0) override;
|
|
105
|
+
ASMJIT_API Error embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0) override;
|
|
106
|
+
|
|
107
|
+
//! \}
|
|
108
|
+
|
|
109
|
+
//! \name Comment
|
|
110
|
+
//! \{
|
|
111
|
+
|
|
112
|
+
ASMJIT_API Error comment(const char* data, size_t size = SIZE_MAX) override;
|
|
113
|
+
|
|
114
|
+
//! \}
|
|
115
|
+
|
|
116
|
+
//! \name Events
|
|
117
|
+
//! \{
|
|
118
|
+
|
|
119
|
+
ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
|
|
120
|
+
ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
|
|
121
|
+
|
|
122
|
+
//! \}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
//! \}
|
|
126
|
+
|
|
127
|
+
ASMJIT_END_NAMESPACE
|
|
128
|
+
|
|
129
|
+
#endif // ASMJIT_CORE_ASSEMBLER_H_INCLUDED
|