summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp')
-rw-r--r--3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp583
1 files changed, 334 insertions, 249 deletions
diff --git a/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp b/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp
index 06553e401e0..67b38dfa779 100644
--- a/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp
+++ b/3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp
@@ -1,33 +1,16 @@
-// 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"
-#ifndef ASMJIT_NO_LOGGING
+#if !defined(ASMJIT_NO_X86) && !defined(ASMJIT_NO_LOGGING)
+#include "../core/cpuinfo.h"
#include "../core/misc_p.h"
#include "../core/support.h"
-#include "../x86/x86features.h"
#include "../x86/x86formatter_p.h"
+#include "../x86/x86instapi_p.h"
#include "../x86/x86instdb_p.h"
#include "../x86/x86operand.h"
@@ -37,9 +20,8 @@
ASMJIT_BEGIN_SUB_NAMESPACE(x86)
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Constants]
-// ============================================================================
+// x86::FormatterInternal - Constants
+// ==================================
struct RegFormatInfo {
struct TypeEntry {
@@ -53,65 +35,85 @@ struct RegFormatInfo {
uint8_t specialCount;
};
- TypeEntry typeEntries[BaseReg::kTypeMax + 1];
+ TypeEntry typeEntries[uint32_t(RegType::kMaxValue) + 1];
char typeStrings[128 - 32];
- NameEntry nameEntries[BaseReg::kTypeMax + 1];
+ NameEntry nameEntries[uint32_t(RegType::kMaxValue) + 1];
char nameStrings[280];
};
template<uint32_t X>
struct RegFormatInfo_T {
enum {
- kTypeIndex = X == Reg::kTypeGpbLo ? 1 :
- X == Reg::kTypeGpbHi ? 8 :
- X == Reg::kTypeGpw ? 15 :
- X == Reg::kTypeGpd ? 19 :
- X == Reg::kTypeGpq ? 23 :
- X == Reg::kTypeXmm ? 27 :
- X == Reg::kTypeYmm ? 31 :
- X == Reg::kTypeZmm ? 35 :
- X == Reg::kTypeMm ? 50 :
- X == Reg::kTypeKReg ? 53 :
- X == Reg::kTypeSReg ? 43 :
- X == Reg::kTypeCReg ? 59 :
- X == Reg::kTypeDReg ? 62 :
- X == Reg::kTypeSt ? 47 :
- X == Reg::kTypeBnd ? 55 :
- X == Reg::kTypeRip ? 39 : 0,
-
- kFormatIndex = X == Reg::kTypeGpbLo ? 1 :
- X == Reg::kTypeGpbHi ? 6 :
- X == Reg::kTypeGpw ? 11 :
- X == Reg::kTypeGpd ? 16 :
- X == Reg::kTypeGpq ? 21 :
- X == Reg::kTypeXmm ? 25 :
- X == Reg::kTypeYmm ? 31 :
- X == Reg::kTypeZmm ? 37 :
- X == Reg::kTypeMm ? 60 :
- X == Reg::kTypeKReg ? 65 :
- X == Reg::kTypeSReg ? 49 :
- X == Reg::kTypeCReg ? 75 :
- X == Reg::kTypeDReg ? 80 :
- X == Reg::kTypeSt ? 55 :
- X == Reg::kTypeBnd ? 69 :
- X == Reg::kTypeRip ? 43 : 0,
-
- kSpecialIndex = X == Reg::kTypeGpbLo ? 96 :
- X == Reg::kTypeGpbHi ? 128 :
- X == Reg::kTypeGpw ? 161 :
- X == Reg::kTypeGpd ? 160 :
- X == Reg::kTypeGpq ? 192 :
- X == Reg::kTypeSReg ? 224 :
- X == Reg::kTypeRip ? 85 : 0,
-
- kSpecialCount = X == Reg::kTypeGpbLo ? 8 :
- X == Reg::kTypeGpbHi ? 4 :
- X == Reg::kTypeGpw ? 8 :
- X == Reg::kTypeGpd ? 8 :
- X == Reg::kTypeGpq ? 8 :
- X == Reg::kTypeSReg ? 7 :
- X == Reg::kTypeRip ? 1 : 0
+ kTypeIndex = X == uint32_t(RegType::kX86_GpbLo) ? 1 :
+ X == uint32_t(RegType::kX86_GpbHi) ? 8 :
+ X == uint32_t(RegType::kX86_Gpw ) ? 15 :
+ X == uint32_t(RegType::kX86_Gpd ) ? 19 :
+ X == uint32_t(RegType::kX86_Gpq ) ? 23 :
+ X == uint32_t(RegType::kX86_Xmm ) ? 27 :
+ X == uint32_t(RegType::kX86_Ymm ) ? 31 :
+ X == uint32_t(RegType::kX86_Zmm ) ? 35 :
+ X == uint32_t(RegType::kX86_Mm ) ? 50 :
+ X == uint32_t(RegType::kX86_KReg ) ? 53 :
+ X == uint32_t(RegType::kX86_SReg ) ? 43 :
+ X == uint32_t(RegType::kX86_CReg ) ? 59 :
+ X == uint32_t(RegType::kX86_DReg ) ? 62 :
+ X == uint32_t(RegType::kX86_St ) ? 47 :
+ X == uint32_t(RegType::kX86_Bnd ) ? 55 :
+ X == uint32_t(RegType::kX86_Tmm ) ? 65 :
+ X == uint32_t(RegType::kX86_Rip ) ? 39 : 0,
+
+ kFormatIndex = X == uint32_t(RegType::kX86_GpbLo) ? 1 :
+ X == uint32_t(RegType::kX86_GpbHi) ? 6 :
+ X == uint32_t(RegType::kX86_Gpw ) ? 11 :
+ X == uint32_t(RegType::kX86_Gpd ) ? 16 :
+ X == uint32_t(RegType::kX86_Gpq ) ? 21 :
+ X == uint32_t(RegType::kX86_Xmm ) ? 25 :
+ X == uint32_t(RegType::kX86_Ymm ) ? 31 :
+ X == uint32_t(RegType::kX86_Zmm ) ? 37 :
+ X == uint32_t(RegType::kX86_Mm ) ? 60 :
+ X == uint32_t(RegType::kX86_KReg ) ? 65 :
+ X == uint32_t(RegType::kX86_SReg ) ? 49 :
+ X == uint32_t(RegType::kX86_CReg ) ? 75 :
+ X == uint32_t(RegType::kX86_DReg ) ? 80 :
+ X == uint32_t(RegType::kX86_St ) ? 55 :
+ X == uint32_t(RegType::kX86_Bnd ) ? 69 :
+ X == uint32_t(RegType::kX86_Tmm ) ? 89 :
+ X == uint32_t(RegType::kX86_Rip ) ? 43 : 0,
+
+ kSpecialIndex = X == uint32_t(RegType::kX86_GpbLo) ? 96 :
+ X == uint32_t(RegType::kX86_GpbHi) ? 128 :
+ X == uint32_t(RegType::kX86_Gpw ) ? 161 :
+ X == uint32_t(RegType::kX86_Gpd ) ? 160 :
+ X == uint32_t(RegType::kX86_Gpq ) ? 192 :
+ X == uint32_t(RegType::kX86_SReg ) ? 224 :
+ X == uint32_t(RegType::kX86_Rip ) ? 85 : 0,
+
+ kSpecialCount = X == uint32_t(RegType::kX86_GpbLo) ? 8 :
+ X == uint32_t(RegType::kX86_GpbHi) ? 4 :
+ X == uint32_t(RegType::kX86_Gpw ) ? 8 :
+ X == uint32_t(RegType::kX86_Gpd ) ? 8 :
+ X == uint32_t(RegType::kX86_Gpq ) ? 8 :
+ X == uint32_t(RegType::kX86_SReg ) ? 7 :
+ X == uint32_t(RegType::kX86_Rip ) ? 1 : 0,
+
+ kRegCount = X == uint32_t(RegType::kX86_GpbLo) ? 32 :
+ X == uint32_t(RegType::kX86_GpbHi) ? 4 :
+ X == uint32_t(RegType::kX86_Gpw ) ? 32 :
+ X == uint32_t(RegType::kX86_Gpd ) ? 32 :
+ X == uint32_t(RegType::kX86_Gpq ) ? 32 :
+ X == uint32_t(RegType::kX86_Xmm ) ? 32 :
+ X == uint32_t(RegType::kX86_Ymm ) ? 32 :
+ X == uint32_t(RegType::kX86_Zmm ) ? 32 :
+ X == uint32_t(RegType::kX86_Mm ) ? 8 :
+ X == uint32_t(RegType::kX86_KReg ) ? 8 :
+ X == uint32_t(RegType::kX86_SReg ) ? 7 :
+ X == uint32_t(RegType::kX86_CReg ) ? 16 :
+ X == uint32_t(RegType::kX86_DReg ) ? 16 :
+ X == uint32_t(RegType::kX86_St ) ? 8 :
+ X == uint32_t(RegType::kX86_Bnd ) ? 4 :
+ X == uint32_t(RegType::kX86_Tmm ) ? 8 :
+ X == uint32_t(RegType::kX86_Rip ) ? 1 : 0
};
};
@@ -120,7 +122,7 @@ struct RegFormatInfo_T {
}
#define ASMJIT_REG_NAME_ENTRY(TYPE) { \
- RegTraits<TYPE>::kCount, \
+ RegFormatInfo_T<TYPE>::kRegCount, \
RegFormatInfo_T<TYPE>::kFormatIndex, \
RegFormatInfo_T<TYPE>::kSpecialIndex, \
RegFormatInfo_T<TYPE>::kSpecialCount \
@@ -146,7 +148,9 @@ static const RegFormatInfo x86RegFormatInfo = {
"k\0" // #53
"bnd\0" // #55
"cr\0" // #59
- "dr\0", // #62
+ "dr\0" // #62
+ "tmm\0" // #65
+ ,
// Register name entries and strings.
{ ASMJIT_LOOKUP_TABLE_32(ASMJIT_REG_NAME_ENTRY, 0) },
@@ -170,7 +174,8 @@ static const RegFormatInfo x86RegFormatInfo = {
"dr%u\0" // #80
"rip\0" // #85
- "\0\0\0\0\0\0\0" // #89
+ "tmm%u\0" // #89
+ "\0" // #95
"al\0\0" "cl\0\0" "dl\0\0" "bl\0\0" "spl\0" "bpl\0" "sil\0" "dil\0" // #96
"ah\0\0" "ch\0\0" "dh\0\0" "bh\0\0" "n/a\0" "n/a\0" "n/a\0" "n/a\0" // #128
@@ -183,25 +188,24 @@ static const RegFormatInfo x86RegFormatInfo = {
static const char* x86GetAddressSizeString(uint32_t size) noexcept {
switch (size) {
- case 1 : return "byte ";
- case 2 : return "word ";
- case 4 : return "dword ";
- case 6 : return "fword ";
- case 8 : return "qword ";
- case 10: return "tword ";
- case 16: return "oword ";
- case 32: return "yword ";
- case 64: return "zword ";
+ case 1 : return "byte ptr ";
+ case 2 : return "word ptr ";
+ case 4 : return "dword ptr ";
+ case 6 : return "fword ptr ";
+ case 8 : return "qword ptr ";
+ case 10: return "tbyte ptr ";
+ case 16: return "xmmword ptr ";
+ case 32: return "ymmword ptr ";
+ case 64: return "zmmword ptr ";
default: return "";
}
}
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Format Feature]
-// ============================================================================
+// x86::FormatterInternal - Format FeatureId
+// =========================================
Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept {
- // @EnumStringBegin{"enum": "x86::Features::Id", "output": "sFeature", "strip": "k"}@
+ // @EnumStringBegin{"enum": "CpuFeatures::X86", "output": "sFeature", "strip": "k"}@
static const char sFeatureString[] =
"None\0"
"MT\0"
@@ -211,6 +215,12 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"ADX\0"
"AESNI\0"
"ALTMOVCR8\0"
+ "AMX_BF16\0"
+ "AMX_COMPLEX\0"
+ "AMX_FP16\0"
+ "AMX_INT8\0"
+ "AMX_TILE\0"
+ "APX_F\0"
"AVX\0"
"AVX2\0"
"AVX512_4FMAPS\0"
@@ -218,26 +228,36 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"AVX512_BF16\0"
"AVX512_BITALG\0"
"AVX512_BW\0"
- "AVX512_CDI\0"
+ "AVX512_CD\0"
"AVX512_DQ\0"
- "AVX512_ERI\0"
+ "AVX512_ER\0"
"AVX512_F\0"
+ "AVX512_FP16\0"
"AVX512_IFMA\0"
- "AVX512_PFI\0"
+ "AVX512_PF\0"
"AVX512_VBMI\0"
"AVX512_VBMI2\0"
"AVX512_VL\0"
"AVX512_VNNI\0"
"AVX512_VP2INTERSECT\0"
"AVX512_VPOPCNTDQ\0"
+ "AVX_IFMA\0"
+ "AVX_NE_CONVERT\0"
+ "AVX_VNNI\0"
+ "AVX_VNNI_INT16\0"
+ "AVX_VNNI_INT8\0"
"BMI\0"
"BMI2\0"
+ "CET_IBT\0"
+ "CET_SS\0"
+ "CET_SSS\0"
"CLDEMOTE\0"
"CLFLUSH\0"
"CLFLUSHOPT\0"
"CLWB\0"
"CLZERO\0"
"CMOV\0"
+ "CMPCCXADD\0"
"CMPXCHG16B\0"
"CMPXCHG8B\0"
"ENCLV\0"
@@ -248,15 +268,23 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"FMA4\0"
"FPU\0"
"FSGSBASE\0"
+ "FSRM\0"
+ "FSRC\0"
+ "FSRS\0"
"FXSR\0"
"FXSROPT\0"
+ "FZRM\0"
"GEODE\0"
"GFNI\0"
"HLE\0"
+ "HRESET\0"
"I486\0"
+ "INVLPGB\0"
"LAHFSAHF\0"
+ "LAM\0"
"LWP\0"
"LZCNT\0"
+ "MCOMMIT\0"
"MMX\0"
"MMX2\0"
"MONITOR\0"
@@ -266,23 +294,38 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"MOVDIRI\0"
"MPX\0"
"MSR\0"
+ "MSRLIST\0"
"MSSE\0"
"OSXSAVE\0"
+ "OSPKE\0"
"PCLMULQDQ\0"
- "PCOMMIT\0"
"PCONFIG\0"
"POPCNT\0"
+ "PREFETCHI\0"
"PREFETCHW\0"
"PREFETCHWT1\0"
+ "PTWRITE\0"
+ "RAO_INT\0"
+ "RMPQUERY\0"
"RDPID\0"
+ "RDPRU\0"
"RDRAND\0"
"RDSEED\0"
"RDTSC\0"
"RDTSCP\0"
"RTM\0"
+ "SEAM\0"
+ "SERIALIZE\0"
+ "SEV\0"
+ "SEV_ES\0"
+ "SEV_SNP\0"
"SHA\0"
+ "SHA512\0"
"SKINIT\0"
+ "SM3\0"
+ "SM4\0"
"SMAP\0"
+ "SME\0"
"SMEP\0"
"SMX\0"
"SSE\0"
@@ -294,12 +337,16 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"SSSE3\0"
"SVM\0"
"TBM\0"
+ "TSE\0"
"TSX\0"
+ "TSXLDTRK\0"
+ "UINTR\0"
"VAES\0"
"VMX\0"
"VPCLMULQDQ\0"
"WAITPKG\0"
"WBNOINVD\0"
+ "WRMSRNS\0"
"XOP\0"
"XSAVE\0"
"XSAVEC\0"
@@ -308,32 +355,89 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"<Unknown>\0";
static const uint16_t sFeatureIndex[] = {
- 0, 5, 8, 11, 17, 24, 28, 34, 44, 48, 53, 67, 81, 93, 107, 117, 128, 138,
- 149, 158, 170, 181, 193, 206, 216, 228, 248, 265, 269, 274, 283, 291, 302,
- 307, 314, 319, 330, 340, 346, 353, 358, 363, 367, 372, 376, 385, 390, 398,
- 404, 409, 413, 418, 427, 431, 437, 441, 446, 454, 463, 469, 479, 487, 491,
- 495, 500, 508, 518, 526, 534, 541, 551, 563, 569, 576, 583, 589, 596, 600,
- 604, 611, 616, 621, 625, 629, 634, 639, 646, 653, 659, 665, 669, 673, 677,
- 682, 686, 697, 705, 714, 718, 724, 731, 740, 747
+ 0, 5, 8, 11, 17, 24, 28, 34, 44, 53, 65, 74, 83, 92, 98, 102, 107, 121, 135,
+ 147, 161, 171, 181, 191, 201, 210, 222, 234, 244, 256, 269, 279, 291, 311,
+ 328, 337, 352, 361, 376, 390, 394, 399, 407, 414, 422, 431, 439, 450, 455,
+ 462, 467, 477, 488, 498, 504, 511, 516, 521, 525, 530, 534, 543, 548, 553,
+ 558, 563, 571, 576, 582, 587, 591, 598, 603, 611, 620, 624, 628, 634, 642,
+ 646, 651, 659, 668, 674, 684, 692, 696, 700, 708, 713, 721, 727, 737, 745,
+ 752, 762, 772, 784, 792, 800, 809, 815, 821, 828, 835, 841, 848, 852, 857,
+ 867, 871, 878, 886, 890, 897, 904, 908, 912, 917, 921, 926, 930, 934, 939,
+ 944, 951, 958, 964, 970, 974, 978, 982, 986, 995, 1001, 1006, 1010, 1021,
+ 1029, 1038, 1046, 1050, 1056, 1063, 1072, 1079
};
// @EnumStringEnd@
- return sb.append(sFeatureString + sFeatureIndex[Support::min<uint32_t>(featureId, x86::Features::kCount)]);
+ return sb.append(sFeatureString + sFeatureIndex[Support::min<uint32_t>(featureId, uint32_t(CpuFeatures::X86::kMaxValue) + 1)]);
}
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Format Operand]
-// ============================================================================
+// x86::FormatterInternal - Format Register
+// ========================================
+
+ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(String& sb, FormatFlags formatFlags, const BaseEmitter* emitter, Arch arch, RegType type, uint32_t id) noexcept {
+ DebugUtils::unused(arch);
+ const RegFormatInfo& info = x86RegFormatInfo;
+
+#ifndef ASMJIT_NO_COMPILER
+ if (Operand::isVirtId(id)) {
+ if (emitter && emitter->emitterType() == EmitterType::kCompiler) {
+ const BaseCompiler* cc = static_cast<const BaseCompiler*>(emitter);
+ if (cc->isVirtIdValid(id)) {
+ VirtReg* vReg = cc->virtRegById(id);
+ ASMJIT_ASSERT(vReg != nullptr);
+
+ const char* name = vReg->name();
+ if (name && name[0] != '\0')
+ ASMJIT_PROPAGATE(sb.append(name));
+ else
+ ASMJIT_PROPAGATE(sb.appendFormat("%%%u", unsigned(Operand::virtIdToIndex(id))));
+
+ bool formatType = (Support::test(formatFlags, FormatFlags::kRegType)) ||
+ (Support::test(formatFlags, FormatFlags::kRegCasts) && vReg->type() != type);
+
+ if (formatType && uint32_t(type) <= uint32_t(RegType::kMaxValue)) {
+ const RegFormatInfo::TypeEntry& typeEntry = info.typeEntries[size_t(type)];
+ if (typeEntry.index)
+ ASMJIT_PROPAGATE(sb.appendFormat("@%s", info.typeStrings + typeEntry.index));
+ }
+
+ return kErrorOk;
+ }
+ }
+ }
+#else
+ DebugUtils::unused(emitter, formatFlags);
+#endif
+
+ if (uint32_t(type) <= uint32_t(RegType::kMaxValue)) {
+ const RegFormatInfo::NameEntry& nameEntry = info.nameEntries[size_t(type)];
+
+ if (id < nameEntry.specialCount)
+ return sb.append(info.nameStrings + nameEntry.specialIndex + id * 4);
+
+ if (id < nameEntry.count)
+ return sb.appendFormat(info.nameStrings + nameEntry.formatIndex, unsigned(id));
+
+ const RegFormatInfo::TypeEntry& typeEntry = info.typeEntries[size_t(type)];
+ if (typeEntry.index)
+ return sb.appendFormat("%s@%u", info.typeStrings + typeEntry.index, id);
+ }
+
+ return sb.appendFormat("<Reg-%u>?%u", uint32_t(type), id);
+}
+
+// x86::FormatterInternal - Format Operand
+// =======================================
ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
String& sb,
- uint32_t flags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
- uint32_t arch,
+ Arch arch,
const Operand_& op) noexcept {
if (op.isReg())
- return formatRegister(sb, flags, emitter, arch, op.as<BaseReg>().type(), op.as<BaseReg>().id());
+ return formatRegister(sb, formatFlags, emitter, arch, op.as<BaseReg>().type(), op.as<BaseReg>().id());
if (op.isMem()) {
const Mem& m = op.as<Mem>();
@@ -346,21 +450,27 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
ASMJIT_PROPAGATE(sb.append('['));
switch (m.addrType()) {
- case BaseMem::kAddrTypeAbs: ASMJIT_PROPAGATE(sb.append("abs ")); break;
- case BaseMem::kAddrTypeRel: ASMJIT_PROPAGATE(sb.append("rel ")); break;
+ case Mem::AddrType::kDefault:
+ break;
+ case Mem::AddrType::kAbs:
+ ASMJIT_PROPAGATE(sb.append("abs "));
+ break;
+ case Mem::AddrType::kRel:
+ ASMJIT_PROPAGATE(sb.append("rel "));
+ break;
}
char opSign = '\0';
if (m.hasBase()) {
opSign = '+';
if (m.hasBaseLabel()) {
- ASMJIT_PROPAGATE(Formatter::formatLabel(sb, flags, emitter, m.baseId()));
+ ASMJIT_PROPAGATE(Formatter::formatLabel(sb, formatFlags, emitter, m.baseId()));
}
else {
- uint32_t modifiedFlags = flags;
+ FormatFlags modifiedFlags = formatFlags;
if (m.isRegHome()) {
ASMJIT_PROPAGATE(sb.append("&"));
- modifiedFlags &= ~FormatOptions::kFlagRegCasts;
+ modifiedFlags &= ~FormatFlags::kRegCasts;
}
ASMJIT_PROPAGATE(formatRegister(sb, modifiedFlags, emitter, arch, m.baseType(), m.baseId()));
}
@@ -371,7 +481,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
ASMJIT_PROPAGATE(sb.append(opSign));
opSign = '+';
- ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, m.indexType(), m.indexId()));
+ ASMJIT_PROPAGATE(formatRegister(sb, formatFlags, emitter, arch, m.indexType(), m.indexId()));
if (m.hasShift())
ASMJIT_PROPAGATE(sb.appendFormat("*%u", 1 << m.shift()));
}
@@ -387,7 +497,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
ASMJIT_PROPAGATE(sb.append(opSign));
uint32_t base = 10;
- if ((flags & FormatOptions::kFlagHexOffsets) != 0 && off > 9) {
+ if (Support::test(formatFlags, FormatFlags::kHexOffsets) && off > 9) {
ASMJIT_PROPAGATE(sb.append("0x", 2));
base = 16;
}
@@ -402,7 +512,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
const Imm& i = op.as<Imm>();
int64_t val = i.value();
- if ((flags & FormatOptions::kFlagHexImms) != 0 && uint64_t(val) > 9) {
+ if (Support::test(formatFlags, FormatFlags::kHexImms) && uint64_t(val) > 9) {
ASMJIT_PROPAGATE(sb.append("0x", 2));
return sb.appendUInt(uint64_t(val), 16);
}
@@ -412,19 +522,18 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
}
if (op.isLabel()) {
- return Formatter::formatLabel(sb, flags, emitter, op.id());
+ return Formatter::formatLabel(sb, formatFlags, emitter, op.id());
}
return sb.append("<None>");
}
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Format Immediate (Extension)]
-// ============================================================================
+// x86::FormatterInternal - Format Immediate (Extension)
+// =====================================================
static constexpr char kImmCharStart = '{';
-static constexpr char kImmCharEnd = '}';
-static constexpr char kImmCharOr = '|';
+static constexpr char kImmCharEnd = '}';
+static constexpr char kImmCharOr = '|';
struct ImmBits {
enum Mode : uint32_t {
@@ -438,29 +547,29 @@ struct ImmBits {
char text[48 - 3];
};
-ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmShuf(String& sb, uint32_t u8, uint32_t bits, uint32_t count) noexcept {
+ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmShuf(String& sb, uint32_t imm8, uint32_t bits, uint32_t count) noexcept {
uint32_t mask = (1 << bits) - 1;
+ uint32_t lastPredicateShift = bits * (count - 1u);
- for (uint32_t i = 0; i < count; i++, u8 >>= bits) {
- uint32_t value = u8 & mask;
+ for (uint32_t i = 0; i < count; i++, imm8 <<= bits) {
+ uint32_t index = (imm8 >> lastPredicateShift) & mask;
ASMJIT_PROPAGATE(sb.append(i == 0 ? kImmCharStart : kImmCharOr));
- ASMJIT_PROPAGATE(sb.appendUInt(value));
+ ASMJIT_PROPAGATE(sb.appendUInt(index));
}
- if (kImmCharEnd)
- ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
+ ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
return kErrorOk;
}
-ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmBits(String& sb, uint32_t u8, const ImmBits* bits, uint32_t count) noexcept {
+ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmBits(String& sb, uint32_t imm8, const ImmBits* bits, uint32_t count) noexcept {
uint32_t n = 0;
char buf[64];
for (uint32_t i = 0; i < count; i++) {
const ImmBits& spec = bits[i];
- uint32_t value = (u8 & uint32_t(spec.mask)) >> spec.shift;
+ uint32_t value = (imm8 & uint32_t(spec.mask)) >> spec.shift;
const char* str = nullptr;
switch (spec.mode) {
@@ -484,36 +593,33 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmBits(String& sb, uint3
ASMJIT_PROPAGATE(sb.append(str));
}
- if (n && kImmCharEnd)
+ if (n)
ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
return kErrorOk;
}
-ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmText(String& sb, uint32_t u8, uint32_t bits, uint32_t advance, const char* text, uint32_t count = 1) noexcept {
+ASMJIT_FAVOR_SIZE static Error FormatterInternal_formatImmText(String& sb, uint32_t imm8, uint32_t bits, uint32_t advance, const char* text, uint32_t count = 1) noexcept {
uint32_t mask = (1u << bits) - 1;
uint32_t pos = 0;
- for (uint32_t i = 0; i < count; i++, u8 >>= bits, pos += advance) {
- uint32_t value = (u8 & mask) + pos;
+ for (uint32_t i = 0; i < count; i++, imm8 >>= bits, pos += advance) {
+ uint32_t value = (imm8 & mask) + pos;
ASMJIT_PROPAGATE(sb.append(i == 0 ? kImmCharStart : kImmCharOr));
ASMJIT_PROPAGATE(sb.append(Support::findPackedString(text, value)));
}
- if (kImmCharEnd)
- ASMJIT_PROPAGATE(sb.append(kImmCharEnd));
-
- return kErrorOk;
+ return sb.append(kImmCharEnd);
}
ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(
String& sb,
- uint32_t flags,
- uint32_t instId,
+ FormatFlags formatFlags,
+ InstId instId,
uint32_t vecSize,
const Imm& imm) noexcept {
- DebugUtils::unused(flags);
+ DebugUtils::unused(formatFlags);
static const char vcmpx[] =
"EQ_OQ\0" "LT_OS\0" "LE_OS\0" "UNORD_Q\0" "NEQ_UQ\0" "NLT_US\0" "NLE_US\0" "ORD_Q\0"
@@ -525,8 +631,8 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(
static const char vpcmpx[] = "EQ\0" "LT\0" "LE\0" "FALSE\0" "NEQ\0" "GE\0" "GT\0" "TRUE\0";
static const char vpcomx[] = "LT\0" "LE\0" "GT\0" "GE\0" "EQ\0" "NEQ\0" "FALSE\0" "TRUE\0";
- static const char vshufpd[] = "A0\0A1\0B0\0B1\0A2\0A3\0B2\0B3\0A4\0A5\0B4\0B5\0A6\0A7\0B6\0B7\0";
- static const char vshufps[] = "A0\0A1\0A2\0A3\0A0\0A1\0A2\0A3\0B0\0B1\0B2\0B3\0B0\0B1\0B2\0B3\0";
+ static const char vshufpd[] = "A0\0" "A1\0" "B0\0" "B1\0" "A2\0" "A3\0" "B2\0" "B3\0" "A4\0" "A5\0" "B4\0" "B5\0" "A6\0" "A7\0" "B6\0" "B7\0";
+ static const char vshufps[] = "A0\0" "A1\0" "A2\0" "A3\0" "A0\0" "A1\0" "A2\0" "A3\0" "B0\0" "B1\0" "B2\0" "B3\0" "B0\0" "B1\0" "B2\0" "B3\0";
static const ImmBits vfpclassxx[] = {
{ 0x07u, 0, ImmBits::kModeLookup, "QNAN\0" "+0\0" "-0\0" "+INF\0" "-INF\0" "DENORMAL\0" "-FINITE\0" "SNAN\0" }
@@ -550,25 +656,25 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(
};
static const ImmBits vmpsadbw[] = {
- { 0x04u, 2, ImmBits::kModeLookup, "BLK1[0]\0" "BLK1[1]\0" },
- { 0x03u, 0, ImmBits::kModeLookup, "BLK2[0]\0" "BLK2[1]\0" "BLK2[2]\0" "BLK2[3]\0" },
{ 0x40u, 6, ImmBits::kModeLookup, "BLK1[4]\0" "BLK1[5]\0" },
- { 0x30u, 4, ImmBits::kModeLookup, "BLK2[4]\0" "BLK2[5]\0" "BLK2[6]\0" "BLK2[7]\0" }
+ { 0x30u, 4, ImmBits::kModeLookup, "BLK2[4]\0" "BLK2[5]\0" "BLK2[6]\0" "BLK2[7]\0" },
+ { 0x04u, 2, ImmBits::kModeLookup, "BLK1[0]\0" "BLK1[1]\0" },
+ { 0x03u, 0, ImmBits::kModeLookup, "BLK2[0]\0" "BLK2[1]\0" "BLK2[2]\0" "BLK2[3]\0" }
};
static const ImmBits vpclmulqdq[] = {
- { 0x01u, 0, ImmBits::kModeLookup, "LQ\0" "HQ\0" },
- { 0x10u, 4, ImmBits::kModeLookup, "LQ\0" "HQ\0" }
+ { 0x10u, 4, ImmBits::kModeLookup, "LQ\0" "HQ\0" },
+ { 0x01u, 0, ImmBits::kModeLookup, "LQ\0" "HQ\0" }
};
static const ImmBits vperm2x128[] = {
- { 0x0Bu, 0, ImmBits::kModeLookup, "A0\0" "A1\0" "B0\0" "B1\0" "\0" "\0" "\0" "\0" "0\0" "0\0" "0\0" "0\0" },
- { 0xB0u, 4, ImmBits::kModeLookup, "A0\0" "A1\0" "B0\0" "B1\0" "\0" "\0" "\0" "\0" "0\0" "0\0" "0\0" "0\0" }
+ { 0xB0u, 4, ImmBits::kModeLookup, "A0\0" "A1\0" "B0\0" "B1\0" "\0" "\0" "\0" "\0" "0\0" "0\0" "0\0" "0\0" },
+ { 0x0Bu, 0, ImmBits::kModeLookup, "A0\0" "A1\0" "B0\0" "B1\0" "\0" "\0" "\0" "\0" "0\0" "0\0" "0\0" "0\0" }
};
static const ImmBits vrangexx[] = {
- { 0x03u, 0, ImmBits::kModeLookup, "MIN\0" "MAX\0" "MIN_ABS\0" "MAX_ABS\0" },
- { 0x0Cu, 2, ImmBits::kModeLookup, "SIGN_A\0" "SIGN_B\0" "SIGN_0\0" "SIGN_1\0" }
+ { 0x0Cu, 2, ImmBits::kModeLookup, "SIGN_A\0" "SIGN_B\0" "SIGN_0\0" "SIGN_1\0" },
+ { 0x03u, 0, ImmBits::kModeLookup, "MIN\0" "MAX\0" "MIN_ABS\0" "MAX_ABS\0" }
};
static const ImmBits vreducexx_vrndscalexx[] = {
@@ -746,106 +852,76 @@ ASMJIT_FAVOR_SIZE static Error FormatterInternal_explainConst(
}
}
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Format Register]
-// ============================================================================
-
-ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(String& sb, uint32_t flags, const BaseEmitter* emitter, uint32_t arch, uint32_t rType, uint32_t rId) noexcept {
- DebugUtils::unused(arch);
- const RegFormatInfo& info = x86RegFormatInfo;
-
-#ifndef ASMJIT_NO_COMPILER
- if (Operand::isVirtId(rId)) {
- if (emitter && emitter->emitterType() == BaseEmitter::kTypeCompiler) {
- const BaseCompiler* cc = static_cast<const BaseCompiler*>(emitter);
- if (cc->isVirtIdValid(rId)) {
- VirtReg* vReg = cc->virtRegById(rId);
- ASMJIT_ASSERT(vReg != nullptr);
-
- const char* name = vReg->name();
- if (name && name[0] != '\0')
- ASMJIT_PROPAGATE(sb.append(name));
- else
- ASMJIT_PROPAGATE(sb.appendFormat("%%%u", unsigned(Operand::virtIdToIndex(rId))));
-
- if (vReg->type() != rType && rType <= BaseReg::kTypeMax && (flags & FormatOptions::kFlagRegCasts) != 0) {
- const RegFormatInfo::TypeEntry& typeEntry = info.typeEntries[rType];
- if (typeEntry.index)
- ASMJIT_PROPAGATE(sb.appendFormat("@%s", info.typeStrings + typeEntry.index));
- }
-
- return kErrorOk;
- }
- }
- }
-#else
- DebugUtils::unused(emitter, flags);
-#endif
-
- if (ASMJIT_LIKELY(rType <= BaseReg::kTypeMax)) {
- const RegFormatInfo::NameEntry& nameEntry = info.nameEntries[rType];
-
- if (rId < nameEntry.specialCount)
- return sb.append(info.nameStrings + nameEntry.specialIndex + rId * 4);
-
- if (rId < nameEntry.count)
- return sb.appendFormat(info.nameStrings + nameEntry.formatIndex, unsigned(rId));
-
- const RegFormatInfo::TypeEntry& typeEntry = info.typeEntries[rType];
- if (typeEntry.index)
- return sb.appendFormat("%s@%u", info.typeStrings + typeEntry.index, rId);
- }
-
- return sb.appendFormat("Reg?%u@%u", rType, rId);
-}
-
-// ============================================================================
-// [asmjit::x86::FormatterInternal - Format Instruction]
-// ============================================================================
+// x86::FormatterInternal - Format Instruction
+// ===========================================
ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
String& sb,
- uint32_t flags,
+ FormatFlags formatFlags,
const BaseEmitter* emitter,
- uint32_t arch,
+ Arch arch,
const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept {
- uint32_t instId = inst.id();
- uint32_t options = inst.options();
+ InstId instId = inst.id();
+ InstOptions options = inst.options();
// Format instruction options and instruction mnemonic.
if (instId < Inst::_kIdCount) {
+ // VEX|EVEX options.
+ if (Support::test(options, InstOptions::kX86_Vex))
+ ASMJIT_PROPAGATE(sb.append("{vex} "));
+
+ if (Support::test(options, InstOptions::kX86_Vex3))
+ ASMJIT_PROPAGATE(sb.append("{vex3} "));
+
+ if (Support::test(options, InstOptions::kX86_Evex))
+ ASMJIT_PROPAGATE(sb.append("{evex} "));
+
+ // MOD/RM and MOD/MR options
+ if (Support::test(options, InstOptions::kX86_ModRM))
+ ASMJIT_PROPAGATE(sb.append("{modrm} "));
+ else if (Support::test(options, InstOptions::kX86_ModMR))
+ ASMJIT_PROPAGATE(sb.append("{modmr} "));
+
// SHORT|LONG options.
- if (options & Inst::kOptionShortForm) ASMJIT_PROPAGATE(sb.append("short "));
- if (options & Inst::kOptionLongForm) ASMJIT_PROPAGATE(sb.append("long "));
+ if (Support::test(options, InstOptions::kShortForm))
+ ASMJIT_PROPAGATE(sb.append("short "));
+
+ if (Support::test(options, InstOptions::kLongForm))
+ ASMJIT_PROPAGATE(sb.append("long "));
// LOCK|XACQUIRE|XRELEASE options.
- if (options & Inst::kOptionXAcquire) ASMJIT_PROPAGATE(sb.append("xacquire "));
- if (options & Inst::kOptionXRelease) ASMJIT_PROPAGATE(sb.append("xrelease "));
- if (options & Inst::kOptionLock) ASMJIT_PROPAGATE(sb.append("lock "));
+ if (Support::test(options, InstOptions::kX86_XAcquire))
+ ASMJIT_PROPAGATE(sb.append("xacquire "));
+
+ if (Support::test(options, InstOptions::kX86_XRelease))
+ ASMJIT_PROPAGATE(sb.append("xrelease "));
+
+ if (Support::test(options, InstOptions::kX86_Lock))
+ ASMJIT_PROPAGATE(sb.append("lock "));
// REP|REPNE options.
- if (options & (Inst::kOptionRep | Inst::kOptionRepne)) {
- sb.append((options & Inst::kOptionRep) ? "rep " : "repnz ");
+ if (Support::test(options, InstOptions::kX86_Rep | InstOptions::kX86_Repne)) {
+ sb.append(Support::test(options, InstOptions::kX86_Rep) ? "rep " : "repnz ");
if (inst.hasExtraReg()) {
ASMJIT_PROPAGATE(sb.append("{"));
- ASMJIT_PROPAGATE(formatOperand(sb, flags, emitter, arch, inst.extraReg().toReg<BaseReg>()));
+ ASMJIT_PROPAGATE(formatOperand(sb, formatFlags, emitter, arch, inst.extraReg().toReg<BaseReg>()));
ASMJIT_PROPAGATE(sb.append("} "));
}
}
// REX options.
- if (options & Inst::kOptionRex) {
- const uint32_t kRXBWMask = Inst::kOptionOpCodeR |
- Inst::kOptionOpCodeX |
- Inst::kOptionOpCodeB |
- Inst::kOptionOpCodeW ;
- if (options & kRXBWMask) {
- sb.append("rex.");
- if (options & Inst::kOptionOpCodeR) sb.append('r');
- if (options & Inst::kOptionOpCodeX) sb.append('x');
- if (options & Inst::kOptionOpCodeB) sb.append('b');
- if (options & Inst::kOptionOpCodeW) sb.append('w');
+ if (Support::test(options, InstOptions::kX86_Rex)) {
+ const InstOptions kRXBWMask = InstOptions::kX86_OpCodeR |
+ InstOptions::kX86_OpCodeX |
+ InstOptions::kX86_OpCodeB |
+ InstOptions::kX86_OpCodeW ;
+ if (Support::test(options, kRXBWMask)) {
+ ASMJIT_PROPAGATE(sb.append("rex."));
+ if (Support::test(options, InstOptions::kX86_OpCodeR)) sb.append('r');
+ if (Support::test(options, InstOptions::kX86_OpCodeX)) sb.append('x');
+ if (Support::test(options, InstOptions::kX86_OpCodeB)) sb.append('b');
+ if (Support::test(options, InstOptions::kX86_OpCodeW)) sb.append('w');
sb.append(' ');
}
else {
@@ -853,11 +929,7 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
}
}
- // VEX|EVEX options.
- if (options & Inst::kOptionVex3) ASMJIT_PROPAGATE(sb.append("vex3 "));
- if (options & Inst::kOptionEvex) ASMJIT_PROPAGATE(sb.append("evex "));
-
- ASMJIT_PROPAGATE(InstAPI::instIdToString(arch, instId, sb));
+ ASMJIT_PROPAGATE(InstInternal::instIdToString(instId, sb));
}
else {
ASMJIT_PROPAGATE(sb.appendFormat("[InstId=#%u]", unsigned(instId)));
@@ -868,34 +940,47 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
if (op.isNone()) break;
ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", "));
- ASMJIT_PROPAGATE(formatOperand(sb, flags, emitter, arch, op));
+ ASMJIT_PROPAGATE(formatOperand(sb, formatFlags, emitter, arch, op));
- if (op.isImm() && (flags & FormatOptions::kFlagExplainImms)) {
+ if (op.isImm() && uint32_t(formatFlags & FormatFlags::kExplainImms)) {
uint32_t vecSize = 16;
for (uint32_t j = 0; j < opCount; j++)
if (operands[j].isReg())
- vecSize = Support::max<uint32_t>(vecSize, operands[j].size());
- ASMJIT_PROPAGATE(FormatterInternal_explainConst(sb, flags, instId, vecSize, op.as<Imm>()));
+ vecSize = Support::max<uint32_t>(vecSize, operands[j].as<Reg>().size());
+ ASMJIT_PROPAGATE(FormatterInternal_explainConst(sb, formatFlags, instId, vecSize, op.as<Imm>()));
}
// Support AVX-512 masking - {k}{z}.
if (i == 0) {
- if (inst.extraReg().group() == Reg::kGroupKReg) {
+ if (inst.extraReg().group() == RegGroup::kX86_K) {
ASMJIT_PROPAGATE(sb.append(" {"));
- ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, inst.extraReg().type(), inst.extraReg().id()));
+ ASMJIT_PROPAGATE(formatRegister(sb, formatFlags, emitter, arch, inst.extraReg().type(), inst.extraReg().id()));
ASMJIT_PROPAGATE(sb.append('}'));
- if (options & Inst::kOptionZMask)
+ if (Support::test(options, InstOptions::kX86_ZMask))
ASMJIT_PROPAGATE(sb.append("{z}"));
}
- else if (options & Inst::kOptionZMask) {
+ else if (Support::test(options, InstOptions::kX86_ZMask)) {
ASMJIT_PROPAGATE(sb.append(" {z}"));
}
}
// Support AVX-512 broadcast - {1tox}.
if (op.isMem() && op.as<Mem>().hasBroadcast()) {
- ASMJIT_PROPAGATE(sb.appendFormat(" {1to%u}", Support::bitMask(op.as<Mem>().getBroadcast())));
+ ASMJIT_PROPAGATE(sb.appendFormat(" {1to%u}", Support::bitMask(uint32_t(op.as<Mem>().getBroadcast()))));
+ }
+ }
+
+ // Support AVX-512 embedded rounding and suppress-all-exceptions {sae}.
+ if (inst.hasOption(InstOptions::kX86_ER | InstOptions::kX86_SAE)) {
+ if (inst.hasOption(InstOptions::kX86_ER)) {
+ uint32_t bits = uint32_t(inst.options() & InstOptions::kX86_ERMask) >> Support::ConstCTZ<uint32_t(InstOptions::kX86_ERMask)>::value;
+
+ const char roundingModes[] = "rn\0rd\0ru\0rz";
+ ASMJIT_PROPAGATE(sb.appendFormat(", {%s-sae}", roundingModes + bits * 3));
+ }
+ else {
+ ASMJIT_PROPAGATE(sb.append(", {sae}"));
}
}
@@ -904,4 +989,4 @@ ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
ASMJIT_END_SUB_NAMESPACE
-#endif // !ASMJIT_NO_LOGGING
+#endif // !ASMJIT_NO_X86 && !ASMJIT_NO_LOGGING