summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/X86/AsmParser/X86Operand.h3
-rw-r--r--llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h2
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.td17
-rw-r--r--llvm/test/MC/Disassembler/X86/prefixes.txt4
-rw-r--r--llvm/test/MC/Disassembler/X86/x86-64.txt12
-rw-r--r--llvm/utils/TableGen/X86DisassemblerTables.cpp10
-rw-r--r--llvm/utils/TableGen/X86RecognizableInstr.cpp4
7 files changed, 48 insertions, 4 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h
index 04614332755..4362fc5026d 100644
--- a/llvm/lib/Target/X86/AsmParser/X86Operand.h
+++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h
@@ -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);
}
diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
index d04d8c0f063..3e8172e6cee 100644
--- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
+++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
@@ -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/" \
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index 0efbd06548b..5a9b51aa0cc 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -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),
diff --git a/llvm/test/MC/Disassembler/X86/prefixes.txt b/llvm/test/MC/Disassembler/X86/prefixes.txt
index ee0ba086618..9e002fab465 100644
--- a/llvm/test/MC/Disassembler/X86/prefixes.txt
+++ b/llvm/test/MC/Disassembler/X86/prefixes.txt
@@ -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
diff --git a/llvm/test/MC/Disassembler/X86/x86-64.txt b/llvm/test/MC/Disassembler/X86/x86-64.txt
index 6f072df7e4b..70c8ae0dcc0 100644
--- a/llvm/test/MC/Disassembler/X86/x86-64.txt
+++ b/llvm/test/MC/Disassembler/X86/x86-64.txt
@@ -265,3 +265,15 @@
# 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
diff --git a/llvm/utils/TableGen/X86DisassemblerTables.cpp b/llvm/utils/TableGen/X86DisassemblerTables.cpp
index 138a34b4dc9..fbe5502bc90 100644
--- a/llvm/utils/TableGen/X86DisassemblerTables.cpp
+++ b/llvm/utils/TableGen/X86DisassemblerTables.cpp
@@ -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))
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index 91c64aa049e..56976d3ec38 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -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)
OpenPOWER on IntegriCloud