Added new instructions and removed deprecated PCOMMIT

This commit is contained in:
kobalicek
2020-07-05 00:45:03 +02:00
parent ba30278d66
commit 75f2b69a26
11 changed files with 3055 additions and 2889 deletions

View File

@@ -662,7 +662,8 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
// This sequence seems to be the fastest.
opcode = InstDB::_mainOpcodeTable[instInfo->_mainOpcodeIndex];
opReg = opcode.extractO();
opReg = opcode.extractModO();
rbReg = 0;
opcode |= instInfo->_mainOpcodeValue;
// --------------------------------------------------------------------------
@@ -687,16 +688,17 @@ ASMJIT_FAVOR_SPEED Error Assembler::_emit(uint32_t instId, const Operand_& o0, c
case InstDB::kEncodingX86Op:
goto EmitX86Op;
case InstDB::kEncodingX86Op_O_I8:
case InstDB::kEncodingX86Op_Mod11RM:
rbReg = opcode.extractModRM();
goto EmitX86R;
case InstDB::kEncodingX86Op_Mod11RM_I8:
if (ASMJIT_UNLIKELY(isign3 != ENC_OPS1(Imm)))
goto InvalidInstruction;
rbReg = opcode.extractModRM();
immValue = o0.as<Imm>().valueAs<uint8_t>();
immSize = 1;
ASMJIT_FALLTHROUGH;
case InstDB::kEncodingX86Op_O:
rbReg = 0;
goto EmitX86R;
case InstDB::kEncodingX86Op_xAddr:
@@ -1126,7 +1128,7 @@ CaseX86M_GPB_MulDiv:
opcode = x86AltOpcodeOf(instInfo);
opcode.addPrefixBySize(o0.size());
opReg = opcode.extractO();
opReg = opcode.extractModO();
if (isign3 == ENC_OPS2(Reg, Imm)) {
rbReg = o0.id();
@@ -2093,7 +2095,7 @@ CaseX86PushPop_Gp:
// The following instructions use the secondary opcode.
opcode = x86AltOpcodeOf(instInfo);
opReg = opcode.extractO();
opReg = opcode.extractModO();
if (isign3 == ENC_OPS2(Reg, Imm)) {
opcode.addArithBySize(o0.size());
@@ -2294,7 +2296,7 @@ CaseFpuArith_Mem:
if (o0.size() == 10 && commonInfo->hasFlag(InstDB::kFlagFpuM80)) {
opcode = x86AltOpcodeOf(instInfo);
opReg = opcode.extractO();
opReg = opcode.extractModO();
goto EmitX86M;
}
}
@@ -2323,7 +2325,7 @@ CaseFpuArith_Mem:
if (o0.size() == 8 && commonInfo->hasFlag(InstDB::kFlagFpuM64)) {
opcode = x86AltOpcodeOf(instInfo) & ~uint32_t(Opcode::kCDSHL_Mask);
opReg = opcode.extractO();
opReg = opcode.extractModO();
goto EmitX86M;
}
}
@@ -2642,7 +2644,7 @@ CaseExtRm:
// The following instruction uses the secondary opcode.
opcode = x86AltOpcodeOf(instInfo);
opReg = opcode.extractO();
opReg = opcode.extractModO();
if (isign3 == ENC_OPS2(Reg, Imm)) {
immValue = o1.as<Imm>().value();
@@ -2672,7 +2674,7 @@ CaseExtRm:
// The following instruction uses the secondary opcode.
opcode = x86AltOpcodeOf(instInfo);
opReg = opcode.extractO();
opReg = opcode.extractModO();
if (isign3 == ENC_OPS2(Reg, Imm)) {
opcode.add66hIf(Reg::isXmm(o0));
@@ -2742,7 +2744,7 @@ CaseExtRm:
(uint32_t(o2.as<Imm>().valueAs<uint8_t>()) << 8) ;
immSize = 2;
rbReg = opcode.extractO();
rbReg = opcode.extractModO();
goto EmitX86R;
}
break;
@@ -3065,7 +3067,6 @@ CaseVexRvm_R:
if (o3.isMem()) {
rmRel = &o3;
goto EmitVexEvexM;
}
}
break;
@@ -3454,7 +3455,7 @@ CaseVexRvm_R:
// The following instruction uses the secondary opcode.
opcode &= Opcode::kLL_Mask;
opcode |= x86AltOpcodeOf(instInfo);
opReg = opcode.extractO();
opReg = opcode.extractModO();
immValue = o2.as<Imm>().value();
immSize = 1;
@@ -3804,7 +3805,7 @@ EmitX86R:
{
uint32_t rex = opcode.extractRex(options) |
((opReg & 0x08) >> 1) | // REX.R (0x04).
((rbReg ) >> 3) ; // REX.B (0x01).
((rbReg & 0x08) >> 3) ; // REX.B (0x01).
if (ASMJIT_UNLIKELY(x86IsRexInvalid(rex)))
goto InvalidRexPrefix;
@@ -3820,8 +3821,8 @@ EmitX86R:
// Emit ModR.
writer.emit8(x86EncodeMod(3, opReg, rbReg));
// Emit immediate value.
// Emit immediate value.
writer.emitImmediate(uint64_t(immValue), immSize);
goto EmitDone;

View File

@@ -178,9 +178,11 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
// [asmjit::x86::EmitterExplicitT]
// ============================================================================
//! Emitter (X86 - explicit).
template<typename This>
struct EmitterExplicitT {
//! \cond
// These typedefs are used to describe implicit operands passed explicitly.
typedef Gp AL;
typedef Gp AH;
@@ -721,6 +723,10 @@ public:
ASMJIT_INST_2i(test, Test, Gp, Imm) // ANY
ASMJIT_INST_2x(test, Test, Mem, Gp) // ANY
ASMJIT_INST_2i(test, Test, Mem, Imm) // ANY
ASMJIT_INST_2x(ud0, Ud0, Reg, Reg) // ANY
ASMJIT_INST_2x(ud0, Ud0, Reg, Mem) // ANY
ASMJIT_INST_2x(ud1, Ud1, Reg, Reg) // ANY
ASMJIT_INST_2x(ud1, Ud1, Reg, Mem) // ANY
ASMJIT_INST_0x(ud2, Ud2) // ANY
ASMJIT_INST_2x(xadd, Xadd, Gp, Gp) // ANY
ASMJIT_INST_2x(xadd, Xadd, Mem, Gp) // ANY
@@ -755,9 +761,12 @@ public:
//! \}
//! \name In/Out Instructions
//! \name IN/OUT Instructions
//! \{
// NOTE: For some reason Doxygen is messed up here and thinks we are in cond.
//! \endcond
ASMJIT_INST_2i(in, In, ZAX, Imm) // ANY
ASMJIT_INST_2x(in, In, ZAX, DX) // ANY
ASMJIT_INST_2x(ins, Ins, ES_ZDI, DX) // ANY
@@ -767,7 +776,7 @@ public:
//! \}
//! \name Clear/Set CL/DF Instructions
//! \name Clear/Set CF/DF Instructions
//! \{
ASMJIT_INST_0x(clc, Clc) // ANY
@@ -956,10 +965,11 @@ public:
//! \}
//! \name RDPRU Instruction
//! \name RDPRU/RDPKRU Instructions
//! \{
ASMJIT_INST_3x(rdpru, Rdpru, ECX, EDX, EAX) // RDPRU [EXPLICIT] EDX:EAX <- PRU[ECX]
ASMJIT_INST_3x(rdpru, Rdpru, EDX, EAX, ECX) // RDPRU [EXPLICIT] EDX:EAX <- PRU[ECX]
ASMJIT_INST_3x(rdpkru, Rdpkru, EDX, EAX, ECX) // RDPKRU [EXPLICIT] EDX:EAX <- PKRU[ECX]
//! \}
@@ -1061,14 +1071,21 @@ public:
//! \}
//! \name PCOMMIT/MCOMMIT Instructions
//! \name MCOMMIT Instruction
//! \{
ASMJIT_INST_0x(pcommit, Pcommit) // PCOMMIT
ASMJIT_INST_0x(mcommit, Mcommit) // MCOMMIT
//! \}
//! \name PTWRITE Instruction
//! \{
ASMJIT_INST_1x(ptwrite, Ptwrite, Gp) // PTWRITE
ASMJIT_INST_1x(ptwrite, Ptwrite, Mem) // PTWRITE
//! \}
//! \name ENQCMD Instructions
//! \{
@@ -1126,6 +1143,34 @@ public:
//! \}
//! \name CET-IBT Instructions
//! \{
ASMJIT_INST_0x(endbr32, Endbr32)
ASMJIT_INST_0x(endbr64, Endbr64)
//! \}
//! \name CET-SS Instructions
//! \{
ASMJIT_INST_1x(clrssbsy, Clrssbsy, Mem)
ASMJIT_INST_0x(setssbsy, Setssbsy)
ASMJIT_INST_1x(rstorssp, Rstorssp, Mem)
ASMJIT_INST_0x(saveprevssp, Saveprevssp)
ASMJIT_INST_1x(incsspd, Incsspd, Gp)
ASMJIT_INST_1x(incsspq, Incsspq, Gp)
ASMJIT_INST_1x(rdsspd, Rdsspd, Gp)
ASMJIT_INST_1x(rdsspq, Rdsspq, Gp)
ASMJIT_INST_2x(wrssd, Wrssd, Mem, Gp)
ASMJIT_INST_2x(wrssq, Wrssq, Mem, Gp)
ASMJIT_INST_2x(wrussd, Wrussd, Mem, Gp)
ASMJIT_INST_2x(wrussq, Wrussq, Mem, Gp)
//! \}
//! \name Core Privileged Instructions
//! \{
@@ -1216,13 +1261,6 @@ public:
//! \}
//! \name SYSCALL & SYSENTER Instructions
//! \{
//! \}
//! \name FPU Instructions
//! \{
@@ -2127,6 +2165,9 @@ public:
//! \name GFNI Instructions
//! \{
// NOTE: For some reason Doxygen is messed up here and thinks we are in cond.
//! \endcond
ASMJIT_INST_3i(gf2p8affineinvqb, Gf2p8affineinvqb, Xmm, Xmm, Imm) // GFNI
ASMJIT_INST_3i(gf2p8affineinvqb, Gf2p8affineinvqb, Xmm, Mem, Imm) // GFNI
ASMJIT_INST_3i(gf2p8affineqb, Gf2p8affineqb, Xmm, Xmm, Imm) // GFNI
@@ -3707,6 +3748,7 @@ public:
// [asmjit::x86::EmitterImplicitT]
// ============================================================================
//! Emitter (X86 - implicit).
template<typename This>
struct EmitterImplicitT : public EmitterExplicitT<This> {
//! \cond
@@ -3863,6 +3905,7 @@ struct EmitterImplicitT : public EmitterExplicitT<This> {
//! \}
//! \name CPUID Instruction
//! \{
//! \cond
using EmitterExplicitT<This>::cpuid;
@@ -3883,14 +3926,16 @@ struct EmitterImplicitT : public EmitterExplicitT<This> {
//! \}
//! \name RDPRU Instruction
//! \name RDPRU/RDPKRU Instructions
//! \{
//! \cond
using EmitterExplicitT<This>::rdpru;
using EmitterExplicitT<This>::rdpkru;
//! \endcond
ASMJIT_INST_0x(rdpru, Rdpru) // RDPRU [IMPLICIT] EDX:EAX <- PRU[ECX]
ASMJIT_INST_0x(rdpkru, Rdpkru) // RDPKRU [IMPLICIT] EDX:EAX <- PKRU[ECX]
//! \}

View File

@@ -146,17 +146,19 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
features.add(Features::kI486);
// --------------------------------------------------------------------------
// [CPUID EAX=0x0]
// [CPUID EAX=0]
// --------------------------------------------------------------------------
// Get vendor string/id.
cpuidQuery(&regs, 0x0);
uint32_t maxId = regs.eax;
uint32_t maxSubLeafId_0x7 = 0;
simplifyCpuVendor(cpu, regs.ebx, regs.edx, regs.ecx);
// --------------------------------------------------------------------------
// [CPUID EAX=0x1]
// [CPUID EAX=1]
// --------------------------------------------------------------------------
if (maxId >= 0x1) {
@@ -205,12 +207,12 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
if (bitTest(regs.edx, 19)) features.add(Features::kCLFLUSH);
if (bitTest(regs.edx, 23)) features.add(Features::kMMX);
if (bitTest(regs.edx, 24)) features.add(Features::kFXSR);
if (bitTest(regs.edx, 25)) features.add(Features::kSSE, Features::kMMX2);
if (bitTest(regs.edx, 25)) features.add(Features::kSSE);
if (bitTest(regs.edx, 26)) features.add(Features::kSSE, Features::kSSE2);
if (bitTest(regs.edx, 28)) features.add(Features::kMT);
// Get the content of XCR0 if supported by CPU and enabled by OS.
if ((regs.ecx & 0x0C000000u) == 0x0C000000u) {
// Get the content of XCR0 if supported by the CPU and enabled by the OS.
if (features.hasXSAVE() && features.hasOSXSAVE()) {
xgetbvQuery(&xcr0, 0);
}
@@ -227,8 +229,23 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
}
}
constexpr uint32_t kXCR0_AMX_Bits = 0x3u << 17;
bool amxEnabledByOS = (xcr0.eax & kXCR0_AMX_Bits) == kXCR0_AMX_Bits;
#if defined(__APPLE__)
// Apple platform provides on-demand AVX512 support. When an AVX512 instruction is used
// the first time it results in #UD, which would cause the thread being promoted to use
// AVX512 support by the OS in addition to enabling the necessary bits in XCR0 register.
bool avx512EnabledByOS = true;
#else
// - XCR0[2:1] == 11b - XMM/YMM states need to be enabled by OS.
// - XCR0[7:5] == 111b - Upper 256-bit of ZMM0-XMM15 and ZMM16-ZMM31 need to be enabled by OS.
constexpr uint32_t kXCR0_AVX512_Bits = (0x3u << 1) | (0x7u << 5);
bool avx512EnabledByOS = (xcr0.eax & kXCR0_AVX512_Bits) == kXCR0_AVX512_Bits;
#endif
// --------------------------------------------------------------------------
// [CPUID EAX=0x7]
// [CPUID EAX=7 ECX=0]
// --------------------------------------------------------------------------
// Detect new features if the processor supports CPUID-07.
@@ -236,7 +253,9 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
if (maxId >= 0x7) {
cpuidQuery(&regs, 0x7);
uint32_t maxSubLeafId = regs.eax;
maybeMPX = bitTest(regs.ebx, 14);
maxSubLeafId_0x7 = regs.eax;
if (bitTest(regs.ebx, 0)) features.add(Features::kFSGSBASE);
if (bitTest(regs.ebx, 3)) features.add(Features::kBMI);
@@ -245,15 +264,18 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
if (bitTest(regs.ebx, 8)) features.add(Features::kBMI2);
if (bitTest(regs.ebx, 9)) features.add(Features::kERMS);
if (bitTest(regs.ebx, 11)) features.add(Features::kRTM);
if (bitTest(regs.ebx, 14)) maybeMPX = true;
if (bitTest(regs.ebx, 18)) features.add(Features::kRDSEED);
if (bitTest(regs.ebx, 19)) features.add(Features::kADX);
if (bitTest(regs.ebx, 20)) features.add(Features::kSMAP);
if (bitTest(regs.ebx, 22)) features.add(Features::kPCOMMIT);
if (bitTest(regs.ebx, 23)) features.add(Features::kCLFLUSHOPT);
if (bitTest(regs.ebx, 24)) features.add(Features::kCLWB);
if (bitTest(regs.ebx, 29)) features.add(Features::kSHA);
if (bitTest(regs.ecx, 0)) features.add(Features::kPREFETCHWT1);
if (bitTest(regs.ecx, 4)) features.add(Features::kOSPKE);
if (bitTest(regs.ecx, 5)) features.add(Features::kWAITPKG);
if (bitTest(regs.ecx, 8)) features.add(Features::kGFNI);
if (bitTest(regs.ecx, 9)) features.add(Features::kVAES);
if (bitTest(regs.ecx, 10)) features.add(Features::kVPCLMULQDQ);
if (bitTest(regs.ecx, 22)) features.add(Features::kRDPID);
if (bitTest(regs.ecx, 25)) features.add(Features::kCLDEMOTE);
if (bitTest(regs.ecx, 27)) features.add(Features::kMOVDIRI);
@@ -262,9 +284,6 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
if (bitTest(regs.edx, 14)) features.add(Features::kSERIALIZE);
if (bitTest(regs.edx, 16)) features.add(Features::kTSXLDTRK);
if (bitTest(regs.edx, 18)) features.add(Features::kPCONFIG);
if (bitTest(regs.edx, 22)) features.add(Features::kAMX_BF16);
if (bitTest(regs.edx, 24)) features.add(Features::kAMX_TILE);
if (bitTest(regs.edx, 25)) features.add(Features::kAMX_INT8);
// Detect 'TSX' - Requires at least one of `HLE` and `RTM` features.
if (features.hasHLE() || features.hasRTM())
@@ -274,11 +293,15 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
if (bitTest(regs.ebx, 5) && features.hasAVX())
features.add(Features::kAVX2);
// Detect 'AMX'.
if (amxEnabledByOS) {
if (bitTest(regs.edx, 22)) features.add(Features::kAMX_BF16);
if (bitTest(regs.edx, 24)) features.add(Features::kAMX_TILE);
if (bitTest(regs.edx, 25)) features.add(Features::kAMX_INT8);
}
// Detect 'AVX_512'.
if (bitTest(regs.ebx, 16)) {
// - XCR0[2:1] == 11b - XMM/YMM states need to be enabled by OS.
// - XCR0[7:5] == 111b - Upper 256-bit of ZMM0-XMM15 and ZMM16-ZMM31 need to be enabled by OS.
if ((xcr0.eax & 0x000000E6u) == 0x000000E6u) {
if (avx512EnabledByOS && bitTest(regs.ebx, 16)) {
features.add(Features::kAVX512_F);
if (bitTest(regs.ebx, 17)) features.add(Features::kAVX512_DQ);
@@ -289,11 +312,7 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
if (bitTest(regs.ebx, 30)) features.add(Features::kAVX512_BW);
if (bitTest(regs.ebx, 31)) features.add(Features::kAVX512_VL);
if (bitTest(regs.ecx, 1)) features.add(Features::kAVX512_VBMI);
if (bitTest(regs.ecx, 5)) features.add(Features::kWAITPKG);
if (bitTest(regs.ecx, 6)) features.add(Features::kAVX512_VBMI2);
if (bitTest(regs.ecx, 8)) features.add(Features::kGFNI);
if (bitTest(regs.ecx, 9)) features.add(Features::kVAES);
if (bitTest(regs.ecx, 10)) features.add(Features::kVPCLMULQDQ);
if (bitTest(regs.ecx, 11)) features.add(Features::kAVX512_VNNI);
if (bitTest(regs.ecx, 12)) features.add(Features::kAVX512_BITALG);
if (bitTest(regs.ecx, 14)) features.add(Features::kAVX512_VPOPCNTDQ);
@@ -303,15 +322,18 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
}
}
if (maxSubLeafId >= 1 && features.hasAVX512_F()) {
// --------------------------------------------------------------------------
// [CPUID EAX=7 ECX=1]
// --------------------------------------------------------------------------
if (features.hasAVX512_F() && maxSubLeafId_0x7 >= 1) {
cpuidQuery(&regs, 0x7, 1);
if (bitTest(regs.eax, 5)) features.add(Features::kAVX512_BF16);
}
}
// --------------------------------------------------------------------------
// [CPUID EAX=0xD]
// [CPUID EAX=13 ECX=0]
// --------------------------------------------------------------------------
if (maxId >= 0xD) {
@@ -322,11 +344,22 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
features.add(Features::kMPX);
cpuidQuery(&regs, 0xD, 1);
if (bitTest(regs.eax, 0)) features.add(Features::kXSAVEOPT);
if (bitTest(regs.eax, 1)) features.add(Features::kXSAVEC);
if (bitTest(regs.eax, 3)) features.add(Features::kXSAVES);
}
// --------------------------------------------------------------------------
// [CPUID EAX=14 ECX=0]
// --------------------------------------------------------------------------
if (maxId >= 0xE) {
cpuidQuery(&regs, 0xE, 0);
if (bitTest(regs.ebx, 4)) features.add(Features::kPTWRITE);
}
// --------------------------------------------------------------------------
// [CPUID EAX=0x80000000...maxId]
// --------------------------------------------------------------------------

View File

@@ -76,6 +76,8 @@ public:
kAVX512_VPOPCNTDQ, //!< CPU has AVX512_VPOPCNTDQ (VPOPCNT[D|Q] instructions).
kBMI, //!< CPU has BMI (bit manipulation instructions #1).
kBMI2, //!< CPU has BMI2 (bit manipulation instructions #2).
kCET_IBT, //!< CPU has CET-IBT.
kCET_SS, //!< CPU has CET-SS.
kCLDEMOTE, //!< CPU has CLDEMOTE (cache line demote).
kCLFLUSH, //!< CPU has CLFUSH (Cache Line flush).
kCLFLUSHOPT, //!< CPU has CLFUSHOPT (Cache Line flush - optimized).
@@ -113,12 +115,13 @@ public:
kMSR, //!< CPU has MSR (RDMSR/WRMSR instructions).
kMSSE, //!< CPU has MSSE (misaligned SSE support).
kOSXSAVE, //!< CPU has OSXSAVE (XSAVE enabled by OS).
kOSPKE, //!< CPU has OSPKE (PKE enabled by OS).
kPCLMULQDQ, //!< CPU has PCLMULQDQ (packed carry-less multiplication).
kPCOMMIT, //!< CPU has PCOMMIT (PCOMMIT instruction).
kPCONFIG, //!< CPU has PCONFIG (PCONFIG instruction).
kPOPCNT, //!< CPU has POPCNT (POPCNT instruction).
kPREFETCHW, //!< CPU has PREFETCHW.
kPREFETCHWT1, //!< CPU has PREFETCHWT1.
kPTWRITE, //!< CPU has PTWRITE.
kRDPID, //!< CPU has RDPID.
kRDPRU, //!< CPU has RDPRU.
kRDRAND, //!< CPU has RDRAND.
@@ -253,11 +256,11 @@ public:
ASMJIT_X86_FEATURE(MSSE)
ASMJIT_X86_FEATURE(OSXSAVE)
ASMJIT_X86_FEATURE(PCLMULQDQ)
ASMJIT_X86_FEATURE(PCOMMIT)
ASMJIT_X86_FEATURE(PCONFIG)
ASMJIT_X86_FEATURE(POPCNT)
ASMJIT_X86_FEATURE(PREFETCHW)
ASMJIT_X86_FEATURE(PREFETCHWT1)
ASMJIT_X86_FEATURE(PTWRITE)
ASMJIT_X86_FEATURE(RDPID)
ASMJIT_X86_FEATURE(RDPRU)
ASMJIT_X86_FEATURE(RDRAND)

View File

@@ -240,6 +240,8 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"AVX512_VPOPCNTDQ\0"
"BMI\0"
"BMI2\0"
"CET_IBT\0"
"CET_SS\0"
"CLDEMOTE\0"
"CLFLUSH\0"
"CLFLUSHOPT\0"
@@ -277,12 +279,13 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
"MSR\0"
"MSSE\0"
"OSXSAVE\0"
"OSPKE\0"
"PCLMULQDQ\0"
"PCOMMIT\0"
"PCONFIG\0"
"POPCNT\0"
"PREFETCHW\0"
"PREFETCHWT1\0"
"PTWRITE\0"
"RDPID\0"
"RDPRU\0"
"RDRAND\0"
@@ -322,13 +325,13 @@ Error FormatterInternal::formatFeature(String& sb, uint32_t featureId) noexcept
static const uint16_t sFeatureIndex[] = {
0, 5, 8, 11, 17, 24, 28, 34, 44, 53, 62, 71, 75, 80, 94, 108, 120, 134, 144,
155, 165, 176, 185, 197, 208, 220, 233, 243, 255, 275, 292, 296, 301, 310,
318, 329, 334, 341, 346, 357, 367, 373, 380, 385, 390, 394, 399, 403, 412,
417, 425, 431, 436, 440, 445, 454, 458, 464, 472, 476, 481, 489, 498, 504,
514, 522, 526, 530, 535, 543, 553, 561, 569, 576, 586, 598, 604, 610, 617,
624, 630, 637, 641, 651, 655, 662, 667, 672, 676, 680, 684, 689, 694, 701,
708, 714, 720, 724, 728, 732, 741, 746, 750, 761, 769, 778, 782, 788, 795,
804, 811
155, 165, 176, 185, 197, 208, 220, 233, 243, 255, 275, 292, 296, 301, 309,
316, 325, 333, 344, 349, 356, 361, 372, 382, 388, 395, 400, 405, 409, 414,
418, 427, 432, 440, 446, 451, 455, 460, 469, 473, 479, 487, 491, 496, 504,
513, 519, 529, 537, 541, 545, 550, 558, 564, 574, 582, 589, 599, 611, 619,
625, 631, 638, 645, 651, 658, 662, 672, 676, 683, 688, 693, 697, 701, 705,
710, 715, 722, 729, 735, 741, 745, 749, 753, 762, 767, 771, 782, 790, 799,
803, 809, 816, 825, 832
};
// @EnumStringEnd@

View File

@@ -119,6 +119,7 @@ struct Inst : public BaseInst {
kIdClflushopt, //!< Instruction 'clflushopt' {CLFLUSHOPT}.
kIdClgi, //!< Instruction 'clgi' {SVM}.
kIdCli, //!< Instruction 'cli'.
kIdClrssbsy, //!< Instruction 'clrssbsy' {CET_SS}.
kIdClts, //!< Instruction 'clts'.
kIdClwb, //!< Instruction 'clwb' {CLWB}.
kIdClzero, //!< Instruction 'clzero' {CLZERO}.
@@ -202,6 +203,8 @@ struct Inst : public BaseInst {
kIdDppd, //!< Instruction 'dppd' {SSE4_1}.
kIdDpps, //!< Instruction 'dpps' {SSE4_1}.
kIdEmms, //!< Instruction 'emms' {MMX}.
kIdEndbr32, //!< Instruction 'endbr32' {CET_IBT}.
kIdEndbr64, //!< Instruction 'endbr64' {CET_IBT}.
kIdEnqcmd, //!< Instruction 'enqcmd' {ENQCMD}.
kIdEnqcmds, //!< Instruction 'enqcmds' {ENQCMD}.
kIdEnter, //!< Instruction 'enter'.
@@ -318,6 +321,8 @@ struct Inst : public BaseInst {
kIdImul, //!< Instruction 'imul'.
kIdIn, //!< Instruction 'in'.
kIdInc, //!< Instruction 'inc'.
kIdIncsspd, //!< Instruction 'incsspd' {CET_SS}.
kIdIncsspq, //!< Instruction 'incsspq' {CET_SS} (X64).
kIdIns, //!< Instruction 'ins'.
kIdInsertps, //!< Instruction 'insertps' {SSE4_1}.
kIdInsertq, //!< Instruction 'insertq' {SSE4A}.
@@ -551,7 +556,6 @@ struct Inst : public BaseInst {
kIdPcmpgtw, //!< Instruction 'pcmpgtw' {MMX|SSE2}.
kIdPcmpistri, //!< Instruction 'pcmpistri' {SSE4_2}.
kIdPcmpistrm, //!< Instruction 'pcmpistrm' {SSE4_2}.
kIdPcommit, //!< Instruction 'pcommit' {PCOMMIT}.
kIdPconfig, //!< Instruction 'pconfig' {PCONFIG}.
kIdPdep, //!< Instruction 'pdep' {BMI2}.
kIdPext, //!< Instruction 'pext' {BMI2}.
@@ -673,6 +677,7 @@ struct Inst : public BaseInst {
kIdPsubw, //!< Instruction 'psubw' {MMX|SSE2}.
kIdPswapd, //!< Instruction 'pswapd' {3DNOW2}.
kIdPtest, //!< Instruction 'ptest' {SSE4_1}.
kIdPtwrite, //!< Instruction 'ptwrite' {PTWRITE}.
kIdPunpckhbw, //!< Instruction 'punpckhbw' {MMX|SSE2}.
kIdPunpckhdq, //!< Instruction 'punpckhdq' {MMX|SSE2}.
kIdPunpckhqdq, //!< Instruction 'punpckhqdq' {SSE2}.
@@ -697,10 +702,13 @@ struct Inst : public BaseInst {
kIdRdgsbase, //!< Instruction 'rdgsbase' {FSGSBASE} (X64).
kIdRdmsr, //!< Instruction 'rdmsr' {MSR}.
kIdRdpid, //!< Instruction 'rdpid' {RDPID}.
kIdRdpkru, //!< Instruction 'rdpkru' {OSPKE}.
kIdRdpmc, //!< Instruction 'rdpmc'.
kIdRdpru, //!< Instruction 'rdpru' {RDPRU}.
kIdRdrand, //!< Instruction 'rdrand' {RDRAND}.
kIdRdseed, //!< Instruction 'rdseed' {RDSEED}.
kIdRdsspd, //!< Instruction 'rdsspd' {CET_SS}.
kIdRdsspq, //!< Instruction 'rdsspq' {CET_SS} (X64).
kIdRdtsc, //!< Instruction 'rdtsc' {RDTSC}.
kIdRdtscp, //!< Instruction 'rdtscp' {RDTSCP}.
kIdRet, //!< Instruction 'ret'.
@@ -716,10 +724,12 @@ struct Inst : public BaseInst {
kIdRsm, //!< Instruction 'rsm' (X86).
kIdRsqrtps, //!< Instruction 'rsqrtps' {SSE}.
kIdRsqrtss, //!< Instruction 'rsqrtss' {SSE}.
kIdRstorssp, //!< Instruction 'rstorssp' {CET_SS}.
kIdSahf, //!< Instruction 'sahf' {LAHFSAHF}.
kIdSal, //!< Instruction 'sal'.
kIdSar, //!< Instruction 'sar'.
kIdSarx, //!< Instruction 'sarx' {BMI2}.
kIdSaveprevssp, //!< Instruction 'saveprevssp' {CET_SS}.
kIdSbb, //!< Instruction 'sbb'.
kIdScas, //!< Instruction 'scas'.
kIdSerialize, //!< Instruction 'serialize' {SERIALIZE}.
@@ -752,6 +762,7 @@ struct Inst : public BaseInst {
kIdSetpe, //!< Instruction 'setpe'.
kIdSetpo, //!< Instruction 'setpo'.
kIdSets, //!< Instruction 'sets'.
kIdSetssbsy, //!< Instruction 'setssbsy' {CET_SS}.
kIdSetz, //!< Instruction 'setz'.
kIdSfence, //!< Instruction 'sfence' {MMX2}.
kIdSgdt, //!< Instruction 'sgdt'.
@@ -817,6 +828,8 @@ struct Inst : public BaseInst {
kIdTzmsk, //!< Instruction 'tzmsk' {TBM}.
kIdUcomisd, //!< Instruction 'ucomisd' {SSE2}.
kIdUcomiss, //!< Instruction 'ucomiss' {SSE}.
kIdUd0, //!< Instruction 'ud0'.
kIdUd1, //!< Instruction 'ud1'.
kIdUd2, //!< Instruction 'ud2'.
kIdUmonitor, //!< Instruction 'umonitor' {WAITPKG}.
kIdUmwait, //!< Instruction 'umwait' {WAITPKG}.
@@ -1553,6 +1566,10 @@ struct Inst : public BaseInst {
kIdWrfsbase, //!< Instruction 'wrfsbase' {FSGSBASE} (X64).
kIdWrgsbase, //!< Instruction 'wrgsbase' {FSGSBASE} (X64).
kIdWrmsr, //!< Instruction 'wrmsr' {MSR}.
kIdWrssd, //!< Instruction 'wrssd' {CET_SS}.
kIdWrssq, //!< Instruction 'wrssq' {CET_SS} (X64).
kIdWrussd, //!< Instruction 'wrussd' {CET_SS}.
kIdWrussq, //!< Instruction 'wrussq' {CET_SS} (X64).
kIdXabort, //!< Instruction 'xabort' {RTM}.
kIdXadd, //!< Instruction 'xadd' {I486}.
kIdXbegin, //!< Instruction 'xbegin' {RTM}.

File diff suppressed because it is too large Load Diff

View File

@@ -48,8 +48,8 @@ namespace InstDB {
enum EncodingId : uint32_t {
kEncodingNone = 0, //!< Never used.
kEncodingX86Op, //!< X86 [OP].
kEncodingX86Op_O, //!< X86 [OP] (opcode and /0-7).
kEncodingX86Op_O_I8, //!< X86 [OP] (opcode and /0-7 + 8-bit immediate).
kEncodingX86Op_Mod11RM, //!< X86 [OP] (opcode with ModRM byte where MOD must be 11b).
kEncodingX86Op_Mod11RM_I8, //!< X86 [OP] (opcode with ModRM byte + 8-bit immediate).
kEncodingX86Op_xAddr, //!< X86 [OP] (implicit address in the first register operand).
kEncodingX86Op_xAX, //!< X86 [OP] (implicit or explicit '?AX' form).
kEncodingX86Op_xDX_xAX, //!< X86 [OP] (implicit or explicit '?DX, ?AX' form).

View File

@@ -230,21 +230,41 @@ struct Opcode {
kCDTT_T4X = kCDTT_T1_4X, // Alias to have only 3 letters.
// `O` Field in MorR/M
// -------------------
// `O` Field in ModR/M (??:xxx:???)
// --------------------------------
kO_Shift = 18,
kO_Mask = 0x7u << kO_Shift,
kModO_Shift = 18,
kModO_Mask = 0x7u << kModO_Shift,
kO__ = 0x0u,
kO_0 = 0x0u << kO_Shift,
kO_1 = 0x1u << kO_Shift,
kO_2 = 0x2u << kO_Shift,
kO_3 = 0x3u << kO_Shift,
kO_4 = 0x4u << kO_Shift,
kO_5 = 0x5u << kO_Shift,
kO_6 = 0x6u << kO_Shift,
kO_7 = 0x7u << kO_Shift,
kModO__ = 0x0u,
kModO_0 = 0x0u << kModO_Shift,
kModO_1 = 0x1u << kModO_Shift,
kModO_2 = 0x2u << kModO_Shift,
kModO_3 = 0x3u << kModO_Shift,
kModO_4 = 0x4u << kModO_Shift,
kModO_5 = 0x5u << kModO_Shift,
kModO_6 = 0x6u << kModO_Shift,
kModO_7 = 0x7u << kModO_Shift,
// `RM` Field in ModR/M (??:???:xxx)
// ---------------------------------
//
// Second data field used by ModR/M byte. This is only used by few
// instructions that use OPCODE+MOD/RM where both values in Mod/RM
// are part of the opcode.
kModRM_Shift = 10,
kModRM_Mask = 0x7u << kModRM_Shift,
kModRM__ = 0x0u,
kModRM_0 = 0x0u << kModRM_Shift,
kModRM_1 = 0x1u << kModRM_Shift,
kModRM_2 = 0x2u << kModRM_Shift,
kModRM_3 = 0x3u << kModRM_Shift,
kModRM_4 = 0x4u << kModRM_Shift,
kModRM_5 = 0x5u << kModRM_Shift,
kModRM_6 = 0x6u << kModRM_Shift,
kModRM_7 = 0x7u << kModRM_Shift,
// `PP` Field
// ----------
@@ -412,9 +432,14 @@ struct Opcode {
return operator|=(mask[size & 0xF]);
}
//! Extract `O` field from the opcode.
ASMJIT_INLINE uint32_t extractO() const noexcept {
return (v >> kO_Shift) & 0x07;
//! Extract `O` field (R) from the opcode (specified as /0..7 in instruction manuals).
ASMJIT_INLINE uint32_t extractModO() const noexcept {
return (v >> kModO_Shift) & 0x07;
}
//! Extract `RM` field (RM) from the opcode (usually specified as another opcode value).
ASMJIT_INLINE uint32_t extractModRM() const noexcept {
return (v >> kModRM_Shift) & 0x07;
}
//! Extract `REX` prefix from opcode combined with `options`.

View File

@@ -1066,10 +1066,6 @@ static void generateOpcodes(asmjit::x86::Emitter* e, bool useRex1 = false, bool
e->mwait(); // Implicit <EAX>, <ECX>
e->mwaitx(); // Implicit <EAX>, <ECX>, <EBX>
// PCOMMIT.
e->nop();
e->pcommit();
// PREFETCH / PREFETCHW / PREFETCHWT1.
e->nop();
e->prefetch(anyptr_gpA); // 3DNOW.

View File

@@ -552,7 +552,7 @@ class X86TableGen extends core.TableGen {
var enum_ = name[0].toUpperCase() + name.substr(1);
var opcode = dbi.opcodeHex;
var rm = dbi.rm;
var modR = dbi.modR;
var mm = dbi.mm;
var pp = dbi.pp;
var encoding = dbi.encoding;
@@ -590,7 +590,7 @@ class X86TableGen extends core.TableGen {
}
if (opcode !== dbi.opcodeHex ) { console.log(`ISSUE: Opcode ${opcode} != ${dbi.opcodeHex}`); return null; }
if (rm !== dbi.rm ) { console.log(`ISSUE: RM ${rm} != ${dbi.rm}`); return null; }
if (modR !== dbi.modR ) { console.log(`ISSUE: ModR ${modR} != ${dbi.modR}`); return null; }
if (mm !== dbi.mm ) { console.log(`ISSUE: MM ${mm} != ${dbi.mm}`); return null; }
if (pp !== dbi.pp ) { console.log(`ISSUE: PP ${pp} != ${dbi.pp}`); return null; }
if (encoding !== dbi.encoding ) { console.log(`ISSUE: Enc ${encoding} != ${dbi.encoding}`); return null; }
@@ -605,12 +605,12 @@ class X86TableGen extends core.TableGen {
type : isVec ? "V" : "O",
prefix: ppmm,
opcode: opcode,
o : rm === "r" ? "_" : (rm ? rm : "_"),
o : modR === "r" ? "_" : (modR ? modR : "_"),
l : vexL !== undefined ? vexL : "_",
w : vexW !== undefined ? vexW : "_",
ew : evexW !== undefined ? evexW : "_",
en : "_",
tt : "_ "
tt : dbi.modRM ? dbi.modRM + " " : "_ "
});
return {
@@ -736,7 +736,7 @@ class AltOpcodeTable extends core.Task {
}
// X(______,OP,_,_,_,_,_,_ )
if (opcode.startsWith("O_FPU(") || opcode.startsWith("O(") || opcode.startsWith("V(") || opcode.startsWith("E(")) {
if (opcode.startsWith("O(") || opcode.startsWith("V(") || opcode.startsWith("E(")) {
var value = opcode.substring(9, 11);
var remaining = opcode.substring(0, 9) + "00" + opcode.substring(11);