diff options
Diffstat (limited to '3rdparty/asmjit/src/asmjit/core/assembler.cpp')
-rw-r--r-- | 3rdparty/asmjit/src/asmjit/core/assembler.cpp | 230 |
1 files changed, 118 insertions, 112 deletions
diff --git a/3rdparty/asmjit/src/asmjit/core/assembler.cpp b/3rdparty/asmjit/src/asmjit/core/assembler.cpp index 2eea9cbae94..d6c87627ec4 100644 --- a/3rdparty/asmjit/src/asmjit/core/assembler.cpp +++ b/3rdparty/asmjit/src/asmjit/core/assembler.cpp @@ -1,29 +1,11 @@ -// AsmJit - Machine code generation for C++ +// This file is part of AsmJit project <https://asmjit.com> // -// * Official AsmJit Home Page: https://asmjit.com -// * Official Github Repository: https://github.com/asmjit/asmjit -// -// Copyright (c) 2008-2020 The AsmJit Authors -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// 3. This notice may not be removed or altered from any source distribution. +// See asmjit.h or LICENSE.md for license and copyright information +// SPDX-License-Identifier: Zlib #include "../core/api-build_p.h" #include "../core/assembler.h" -#include "../core/codebufferwriter_p.h" +#include "../core/codewriter_p.h" #include "../core/constpool.h" #include "../core/emitterutils_p.h" #include "../core/formatter.h" @@ -32,21 +14,16 @@ ASMJIT_BEGIN_NAMESPACE -// ============================================================================ -// [asmjit::BaseAssembler - Construction / Destruction] -// ============================================================================ +// BaseAssembler - Construction & Destruction +// ========================================== BaseAssembler::BaseAssembler() noexcept - : BaseEmitter(kTypeAssembler), - _section(nullptr), - _bufferData(nullptr), - _bufferEnd(nullptr), - _bufferPtr(nullptr) {} + : BaseEmitter(EmitterType::kAssembler) {} + BaseAssembler::~BaseAssembler() noexcept {} -// ============================================================================ -// [asmjit::BaseAssembler - Buffer Management] -// ============================================================================ +// BaseAssembler - Buffer Management +// ================================= Error BaseAssembler::setOffset(size_t offset) { if (ASMJIT_UNLIKELY(!_code)) @@ -60,9 +37,8 @@ Error BaseAssembler::setOffset(size_t offset) { return kErrorOk; } -// ============================================================================ -// [asmjit::BaseAssembler - Section Management] -// ============================================================================ +// BaseAssembler - Section Management +// ================================== static void BaseAssembler_initSection(BaseAssembler* self, Section* section) noexcept { uint8_t* p = section->_buffer._data; @@ -89,9 +65,8 @@ Error BaseAssembler::section(Section* section) { return kErrorOk; } -// ============================================================================ -// [asmjit::BaseAssembler - Label Management] -// ============================================================================ +// BaseAssembler - Label Management +// ================================ Label BaseAssembler::newLabel() { uint32_t labelId = Globals::kInvalidId; @@ -106,7 +81,7 @@ Label BaseAssembler::newLabel() { return Label(labelId); } -Label BaseAssembler::newNamedLabel(const char* name, size_t nameSize, uint32_t type, uint32_t parentId) { +Label BaseAssembler::newNamedLabel(const char* name, size_t nameSize, LabelType type, uint32_t parentId) { uint32_t labelId = Globals::kInvalidId; if (ASMJIT_LIKELY(_code)) { LabelEntry* le; @@ -137,22 +112,8 @@ Error BaseAssembler::bind(const Label& label) { return kErrorOk; } -// ============================================================================ -// [asmjit::BaseAssembler - Embed] -// ============================================================================ - -#ifndef ASMJIT_NO_LOGGING -struct DataSizeByPower { - char str[4]; -}; - -static const DataSizeByPower dataSizeByPowerTable[] = { - { "db" }, - { "dw" }, - { "dd" }, - { "dq" } -}; -#endif +// BaseAssembler - Embed +// ===================== Error BaseAssembler::embed(const void* data, size_t dataSize) { if (ASMJIT_UNLIKELY(!_code)) @@ -161,59 +122,77 @@ Error BaseAssembler::embed(const void* data, size_t dataSize) { if (dataSize == 0) return kErrorOk; - CodeBufferWriter writer(this); + CodeWriter writer(this); ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize)); writer.emitData(data, dataSize); + writer.done(this); #ifndef ASMJIT_NO_LOGGING - if (_logger) - _logger->logBinary(data, dataSize); + if (_logger) { + StringTmp<512> sb; + Formatter::formatData(sb, _logger->flags(), arch(), TypeId::kUInt8, data, dataSize, 1); + sb.append('\n'); + _logger->log(sb); + } #endif - writer.done(this); return kErrorOk; } -Error BaseAssembler::embedDataArray(uint32_t typeId, const void* data, size_t itemCcount, size_t repeatCount) { - uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize()); - uint32_t finalTypeId = Type::deabstract(typeId, deabstractDelta); +Error BaseAssembler::embedDataArray(TypeId typeId, const void* data, size_t itemCount, size_t repeatCount) { + uint32_t deabstractDelta = TypeUtils::deabstractDeltaOfSize(registerSize()); + TypeId finalTypeId = TypeUtils::deabstract(typeId, deabstractDelta); - if (ASMJIT_UNLIKELY(!Type::isValid(finalTypeId))) + if (ASMJIT_UNLIKELY(!TypeUtils::isValid(finalTypeId))) return reportError(DebugUtils::errored(kErrorInvalidArgument)); - if (itemCcount == 0 || repeatCount == 0) + if (itemCount == 0 || repeatCount == 0) return kErrorOk; - uint32_t typeSize = Type::sizeOf(finalTypeId); + uint32_t typeSize = TypeUtils::sizeOf(finalTypeId); Support::FastUInt8 of = 0; - size_t dataSize = Support::mulOverflow(itemCcount, size_t(typeSize), &of); + size_t dataSize = Support::mulOverflow(itemCount, size_t(typeSize), &of); size_t totalSize = Support::mulOverflow(dataSize, repeatCount, &of); if (ASMJIT_UNLIKELY(of)) return reportError(DebugUtils::errored(kErrorOutOfMemory)); - CodeBufferWriter writer(this); + CodeWriter writer(this); ASMJIT_PROPAGATE(writer.ensureSpace(this, totalSize)); -#ifndef ASMJIT_NO_LOGGING - const uint8_t* start = writer.cursor(); -#endif - - for (size_t i = 0; i < repeatCount; i++) { + for (size_t i = 0; i < repeatCount; i++) writer.emitData(data, dataSize); - } + + writer.done(this); #ifndef ASMJIT_NO_LOGGING - if (_logger) - _logger->logBinary(start, totalSize); + if (_logger) { + StringTmp<512> sb; + Formatter::formatData(sb, _logger->flags(), arch(), typeId, data, itemCount, repeatCount); + sb.append('\n'); + _logger->log(sb); + } #endif - writer.done(this); return kErrorOk; } +#ifndef ASMJIT_NO_LOGGING +static const TypeId dataTypeIdBySize[9] = { + TypeId::kVoid, // [0] (invalid) + TypeId::kUInt8, // [1] (uint8_t) + TypeId::kUInt16, // [2] (uint16_t) + TypeId::kVoid, // [3] (invalid) + TypeId::kUInt32, // [4] (uint32_t) + TypeId::kVoid, // [5] (invalid) + TypeId::kVoid, // [6] (invalid) + TypeId::kVoid, // [7] (invalid) + TypeId::kUInt64 // [8] (uint64_t) +}; +#endif + Error BaseAssembler::embedConstPool(const Label& label, const ConstPool& pool) { if (ASMJIT_UNLIKELY(!_code)) return reportError(DebugUtils::errored(kErrorNotInitialized)); @@ -221,27 +200,40 @@ Error BaseAssembler::embedConstPool(const Label& label, const ConstPool& pool) { if (ASMJIT_UNLIKELY(!isLabelValid(label))) return reportError(DebugUtils::errored(kErrorInvalidLabel)); - ASMJIT_PROPAGATE(align(kAlignData, uint32_t(pool.alignment()))); + ASMJIT_PROPAGATE(align(AlignMode::kData, uint32_t(pool.alignment()))); ASMJIT_PROPAGATE(bind(label)); size_t size = pool.size(); - CodeBufferWriter writer(this); - ASMJIT_PROPAGATE(writer.ensureSpace(this, size)); + if (!size) + return kErrorOk; - pool.fill(writer.cursor()); + CodeWriter writer(this); + ASMJIT_PROPAGATE(writer.ensureSpace(this, size)); #ifndef ASMJIT_NO_LOGGING - if (_logger) - _logger->logBinary(writer.cursor(), size); + uint8_t* data = writer.cursor(); #endif + pool.fill(writer.cursor()); writer.advance(size); writer.done(this); +#ifndef ASMJIT_NO_LOGGING + if (_logger) { + uint32_t dataSizeLog2 = Support::min<uint32_t>(Support::ctz(pool.minItemSize()), 3); + uint32_t dataSize = 1 << dataSizeLog2; + + StringTmp<512> sb; + Formatter::formatData(sb, _logger->flags(), arch(), dataTypeIdBySize[dataSize], data, size >> dataSizeLog2); + sb.append('\n'); + _logger->log(sb); + } +#endif + return kErrorOk; } -Error BaseAssembler::embedLabel(const Label& label) { +Error BaseAssembler::embedLabel(const Label& label, size_t dataSize) { if (ASMJIT_UNLIKELY(!_code)) return reportError(DebugUtils::errored(kErrorNotInitialized)); @@ -252,37 +244,47 @@ Error BaseAssembler::embedLabel(const Label& label) { if (ASMJIT_UNLIKELY(!le)) return reportError(DebugUtils::errored(kErrorInvalidLabel)); - uint32_t dataSize = registerSize(); - ASMJIT_ASSERT(dataSize <= 8); + if (dataSize == 0) + dataSize = registerSize(); - CodeBufferWriter writer(this); + if (ASMJIT_UNLIKELY(!Support::isPowerOf2(dataSize) || dataSize > 8)) + return reportError(DebugUtils::errored(kErrorInvalidOperandSize)); + + CodeWriter writer(this); ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize)); #ifndef ASMJIT_NO_LOGGING if (_logger) { StringTmp<256> sb; - sb.appendFormat("%s ", dataSizeByPowerTable[Support::ctz(dataSize)].str); - Formatter::formatLabel(sb, 0, this, label.id()); + sb.append('.'); + Formatter::formatDataType(sb, _logger->flags(), arch(), dataTypeIdBySize[dataSize]); + sb.append(' '); + Formatter::formatLabel(sb, FormatFlags::kNone, this, label.id()); sb.append('\n'); _logger->log(sb); } #endif - Error err = _code->newRelocEntry(&re, RelocEntry::kTypeRelToAbs, dataSize); + Error err = _code->newRelocEntry(&re, RelocType::kRelToAbs); if (ASMJIT_UNLIKELY(err)) return reportError(err); re->_sourceSectionId = _section->id(); re->_sourceOffset = offset(); + re->_format.resetToSimpleValue(OffsetType::kUnsignedOffset, dataSize); if (le->isBound()) { re->_targetSectionId = le->section()->id(); re->_payload = le->offset(); } else { - LabelLink* link = _code->newLabelLink(le, _section->id(), offset(), 0); + OffsetFormat of; + of.resetToSimpleValue(OffsetType::kUnsignedOffset, dataSize); + + LabelLink* link = _code->newLabelLink(le, _section->id(), offset(), 0, of); if (ASMJIT_UNLIKELY(!link)) return reportError(DebugUtils::errored(kErrorOutOfMemory)); + link->relocId = re->id(); } @@ -309,16 +311,18 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size if (ASMJIT_UNLIKELY(!Support::isPowerOf2(dataSize) || dataSize > 8)) return reportError(DebugUtils::errored(kErrorInvalidOperandSize)); - CodeBufferWriter writer(this); + CodeWriter writer(this); ASMJIT_PROPAGATE(writer.ensureSpace(this, dataSize)); #ifndef ASMJIT_NO_LOGGING if (_logger) { StringTmp<256> sb; - sb.appendFormat(".%s (", dataSizeByPowerTable[Support::ctz(dataSize)].str); - Formatter::formatLabel(sb, 0, this, label.id()); + sb.append('.'); + Formatter::formatDataType(sb, _logger->flags(), arch(), dataTypeIdBySize[dataSize]); + sb.append(" ("); + Formatter::formatLabel(sb, FormatFlags::kNone, this, label.id()); sb.append(" - "); - Formatter::formatLabel(sb, 0, this, base.id()); + Formatter::formatLabel(sb, FormatFlags::kNone, this, base.id()); sb.append(")\n"); _logger->log(sb); } @@ -331,7 +335,7 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size } else { RelocEntry* re; - Error err = _code->newRelocEntry(&re, RelocEntry::kTypeExpression, uint32_t(dataSize)); + Error err = _code->newRelocEntry(&re, RelocType::kExpression); if (ASMJIT_UNLIKELY(err)) return reportError(err); @@ -340,10 +344,11 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size return reportError(DebugUtils::errored(kErrorOutOfMemory)); exp->reset(); - exp->opType = Expression::kOpSub; + exp->opType = ExpressionOpType::kSub; exp->setValueAsLabel(0, labelEntry); exp->setValueAsLabel(1, baseEntry); + re->_format.resetToSimpleValue(OffsetType::kSignedOffset, dataSize); re->_sourceSectionId = _section->id(); re->_sourceOffset = offset(); re->_payload = (uint64_t)(uintptr_t)exp; @@ -355,30 +360,31 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size return kErrorOk; } -// ============================================================================ -// [asmjit::BaseAssembler - Comment] -// ============================================================================ +// BaseAssembler - Comment +// ======================= Error BaseAssembler::comment(const char* data, size_t size) { - if (ASMJIT_UNLIKELY(!_code)) - return reportError(DebugUtils::errored(kErrorNotInitialized)); - -#ifndef ASMJIT_NO_LOGGING - if (_logger) { - _logger->log(data, size); - _logger->log("\n", 1); + if (!hasEmitterFlag(EmitterFlags::kLogComments)) { + if (!hasEmitterFlag(EmitterFlags::kAttached)) + return reportError(DebugUtils::errored(kErrorNotInitialized)); return kErrorOk; } + +#ifndef ASMJIT_NO_LOGGING + // Logger cannot be NULL if `EmitterFlags::kLogComments` is set. + ASMJIT_ASSERT(_logger != nullptr); + + _logger->log(data, size); + _logger->log("\n", 1); + return kErrorOk; #else DebugUtils::unused(data, size); -#endif - return kErrorOk; +#endif } -// ============================================================================ -// [asmjit::BaseAssembler - Events] -// ============================================================================ +// BaseAssembler - Events +// ====================== Error BaseAssembler::onAttach(CodeHolder* code) noexcept { ASMJIT_PROPAGATE(Base::onAttach(code)); |