[X86] Disassembler support for move to/from %rax with a 32-bit memory offset is REX...
authorCraig Topper <craig.topper@gmail.com>
Sat, 3 Jan 2015 00:00:20 +0000 (00:00 +0000)
committerCraig Topper <craig.topper@gmail.com>
Sat, 3 Jan 2015 00:00:20 +0000 (00:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225099 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/AsmParser/X86Operand.h
lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
lib/Target/X86/X86InstrInfo.td
test/MC/Disassembler/X86/prefixes.txt
test/MC/Disassembler/X86/x86-64.txt
utils/TableGen/X86DisassemblerTables.cpp
utils/TableGen/X86RecognizableInstr.cpp

index 0461433275591c397782e0c3a00d9bec3f106c36..4362fc5026d146a27ab6d98faa5e4df9bafd3007 100644 (file)
@@ -316,6 +316,9 @@ struct X86Operand : public MCParsedAsmOperand {
   bool isMemOffs32_32() const {
     return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 32);
   }
+  bool isMemOffs32_64() const {
+    return isMemOffs() && Mem.ModeSize == 32 && (!Mem.Size || Mem.Size == 64);
+  }
   bool isMemOffs64_8() const {
     return isMemOffs() && Mem.ModeSize == 64 && (!Mem.Size || Mem.Size == 8);
   }
index d04d8c0f0632f6d20d21bc19e96ee9683a8368ea..3e8172e6cee81a7c7ca0b0b5ee2c129920a1a52c 100644 (file)
@@ -93,6 +93,8 @@ enum attributeBits {
                                         "operands change width")               \
   ENUM_ENTRY(IC_64BIT_REXW,         5,  "requires a REX.W prefix, so operands "\
                                         "change width; overrides IC_OPSIZE")   \
+  ENUM_ENTRY(IC_64BIT_REXW_ADSIZE,  6,  "requires a REX.W prefix and 0x67 "    \
+                                        "prefix")                              \
   ENUM_ENTRY(IC_64BIT_OPSIZE,       3,  "Just as meaningful as IC_OPSIZE")     \
   ENUM_ENTRY(IC_64BIT_ADSIZE,       3,  "Just as meaningful as IC_ADSIZE")     \
   ENUM_ENTRY(IC_64BIT_OPSIZE_ADSIZE, 4, "Just as meaningful as IC_OPSIZE/"     \
index 0efbd06548b47d65c88db419a16974b9e3cb2537..5a9b51aa0cce641b55b7bdd4620c048e9c983c67 100644 (file)
@@ -494,6 +494,11 @@ def X86MemOffs32_32AsmOperand : AsmOperandClass {
   let RenderMethod = "addMemOffsOperands";
   let SuperClasses = [X86Mem32AsmOperand];
 }
+def X86MemOffs32_64AsmOperand : AsmOperandClass {
+  let Name = "MemOffs32_64";
+  let RenderMethod = "addMemOffsOperands";
+  let SuperClasses = [X86Mem64AsmOperand];
+}
 def X86MemOffs64_8AsmOperand : AsmOperandClass {
   let Name = "MemOffs64_8";
   let RenderMethod = "addMemOffsOperands";
@@ -571,6 +576,10 @@ def offset32_32 : Operand<iPTR> {
   let ParserMatchClass = X86MemOffs32_32AsmOperand;
   let MIOperandInfo = (ops i64imm, i8imm);
   let PrintMethod = "printMemOffs32"; }
+def offset32_64 : Operand<iPTR> {
+  let ParserMatchClass = X86MemOffs32_64AsmOperand;
+  let MIOperandInfo = (ops i64imm, i8imm);
+  let PrintMethod = "printMemOffs64"; }
 def offset64_8 : Operand<iPTR> {
   let ParserMatchClass = X86MemOffs64_8AsmOperand;
   let MIOperandInfo = (ops i64imm, i8imm);
@@ -1318,6 +1327,10 @@ let Defs = [EAX] in
 def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
                      "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
                      OpSize32, AdSize32;
+let Defs = [RAX] in
+def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
+                      "mov{q}\t{$src, %rax|rax, $src}", [], IIC_MOV_MEM>,
+                      AdSize32;
 
 let Defs = [AL] in
 def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
@@ -1343,6 +1356,10 @@ let Uses = [EAX] in
 def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs offset32_32:$dst), (ins),
                      "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
                      OpSize32, AdSize32;
+let Uses = [RAX] in
+def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs offset32_64:$dst), (ins),
+                      "mov{q}\t{%rax, $dst|$dst, rax}", [], IIC_MOV_MEM>,
+                      AdSize32;
 
 let Uses = [AL] in
 def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs offset16_8:$dst), (ins),
index ee0ba086618accc74a67d9a3a62621ed4cab12d6..9e002fab465680f86fcc97d4e9b9c638cf1d97d4 100644 (file)
@@ -8,11 +8,11 @@
 0x64 0x48 0x8b 0x3c 0x25 0x00 0x03 0x00 0x00
 
 # CHECK: rep
-# CHECK-NEXT:          stosq
+# CHECK-NEXT:          stosq %rax, %es:(%rdi)
 0xf3 0x48 0xab
 
 # CHECK: rep
-# CHECK-NEXT:          stosl
+# CHECK-NEXT:          stosq %rax, %es:(%edi)
 0xf3 0x67 0x48 0xab
 
 # CHECK: movl 32(%rbp), %eax
index 6f072df7e4b7bb4f46fd216de0516cef4646f303..70c8ae0dcc0688f2b5c9dc005e2691efca5919c6 100644 (file)
 
 # CHECK: $0, 305419896(%rbp)
 0x80 0x84 0x25 0x78 0x56 0x34 0x12 0x00
+
+# CHECK: movabsq 6510615555426900570, %rax
+0x48 0xa1 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
+
+# CHECK: movq 1515870810, %rax
+0x67, 0x48 0xa1 0x5a 0x5a 0x5a 0x5a
+
+# CHECK: movabsq %rax, 6510615555426900570
+0x48 0xa3 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a 0x5a
+
+# CHECK: movq %rax, 1515870810
+0x67, 0x48 0xa3 0x5a 0x5a 0x5a 0x5a
index 138a34b4dc9a5866dd3077cd36fbefe41175b7a7..fbe5502bc90e8a91af3f9d8d5017e6d3b5b59381 100644 (file)
@@ -114,10 +114,12 @@ static inline bool inheritsFrom(InstructionContext child,
   case IC_64BIT_REXW:
     return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
            inheritsFrom(child, IC_64BIT_REXW_XD) ||
-           inheritsFrom(child, IC_64BIT_REXW_OPSIZE));
+           inheritsFrom(child, IC_64BIT_REXW_OPSIZE) ||
+           (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE)));
   case IC_64BIT_OPSIZE:
     return inheritsFrom(child, IC_64BIT_REXW_OPSIZE) ||
