summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2014-01-01 15:29:32 +0000
committerCraig Topper <craig.topper@gmail.com>2014-01-01 15:29:32 +0000
commit91551186028359e36ba21e212b3a0ec451edbb8b (patch)
tree8b0a3351a841e3e74f2b6f52218ac0662afc6220 /llvm
parentde3f751bafe64d1d71d8c87b10a8254b276ec4d9 (diff)
downloadbcm5719-llvm-91551186028359e36ba21e212b3a0ec451edbb8b.tar.gz
bcm5719-llvm-91551186028359e36ba21e212b3a0ec451edbb8b.zip
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.
llvm-svn: 198278
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp16
-rw-r--r--llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c41
-rw-r--r--llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h2
-rw-r--r--llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h3
-rw-r--r--llvm/test/MC/Disassembler/X86/simple-tests.txt12
-rw-r--r--llvm/utils/TableGen/X86RecognizableInstr.cpp12
6 files changed, 26 insertions, 60 deletions
diff --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
index f766150cc24..1bc4dc477e4 100644
--- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
+++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
@@ -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);
diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
index 0659e4f4a94..52631bcbf2d 100644
--- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
+++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
@@ -1502,39 +1502,11 @@ static int fixupReg(struct InternalInstruction *insn,
}
/*
- * 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;
}
diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
index 294c47688ff..c4c86ada3fa 100644
--- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
+++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
@@ -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 */
diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
index dc06819bf5a..8ecda65d989 100644
--- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
+++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
@@ -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 {
diff --git a/llvm/test/MC/Disassembler/X86/simple-tests.txt b/llvm/test/MC/Disassembler/X86/simple-tests.txt
index 7ca08743897..e6e9c7bc9cc 100644
--- a/llvm/test/MC/Disassembler/X86/simple-tests.txt
+++ b/llvm/test/MC/Disassembler/X86/simple-tests.txt
@@ -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
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index 678e843e9c9..4016116de13 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -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;
OpenPOWER on IntegriCloud