diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-09 13:28:42 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-09 13:28:42 +0000 |
| commit | b1c73532ee8997fe5dfbeb7d223027bdf99758a0 (patch) | |
| tree | 7d6e51c294ab6719475d660217aa0c0ad0526292 /llvm/lib/Target/X86/Disassembler | |
| parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) | |
Diffstat (limited to 'llvm/lib/Target/X86/Disassembler')
| -rw-r--r-- | llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp | 151 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h | 495 |
2 files changed, 430 insertions, 216 deletions
diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp index 49651da63ecf..d50e6514b86d 100644 --- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -150,12 +150,18 @@ static InstrUID decode(OpcodeType type, InstructionContext insnContext, dec = &THREEDNOW_MAP_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode]; break; + case MAP4: + dec = &MAP4_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode]; + break; case MAP5: dec = &MAP5_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode]; break; case MAP6: dec = &MAP6_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode]; break; + case MAP7: + dec = &MAP7_SYM.opcodeDecisions[insnContext].modRMDecisions[opcode]; + break; } switch (dec->modrm_type) { @@ -194,7 +200,7 @@ template <typename T> static bool consume(InternalInstruction *insn, T &ptr) { uint64_t offset = insn->readerCursor - insn->startLocation; if (offset + sizeof(T) > r.size()) return true; - ptr = support::endian::read<T>(&r[offset], support::little); + ptr = support::endian::read<T>(&r[offset], llvm::endianness::little); insn->readerCursor += sizeof(T); return false; } @@ -203,6 +209,10 @@ static bool isREX(struct InternalInstruction *insn, uint8_t prefix) { return insn->mode == MODE_64BIT && prefix >= 0x40 && prefix <= 0x4f; } +static bool isREX2(struct InternalInstruction *insn, uint8_t prefix) { + return insn->mode == MODE_64BIT && prefix == 0xd5; +} + // Consumes all of an instruction's prefix bytes, and marks the // instruction as having them. Also sets the instruction's default operand, // address, and other relevant data sizes to report operands correctly. @@ -334,8 +344,7 @@ static int readPrefixes(struct InternalInstruction *insn) { return -1; } - if ((insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) && - ((~byte1 & 0x8) == 0x8) && ((byte2 & 0x4) == 0x4)) { + if ((insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0)) { insn->vectorExtensionType = TYPE_EVEX; } else { --insn->readerCursor; // unconsume byte1 @@ -354,13 +363,19 @@ static int readPrefixes(struct InternalInstruction *insn) { return -1; } - // We simulate the REX prefix for simplicity's sake if (insn->mode == MODE_64BIT) { + // We simulate the REX prefix for simplicity's sake insn->rexPrefix = 0x40 | (wFromEVEX3of4(insn->vectorExtensionPrefix[2]) << 3) | (rFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 2) | (xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 1) | (bFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 0); + + // We simulate the REX2 prefix for simplicity's sake + insn->rex2ExtensionPrefix[1] = + (r2FromEVEX2of4(insn->vectorExtensionPrefix[1]) << 6) | + (x2FromEVEX3of4(insn->vectorExtensionPrefix[2]) << 5) | + (b2FromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4); } LLVM_DEBUG( @@ -471,6 +486,23 @@ static int readPrefixes(struct InternalInstruction *insn) { insn->vectorExtensionPrefix[1], insn->vectorExtensionPrefix[2])); } + } else if (isREX2(insn, byte)) { + uint8_t byte1; + if (peek(insn, byte1)) { + LLVM_DEBUG(dbgs() << "Couldn't read second byte of REX2"); + return -1; + } + insn->rex2ExtensionPrefix[0] = byte; + consume(insn, insn->rex2ExtensionPrefix[1]); + + // We simulate the REX prefix for simplicity's sake + insn->rexPrefix = 0x40 | (wFromREX2(insn->rex2ExtensionPrefix[1]) << 3) | + (rFromREX2(insn->rex2ExtensionPrefix[1]) << 2) | + (xFromREX2(insn->rex2ExtensionPrefix[1]) << 1) | + (bFromREX2(insn->rex2ExtensionPrefix[1]) << 0); + LLVM_DEBUG(dbgs() << format("Found REX2 prefix 0x%hhx 0x%hhx", + insn->rex2ExtensionPrefix[0], + insn->rex2ExtensionPrefix[1])); } else if (isREX(insn, byte)) { if (peek(insn, nextByte)) return -1; @@ -529,7 +561,8 @@ static int readSIB(struct InternalInstruction *insn) { if (consume(insn, insn->sib)) return -1; - index = indexFromSIB(insn->sib) | (xFromREX(insn->rexPrefix) << 3); + index = indexFromSIB(insn->sib) | (xFromREX(insn->rexPrefix) << 3) | + (x2FromREX2(insn->rex2ExtensionPrefix[1]) << 4); if (index == 0x4) { insn->sibIndex = SIB_INDEX_NONE; @@ -539,7 +572,8 @@ static int readSIB(struct InternalInstruction *insn) { insn->sibScale = 1 << scaleFromSIB(insn->sib); - base = baseFromSIB(insn->sib) | (bFromREX(insn->rexPrefix) << 3); + base = baseFromSIB(insn->sib) | (bFromREX(insn->rexPrefix) << 3) | + (b2FromREX2(insn->rex2ExtensionPrefix[1]) << 4); switch (base) { case 0x5: @@ -601,7 +635,7 @@ static int readDisplacement(struct InternalInstruction *insn) { // Consumes all addressing information (ModR/M byte, SIB byte, and displacement. static int readModRM(struct InternalInstruction *insn) { - uint8_t mod, rm, reg, evexrm; + uint8_t mod, rm, reg; LLVM_DEBUG(dbgs() << "readModRM()"); if (insn->consumedModRM) @@ -633,14 +667,13 @@ static int readModRM(struct InternalInstruction *insn) { break; } - reg |= rFromREX(insn->rexPrefix) << 3; - rm |= bFromREX(insn->rexPrefix) << 3; + reg |= (rFromREX(insn->rexPrefix) << 3) | + (r2FromREX2(insn->rex2ExtensionPrefix[1]) << 4); + rm |= (bFromREX(insn->rexPrefix) << 3) | + (b2FromREX2(insn->rex2ExtensionPrefix[1]) << 4); - evexrm = 0; - if (insn->vectorExtensionType == TYPE_EVEX && insn->mode == MODE_64BIT) { + if (insn->vectorExtensionType == TYPE_EVEX && insn->mode == MODE_64BIT) reg |= r2FromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4; - evexrm = xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4; - } insn->reg = (Reg)(insn->regBase + reg); @@ -728,7 +761,7 @@ static int readModRM(struct InternalInstruction *insn) { break; case 0x3: insn->eaDisplacement = EA_DISP_NONE; - insn->eaBase = (EABase)(insn->eaRegBase + rm + evexrm); + insn->eaBase = (EABase)(insn->eaRegBase + rm); break; } break; @@ -738,7 +771,7 @@ static int readModRM(struct InternalInstruction *insn) { return 0; } -#define GENERIC_FIXUP_FUNC(name, base, prefix, mask) \ +#define GENERIC_FIXUP_FUNC(name, base, prefix) \ static uint16_t name(struct InternalInstruction *insn, OperandType type, \ uint8_t index, uint8_t *valid) { \ *valid = 1; \ @@ -750,28 +783,15 @@ static int readModRM(struct InternalInstruction *insn) { case TYPE_Rv: \ return base + index; \ case TYPE_R8: \ - index &= mask; \ - if (index > 0xf) \ - *valid = 0; \ - if (insn->rexPrefix && index >= 4 && index <= 7) { \ + if (insn->rexPrefix && index >= 4 && index <= 7) \ return prefix##_SPL + (index - 4); \ - } else { \ + else \ return prefix##_AL + index; \ - } \ case TYPE_R16: \ - index &= mask; \ - if (index > 0xf) \ - *valid = 0; \ return prefix##_AX + index; \ case TYPE_R32: \ - index &= mask; \ - if (index > 0xf) \ - *valid = 0; \ return prefix##_EAX + index; \ case TYPE_R64: \ - index &= mask; \ - if (index > 0xf) \ - *valid = 0; \ return prefix##_RAX + index; \ case TYPE_ZMM: \ return prefix##_ZMM0 + index; \ @@ -821,8 +841,8 @@ static int readModRM(struct InternalInstruction *insn) { // @param valid - The address of a uint8_t. The target is set to 1 if the // field is valid for the register class; 0 if not. // @return - The proper value. -GENERIC_FIXUP_FUNC(fixupRegValue, insn->regBase, MODRM_REG, 0x1f) -GENERIC_FIXUP_FUNC(fixupRMValue, insn->eaRegBase, EA_REG, 0xf) +GENERIC_FIXUP_FUNC(fixupRegValue, insn->regBase, MODRM_REG) +GENERIC_FIXUP_FUNC(fixupRMValue, insn->eaRegBase, EA_REG) // Consult an operand specifier to determine which of the fixup*Value functions // to use in correcting readModRM()'ss interpretation. @@ -852,8 +872,31 @@ static int fixupReg(struct InternalInstruction *insn, if (!valid) return -1; break; - case ENCODING_SIB: CASE_ENCODING_RM: + if (insn->vectorExtensionType == TYPE_EVEX && insn->mode == MODE_64BIT && + modFromModRM(insn->modRM) == 3) { + // EVEX_X can extend the register id to 32 for a non-GPR register that is + // encoded in RM. + // mode : MODE_64_BIT + // Only 8 vector registers are available in 32 bit mode + // mod : 3 + // RM encodes a register + switch (op->type) { + case TYPE_Rv: + case TYPE_R8: + case TYPE_R16: + case TYPE_R32: + case TYPE_R64: + break; + default: + insn->eaBase = + (EABase)(insn->eaBase + + (xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4)); + break; + } + } + [[fallthrough]]; + case ENCODING_SIB: if (insn->eaBase >= insn->eaRegBase) { insn->eaBase = (EABase)fixupRMValue( insn, (OperandType)op->type, insn->eaBase - insn->eaRegBase, &valid); @@ -889,6 +932,9 @@ static bool readOpcode(struct InternalInstruction *insn) { case VEX_LOB_0F3A: insn->opcodeType = THREEBYTE_3A; return consume(insn, insn->opcode); + case VEX_LOB_MAP4: + insn->opcodeType = MAP4; + return consume(insn, insn->opcode); case VEX_LOB_MAP5: insn->opcodeType = MAP5; return consume(insn, insn->opcode); @@ -918,6 +964,9 @@ static bool readOpcode(struct InternalInstruction *insn) { case VEX_LOB_MAP6: insn->opcodeType = MAP6; return consume(insn, insn->opcode); + case VEX_LOB_MAP7: + insn->opcodeType = MAP7; + return consume(insn, insn->opcode); } } else if (insn->vectorExtensionType == TYPE_VEX_2B) { insn->opcodeType = TWOBYTE; @@ -939,6 +988,10 @@ static bool readOpcode(struct InternalInstruction *insn) { insn->opcodeType = XOPA_MAP; return consume(insn, insn->opcode); } + } else if (mFromREX2(insn->rex2ExtensionPrefix[1])) { + // m bit indicates opcode map 1 + insn->opcodeType = TWOBYTE; + return consume(insn, insn->opcode); } if (consume(insn, current)) @@ -1053,12 +1106,18 @@ static int getInstructionIDWithAttrMask(uint16_t *instructionID, case THREEDNOW_MAP: decision = &THREEDNOW_MAP_SYM; break; + case MAP4: + decision = &MAP4_SYM; + break; case MAP5: decision = &MAP5_SYM; break; case MAP6: decision = &MAP6_SYM; break; + case MAP7: + decision = &MAP7_SYM; + break; } if (decision->opcodeDecisions[insnCtx] @@ -1207,6 +1266,11 @@ static int getInstructionID(struct InternalInstruction *insn, attrMask &= ~ATTR_ADSIZE; } + // Absolute jump and pushp/popp need special handling + if (insn->rex2ExtensionPrefix[0] == 0xd5 && insn->opcodeType == ONEBYTE && + (insn->opcode == 0xA1 || (insn->opcode & 0xf0) == 0x50)) + attrMask |= ATTR_REX2; + if (insn->mode == MODE_16BIT) { // JCXZ/JECXZ need special handling for 16-bit mode because the meaning // of the AdSize prefix is inverted w.r.t. 32-bit mode. @@ -1379,10 +1443,16 @@ static int readOpcodeRegister(struct InternalInstruction *insn, uint8_t size) { if (size == 0) size = insn->registerSize; + auto setOpcodeRegister = [&](unsigned base) { + insn->opcodeRegister = + (Reg)(base + ((bFromREX(insn->rexPrefix) << 3) | + (b2FromREX2(insn->rex2ExtensionPrefix[1]) << 4) | + (insn->opcode & 7))); + }; + switch (size) { case 1: - insn->opcodeRegister = (Reg)( - MODRM_REG_AL + ((bFromREX(insn->rexPrefix) << 3) | (insn->opcode & 7))); + setOpcodeRegister(MODRM_REG_AL); if (insn->rexPrefix && insn->opcodeRegister >= MODRM_REG_AL + 0x4 && insn->opcodeRegister < MODRM_REG_AL + 0x8) { insn->opcodeRegister = @@ -1391,18 +1461,13 @@ static int readOpcodeRegister(struct InternalInstruction *insn, uint8_t size) { break; case 2: - insn->opcodeRegister = (Reg)( - MODRM_REG_AX + ((bFromREX(insn->rexPrefix) << 3) | (insn->opcode & 7))); + setOpcodeRegister(MODRM_REG_AX); break; case 4: - insn->opcodeRegister = - (Reg)(MODRM_REG_EAX + - ((bFromREX(insn->rexPrefix) << 3) | (insn->opcode & 7))); + setOpcodeRegister(MODRM_REG_EAX); break; case 8: - insn->opcodeRegister = - (Reg)(MODRM_REG_RAX + - ((bFromREX(insn->rexPrefix) << 3) | (insn->opcode & 7))); + setOpcodeRegister(MODRM_REG_RAX); break; } diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h index 95d3c8ede366..decc45091941 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h @@ -20,187 +20,332 @@ namespace llvm { namespace X86Disassembler { - -// Accessor functions for various fields of an Intel instruction -#define modFromModRM(modRM) (((modRM) & 0xc0) >> 6) -#define regFromModRM(modRM) (((modRM) & 0x38) >> 3) -#define rmFromModRM(modRM) ((modRM) & 0x7) -#define scaleFromSIB(sib) (((sib) & 0xc0) >> 6) -#define indexFromSIB(sib) (((sib) & 0x38) >> 3) -#define baseFromSIB(sib) ((sib) & 0x7) -#define wFromREX(rex) (((rex) & 0x8) >> 3) -#define rFromREX(rex) (((rex) & 0x4) >> 2) -#define xFromREX(rex) (((rex) & 0x2) >> 1) -#define bFromREX(rex) ((rex) & 0x1) - -#define rFromEVEX2of4(evex) (((~(evex)) & 0x80) >> 7) -#define xFromEVEX2of4(evex) (((~(evex)) & 0x40) >> 6) -#define bFromEVEX2of4(evex) (((~(evex)) & 0x20) >> 5) -#define r2FromEVEX2of4(evex) (((~(evex)) & 0x10) >> 4) -#define mmmFromEVEX2of4(evex) ((evex) & 0x7) -#define wFromEVEX3of4(evex) (((evex) & 0x80) >> 7) -#define vvvvFromEVEX3of4(evex) (((~(evex)) & 0x78) >> 3) -#define ppFromEVEX3of4(evex) ((evex) & 0x3) -#define zFromEVEX4of4(evex) (((evex) & 0x80) >> 7) -#define l2FromEVEX4of4(evex) (((evex) & 0x40) >> 6) -#define lFromEVEX4of4(evex) (((evex) & 0x20) >> 5) -#define bFromEVEX4of4(evex) (((evex) & 0x10) >> 4) -#define v2FromEVEX4of4(evex) (((~evex) & 0x8) >> 3) -#define aaaFromEVEX4of4(evex) ((evex) & 0x7) - -#define rFromVEX2of3(vex) (((~(vex)) & 0x80) >> 7) -#define xFromVEX2of3(vex) (((~(vex)) & 0x40) >> 6) -#define bFromVEX2of3(vex) (((~(vex)) & 0x20) >> 5) -#define mmmmmFromVEX2of3(vex) ((vex) & 0x1f) -#define wFromVEX3of3(vex) (((vex) & 0x80) >> 7) -#define vvvvFromVEX3of3(vex) (((~(vex)) & 0x78) >> 3) -#define lFromVEX3of3(vex) (((vex) & 0x4) >> 2) -#define ppFromVEX3of3(vex) ((vex) & 0x3) - -#define rFromVEX2of2(vex) (((~(vex)) & 0x80) >> 7) -#define vvvvFromVEX2of2(vex) (((~(vex)) & 0x78) >> 3) -#define lFromVEX2of2(vex) (((vex) & 0x4) >> 2) -#define ppFromVEX2of2(vex) ((vex) & 0x3) - -#define rFromXOP2of3(xop) (((~(xop)) & 0x80) >> 7) -#define xFromXOP2of3(xop) (((~(xop)) & 0x40) >> 6) -#define bFromXOP2of3(xop) (((~(xop)) & 0x20) >> 5) -#define mmmmmFromXOP2of3(xop) ((xop) & 0x1f) -#define wFromXOP3of3(xop) (((xop) & 0x80) >> 7) -#define vvvvFromXOP3of3(vex) (((~(vex)) & 0x78) >> 3) -#define lFromXOP3of3(xop) (((xop) & 0x4) >> 2) -#define ppFromXOP3of3(xop) ((xop) & 0x3) +// Helper macros +#define bitFromOffset0(val) ((val) & 0x1) +#define bitFromOffset1(val) (((val) >> 1) & 0x1) +#define bitFromOffset2(val) (((val) >> 2) & 0x1) +#define bitFromOffset3(val) (((val) >> 3) & 0x1) +#define bitFromOffset4(val) (((val) >> 4) & 0x1) +#define bitFromOffset5(val) (((val) >> 5) & 0x1) +#define bitFromOffset6(val) (((val) >> 6) & 0x1) +#define bitFromOffset7(val) (((val) >> 7) & 0x1) +#define twoBitsFromOffset0(val) ((val) & 0x3) +#define twoBitsFromOffset6(val) (((val) >> 6) & 0x3) +#define threeBitsFromOffset0(val) ((val) & 0x7) +#define threeBitsFromOffset3(val) (((val) >> 3) & 0x7) +#define fiveBitsFromOffset0(val) ((val) & 0x1f) +#define invertedBitFromOffset2(val) (((~(val)) >> 2) & 0x1) +#define invertedBitFromOffset3(val) (((~(val)) >> 3) & 0x1) +#define invertedBitFromOffset4(val) (((~(val)) >> 4) & 0x1) +#define invertedBitFromOffset5(val) (((~(val)) >> 5) & 0x1) +#define invertedBitFromOffset6(val) (((~(val)) >> 6) & 0x1) +#define invertedBitFromOffset7(val) (((~(val)) >> 7) & 0x1) +#define invertedFourBitsFromOffset3(val) (((~(val)) >> 3) & 0xf) +// MOD/RM +#define modFromModRM(modRM) twoBitsFromOffset6(modRM) +#define regFromModRM(modRM) threeBitsFromOffset3(modRM) +#define rmFromModRM(modRM) threeBitsFromOffset0(modRM) +// SIB +#define scaleFromSIB(sib) twoBitsFromOffset6(sib) +#define indexFromSIB(sib) threeBitsFromOffset3(sib) +#define baseFromSIB(sib) threeBitsFromOffset0(sib) +// REX +#define wFromREX(rex) bitFromOffset3(rex) +#define rFromREX(rex) bitFromOffset2(rex) +#define xFromREX(rex) bitFromOffset1(rex) +#define bFromREX(rex) bitFromOffset0(rex) +// REX2 +#define mFromREX2(rex2) bitFromOffset7(rex2) +#define r2FromREX2(rex2) bitFromOffset6(rex2) +#define x2FromREX2(rex2) bitFromOffset5(rex2) +#define b2FromREX2(rex2) bitFromOffset4(rex2) +#define wFromREX2(rex2) bitFromOffset3(rex2) +#define rFromREX2(rex2) bitFromOffset2(rex2) +#define xFromREX2(rex2) bitFromOffset1(rex2) +#define bFromREX2(rex2) bitFromOffset0(rex2) +// XOP +#define rFromXOP2of3(xop) invertedBitFromOffset7(xop) +#define xFromXOP2of3(xop) invertedBitFromOffset6(xop) +#define bFromXOP2of3(xop) invertedBitFromOffset5(xop) +#define mmmmmFromXOP2of3(xop) fiveBitsFromOffset0(xop) +#define wFromXOP3of3(xop) bitFromOffset7(xop) +#define vvvvFromXOP3of3(xop) invertedFourBitsFromOffset3(xop) +#define lFromXOP3of3(xop) bitFromOffset2(xop) +#define ppFromXOP3of3(xop) twoBitsFromOffset0(xop) +// VEX2 +#define rFromVEX2of2(vex) invertedBitFromOffset7(vex) +#define vvvvFromVEX2of2(vex) invertedFourBitsFromOffset3(vex) +#define lFromVEX2of2(vex) bitFromOffset2(vex) +#define ppFromVEX2of2(vex) twoBitsFromOffset0(vex) +// VEX3 +#define rFromVEX2of3(vex) invertedBitFromOffset7(vex) +#define xFromVEX2of3(vex) invertedBitFromOffset6(vex) +#define bFromVEX2of3(vex) invertedBitFromOffset5(vex) +#define mmmmmFromVEX2of3(vex) fiveBitsFromOffset0(vex) +#define wFromVEX3of3(vex) bitFromOffset7(vex) +#define vvvvFromVEX3of3(vex) invertedFourBitsFromOffset3(vex) +#define lFromVEX3of3(vex) bitFromOffset2(vex) +#define ppFromVEX3of3(vex) twoBitsFromOffset0(vex) +// EVEX +#define rFromEVEX2of4(evex) invertedBitFromOffset7(evex) +#define xFromEVEX2of4(evex) invertedBitFromOffset6(evex) +#define bFromEVEX2of4(evex) invertedBitFromOffset5(evex) +#define r2FromEVEX2of4(evex) invertedBitFromOffset4(evex) +#define b2FromEVEX2of4(evex) bitFromOffset3(evex) +#define mmmFromEVEX2of4(evex) threeBitsFromOffset0(evex) +#define wFromEVEX3of4(evex) bitFromOffset7(evex) +#define vvvvFromEVEX3of4(evex) invertedFourBitsFromOffset3(evex) +#define x2FromEVEX3of4(evex) invertedBitFromOffset2(evex) +#define ppFromEVEX3of4(evex) twoBitsFromOffset0(evex) +#define zFromEVEX4of4(evex) bitFromOffset7(evex) +#define l2FromEVEX4of4(evex) bitFromOffset6(evex) +#define lFromEVEX4of4(evex) bitFromOffset5(evex) +#define bFromEVEX4of4(evex) bitFromOffset4(evex) +#define v2FromEVEX4of4(evex) invertedBitFromOffset3(evex) +#define aaaFromEVEX4of4(evex) threeBitsFromOffset0(evex) // These enums represent Intel registers for use by the decoder. -#define REGS_8BIT \ - ENTRY(AL) \ - ENTRY(CL) \ - ENTRY(DL) \ - ENTRY(BL) \ - ENTRY(AH) \ - ENTRY(CH) \ - ENTRY(DH) \ - ENTRY(BH) \ - ENTRY(R8B) \ - ENTRY(R9B) \ - ENTRY(R10B) \ - ENTRY(R11B) \ - ENTRY(R12B) \ - ENTRY(R13B) \ - ENTRY(R14B) \ - ENTRY(R15B) \ - ENTRY(SPL) \ - ENTRY(BPL) \ - ENTRY(SIL) \ +#define REGS_8BIT \ + ENTRY(AL) \ + ENTRY(CL) \ + ENTRY(DL) \ + ENTRY(BL) \ + ENTRY(AH) \ + ENTRY(CH) \ + ENTRY(DH) \ + ENTRY(BH) \ + ENTRY(R8B) \ + ENTRY(R9B) \ + ENTRY(R10B) \ + ENTRY(R11B) \ + ENTRY(R12B) \ + ENTRY(R13B) \ + ENTRY(R14B) \ + ENTRY(R15B) \ + ENTRY(R16B) \ + ENTRY(R17B) \ + ENTRY(R18B) \ + ENTRY(R19B) \ + ENTRY(R20B) \ + ENTRY(R21B) \ + ENTRY(R22B) \ + ENTRY(R23B) \ + ENTRY(R24B) \ + ENTRY(R25B) \ + ENTRY(R26B) \ + ENTRY(R27B) \ + ENTRY(R28B) \ + ENTRY(R29B) \ + ENTRY(R30B) \ + ENTRY(R31B) \ + ENTRY(SPL) \ + ENTRY(BPL) \ + ENTRY(SIL) \ ENTRY(DIL) -#define EA_BASES_16BIT \ - ENTRY(BX_SI) \ - ENTRY(BX_DI) \ - ENTRY(BP_SI) \ - ENTRY(BP_DI) \ - ENTRY(SI) \ - ENTRY(DI) \ - ENTRY(BP) \ - ENTRY(BX) \ - ENTRY(R8W) \ - ENTRY(R9W) \ - ENTRY(R10W) \ - ENTRY(R11W) \ - ENTRY(R12W) \ - ENTRY(R13W) \ - ENTRY(R14W) \ - ENTRY(R15W) +#define EA_BASES_16BIT \ + ENTRY(BX_SI) \ + ENTRY(BX_DI) \ + ENTRY(BP_SI) \ + ENTRY(BP_DI) \ + ENTRY(SI) \ + ENTRY(DI) \ + ENTRY(BP) \ + ENTRY(BX) \ + ENTRY(R8W) \ + ENTRY(R9W) \ + ENTRY(R10W) \ + ENTRY(R11W) \ + ENTRY(R12W) \ + ENTRY(R13W) \ + ENTRY(R14W) \ + ENTRY(R15W) \ + ENTRY(R16W) \ + ENTRY(R17W) \ + ENTRY(R18W) \ + ENTRY(R19W) \ + ENTRY(R20W) \ + ENTRY(R21W) \ + ENTRY(R22W) \ + ENTRY(R23W) \ + ENTRY(R24W) \ + ENTRY(R25W) \ + ENTRY(R26W) \ + ENTRY(R27W) \ + ENTRY(R28W) \ + ENTRY(R29W) \ + ENTRY(R30W) \ + ENTRY(R31W) -#define REGS_16BIT \ - ENTRY(AX) \ - ENTRY(CX) \ - ENTRY(DX) \ - ENTRY(BX) \ - ENTRY(SP) \ - ENTRY(BP) \ - ENTRY(SI) \ - ENTRY(DI) \ - ENTRY(R8W) \ - ENTRY(R9W) \ - ENTRY(R10W) \ - ENTRY(R11W) \ - ENTRY(R12W) \ - ENTRY(R13W) \ - ENTRY(R14W) \ - ENTRY(R15W) +#define REGS_16BIT \ + ENTRY(AX) \ + ENTRY(CX) \ + ENTRY(DX) \ + ENTRY(BX) \ + ENTRY(SP) \ + ENTRY(BP) \ + ENTRY(SI) \ + ENTRY(DI) \ + ENTRY(R8W) \ + ENTRY(R9W) \ + ENTRY(R10W) \ + ENTRY(R11W) \ + ENTRY(R12W) \ + ENTRY(R13W) \ + ENTRY(R14W) \ + ENTRY(R15W) \ + ENTRY(R16W) \ + ENTRY(R17W) \ + ENTRY(R18W) \ + ENTRY(R19W) \ + ENTRY(R20W) \ + ENTRY(R21W) \ + ENTRY(R22W) \ + ENTRY(R23W) \ + ENTRY(R24W) \ + ENTRY(R25W) \ + ENTRY(R26W) \ + ENTRY(R27W) \ + ENTRY(R28W) \ + ENTRY(R29W) \ + ENTRY(R30W) \ + ENTRY(R31W) -#define EA_BASES_32BIT \ - ENTRY(EAX) \ - ENTRY(ECX) \ - ENTRY(EDX) \ - ENTRY(EBX) \ - ENTRY(sib) \ - ENTRY(EBP) \ - ENTRY(ESI) \ - ENTRY(EDI) \ - ENTRY(R8D) \ - ENTRY(R9D) \ - ENTRY(R10D) \ - ENTRY(R11D) \ - ENTRY(R12D) \ - ENTRY(R13D) \ - ENTRY(R14D) \ - ENTRY(R15D) +#define EA_BASES_32BIT \ + ENTRY(EAX) \ + ENTRY(ECX) \ + ENTRY(EDX) \ + ENTRY(EBX) \ + ENTRY(sib) \ + ENTRY(EBP) \ + ENTRY(ESI) \ + ENTRY(EDI) \ + ENTRY(R8D) \ + ENTRY(R9D) \ + ENTRY(R10D) \ + ENTRY(R11D) \ + ENTRY(R12D) \ + ENTRY(R13D) \ + ENTRY(R14D) \ + ENTRY(R15D) \ + ENTRY(R16D) \ + ENTRY(R17D) \ + ENTRY(R18D) \ + ENTRY(R19D) \ + ENTRY(R20D) \ + ENTRY(R21D) \ + ENTRY(R22D) \ + ENTRY(R23D) \ + ENTRY(R24D) \ + ENTRY(R25D) \ + ENTRY(R26D) \ + ENTRY(R27D) \ + ENTRY(R28D) \ + ENTRY(R29D) \ + ENTRY(R30D) \ + ENTRY(R31D) -#define REGS_32BIT \ - ENTRY(EAX) \ - ENTRY(ECX) \ - ENTRY(EDX) \ - ENTRY(EBX) \ - ENTRY(ESP) \ - ENTRY(EBP) \ - ENTRY(ESI) \ - ENTRY(EDI) \ - ENTRY(R8D) \ - ENTRY(R9D) \ - ENTRY(R10D) \ - ENTRY(R11D) \ - ENTRY(R12D) \ - ENTRY(R13D) \ - ENTRY(R14D) \ - ENTRY(R15D) +#define REGS_32BIT \ + ENTRY(EAX) \ + ENTRY(ECX) \ + ENTRY(EDX) \ + ENTRY(EBX) \ + ENTRY(ESP) \ + ENTRY(EBP) \ + ENTRY(ESI) \ + ENTRY(EDI) \ + ENTRY(R8D) \ + ENTRY(R9D) \ + ENTRY(R10D) \ + ENTRY(R11D) \ + ENTRY(R12D) \ + ENTRY(R13D) \ + ENTRY(R14D) \ + ENTRY(R15D) \ + ENTRY(R16D) \ + ENTRY(R17D) \ + ENTRY(R18D) \ + ENTRY(R19D) \ + ENTRY(R20D) \ + ENTRY(R21D) \ + ENTRY(R22D) \ + ENTRY(R23D) \ + ENTRY(R24D) \ + ENTRY(R25D) \ + ENTRY(R26D) \ + ENTRY(R27D) \ + ENTRY(R28D) \ + ENTRY(R29D) \ + ENTRY(R30D) \ + ENTRY(R31D) -#define EA_BASES_64BIT \ - ENTRY(RAX) \ - ENTRY(RCX) \ - ENTRY(RDX) \ - ENTRY(RBX) \ - ENTRY(sib64) \ - ENTRY(RBP) \ - ENTRY(RSI) \ - ENTRY(RDI) \ - ENTRY(R8) \ - ENTRY(R9) \ - ENTRY(R10) \ - ENTRY(R11) \ - ENTRY(R12) \ - ENTRY(R13) \ - ENTRY(R14) \ - ENTRY(R15) +#define EA_BASES_64BIT \ + ENTRY(RAX) \ + ENTRY(RCX) \ + ENTRY(RDX) \ + ENTRY(RBX) \ + ENTRY(sib64) \ + ENTRY(RBP) \ + ENTRY(RSI) \ + ENTRY(RDI) \ + ENTRY(R8) \ + ENTRY(R9) \ + ENTRY(R10) \ + ENTRY(R11) \ + ENTRY(R12) \ + ENTRY(R13) \ + ENTRY(R14) \ + ENTRY(R15) \ + ENTRY(R16) \ + ENTRY(R17) \ + ENTRY(R18) \ + ENTRY(R19) \ + ENTRY(R20) \ + ENTRY(R21) \ + ENTRY(R22) \ + ENTRY(R23) \ + ENTRY(R24) \ + ENTRY(R25) \ + ENTRY(R26) \ + ENTRY(R27) \ + ENTRY(R28) \ + ENTRY(R29) \ + ENTRY(R30) \ + ENTRY(R31) -#define REGS_64BIT \ - ENTRY(RAX) \ - ENTRY(RCX) \ - ENTRY(RDX) \ - ENTRY(RBX) \ - ENTRY(RSP) \ - ENTRY(RBP) \ - ENTRY(RSI) \ - ENTRY(RDI) \ - ENTRY(R8) \ - ENTRY(R9) \ - ENTRY(R10) \ - ENTRY(R11) \ - ENTRY(R12) \ - ENTRY(R13) \ - ENTRY(R14) \ - ENTRY(R15) +#define REGS_64BIT \ + ENTRY(RAX) \ + ENTRY(RCX) \ + ENTRY(RDX) \ + ENTRY(RBX) \ + ENTRY(RSP) \ + ENTRY(RBP) \ + ENTRY(RSI) \ + ENTRY(RDI) \ + ENTRY(R8) \ + ENTRY(R9) \ + ENTRY(R10) \ + ENTRY(R11) \ + ENTRY(R12) \ + ENTRY(R13) \ + ENTRY(R14) \ + ENTRY(R15) \ + ENTRY(R16) \ + ENTRY(R17) \ + ENTRY(R18) \ + ENTRY(R19) \ + ENTRY(R20) \ + ENTRY(R21) \ + ENTRY(R22) \ + ENTRY(R23) \ + ENTRY(R24) \ + ENTRY(R25) \ + ENTRY(R26) \ + ENTRY(R27) \ + ENTRY(R28) \ + ENTRY(R29) \ + ENTRY(R30) \ + ENTRY(R31) #define REGS_MMX \ ENTRY(MM0) \ @@ -483,8 +628,10 @@ enum VEXLeadingOpcodeByte { VEX_LOB_0F = 0x1, VEX_LOB_0F38 = 0x2, VEX_LOB_0F3A = 0x3, + VEX_LOB_MAP4 = 0x4, VEX_LOB_MAP5 = 0x5, - VEX_LOB_MAP6 = 0x6 + VEX_LOB_MAP6 = 0x6, + VEX_LOB_MAP7 = 0x7 }; enum XOPMapSelect { @@ -539,6 +686,8 @@ struct InternalInstruction { uint8_t vectorExtensionPrefix[4]; // The type of the vector extension prefix VectorExtensionType vectorExtensionType; + // The value of the REX2 prefix, if present + uint8_t rex2ExtensionPrefix[2]; // The value of the REX prefix, if present uint8_t rexPrefix; // The segment override type |