-           (!AdSize64 && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE));
+           (!AdSize64 && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE)) ||
+           (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE));
   case IC_64BIT_XD:
     return(inheritsFrom(child, IC_64BIT_REXW_XD));
   case IC_64BIT_XS:
@@ -128,6 +130,7 @@ static inline bool inheritsFrom(InstructionContext child,
   case IC_64BIT_REXW_XD:
   case IC_64BIT_REXW_XS:
   case IC_64BIT_REXW_OPSIZE:
+  case IC_64BIT_REXW_ADSIZE:
     return false;
   case IC_VEX:
     return (VEX_LIG && inheritsFrom(child, IC_VEX_L_W)) ||
@@ -720,6 +723,9 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const {
     else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&
              (index & ATTR_OPSIZE))
       o << "IC_64BIT_REXW_OPSIZE";
+    else if ((index & ATTR_64BIT) && (index & ATTR_REXW) &&
+             (index & ATTR_ADSIZE))
+      o << "IC_64BIT_REXW_ADSIZE";
     else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE))
       o << "IC_64BIT_XD_OPSIZE";
     else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE))
index 91c64aa049e850240019d3e85d85cba05e0c3d2c..56976d3ec3833068fb172c9d5159cf9bdd1a3fe0 100644 (file)
@@ -408,6 +408,8 @@ InstructionContext RecognizableInstr::insnContext() const {
   } else if (Is64Bit || HasREX_WPrefix || AdSize == X86Local::AdSize64) {
     if (HasREX_WPrefix && (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD))
       insnContext = IC_64BIT_REXW_OPSIZE;
+    else if (HasREX_WPrefix && AdSize == X86Local::AdSize32)
+      insnContext = IC_64BIT_REXW_ADSIZE;
     else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XD)
       insnContext = IC_64BIT_XD_OPSIZE;
     else if (OpSize == X86Local::OpSize16 && OpPrefix == X86Local::XS)
@@ -984,6 +986,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
   TYPE("offset32_8",          TYPE_MOFFS8)
   TYPE("offset32_16",         TYPE_MOFFS16)
   TYPE("offset32_32",         TYPE_MOFFS32)
+  TYPE("offset32_64",         TYPE_MOFFS64)
   TYPE("offset64_8",          TYPE_MOFFS8)
   TYPE("offset64_16",         TYPE_MOFFS16)
   TYPE("offset64_32",         TYPE_MOFFS32)
@@ -1219,6 +1222,7 @@ RecognizableInstr::relocationEncodingFromString(const std::string &s,
   ENCODING("offset32_8",      ENCODING_Ia)
   ENCODING("offset32_16",     ENCODING_Ia)
   ENCODING("offset32_32",     ENCODING_Ia)
+  ENCODING("offset32_64",     ENCODING_Ia)
   ENCODING("offset64_8",      ENCODING_Ia)
   ENCODING("offset64_16",     ENCODING_Ia)
   ENCODING("offset64_32",     ENCODING_Ia)