summaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86InstrInfo.td
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2014-01-22 15:08:08 +0000
committerDavid Woodhouse <dwmw2@infradead.org>2014-01-22 15:08:08 +0000
commitdb9fa461d7d9643a1b25f13df73638be9c36cafb (patch)
tree26638c68d124efa7c6e7e97d951c810a3b2f4171 /lib/Target/X86/X86InstrInfo.td
parentb9b629cbaa25497872eaa811e7b0c225e3c7f545 (diff)
downloadllvm-db9fa461d7d9643a1b25f13df73638be9c36cafb.tar.gz
llvm-db9fa461d7d9643a1b25f13df73638be9c36cafb.tar.bz2
llvm-db9fa461d7d9643a1b25f13df73638be9c36cafb.tar.xz
[x86] Allow segment and address-size overrides for LODS[BWLQ] (PR9385)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199803 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/X86InstrInfo.td')
-rw-r--r--lib/Target/X86/X86InstrInfo.td61
1 files changed, 56 insertions, 5 deletions
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 486435d35d..d3e102747e 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -445,6 +445,26 @@ def brtarget8 : Operand<OtherVT>;
}
+def X86SrcIdx8Operand : AsmOperandClass {
+ let Name = "SrcIdx8";
+ let RenderMethod = "addSrcIdxOperands";
+ let SuperClasses = [X86Mem8AsmOperand];
+}
+def X86SrcIdx16Operand : AsmOperandClass {
+ let Name = "SrcIdx16";
+ let RenderMethod = "addSrcIdxOperands";
+ let SuperClasses = [X86Mem16AsmOperand];
+}
+def X86SrcIdx32Operand : AsmOperandClass {
+ let Name = "SrcIdx32";
+ let RenderMethod = "addSrcIdxOperands";
+ let SuperClasses = [X86Mem32AsmOperand];
+}
+def X86SrcIdx64Operand : AsmOperandClass {
+ let Name = "SrcIdx64";
+ let RenderMethod = "addSrcIdxOperands";
+ let SuperClasses = [X86Mem64AsmOperand];
+}
def X86MemOffs8AsmOperand : AsmOperandClass {
let Name = "MemOffs8";
let RenderMethod = "addMemOffsOperands";
@@ -465,8 +485,23 @@ def X86MemOffs64AsmOperand : AsmOperandClass {
let RenderMethod = "addMemOffsOperands";
let SuperClasses = [X86Mem64AsmOperand];
}
-
let OperandType = "OPERAND_MEMORY" in {
+def srcidx8 : Operand<iPTR> {
+ let ParserMatchClass = X86SrcIdx8Operand;
+ let MIOperandInfo = (ops ptr_rc, i8imm);
+ let PrintMethod = "printSrcIdx8"; }
+def srcidx16 : Operand<iPTR> {
+ let ParserMatchClass = X86SrcIdx16Operand;
+ let MIOperandInfo = (ops ptr_rc, i8imm);
+ let PrintMethod = "printSrcIdx16"; }
+def srcidx32 : Operand<iPTR> {
+ let ParserMatchClass = X86SrcIdx32Operand;
+ let MIOperandInfo = (ops ptr_rc, i8imm);
+ let PrintMethod = "printSrcIdx32"; }
+def srcidx64 : Operand<iPTR> {
+ let ParserMatchClass = X86SrcIdx64Operand;
+ let MIOperandInfo = (ops ptr_rc, i8imm);
+ let PrintMethod = "printSrcIdx64"; }
def offset8 : Operand<iPTR> {
let ParserMatchClass = X86MemOffs8AsmOperand;
let MIOperandInfo = (ops i64imm, i8imm);
@@ -1676,10 +1711,14 @@ def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
// String manipulation instructions
let SchedRW = [WriteMicrocoded] in {
-def LODSB : I<0xAC, RawFrm, (outs), (ins), "lodsb", [], IIC_LODS>;
-def LODSW : I<0xAD, RawFrm, (outs), (ins), "lodsw", [], IIC_LODS>, OpSize;
-def LODSL : I<0xAD, RawFrm, (outs), (ins), "lods{l|d}", [], IIC_LODS>, OpSize16;
-def LODSQ : RI<0xAD, RawFrm, (outs), (ins), "lodsq", [], IIC_LODS>;
+def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
+ "lodsb\t{$src, %al|al, $src}", [], IIC_LODS>;
+def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
+ "lodsw\t{$src, %ax|ax, $src}", [], IIC_LODS>, OpSize;
+def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
+ "lods{l|d}\t{$src, %eax|eax, $src}", [], IIC_LODS>, OpSize16;
+def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
+ "lodsq\t{$src, %rax|rax, $src}", [], IIC_LODS>;
}
let SchedRW = [WriteSystem] in {
@@ -2329,6 +2368,18 @@ def : InstAlias<"clrw $reg", (XOR16rr GR16:$reg, GR16:$reg), 0>;
def : InstAlias<"clrl $reg", (XOR32rr GR32:$reg, GR32:$reg), 0>;
def : InstAlias<"clrq $reg", (XOR64rr GR64:$reg, GR64:$reg), 0>;
+// lods aliases. Accept the destination being omitted because it's implicit
+// in the mnemonic, or the mnemonic suffix being omitted because it's implicit
+// in the destination.
+def : InstAlias<"lodsb $src", (LODSB srcidx8:$src), 0>;
+def : InstAlias<"lodsw $src", (LODSW srcidx16:$src), 0>;
+def : InstAlias<"lods{l|d} $src", (LODSL srcidx32:$src), 0>;
+def : InstAlias<"lodsq $src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
+def : InstAlias<"lods {$src, %al|al, $src}", (LODSB srcidx8:$src), 0>;
+def : InstAlias<"lods {$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>;
+def : InstAlias<"lods {$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>;
+def : InstAlias<"lods {$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>;
+
// div and idiv aliases for explicit A register.
def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>;
def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>;