enum {
OpSize16 = 1, OpSize32 = 2
};
+
+ enum {
+ AdSize16 = 1, AdSize32 = 2, AdSize64 = 3
+ };
}
using namespace X86Disassembler;
Encoding = byteFromRec(Rec, "OpEncBits");
OpSize = byteFromRec(Rec, "OpSizeBits");
- HasAdSizePrefix = Rec->getValueAsBit("hasAdSizePrefix");
+ AdSize = byteFromRec(Rec, "AdSizeBits");
HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix");
HasVEX_4V = Rec->getValueAsBit("hasVEX_4V");
HasVEX_4VOp3 = Rec->getValueAsBit("hasVEX_4VOp3");
insnContext = IC_64BIT_XS_OPSIZE;
else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
insnContext = IC_64BIT_OPSIZE;
- else if (HasAdSizePrefix)
+ else if (AdSize == X86Local::AdSize32)
insnContext = IC_64BIT_ADSIZE;
else if (HasREX_WPrefix && OpPrefix == X86Local::XS)
insnContext = IC_64BIT_REXW_XS;
insnContext = IC_XS_OPSIZE;
else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
insnContext = IC_OPSIZE;
- else if (HasAdSizePrefix)
+ else if (AdSize == X86Local::AdSize16)
insnContext = IC_ADSIZE;
else if (OpPrefix == X86Local::XD)
insnContext = IC_XD;
// physicalOperandIndex should always be < numPhysicalOperands
unsigned physicalOperandIndex = 0;
+ // Given the set of prefix bits, how many additional operands does the
+ // instruction have?
+ unsigned additionalOperands = 0;
+ if (HasVEX_4V || HasVEX_4VOp3)
+ ++additionalOperands;
+ if (HasEVEX_K)
+ ++additionalOperands;
+
switch (Form) {
default: llvm_unreachable("Unhandled form");
case X86Local::RawFrmSrc:
break;
case X86Local::MRMDestReg:
// Operand 1 is a register operand in the R/M field.
+ // - In AVX512 there may be a mask operand here -
// Operand 2 is a register operand in the Reg/Opcode field.
// - In AVX, there is a register operand in the VEX.vvvv field here -
// Operand 3 (optional) is an immediate.
- if (HasVEX_4V)
- assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 &&
- "Unexpected number of operands for MRMDestRegFrm with VEX_4V");
- else
- assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
- "Unexpected number of operands for MRMDestRegFrm");
+ assert(numPhysicalOperands >= 2 + additionalOperands &&
+ numPhysicalOperands <= 3 + additionalOperands &&
+ "Unexpected number of operands for MRMDestRegFrm");
HANDLE_OPERAND(rmRegister)
+ if (HasEVEX_K)
+ HANDLE_OPERAND(writemaskRegister)
if (HasVEX_4V)
// FIXME: In AVX, the register below becomes the one encoded
// Operand 2 is a register operand in the Reg/Opcode field.
// - In AVX, there is a register operand in the VEX.vvvv field here -
// Operand 3 (optional) is an immediate.
- if (HasVEX_4V)
- assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 &&
- "Unexpected number of operands for MRMDestMemFrm with VEX_4V");
- else
- assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
- "Unexpected number of operands for MRMDestMemFrm");
+ assert(numPhysicalOperands >= 2 + additionalOperands &&
+ numPhysicalOperands <= 3 + additionalOperands &&
+ "Unexpected number of operands for MRMDestMemFrm with VEX_4V");
+
HANDLE_OPERAND(memory)
if (HasEVEX_K)
// Operand 3 (optional) is an immediate.
// Operand 4 (optional) is an immediate.
- if (HasVEX_4V || HasVEX_4VOp3)
- assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 &&
- "Unexpected number of operands for MRMSrcRegFrm with VEX_4V");
- else
- assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 4 &&
- "Unexpected number of operands for MRMSrcRegFrm");
+ assert(numPhysicalOperands >= 2 + additionalOperands &&
+ numPhysicalOperands <= 4 + additionalOperands &&
+ "Unexpected number of operands for MRMSrcRegFrm");
HANDLE_OPERAND(roRegister)
// - In AVX, there is a register operand in the VEX.vvvv field here -
// Operand 3 (optional) is an immediate.
- if (HasVEX_4V || HasVEX_4VOp3)
- assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 5 &&
- "Unexpected number of operands for MRMSrcMemFrm with VEX_4V");
- else
- assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 &&
- "Unexpected number of operands for MRMSrcMemFrm");
+ assert(numPhysicalOperands >= 2 + additionalOperands &&
+ numPhysicalOperands <= 4 + additionalOperands &&
+ "Unexpected number of operands for MRMSrcMemFrm");
HANDLE_OPERAND(roRegister)
case X86Local::MRM5r:
case X86Local::MRM6r:
case X86Local::MRM7r:
- {
- // Operand 1 is a register operand in the R/M field.
- // Operand 2 (optional) is an immediate or relocation.
- // Operand 3 (optional) is an immediate.
- unsigned kOp = (HasEVEX_K) ? 1:0;
- unsigned Op4v = (HasVEX_4V) ? 1:0;
- if (numPhysicalOperands > 3 + kOp + Op4v)
- llvm_unreachable("Unexpected number of operands for MRMnr");
- }
+ // Operand 1 is a register operand in the R/M field.
+ // Operand 2 (optional) is an immediate or relocation.
+ // Operand 3 (optional) is an immediate.
+ assert(numPhysicalOperands >= 0 + additionalOperands &&
+ numPhysicalOperands <= 3 + additionalOperands &&
+ "Unexpected number of operands for MRMnr");
+
if (HasVEX_4V)
HANDLE_OPERAND(vvvvRegister)
case X86Local::MRM5m:
case X86Local::MRM6m:
case X86Local::MRM7m:
- {
- // Operand 1 is a memory operand (possibly SIB-extended)
- // Operand 2 (optional) is an immediate or relocation.
- unsigned kOp = (HasEVEX_K) ? 1:0;
- unsigned Op4v = (HasVEX_4V) ? 1:0;
- if (numPhysicalOperands < 1 + kOp + Op4v ||
- numPhysicalOperands > 2 + kOp + Op4v)
- llvm_unreachable("Unexpected number of operands for MRMnm");
- }
+ // Operand 1 is a memory operand (possibly SIB-extended)
+ // Operand 2 (optional) is an immediate or relocation.
+ assert(numPhysicalOperands >= 1 + additionalOperands &&
+ numPhysicalOperands <= 2 + additionalOperands &&
+ "Unexpected number of operands for MRMnm");
+
if (HasVEX_4V)
HANDLE_OPERAND(vvvvRegister)
if (HasEVEX_K)
TYPE("i32mem", TYPE_Mv)
TYPE("i32imm", TYPE_IMMv)
TYPE("i32i8imm", TYPE_IMM32)
- TYPE("u32u8imm", TYPE_IMM32)
TYPE("GR32", TYPE_R32)
TYPE("GR32orGR64", TYPE_R32)
TYPE("i64mem", TYPE_Mv)
ENCODING("i16imm", ENCODING_IW)
}
ENCODING("i32i8imm", ENCODING_IB)
- ENCODING("u32u8imm", ENCODING_IB)
ENCODING("SSECC", ENCODING_IB)
ENCODING("AVXCC", ENCODING_IB)
ENCODING("AVX512RC", ENCODING_IB)