mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-27 22:55:15 +00:00
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:
parent
3062a311ac
commit
95a3ccdd80
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user