Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkobalicek <kobalicek.petr@gmail.com>2021-06-27 01:08:17 +0300
committerkobalicek <kobalicek.petr@gmail.com>2021-06-27 01:39:53 +0300
commitd02235b83434943b52a6d7c57118205c5082de08 (patch)
treeb53d49ed4fa09cd7d3cd6e8226a60fc6a9aa0c37
parent0a709c7a28ba83c6d4e68e528bd39fd0ce734262 (diff)
Refactored naming of data types in formatted text, which is now part of architecture traits
-rw-r--r--src/asmjit/core/archtraits.cpp43
-rw-r--r--src/asmjit/core/archtraits.h51
-rw-r--r--src/asmjit/core/assembler.cpp90
-rw-r--r--src/asmjit/core/assembler.h2
-rw-r--r--src/asmjit/core/constpool.cpp19
-rw-r--r--src/asmjit/core/constpool.h4
-rw-r--r--src/asmjit/core/formatter.cpp112
-rw-r--r--src/asmjit/core/formatter.h14
-rw-r--r--src/asmjit/core/logger.cpp22
-rw-r--r--src/asmjit/core/logger.h3
-rw-r--r--src/asmjit/core/string.cpp45
-rw-r--r--src/asmjit/x86/x86archtraits_p.h72
12 files changed, 357 insertions, 120 deletions
diff --git a/src/asmjit/core/archtraits.cpp b/src/asmjit/core/archtraits.cpp
index ad983e7..6c50bb1 100644
--- a/src/asmjit/core/archtraits.cpp
+++ b/src/asmjit/core/archtraits.cpp
@@ -40,18 +40,37 @@ ASMJIT_BEGIN_NAMESPACE
// ============================================================================
static const constexpr ArchTraits noArchTraits = {
- 0xFF, // SP.
- 0xFF, // FP.
- 0xFF, // LR.
- 0xFF, // PC.
- { 0, 0, 0 }, // Reserved.
- 0, // HW stack alignment.
- 0, // Min stack offset.
- 0, // Max stack offset.
- { 0, 0, 0, 0}, // ISA features [Gp, Vec, Other0, Other1].
- { { 0 } }, // RegTypeToSignature.
- { 0 }, // RegTypeToTypeId.
- { 0 } // TypeIdToRegType.
+ // SP/FP/LR/PC.
+ 0xFF, 0xFF, 0xFF, 0xFF,
+
+ // Reserved,
+ { 0, 0, 0 },
+
+ // HW stack alignment.
+ 0,
+
+ // Min/Max stack offset.
+ 0, 0,
+
+ // ISA features [Gp, Vec, Other0, Other1].
+ { 0, 0, 0, 0},
+
+ // RegTypeToSignature.
+ { { 0 } },
+
+ // RegTypeToTypeId.
+ { 0 },
+
+ // TypeIdToRegType.
+ { 0 },
+
+ // Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities.
+ {
+ ISAWordNameId::kByte,
+ ISAWordNameId::kHalf,
+ ISAWordNameId::kWord,
+ ISAWordNameId::kQuad
+ }
};
ASMJIT_VARAPI const ArchTraits _archTraits[Environment::kArchCount] = {
diff --git a/src/asmjit/core/archtraits.h b/src/asmjit/core/archtraits.h
index 5af6c7e..43ef10f 100644
--- a/src/asmjit/core/archtraits.h
+++ b/src/asmjit/core/archtraits.h
@@ -33,6 +33,41 @@ ASMJIT_BEGIN_NAMESPACE
//! \addtogroup asmjit_core
//! \{
+//! Identifier used to represent names of different data types across architectures.
+enum class ISAWordNameId : uint8_t {
+ //! Describes 'db' (X86/X86_64 convention, always 8-bit quantity).
+ kDB = 0,
+ //! Describes 'dw' (X86/X86_64 convention, always 16-bit word).
+ kDW,
+ //! Describes 'dd' (X86/X86_64 convention, always 32-bit word).
+ kDD,
+ //! Describes 'dq' (X86/X86_64 convention, always 64-bit word).
+ kDQ,
+ //! Describes 'byte' (always 8-bit quantity).
+ kByte,
+ //! Describes 'half' (most likely 16-bit word).
+ kHalf,
+ //! Describes 'word' (either 16-bit or 32-bit word).
+ kWord,
+ //! Describes 'hword' (most likely 16-bit word).
+ kHWord,
+ //! Describes 'dword' (either 32-bit or 64-bit word).
+ kDWord,
+ //! Describes 'qword' (64-bit word).
+ kQWord,
+ //! Describes 'xword' (64-bit word).
+ kXWord,
+ //! Describes 'short' (always 16-bit word).
+ kShort,
+ //! Describes 'long' (most likely 32-bit word).
+ kLong,
+ //! Describes 'quad' (64-bit word).
+ kQuad,
+
+ //! Maximum value.
+ kMaxValue = kQuad
+};
+
// ============================================================================
// [asmjit::ArchTraits]
// ============================================================================
@@ -60,6 +95,7 @@ struct ArchTraits {
uint8_t _reserved[3];
//! Hardware stack alignment requirement.
uint8_t _hwStackAlignment;
+
//! Minimum addressable offset on stack guaranteed for all instructions.
uint32_t _minStackOffset;
//! Maximum addressable offset on stack depending on specific instruction.
@@ -76,6 +112,9 @@ struct ArchTraits {
//! Maps base TypeId values (from TypeId::_kIdBaseStart) to register types, see \ref Type::Id.
uint8_t _typeIdToRegType[32];
+ //! Word name identifiers of 8-bit, 16-bit, 32-biit, and 64-bit quantities that appear in formatted text.
+ ISAWordNameId _isaWordNameIdTable[4];
+
//! Resets all members to zeros.
inline void reset() noexcept { memset(this, 0, sizeof(*this)); }
@@ -141,6 +180,18 @@ struct ArchTraits {
return _regTypeToTypeId[rType];
}
+ //! Returns a table of ISA word names that appear in formatted text. Word names are ISA dependent.
+ //!
+ //! The index of this table is log2 of the size:
+ //! - [0] 8-bits
+ //! - [1] 16-bits
+ //! - [2] 32-bits
+ //! - [3] 64-bits
+ inline const ISAWordNameId* isaWordNameIdTable() const noexcept { return _isaWordNameIdTable; }
+
+ //! Returns an ISA word name identifier of the given `index`, see \ref isaWordNameIdTable() for more details.
+ inline ISAWordNameId isaWordNameId(uint32_t index) const noexcept { return _isaWordNameIdTable[index]; }
+
//! \}
//! \name Statics
diff --git a/src/asmjit/core/assembler.cpp b/src/asmjit/core/assembler.cpp
index c0cbf0f..6f9fe00 100644
--- a/src/asmjit/core/assembler.cpp
+++ b/src/asmjit/core/assembler.cpp
@@ -138,19 +138,6 @@ Error BaseAssembler::bind(const Label& label) {
// [asmjit::BaseAssembler - Embed]
// ============================================================================
-#ifndef ASMJIT_NO_LOGGING
-struct DataSizeByPower {
- char str[4];
-};
-
-static const DataSizeByPower dataSizeByPowerTable[] = {
- { "db" },
- { "dw" },
- { "dd" },
- { "dq" }
-};
-#endif
-
Error BaseAssembler::embed(const void* data, size_t dataSize) {
if (ASMJIT_UNLIKELY(!_code))
return reportError(DebugUtils::errored(kErrorNotInitialized));
@@ -162,30 +149,34 @@ Error BaseAssembler::embed(const void* data, size_t dataSize) {
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(), Type::kIdU8, 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) {
+Error BaseAssembler::embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount) {
uint32_t deabstractDelta = Type::deabstractDeltaOfSize(registerSize());
uint32_t finalTypeId = Type::deabstract(typeId, deabstractDelta);
if (ASMJIT_UNLIKELY(!Type::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);
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))
@@ -194,23 +185,37 @@ Error BaseAssembler::embedDataArray(uint32_t typeId, const void* data, size_t it
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 uint8_t dataTypeIdBySize[9] = {
+ Type::kIdVoid, // [0] (invalid)
+ Type::kIdU8, // [1] (uint8_t)
+ Type::kIdU16, // [2] (uint16_t)
+ Type::kIdVoid, // [3] (invalid)
+ Type::kIdU32, // [4] (uint32_t)
+ Type::kIdVoid, // [5] (invalid)
+ Type::kIdVoid, // [6] (invalid)
+ Type::kIdVoid, // [7] (invalid)
+ Type::kIdU64 // [8] (uint64_t)
+};
+#endif
+
Error BaseAssembler::embedConstPool(const Label& label, const ConstPool& pool) {
if (ASMJIT_UNLIKELY(!_code))
return reportError(DebugUtils::errored(kErrorNotInitialized));
@@ -222,19 +227,32 @@ Error BaseAssembler::embedConstPool(const Label& label, const ConstPool& pool) {
ASMJIT_PROPAGATE(bind(label));
size_t size = pool.size();
+ if (!size)
+ return kErrorOk;
+
CodeWriter writer(this);
ASMJIT_PROPAGATE(writer.ensureSpace(this, size));
- pool.fill(writer.cursor());
-
#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;
}
@@ -261,7 +279,9 @@ Error BaseAssembler::embedLabel(const Label& label, size_t dataSize) {
#ifndef ASMJIT_NO_LOGGING
if (_logger) {
StringTmp<256> sb;
- sb.appendFormat("%s ", dataSizeByPowerTable[Support::ctz(dataSize)].str);
+ sb.append('.');
+ Formatter::formatDataType(sb, _logger->flags(), arch(), dataTypeIdBySize[dataSize]);
+ sb.append(' ');
Formatter::formatLabel(sb, 0, this, label.id());
sb.append('\n');
_logger->log(sb);
@@ -320,7 +340,9 @@ Error BaseAssembler::embedLabelDelta(const Label& label, const Label& base, size
#ifndef ASMJIT_NO_LOGGING
if (_logger) {
StringTmp<256> sb;
- sb.appendFormat(".%s (", dataSizeByPowerTable[Support::ctz(dataSize)].str);
+ sb.append('.');
+ Formatter::formatDataType(sb, _logger->flags(), arch(), dataTypeIdBySize[dataSize]);
+ sb.append(" (");
Formatter::formatLabel(sb, 0, this, label.id());
sb.append(" - ");
Formatter::formatLabel(sb, 0, this, base.id());
diff --git a/src/asmjit/core/assembler.h b/src/asmjit/core/assembler.h
index 6e38bc5..c0da819 100644
--- a/src/asmjit/core/assembler.h
+++ b/src/asmjit/core/assembler.h
@@ -121,7 +121,7 @@ public:
//! \{
ASMJIT_API Error embed(const void* data, size_t dataSize) override;
- ASMJIT_API Error embedDataArray(uint32_t typeId, const void* data, size_t itemCcount, size_t repeatCount = 1) override;
+ ASMJIT_API Error embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1) override;
ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override;
ASMJIT_API Error embedLabel(const Label& label, size_t dataSize = 0) override;
diff --git a/src/asmjit/core/constpool.cpp b/src/asmjit/core/constpool.cpp
index 65c995b..84d7cd3 100644
--- a/src/asmjit/core/constpool.cpp
+++ b/src/asmjit/core/constpool.cpp
@@ -52,6 +52,7 @@ void ConstPool::reset(Zone* zone) noexcept {
_gapPool = nullptr;
_size = 0;
_alignment = 0;
+ _minItemSize = 0;
}
// ============================================================================
@@ -186,7 +187,8 @@ Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept
// Add the initial node to the right index.
node = ConstPool::Tree::_newNode(_zone, data, size, offset, false);
- if (!node) return DebugUtils::errored(kErrorOutOfMemory);
+ if (ASMJIT_UNLIKELY(!node))
+ return DebugUtils::errored(kErrorOutOfMemory);
_tree[treeIndex].insert(node);
_alignment = Support::max<size_t>(_alignment, size);
@@ -197,23 +199,30 @@ Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept
// We stop at size 4, it probably doesn't make sense to split constants down
// to 1 byte.
size_t pCount = 1;
- while (size > 4) {
- size >>= 1;
+ size_t smallerSize = size;
+
+ while (smallerSize > 4) {
pCount <<= 1;
+ smallerSize >>= 1;
ASMJIT_ASSERT(treeIndex != 0);
treeIndex--;
const uint8_t* pData = static_cast<const uint8_t*>(data);
- for (size_t i = 0; i < pCount; i++, pData += size) {
+ for (size_t i = 0; i < pCount; i++, pData += smallerSize) {
node = _tree[treeIndex].get(pData);
if (node) continue;
- node = ConstPool::Tree::_newNode(_zone, pData, size, offset + (i * size), true);
+ node = ConstPool::Tree::_newNode(_zone, pData, smallerSize, offset + (i * smallerSize), true);
_tree[treeIndex].insert(node);
}
}
+ if (_minItemSize == 0)
+ _minItemSize = size;
+ else
+ _minItemSize = Support::min(_minItemSize, size);
+
return kErrorOk;
}
diff --git a/src/asmjit/core/constpool.h b/src/asmjit/core/constpool.h
index d9ac589..fc0e0bc 100644
--- a/src/asmjit/core/constpool.h
+++ b/src/asmjit/core/constpool.h
@@ -206,6 +206,8 @@ public:
size_t _size;
//! Required pool alignment.
size_t _alignment;
+ //! Minimum item size in the pool.
+ size_t _minItemSize;
//! \name Construction & Destruction
//! \{
@@ -226,6 +228,8 @@ public:
inline size_t size() const noexcept { return _size; }
//! Returns minimum alignment.
inline size_t alignment() const noexcept { return _alignment; }
+ //! Returns the minimum size of all items added to the constant pool.
+ inline size_t minItemSize() const noexcept { return _minItemSize; }
//! \}
diff --git a/src/asmjit/core/formatter.cpp b/src/asmjit/core/formatter.cpp
index c757c5a..124eebf 100644
--- a/src/asmjit/core/formatter.cpp
+++ b/src/asmjit/core/formatter.cpp
@@ -24,6 +24,7 @@
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_LOGGING
+#include "../core/archtraits.h"
#include "../core/builder.h"
#include "../core/codeholder.h"
#include "../core/compiler.h"
@@ -53,6 +54,24 @@ class VirtReg;
namespace Formatter {
+static const char wordNameTable[][8] = {
+ "db",
+ "dw",
+ "dd",
+ "dq",
+ "byte",
+ "half",
+ "word",
+ "hword",
+ "dword",
+ "qword",
+ "xword",
+ "short",
+ "long",
+ "quad"
+};
+
+
Error formatTypeId(String& sb, uint32_t typeId) noexcept {
if (typeId == Type::kIdVoid)
return sb.append("void");
@@ -188,6 +207,84 @@ Error formatOperand(
return kErrorInvalidArch;
}
+ASMJIT_API Error formatDataType(
+ String& sb,
+ uint32_t formatFlags,
+ uint32_t arch,
+ uint32_t typeId) noexcept
+{
+ DebugUtils::unused(formatFlags);
+
+ if (ASMJIT_UNLIKELY(arch >= Environment::kArchCount))
+ return DebugUtils::errored(kErrorInvalidArch);
+
+ uint32_t typeSize = Type::sizeOf(typeId);
+ if (typeSize == 0 || typeSize > 8)
+ return DebugUtils::errored(kErrorInvalidState);
+
+ uint32_t typeSizeLog2 = Support::ctz(typeSize);
+ return sb.append(wordNameTable[size_t(_archTraits[arch].isaWordNameId(typeSizeLog2))]);
+}
+
+static Error formatDataHelper(String& sb, const char* typeName, uint32_t typeSize, const uint8_t* data, size_t itemCount) noexcept {
+ sb.append('.');
+ sb.append(typeName);
+ sb.append(' ');
+
+ for (size_t i = 0; i < itemCount; i++) {
+ uint64_t v;
+
+ if (i != 0)
+ ASMJIT_PROPAGATE(sb.append(", ", 2));
+
+ switch (typeSize) {
+ case 1: v = data[0]; break;
+ case 2: v = Support::readU16u(data); break;
+ case 4: v = Support::readU32u(data); break;
+ case 8: v = Support::readU64u(data); break;
+ }
+
+ ASMJIT_PROPAGATE(sb.appendUInt(v, 16, typeSize * 2, String::kFormatAlternate));
+ data += typeSize;
+ }
+
+ return kErrorOk;
+}
+
+Error formatData(
+ String& sb,
+ uint32_t formatFlags,
+ uint32_t arch,
+ uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount) noexcept
+{
+ DebugUtils::unused(formatFlags);
+
+ if (ASMJIT_UNLIKELY(arch >= Environment::kArchCount))
+ return DebugUtils::errored(kErrorInvalidArch);
+
+ uint32_t typeSize = Type::sizeOf(typeId);
+ if (typeSize == 0)
+ return DebugUtils::errored(kErrorInvalidState);
+
+ if (!Support::isPowerOf2(typeSize)) {
+ itemCount *= typeSize;
+ typeSize = 1;
+ }
+
+ while (typeSize > 8u) {
+ typeSize >>= 1;
+ itemCount <<= 1;
+ }
+
+ uint32_t typeSizeLog2 = Support::ctz(typeSize);
+ const char* wordName = wordNameTable[size_t(_archTraits[arch].isaWordNameId(typeSizeLog2))];
+
+ if (repeatCount > 1)
+ ASMJIT_PROPAGATE(sb.appendFormat(".repeat %zu ", repeatCount));
+
+ return formatDataHelper(sb, wordName, typeSize, static_cast<const uint8_t*>(data), itemCount);
+}
+
Error formatInstruction(
String& sb,
uint32_t formatFlags,
@@ -345,7 +442,7 @@ Error formatNode(
case BaseNode::kNodeAlign: {
const AlignNode* alignNode = node->as<AlignNode>();
ASMJIT_PROPAGATE(
- sb.appendFormat("align %u (%s)",
+ sb.appendFormat(".align %u (%s)",
alignNode->alignment(),
alignNode->alignMode() == kAlignCode ? "code" : "data"));
break;
@@ -353,10 +450,9 @@ Error formatNode(
case BaseNode::kNodeEmbedData: {
const EmbedDataNode* embedNode = node->as<EmbedDataNode>();
- ASMJIT_PROPAGATE(sb.append("embed "));
- if (embedNode->repeatCount() != 1)
- ASMJIT_PROPAGATE(sb.appendFormat("[repeat=%zu] ", size_t(embedNode->repeatCount())));
- ASMJIT_PROPAGATE(sb.appendFormat("%u bytes", embedNode->dataSize()));
+ ASMJIT_PROPAGATE(sb.append('.'));
+ ASMJIT_PROPAGATE(formatDataType(sb, formatFlags, builder->arch(), embedNode->typeId()));
+ ASMJIT_PROPAGATE(sb.appendFormat(" {Count=%zu Repeat=%zu TotalSize=%zu}", embedNode->itemCount(), embedNode->repeatCount(), embedNode->dataSize()));
break;
}
@@ -377,6 +473,12 @@ Error formatNode(
break;
}
+ case BaseNode::kNodeConstPool: {
+ const ConstPoolNode* constPoolNode = node->as<ConstPoolNode>();
+ ASMJIT_PROPAGATE(sb.appendFormat("[ConstPool Size=%zu Alignment=%zu]", constPoolNode->size(), constPoolNode->alignment()));
+ break;
+ };
+
case BaseNode::kNodeComment: {
const CommentNode* commentNode = node->as<CommentNode>();
ASMJIT_PROPAGATE(sb.appendFormat("; %s", commentNode->inlineComment()));
diff --git a/src/asmjit/core/formatter.h b/src/asmjit/core/formatter.h
index 14934ba..513d764 100644
--- a/src/asmjit/core/formatter.h
+++ b/src/asmjit/core/formatter.h
@@ -203,6 +203,20 @@ ASMJIT_API Error formatOperand(
uint32_t arch,
const Operand_& op) noexcept;
+//! Appends a formatted data-type to the output string `sb`.
+ASMJIT_API Error formatDataType(
+ String& sb,
+ uint32_t formatFlags,
+ uint32_t arch,
+ uint32_t typeId) noexcept;
+
+//! Appends a formatted data to the output string `sb`.
+ASMJIT_API Error formatData(
+ String& sb,
+ uint32_t formatFlags,
+ uint32_t arch,
+ uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1) noexcept;
+
//! Appends a formatted instruction to the output string `sb`.
//!
//! \note Emitter is optional, but it's required to format named labels and
diff --git a/src/asmjit/core/logger.cpp b/src/asmjit/core/logger.cpp
index 22e0b9a..90b17e3 100644
--- a/src/asmjit/core/logger.cpp
+++ b/src/asmjit/core/logger.cpp
@@ -59,28 +59,6 @@ Error Logger::logv(const char* fmt, va_list ap) noexcept {
return log(sb);
}
-Error Logger::logBinary(const void* data, size_t size) noexcept {
- static const char prefix[] = "db ";
-
- StringTmp<256> sb;
- sb.append(prefix, ASMJIT_ARRAY_SIZE(prefix) - 1);
-
- size_t i = size;
- const uint8_t* s = static_cast<const uint8_t*>(data);
-
- while (i) {
- uint32_t n = uint32_t(Support::min<size_t>(i, 16));
- sb.truncate(ASMJIT_ARRAY_SIZE(prefix) - 1);
- sb.appendHex(s, n);
- sb.append('\n');
- ASMJIT_PROPAGATE(log(sb));
- s += n;
- i -= n;
- }
-
- return kErrorOk;
-}
-
// ============================================================================
// [asmjit::FileLogger - Construction / Destruction]
// ============================================================================
diff --git a/src/asmjit/core/logger.h b/src/asmjit/core/logger.h
index 2840869..ddc1cfc 100644
--- a/src/asmjit/core/logger.h
+++ b/src/asmjit/core/logger.h
@@ -119,9 +119,6 @@ public:
//! string to \ref _log().
ASMJIT_API Error logv(const char* fmt, va_list ap) noexcept;
- //! Logs binary `data` of the given `size`.
- ASMJIT_API Error logBinary(const void* data, size_t size) noexcept;
-
//! \}
};
diff --git a/src/asmjit/core/string.cpp b/src/asmjit/core/string.cpp
index e059884..8cebfcc 100644
--- a/src/asmjit/core/string.cpp
+++ b/src/asmjit/core/string.cpp
@@ -31,7 +31,7 @@ ASMJIT_BEGIN_NAMESPACE
// [asmjit::String - Globals]
// ============================================================================
-static const char String_baseN[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+static const char String_baseN[] = "0123456789ABCDEF";
constexpr size_t kMinAllocSize = 64;
constexpr size_t kMaxAllocSize = SIZE_MAX - Globals::kGrowThreshold;
@@ -256,7 +256,7 @@ Error String::padEnd(size_t n, char c) noexcept {
}
Error String::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, uint32_t flags) noexcept {
- if (base < 2 || base > 36)
+ if (base == 0)
base = 10;
char buf[128];
@@ -284,13 +284,39 @@ Error String::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, ui
// [Number]
// --------------------------------------------------------------------------
- do {
- uint64_t d = i / base;
- uint64_t r = i % base;
+ switch (base) {
+ case 2:
+ case 8:
+ case 16: {
+ uint32_t shift = Support::ctz(base);
+ uint32_t mask = base - 1;
- *--p = String_baseN[r];
- i = d;
- } while (i);
+ do {
+ uint64_t d = i >> shift;
+ size_t r = size_t(i & mask);
+
+ *--p = String_baseN[r];
+ i = d;
+ } while (i);
+
+ break;
+ }
+
+ case 10: {
+ do {
+ uint64_t d = i / 10;
+ uint64_t r = i % 10;
+
+ *--p = char(uint32_t('0') + uint32_t(r));
+ i = d;
+ } while (i);
+
+ break;
+ }
+
+ default:
+ return DebugUtils::errored(kErrorInvalidArgument);
+ }
size_t numberSize = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p);
@@ -540,6 +566,9 @@ UNIT(core_string) {
EXPECT(s.appendUInt(1234) == kErrorOk);
EXPECT(s.eq("1234") == true);
+ EXPECT(s.assignUInt(0xFFFF, 16, 0, String::kFormatAlternate) == kErrorOk);
+ EXPECT(s.eq("0xFFFF"));
+
StringTmp<64> sTmp;
EXPECT(sTmp.isLarge());
EXPECT(sTmp.isExternal());
diff --git a/src/asmjit/x86/x86archtraits_p.h b/src/asmjit/x86/x86archtraits_p.h
index 095919c..66a6f50 100644
--- a/src/asmjit/x86/x86archtraits_p.h
+++ b/src/asmjit/x86/x86archtraits_p.h
@@ -39,22 +39,20 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
// ============================================================================
static const constexpr ArchTraits x86ArchTraits = {
- Gp::kIdSp, // SP.
- Gp::kIdBp, // FP.
- 0xFF, // LR.
- 0xFF, // PC.
- { 0, 0, 0 }, // Reserved.
- 1, // HW stack alignment.
- 0x7FFFFFFFu, // Min stack offset.
- 0x7FFFFFFFu, // Max stack offset.
+ // SP/FP/LR/PC.
+ Gp::kIdSp, Gp::kIdBp, 0xFF, 0xFF,
+
+ // Reserved.
+ { 0, 0, 0 },
+
+ // HW stack alignment.
+ 1,
+
+ // Min/Max stack offset
+ 0x7FFFFFFFu, 0x7FFFFFFFu,
// ISA features [Gp, Vec, Other0, Other1].
- {
- ArchTraits::kIsaFeatureSwap | ArchTraits::kIsaFeaturePushPop,
- 0,
- 0,
- 0
- },
+ { ArchTraits::kIsaFeatureSwap | ArchTraits::kIsaFeaturePushPop, 0, 0, 0 },
// RegInfo.
#define V(index) { x86::RegTraits<index>::kSignature }
@@ -83,8 +81,16 @@ static const constexpr ArchTraits x86ArchTraits = {
index + Type::_kIdBaseStart == Type::kIdMask64 ? Reg::kTypeKReg : \
index + Type::_kIdBaseStart == Type::kIdMmx32 ? Reg::kTypeMm : \
index + Type::_kIdBaseStart == Type::kIdMmx64 ? Reg::kTypeMm : Reg::kTypeNone)
- { ASMJIT_LOOKUP_TABLE_32(V, 0) }
+ { ASMJIT_LOOKUP_TABLE_32(V, 0) },
#undef V
+
+ // Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities.
+ {
+ ISAWordNameId::kDB,
+ ISAWordNameId::kDW,
+ ISAWordNameId::kDD,
+ ISAWordNameId::kDQ
+ }
};
// ============================================================================
@@ -92,22 +98,20 @@ static const constexpr ArchTraits x86ArchTraits = {
// ============================================================================
static const constexpr ArchTraits x64ArchTraits = {
- Gp::kIdSp, // SP.
- Gp::kIdBp, // FP.
- 0xFF, // LR.
- 0xFF, // PC.
- { 0, 0, 0 }, // Reserved.
- 1, // HW stack alignment.
- 0x7FFFFFFFu, // Min stack offset.
- 0x7FFFFFFFu, // Max stack offset.
+ // SP/FP/LR/PC.
+ Gp::kIdSp, Gp::kIdBp, 0xFF, 0xFF,
+
+ // Reserved.
+ { 0, 0, 0 },
+
+ // HW stack alignment.
+ 1,
+
+ // Min/Max stack offset
+ 0x7FFFFFFFu, 0x7FFFFFFFu,
// ISA features [Gp, Vec, Other0, Other1].
- {
- ArchTraits::kIsaFeatureSwap | ArchTraits::kIsaFeaturePushPop,
- 0,
- 0,
- 0
- },
+ { ArchTraits::kIsaFeatureSwap | ArchTraits::kIsaFeaturePushPop, 0, 0, 0 },
// RegInfo.
#define V(index) { x86::RegTraits<index>::kSignature }
@@ -138,8 +142,16 @@ static const constexpr ArchTraits x64ArchTraits = {
index + Type::_kIdBaseStart == Type::kIdMask64 ? Reg::kTypeKReg : \
index + Type::_kIdBaseStart == Type::kIdMmx32 ? Reg::kTypeMm : \
index + Type::_kIdBaseStart == Type::kIdMmx64 ? Reg::kTypeMm : Reg::kTypeNone)
- { ASMJIT_LOOKUP_TABLE_32(V, 0) }
+ { ASMJIT_LOOKUP_TABLE_32(V, 0) },
#undef V
+
+ // Word names of 8-bit, 16-bit, 32-bit, and 64-bit quantities.
+ {
+ ISAWordNameId::kDB,
+ ISAWordNameId::kDW,
+ ISAWordNameId::kDD,
+ ISAWordNameId::kDQ
+ }
};
//! \}