Remove need for MODIFIER_OPCODE in the disassembler tables. AddRegFrms are really...
authorCraig Topper <craig.topper@gmail.com>
Wed, 1 Jan 2014 15:29:32 +0000 (15:29 +0000)
committerCraig Topper <craig.topper@gmail.com>
Wed, 1 Jan 2014 15:29:32 +0000 (15:29 +0000)
llvm-svn: 198278

llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
llvm/test/MC/Disassembler/X86/simple-tests.txt
llvm/utils/TableGen/X86RecognizableInstr.cpp

index f766150..1bc4dc4 100644 (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);
index 0659e4f..52631bc 100644 (file)
@@ -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;
   }
 
index 294c476..c4c86ad 100644 (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 */
index dc06819..8ecda65 100644 (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 {
index 7ca0874..e6e9c7b 100644 (file)
 # 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
 
index 678e843..4016116 100644 (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;