Remove need for MODIFIER_OPCODE in the disassembler tables. AddRegFrms are really more like OrRegFrm so we don't need a difference since we can just mask bits.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198278 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Craig Topper 2014-01-01 15:29:32 +00:00
parent 3062a311ac
commit 95a3ccdd80
6 changed files with 26 additions and 60 deletions

View File

@ -609,16 +609,9 @@ static bool translateRM(MCInst &mcInst, const OperandSpecifier &operand,
/// @param mcInst - The MCInst to append to.
/// @param stackPos - The stack position to translate.
/// @return - false on success; true otherwise.
static bool translateFPRegister(MCInst &mcInst,
uint8_t stackPos) {
if (stackPos >= 8) {
debug("Invalid FP stack position");
return true;
}
static void translateFPRegister(MCInst &mcInst,
uint8_t stackPos) {
mcInst.addOperand(MCOperand::CreateReg(X86::ST0 + stackPos));
return false;
}
/// translateMaskRegister - Translates a 3-bit mask register number to
@ -683,12 +676,11 @@ static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand,
case ENCODING_RW:
case ENCODING_RD:
case ENCODING_RO:
case ENCODING_Rv:
translateRegister(mcInst, insn.opcodeRegister);
return false;
case ENCODING_FP:
return translateFPRegister(mcInst, insn.modRM & 7);
case ENCODING_Rv:
translateRegister(mcInst, insn.opcodeRegister);
translateFPRegister(mcInst, insn.modRM & 7);
return false;
case ENCODING_VVVV:
translateRegister(mcInst, insn.vvvv);

View File

@ -1501,40 +1501,12 @@ static int fixupReg(struct InternalInstruction *insn,
return 0;
}
/*
* readOpcodeModifier - Reads an operand from the opcode field of an
* instruction. Handles AddRegFrm instructions.
*
* @param insn - The instruction whose opcode field is to be read.
* @return - 0 on success; nonzero otherwise.
*/
static int readOpcodeModifier(struct InternalInstruction* insn) {
dbgprintf(insn, "readOpcodeModifier()");
if (insn->consumedOpcodeModifier)
return 0;
insn->consumedOpcodeModifier = TRUE;
switch (insn->spec->modifierType) {
default:
debug("Unknown modifier type.");
return -1;
case MODIFIER_NONE:
debug("No modifier but an operand expects one.");
return -1;
case MODIFIER_OPCODE:
insn->opcodeModifier = insn->opcode - insn->spec->modifierBase;
return 0;
}
}
/*
* readOpcodeRegister - Reads an operand from the opcode field of an
* instruction and interprets it appropriately given the operand width.
* Handles AddRegFrm instructions.
*
* @param insn - See readOpcodeModifier().
* @param insn - the instruction whose opcode field is to be read.
* @param size - The width (in bytes) of the register being specified.
* 1 means AL and friends, 2 means AX, 4 means EAX, and 8 means
* RAX.
@ -1543,16 +1515,13 @@ static int readOpcodeModifier(struct InternalInstruction* insn) {
static int readOpcodeRegister(struct InternalInstruction* insn, uint8_t size) {
dbgprintf(insn, "readOpcodeRegister()");
if (readOpcodeModifier(insn))
return -1;
if (size == 0)
size = insn->registerSize;
switch (size) {
case 1:
insn->opcodeRegister = (Reg)(MODRM_REG_AL + ((bFromREX(insn->rexPrefix) << 3)
| insn->opcodeModifier));
| (insn->opcode & 7)));
if (insn->rexPrefix &&
insn->opcodeRegister >= MODRM_REG_AL + 0x4 &&
insn->opcodeRegister < MODRM_REG_AL + 0x8) {
@ -1564,17 +1533,17 @@ static int readOpcodeRegister(struct InternalInstruction* insn, uint8_t size) {
case 2:
insn->opcodeRegister = (Reg)(MODRM_REG_AX
+ ((bFromREX(insn->rexPrefix) << 3)
| insn->opcodeModifier));
| (insn->opcode & 7)));
break;
case 4:
insn->opcodeRegister = (Reg)(MODRM_REG_EAX
+ ((bFromREX(insn->rexPrefix) << 3)
| insn->opcodeModifier));
| (insn->opcode & 7)));
break;
case 8:
insn->opcodeRegister = (Reg)(MODRM_REG_RAX
+ ((bFromREX(insn->rexPrefix) << 3)
| insn->opcodeModifier));
| (insn->opcode & 7)));
break;
}

View File

@ -634,8 +634,6 @@ struct InternalInstruction {
uint64_t immediates[2];
/* A register or immediate operand encoded into the opcode */
BOOL consumedOpcodeModifier;
uint8_t opcodeModifier;
Reg opcodeRegister;
/* Portions of the ModR/M byte */

View File

@ -525,8 +525,7 @@ struct OperandSpecifier {
*/
#define MODIFIER_TYPES \
ENUM_ENTRY(MODIFIER_NONE) \
ENUM_ENTRY(MODIFIER_OPCODE)
ENUM_ENTRY(MODIFIER_NONE)
#define ENUM_ENTRY(n) n,
typedef enum {

View File

@ -359,6 +359,18 @@
# CHECK: xchgq %r8, %rax
0x49 0x90
# CHECK: xchgl %r9d, %eax
0x41 0x91
# CHECK: xchgq %r9, %rax
0x49 0x91
# CHECK: xchgl %ecx, %eax
0x91
# CHECK: xchgq %rcx, %rax
0x48 0x91
# CHECK: addb $0, %al
0x04 0x00

View File

@ -1162,8 +1162,8 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
assert(filter && "Filter not set");
if (Form == X86Local::AddRegFrm) {
assert(opcodeToSet < 0xf9 &&
"Not enough room for all ADDREG_FRM operands");
assert(((opcodeToSet & 7) == 0) &&
"ADDREG_FRM opcode not aligned");
uint8_t currentOpcode;
@ -1175,19 +1175,15 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
currentOpcode,
*filter,
UID, Is32Bit, IgnoresVEX_L);
Spec->modifierType = MODIFIER_OPCODE;
Spec->modifierBase = opcodeToSet;
} else {
tables.setTableFields(opcodeType,
insnContext(),
opcodeToSet,
*filter,
UID, Is32Bit, IgnoresVEX_L);
Spec->modifierType = MODIFIER_NONE;
Spec->modifierBase = opcodeToSet;
}
Spec->modifierType = MODIFIER_NONE;
Spec->modifierBase = opcodeToSet;
delete filter;