diff options
Diffstat (limited to 'llvm/lib/Target/X86/Disassembler')
3 files changed, 32 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp index acfe88dd8f0..dae1345f708 100644 --- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp +++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp @@ -233,6 +233,29 @@ static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = { X86::GS }; +/// translateSrcIndex - Appends a source index operand to an MCInst. +/// +/// @param mcInst - The MCInst to append to. +/// @param operand - The operand, as stored in the descriptor table. +/// @param insn - The internal instruction. +static bool translateSrcIndex(MCInst &mcInst, InternalInstruction &insn) { + unsigned baseRegNo; + + if (insn.mode == MODE_64BIT) + baseRegNo = insn.prefixPresent[0x67] ? X86::ESI : X86::RSI; + else if (insn.mode == MODE_32BIT) + baseRegNo = insn.prefixPresent[0x67] ? X86::SI : X86::ESI; + else if (insn.mode == MODE_16BIT) + baseRegNo = insn.prefixPresent[0x67] ? X86::ESI : X86::SI; + MCOperand baseReg = MCOperand::CreateReg(baseRegNo); + mcInst.addOperand(baseReg); + + MCOperand segmentReg; + segmentReg = MCOperand::CreateReg(segmentRegnums[insn.segmentOverride]); + mcInst.addOperand(segmentReg); + return false; +} + /// translateImmediate - Appends an immediate operand to an MCInst. /// /// @param mcInst - The MCInst to append to. @@ -694,6 +717,8 @@ static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand, insn, Dis); return false; + case ENCODING_SI: + return translateSrcIndex(mcInst, insn); case ENCODING_RB: case ENCODING_RW: case ENCODING_RD: diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c index 48c16977133..8e591b8fdde 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c @@ -1682,6 +1682,7 @@ static int readOperands(struct InternalInstruction* insn) { for (index = 0; index < X86_MAX_OPERANDS; ++index) { switch (x86OperandSets[insn->spec->operands][index].encoding) { case ENCODING_NONE: + case ENCODING_SI: break; case ENCODING_REG: case ENCODING_RM: diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h index 1acaef1b947..c7fcb0ca200 100644 --- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h +++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h @@ -409,7 +409,8 @@ struct ContextDecision { ENUM_ENTRY(ENCODING_Rv, "Register code of operand size added to the " \ "opcode byte") \ ENUM_ENTRY(ENCODING_DUP, "Duplicate of another operand; ID is encoded " \ - "in type") + "in type") \ + ENUM_ENTRY(ENCODING_SI, "Source index; encoded in OpSize/Adsize prefix") #define ENUM_ENTRY(n, d) n, typedef enum { @@ -460,6 +461,10 @@ struct ContextDecision { ENUM_ENTRY(TYPE_M16_16, "2+2-byte (BOUND)") \ ENUM_ENTRY(TYPE_M32_32, "4+4-byte (BOUND)") \ ENUM_ENTRY(TYPE_M16_64, "2+8-byte (LIDT, LGDT)") \ + ENUM_ENTRY(TYPE_SRCIDX8, "1-byte memory at source index") \ + ENUM_ENTRY(TYPE_SRCIDX16, "2-byte memory at source index") \ + ENUM_ENTRY(TYPE_SRCIDX32, "4-byte memory at source index") \ + ENUM_ENTRY(TYPE_SRCIDX64, "8-byte memory at source index") \ ENUM_ENTRY(TYPE_MOFFS8, "1-byte memory offset (relative to segment " \ "base)") \ ENUM_ENTRY(TYPE_MOFFS16, "2-byte") \ |