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

View File

@@ -178,9 +178,11 @@ ASMJIT_BEGIN_SUB_NAMESPACE(x86)
// [asmjit::x86::EmitterExplicitT] // [asmjit::x86::EmitterExplicitT]
// ============================================================================ // ============================================================================
//! Emitter (X86 - explicit).
template<typename This> template<typename This>
struct EmitterExplicitT { struct EmitterExplicitT {
//! \cond //! \cond
// These typedefs are used to describe implicit operands passed explicitly. // These typedefs are used to describe implicit operands passed explicitly.
typedef Gp AL; typedef Gp AL;
typedef Gp AH; typedef Gp AH;
@@ -721,6 +723,10 @@ public:
ASMJIT_INST_2i(test, Test, Gp, Imm) // ANY ASMJIT_INST_2i(test, Test, Gp, Imm) // ANY
ASMJIT_INST_2x(test, Test, Mem, Gp) // ANY ASMJIT_INST_2x(test, Test, Mem, Gp) // ANY
ASMJIT_INST_2i(test, Test, Mem, Imm) // 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_0x(ud2, Ud2) // ANY
ASMJIT_INST_2x(xadd, Xadd, Gp, Gp) // ANY ASMJIT_INST_2x(xadd, Xadd, Gp, Gp) // ANY
ASMJIT_INST_2x(xadd, Xadd, Mem, 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_2i(in, In, ZAX, Imm) // ANY
ASMJIT_INST_2x(in, In, ZAX, DX) // ANY ASMJIT_INST_2x(in, In, ZAX, DX) // ANY
ASMJIT_INST_2x(ins, Ins, ES_ZDI, 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 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 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 //! \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 //! \name Core Privileged Instructions
//! \{ //! \{
@@ -1216,13 +1261,6 @@ public:
//! \} //! \}
//! \name SYSCALL & SYSENTER Instructions
//! \{
//! \}
//! \name FPU Instructions //! \name FPU Instructions
//! \{ //! \{
@@ -2127,6 +2165,9 @@ public:
//! \name GFNI Instructions //! \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, Xmm, Imm) // GFNI
ASMJIT_INST_3i(gf2p8affineinvqb, Gf2p8affineinvqb, Xmm, Mem, Imm) // GFNI ASMJIT_INST_3i(gf2p8affineinvqb, Gf2p8affineinvqb, Xmm, Mem, Imm) // GFNI
ASMJIT_INST_3i(gf2p8affineqb, Gf2p8affineqb, Xmm, Xmm, Imm) // GFNI ASMJIT_INST_3i(gf2p8affineqb, Gf2p8affineqb, Xmm, Xmm, Imm) // GFNI
@@ -3707,6 +3748,7 @@ public:
// [asmjit::x86::EmitterImplicitT] // [asmjit::x86::EmitterImplicitT]
// ============================================================================ // ============================================================================
//! Emitter (X86 - implicit).
template<typename This> template<typename This>
struct EmitterImplicitT : public EmitterExplicitT<This> { struct EmitterImplicitT : public EmitterExplicitT<This> {
//! \cond //! \cond
@@ -3863,6 +3905,7 @@ struct EmitterImplicitT : public EmitterExplicitT<This> {
//! \} //! \}
//! \name CPUID Instruction //! \name CPUID Instruction
//! \{
//! \cond //! \cond
using EmitterExplicitT<This>::cpuid; using EmitterExplicitT<This>::cpuid;
@@ -3883,14 +3926,16 @@ struct EmitterImplicitT : public EmitterExplicitT<This> {
//! \} //! \}
//! \name RDPRU Instruction //! \name RDPRU/RDPKRU Instructions
//! \{ //! \{
//! \cond //! \cond
using EmitterExplicitT<This>::rdpru; using EmitterExplicitT<This>::rdpru;
using EmitterExplicitT<This>::rdpkru;
//! \endcond //! \endcond
ASMJIT_INST_0x(rdpru, Rdpru) // RDPRU [IMPLICIT] EDX:EAX <- PRU[ECX] 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); features.add(Features::kI486);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [CPUID EAX=0x0] // [CPUID EAX=0]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Get vendor string/id. // Get vendor string/id.
cpuidQuery(&regs, 0x0); cpuidQuery(&regs, 0x0);
uint32_t maxId = regs.eax; uint32_t maxId = regs.eax;
uint32_t maxSubLeafId_0x7 = 0;
simplifyCpuVendor(cpu, regs.ebx, regs.edx, regs.ecx); simplifyCpuVendor(cpu, regs.ebx, regs.edx, regs.ecx);
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [CPUID EAX=0x1] // [CPUID EAX=1]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
if (maxId >= 0x1) { 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, 19)) features.add(Features::kCLFLUSH);
if (bitTest(regs.edx, 23)) features.add(Features::kMMX); if (bitTest(regs.edx, 23)) features.add(Features::kMMX);
if (bitTest(regs.edx, 24)) features.add(Features::kFXSR); 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, 26)) features.add(Features::kSSE, Features::kSSE2);
if (bitTest(regs.edx, 28)) features.add(Features::kMT); if (bitTest(regs.edx, 28)) features.add(Features::kMT);
// Get the content of XCR0 if supported by CPU and enabled by OS. // Get the content of XCR0 if supported by the CPU and enabled by the OS.
if ((regs.ecx & 0x0C000000u) == 0x0C000000u) { if (features.hasXSAVE() && features.hasOSXSAVE()) {
xgetbvQuery(&xcr0, 0); 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. // Detect new features if the processor supports CPUID-07.
@@ -236,7 +253,9 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
if (maxId >= 0x7) { if (maxId >= 0x7) {
cpuidQuery(&regs, 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, 0)) features.add(Features::kFSGSBASE);
if (bitTest(regs.ebx, 3)) features.add(Features::kBMI); 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, 8)) features.add(Features::kBMI2);
if (bitTest(regs.ebx, 9)) features.add(Features::kERMS); if (bitTest(regs.ebx, 9)) features.add(Features::kERMS);
if (bitTest(regs.ebx, 11)) features.add(Features::kRTM); 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, 18)) features.add(Features::kRDSEED);
if (bitTest(regs.ebx, 19)) features.add(Features::kADX); if (bitTest(regs.ebx, 19)) features.add(Features::kADX);
if (bitTest(regs.ebx, 20)) features.add(Features::kSMAP); 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, 23)) features.add(Features::kCLFLUSHOPT);
if (bitTest(regs.ebx, 24)) features.add(Features::kCLWB); if (bitTest(regs.ebx, 24)) features.add(Features::kCLWB);
if (bitTest(regs.ebx, 29)) features.add(Features::kSHA); if (bitTest(regs.ebx, 29)) features.add(Features::kSHA);
if (bitTest(regs.ecx, 0)) features.add(Features::kPREFETCHWT1); 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, 22)) features.add(Features::kRDPID);
if (bitTest(regs.ecx, 25)) features.add(Features::kCLDEMOTE); if (bitTest(regs.ecx, 25)) features.add(Features::kCLDEMOTE);
if (bitTest(regs.ecx, 27)) features.add(Features::kMOVDIRI); 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, 14)) features.add(Features::kSERIALIZE);
if (bitTest(regs.edx, 16)) features.add(Features::kTSXLDTRK); if (bitTest(regs.edx, 16)) features.add(Features::kTSXLDTRK);
if (bitTest(regs.edx, 18)) features.add(Features::kPCONFIG); 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. // Detect 'TSX' - Requires at least one of `HLE` and `RTM` features.
if (features.hasHLE() || features.hasRTM()) if (features.hasHLE() || features.hasRTM())
@@ -274,11 +293,15 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
if (bitTest(regs.ebx, 5) && features.hasAVX()) if (bitTest(regs.ebx, 5) && features.hasAVX())
features.add(Features::kAVX2); 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'. // Detect 'AVX_512'.
if (bitTest(regs.ebx, 16)) { if (avx512EnabledByOS && 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) {
features.add(Features::kAVX512_F); features.add(Features::kAVX512_F);
if (bitTest(regs.ebx, 17)) features.add(Features::kAVX512_DQ); 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, 30)) features.add(Features::kAVX512_BW);
if (bitTest(regs.ebx, 31)) features.add(Features::kAVX512_VL); if (bitTest(regs.ebx, 31)) features.add(Features::kAVX512_VL);
if (bitTest(regs.ecx, 1)) features.add(Features::kAVX512_VBMI); 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, 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, 11)) features.add(Features::kAVX512_VNNI);
if (bitTest(regs.ecx, 12)) features.add(Features::kAVX512_BITALG); if (bitTest(regs.ecx, 12)) features.add(Features::kAVX512_BITALG);
if (bitTest(regs.ecx, 14)) features.add(Features::kAVX512_VPOPCNTDQ); 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); cpuidQuery(&regs, 0x7, 1);
if (bitTest(regs.eax, 5)) features.add(Features::kAVX512_BF16); if (bitTest(regs.eax, 5)) features.add(Features::kAVX512_BF16);
} }
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// [CPUID EAX=0xD] // [CPUID EAX=13 ECX=0]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
if (maxId >= 0xD) { if (maxId >= 0xD) {
@@ -322,11 +344,22 @@ ASMJIT_FAVOR_SIZE void detectCpu(CpuInfo& cpu) noexcept {
features.add(Features::kMPX); features.add(Features::kMPX);
cpuidQuery(&regs, 0xD, 1); cpuidQuery(&regs, 0xD, 1);
if (bitTest(regs.eax, 0)) features.add(Features::kXSAVEOPT); if (bitTest(regs.eax, 0)) features.add(Features::kXSAVEOPT);
if (bitTest(regs.eax, 1)) features.add(Features::kXSAVEC); if (bitTest(regs.eax, 1)) features.add(Features::kXSAVEC);
if (bitTest(regs.eax, 3)) features.add(Features::kXSAVES); 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] // [CPUID EAX=0x80000000...maxId]
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------

View File

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

View File

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

View File

@@ -119,6 +119,7 @@ struct Inst : public BaseInst {
kIdClflushopt, //!< Instruction 'clflushopt' {CLFLUSHOPT}. kIdClflushopt, //!< Instruction 'clflushopt' {CLFLUSHOPT}.
kIdClgi, //!< Instruction 'clgi' {SVM}. kIdClgi, //!< Instruction 'clgi' {SVM}.
kIdCli, //!< Instruction 'cli'. kIdCli, //!< Instruction 'cli'.
kIdClrssbsy, //!< Instruction 'clrssbsy' {CET_SS}.
kIdClts, //!< Instruction 'clts'. kIdClts, //!< Instruction 'clts'.
kIdClwb, //!< Instruction 'clwb' {CLWB}. kIdClwb, //!< Instruction 'clwb' {CLWB}.
kIdClzero, //!< Instruction 'clzero' {CLZERO}. kIdClzero, //!< Instruction 'clzero' {CLZERO}.
@@ -202,6 +203,8 @@ struct Inst : public BaseInst {
kIdDppd, //!< Instruction 'dppd' {SSE4_1}. kIdDppd, //!< Instruction 'dppd' {SSE4_1}.
kIdDpps, //!< Instruction 'dpps' {SSE4_1}. kIdDpps, //!< Instruction 'dpps' {SSE4_1}.
kIdEmms, //!< Instruction 'emms' {MMX}. kIdEmms, //!< Instruction 'emms' {MMX}.
kIdEndbr32, //!< Instruction 'endbr32' {CET_IBT}.
kIdEndbr64, //!< Instruction 'endbr64' {CET_IBT}.
kIdEnqcmd, //!< Instruction 'enqcmd' {ENQCMD}. kIdEnqcmd, //!< Instruction 'enqcmd' {ENQCMD}.
kIdEnqcmds, //!< Instruction 'enqcmds' {ENQCMD}. kIdEnqcmds, //!< Instruction 'enqcmds' {ENQCMD}.
kIdEnter, //!< Instruction 'enter'. kIdEnter, //!< Instruction 'enter'.
@@ -318,6 +321,8 @@ struct Inst : public BaseInst {
kIdImul, //!< Instruction 'imul'. kIdImul, //!< Instruction 'imul'.
kIdIn, //!< Instruction 'in'. kIdIn, //!< Instruction 'in'.
kIdInc, //!< Instruction 'inc'. kIdInc, //!< Instruction 'inc'.
kIdIncsspd, //!< Instruction 'incsspd' {CET_SS}.
kIdIncsspq, //!< Instruction 'incsspq' {CET_SS} (X64).
kIdIns, //!< Instruction 'ins'. kIdIns, //!< Instruction 'ins'.
kIdInsertps, //!< Instruction 'insertps' {SSE4_1}. kIdInsertps, //!< Instruction 'insertps' {SSE4_1}.
kIdInsertq, //!< Instruction 'insertq' {SSE4A}. kIdInsertq, //!< Instruction 'insertq' {SSE4A}.
@@ -551,7 +556,6 @@ struct Inst : public BaseInst {
kIdPcmpgtw, //!< Instruction 'pcmpgtw' {MMX|SSE2}. kIdPcmpgtw, //!< Instruction 'pcmpgtw' {MMX|SSE2}.
kIdPcmpistri, //!< Instruction 'pcmpistri' {SSE4_2}. kIdPcmpistri, //!< Instruction 'pcmpistri' {SSE4_2}.
kIdPcmpistrm, //!< Instruction 'pcmpistrm' {SSE4_2}. kIdPcmpistrm, //!< Instruction 'pcmpistrm' {SSE4_2}.
kIdPcommit, //!< Instruction 'pcommit' {PCOMMIT}.
kIdPconfig, //!< Instruction 'pconfig' {PCONFIG}. kIdPconfig, //!< Instruction 'pconfig' {PCONFIG}.
kIdPdep, //!< Instruction 'pdep' {BMI2}. kIdPdep, //!< Instruction 'pdep' {BMI2}.
kIdPext, //!< Instruction 'pext' {BMI2}. kIdPext, //!< Instruction 'pext' {BMI2}.
@@ -673,6 +677,7 @@ struct Inst : public BaseInst {
kIdPsubw, //!< Instruction 'psubw' {MMX|SSE2}. kIdPsubw, //!< Instruction 'psubw' {MMX|SSE2}.
kIdPswapd, //!< Instruction 'pswapd' {3DNOW2}. kIdPswapd, //!< Instruction 'pswapd' {3DNOW2}.
kIdPtest, //!< Instruction 'ptest' {SSE4_1}. kIdPtest, //!< Instruction 'ptest' {SSE4_1}.
kIdPtwrite, //!< Instruction 'ptwrite' {PTWRITE}.
kIdPunpckhbw, //!< Instruction 'punpckhbw' {MMX|SSE2}. kIdPunpckhbw, //!< Instruction 'punpckhbw' {MMX|SSE2}.
kIdPunpckhdq, //!< Instruction 'punpckhdq' {MMX|SSE2}. kIdPunpckhdq, //!< Instruction 'punpckhdq' {MMX|SSE2}.
kIdPunpckhqdq, //!< Instruction 'punpckhqdq' {SSE2}. kIdPunpckhqdq, //!< Instruction 'punpckhqdq' {SSE2}.
@@ -697,10 +702,13 @@ struct Inst : public BaseInst {
kIdRdgsbase, //!< Instruction 'rdgsbase' {FSGSBASE} (X64). kIdRdgsbase, //!< Instruction 'rdgsbase' {FSGSBASE} (X64).
kIdRdmsr, //!< Instruction 'rdmsr' {MSR}. kIdRdmsr, //!< Instruction 'rdmsr' {MSR}.
kIdRdpid, //!< Instruction 'rdpid' {RDPID}. kIdRdpid, //!< Instruction 'rdpid' {RDPID}.
kIdRdpkru, //!< Instruction 'rdpkru' {OSPKE}.
kIdRdpmc, //!< Instruction 'rdpmc'. kIdRdpmc, //!< Instruction 'rdpmc'.
kIdRdpru, //!< Instruction 'rdpru' {RDPRU}. kIdRdpru, //!< Instruction 'rdpru' {RDPRU}.
kIdRdrand, //!< Instruction 'rdrand' {RDRAND}. kIdRdrand, //!< Instruction 'rdrand' {RDRAND}.
kIdRdseed, //!< Instruction 'rdseed' {RDSEED}. kIdRdseed, //!< Instruction 'rdseed' {RDSEED}.
kIdRdsspd, //!< Instruction 'rdsspd' {CET_SS}.
kIdRdsspq, //!< Instruction 'rdsspq' {CET_SS} (X64).
kIdRdtsc, //!< Instruction 'rdtsc' {RDTSC}. kIdRdtsc, //!< Instruction 'rdtsc' {RDTSC}.
kIdRdtscp, //!< Instruction 'rdtscp' {RDTSCP}. kIdRdtscp, //!< Instruction 'rdtscp' {RDTSCP}.
kIdRet, //!< Instruction 'ret'. kIdRet, //!< Instruction 'ret'.
@@ -716,10 +724,12 @@ struct Inst : public BaseInst {
kIdRsm, //!< Instruction 'rsm' (X86). kIdRsm, //!< Instruction 'rsm' (X86).
kIdRsqrtps, //!< Instruction 'rsqrtps' {SSE}. kIdRsqrtps, //!< Instruction 'rsqrtps' {SSE}.
kIdRsqrtss, //!< Instruction 'rsqrtss' {SSE}. kIdRsqrtss, //!< Instruction 'rsqrtss' {SSE}.
kIdRstorssp, //!< Instruction 'rstorssp' {CET_SS}.
kIdSahf, //!< Instruction 'sahf' {LAHFSAHF}. kIdSahf, //!< Instruction 'sahf' {LAHFSAHF}.
kIdSal, //!< Instruction 'sal'. kIdSal, //!< Instruction 'sal'.
kIdSar, //!< Instruction 'sar'. kIdSar, //!< Instruction 'sar'.
kIdSarx, //!< Instruction 'sarx' {BMI2}. kIdSarx, //!< Instruction 'sarx' {BMI2}.
kIdSaveprevssp, //!< Instruction 'saveprevssp' {CET_SS}.
kIdSbb, //!< Instruction 'sbb'. kIdSbb, //!< Instruction 'sbb'.
kIdScas, //!< Instruction 'scas'. kIdScas, //!< Instruction 'scas'.
kIdSerialize, //!< Instruction 'serialize' {SERIALIZE}. kIdSerialize, //!< Instruction 'serialize' {SERIALIZE}.
@@ -752,6 +762,7 @@ struct Inst : public BaseInst {
kIdSetpe, //!< Instruction 'setpe'. kIdSetpe, //!< Instruction 'setpe'.
kIdSetpo, //!< Instruction 'setpo'. kIdSetpo, //!< Instruction 'setpo'.
kIdSets, //!< Instruction 'sets'. kIdSets, //!< Instruction 'sets'.
kIdSetssbsy, //!< Instruction 'setssbsy' {CET_SS}.
kIdSetz, //!< Instruction 'setz'. kIdSetz, //!< Instruction 'setz'.
kIdSfence, //!< Instruction 'sfence' {MMX2}. kIdSfence, //!< Instruction 'sfence' {MMX2}.
kIdSgdt, //!< Instruction 'sgdt'. kIdSgdt, //!< Instruction 'sgdt'.
@@ -817,6 +828,8 @@ struct Inst : public BaseInst {
kIdTzmsk, //!< Instruction 'tzmsk' {TBM}. kIdTzmsk, //!< Instruction 'tzmsk' {TBM}.
kIdUcomisd, //!< Instruction 'ucomisd' {SSE2}. kIdUcomisd, //!< Instruction 'ucomisd' {SSE2}.
kIdUcomiss, //!< Instruction 'ucomiss' {SSE}. kIdUcomiss, //!< Instruction 'ucomiss' {SSE}.
kIdUd0, //!< Instruction 'ud0'.
kIdUd1, //!< Instruction 'ud1'.
kIdUd2, //!< Instruction 'ud2'. kIdUd2, //!< Instruction 'ud2'.
kIdUmonitor, //!< Instruction 'umonitor' {WAITPKG}. kIdUmonitor, //!< Instruction 'umonitor' {WAITPKG}.
kIdUmwait, //!< Instruction 'umwait' {WAITPKG}. kIdUmwait, //!< Instruction 'umwait' {WAITPKG}.
@@ -1553,6 +1566,10 @@ struct Inst : public BaseInst {
kIdWrfsbase, //!< Instruction 'wrfsbase' {FSGSBASE} (X64). kIdWrfsbase, //!< Instruction 'wrfsbase' {FSGSBASE} (X64).
kIdWrgsbase, //!< Instruction 'wrgsbase' {FSGSBASE} (X64). kIdWrgsbase, //!< Instruction 'wrgsbase' {FSGSBASE} (X64).
kIdWrmsr, //!< Instruction 'wrmsr' {MSR}. 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}. kIdXabort, //!< Instruction 'xabort' {RTM}.
kIdXadd, //!< Instruction 'xadd' {I486}. kIdXadd, //!< Instruction 'xadd' {I486}.
kIdXbegin, //!< Instruction 'xbegin' {RTM}. 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 { enum EncodingId : uint32_t {
kEncodingNone = 0, //!< Never used. kEncodingNone = 0, //!< Never used.
kEncodingX86Op, //!< X86 [OP]. kEncodingX86Op, //!< X86 [OP].
kEncodingX86Op_O, //!< X86 [OP] (opcode and /0-7). kEncodingX86Op_Mod11RM, //!< X86 [OP] (opcode with ModRM byte where MOD must be 11b).
kEncodingX86Op_O_I8, //!< X86 [OP] (opcode and /0-7 + 8-bit immediate). kEncodingX86Op_Mod11RM_I8, //!< X86 [OP] (opcode with ModRM byte + 8-bit immediate).
kEncodingX86Op_xAddr, //!< X86 [OP] (implicit address in the first register operand). kEncodingX86Op_xAddr, //!< X86 [OP] (implicit address in the first register operand).
kEncodingX86Op_xAX, //!< X86 [OP] (implicit or explicit '?AX' form). kEncodingX86Op_xAX, //!< X86 [OP] (implicit or explicit '?AX' form).
kEncodingX86Op_xDX_xAX, //!< X86 [OP] (implicit or explicit '?DX, ?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. 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, kModO_Shift = 18,
kO_Mask = 0x7u << kO_Shift, kModO_Mask = 0x7u << kModO_Shift,
kO__ = 0x0u, kModO__ = 0x0u,
kO_0 = 0x0u << kO_Shift, kModO_0 = 0x0u << kModO_Shift,
kO_1 = 0x1u << kO_Shift, kModO_1 = 0x1u << kModO_Shift,
kO_2 = 0x2u << kO_Shift, kModO_2 = 0x2u << kModO_Shift,
kO_3 = 0x3u << kO_Shift, kModO_3 = 0x3u << kModO_Shift,
kO_4 = 0x4u << kO_Shift, kModO_4 = 0x4u << kModO_Shift,
kO_5 = 0x5u << kO_Shift, kModO_5 = 0x5u << kModO_Shift,
kO_6 = 0x6u << kO_Shift, kModO_6 = 0x6u << kModO_Shift,
kO_7 = 0x7u << kO_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 // `PP` Field
// ---------- // ----------
@@ -412,9 +432,14 @@ struct Opcode {
return operator|=(mask[size & 0xF]); return operator|=(mask[size & 0xF]);
} }
//! Extract `O` field from the opcode. //! Extract `O` field (R) from the opcode (specified as /0..7 in instruction manuals).
ASMJIT_INLINE uint32_t extractO() const noexcept { ASMJIT_INLINE uint32_t extractModO() const noexcept {
return (v >> kO_Shift) & 0x07; 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`. //! 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->mwait(); // Implicit <EAX>, <ECX>
e->mwaitx(); // Implicit <EAX>, <ECX>, <EBX> e->mwaitx(); // Implicit <EAX>, <ECX>, <EBX>
// PCOMMIT.
e->nop();
e->pcommit();
// PREFETCH / PREFETCHW / PREFETCHWT1. // PREFETCH / PREFETCHW / PREFETCHWT1.
e->nop(); e->nop();
e->prefetch(anyptr_gpA); // 3DNOW. 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 enum_ = name[0].toUpperCase() + name.substr(1);
var opcode = dbi.opcodeHex; var opcode = dbi.opcodeHex;
var rm = dbi.rm; var modR = dbi.modR;
var mm = dbi.mm; var mm = dbi.mm;
var pp = dbi.pp; var pp = dbi.pp;
var encoding = dbi.encoding; 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 (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 (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 (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; } 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", type : isVec ? "V" : "O",
prefix: ppmm, prefix: ppmm,
opcode: opcode, opcode: opcode,
o : rm === "r" ? "_" : (rm ? rm : "_"), o : modR === "r" ? "_" : (modR ? modR : "_"),
l : vexL !== undefined ? vexL : "_", l : vexL !== undefined ? vexL : "_",
w : vexW !== undefined ? vexW : "_", w : vexW !== undefined ? vexW : "_",
ew : evexW !== undefined ? evexW : "_", ew : evexW !== undefined ? evexW : "_",
en : "_", en : "_",
tt : "_ " tt : dbi.modRM ? dbi.modRM + " " : "_ "
}); });
return { return {
@@ -736,7 +736,7 @@ class AltOpcodeTable extends core.Task {
} }
// X(______,OP,_,_,_,_,_,_ ) // 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 value = opcode.substring(9, 11);
var remaining = opcode.substring(0, 9) + "00" + opcode.substring(11); var remaining = opcode.substring(0, 9) + "00" + opcode.substring(11);