Files
asmjit-asmjit/asmjit/core/instdb.cpp
T
kobalicek b56f4176cb Codebase update and improvements, instruction DB update
* Denested src folder to root, renamed testing to asmjit-testing

  * Refactored how headers are included into <asmjit/...> form. This
    is necessary as compilers would never simplify a path once a ..
    appears in include directory - then paths such as ../core/../core
    appeared in asserts, which was ugly

  * Moved support utilities into asmjit/support/... (still included
    by asmjit/core.h for convenience and compatibility)

  * Added CMakePresets.json for making it easy to develop AsmJit

  * Reworked CMakeLists to be shorter and use CMake option(),
    etc... This simplifies it and makes it using more standard
    features

  * ASMJIT_EMBED now creates asmjit_embed INTERFACE library,
    which is accessible via asmjit::asmjit target - this simplifies
    embedding and makes it the same as library targets from a CMake
    perspective

  * Removed ASMJIT_DEPS - this is now provided by cmake target
    aliases - 'asmjit::asmjit' so users should not need this variable

  * Changed meaning of ASMJIT_LIBS - this now contains only AsmJit
    dependencies without asmjit::asmjit target alias. Don't rely on
    ASMJIT_LIBS anymore as it's only used internally

  * Removed ASMJIT_NO_DEPRECATED option - AsmJit is not going
    to provide controllable deprecations in the future

  * Removed ASMJIT_NO_VALIDATION in favor of ASMJIT_NO_INTROSPECTION,
    which now controls query, features, and validation API presence

  * Removed ASMJIT_DIR option - it was never really needed

  * Removed AMX_TRANSPOSE feature from instruction database (X86).
    Intel has removed it as well, so it's a feature that won't
    be siliconized
2025-11-02 22:31:46 +01:00

143 lines
4.1 KiB
C++

// This file is part of AsmJit project <https://asmjit.com>
//
// See <asmjit/core.h> or LICENSE.md for license and copyright information
// SPDX-License-Identifier: Zlib
#include <asmjit/core/api-build_p.h>
#include <asmjit/core/instdb_p.h>
ASMJIT_BEGIN_NAMESPACE
namespace InstNameUtils {
static constexpr uint32_t kBufferSize = 32;
static ASMJIT_INLINE_CONSTEXPR char decode_5bit_char(uint32_t c) noexcept {
uint32_t base = c <= 26 ? uint32_t('a') - 1u : uint32_t('0') - 27u;
return char(base + c);
}
static ASMJIT_INLINE size_t decode_to_buffer(char name_out[kBufferSize], uint32_t name_value, InstStringifyOptions options, const char* string_table) noexcept {
size_t i;
if (name_value & 0x80000000u) {
// Small string of 5-bit characters.
//
// NOTE: Small string optimization never provides additional
// aliases formatting, so we don't have to consider `options`.
for (i = 0; i < 6; i++, name_value >>= 5) {
uint32_t c = name_value & 0x1F;
if (c == 0)
break;
name_out[i] = decode_5bit_char(c);
}
return i;
}
else {
size_t prefix_base = name_value & 0xFFFu;
size_t prefix_size = (name_value >> 12) & 0xFu;
size_t suffix_base = (name_value >> 16) & 0xFFFu;
size_t suffix_size = (name_value >> 28) & 0x7u;
if (Support::test(options, InstStringifyOptions::kAliases) && suffix_base == 0xFFFu) {
// Alias formatting immediately follows the instruction name in string table.
// The first character specifies the length and then string data follows.
prefix_base += prefix_size;
prefix_size = uint8_t(string_table[prefix_base]);
ASMJIT_ASSERT(prefix_size <= kBufferSize);
prefix_base += 1; // Skip the byte that specifies the length of a formatted alias.
}
for (i = 0; i < prefix_size; i++) {
name_out[i] = string_table[prefix_base + i];
}
char* suffix_out = name_out + prefix_size;
for (i = 0; i < suffix_size; i++) {
suffix_out[i] = string_table[suffix_base + i];
}
return prefix_size + suffix_size;
}
}
Error decode(uint32_t name_value, InstStringifyOptions options, const char* string_table, String& output) noexcept {
char name_data[kBufferSize];
size_t name_size = decode_to_buffer(name_data, name_value, options, string_table);
return output.append(name_data, name_size);
}
InstId find_instruction(const char* s, size_t len, const uint32_t* name_table, const char* string_table, const InstNameIndex& name_index) noexcept {
ASMJIT_ASSERT(s != nullptr);
ASMJIT_ASSERT(len > 0u);
uint32_t prefix = uint32_t(s[0]) - uint32_t('a');
if (ASMJIT_UNLIKELY(prefix > uint32_t('z') - uint32_t('a'))) {
return BaseInst::kIdNone;
}
size_t base = name_index.data[prefix].start;
size_t end = name_index.data[prefix].end;
if (ASMJIT_UNLIKELY(!base)) {
return BaseInst::kIdNone;
}
char name_data[kBufferSize];
for (size_t lim = end - base; lim != 0; lim >>= 1) {
size_t inst_id = base + (lim >> 1);
size_t name_size = decode_to_buffer(name_data, name_table[inst_id], InstStringifyOptions::kNone, string_table);
int result = Support::compare_string_views(s, len, name_data, name_size);
if (result < 0) {
continue;
}
if (result > 0) {
base = inst_id + 1;
lim--;
continue;
}
return InstId(inst_id);
}
return BaseInst::kIdNone;
}
uint32_t find_alias(const char* s, size_t len, const uint32_t* name_table, const char* string_table, uint32_t alias_name_count) noexcept {
ASMJIT_ASSERT(s != nullptr);
ASMJIT_ASSERT(len > 0u);
size_t base = 0;
char name_data[kBufferSize];
for (size_t lim = size_t(alias_name_count) - base; lim != 0; lim >>= 1) {
size_t index = base + (lim >> 1);
size_t name_size = decode_to_buffer(name_data, name_table[index], InstStringifyOptions::kNone, string_table);
int result = Support::compare_string_views(s, len, name_data, name_size);
if (result < 0) {
continue;
}
if (result > 0) {
base = index + 1;
lim--;
continue;
}
return uint32_t(index);
}
return Globals::kInvalidId;
}
} // {InstNameUtils}
ASMJIT_END_NAMESPACE