add (and document) the ability for alias results to have
[oota-llvm.git] / lib / Target / X86 / X86InstrInfo.td
index 9908ade8c15f98b8eb7df44d3f8bbf5a6cf1d450..fdb29837fd79502652de35b695e0055ce3d6ff3a 100644 (file)
@@ -1060,17 +1060,14 @@ let Constraints = "$val = $dst" in {
 def XCHG8rm  : I<0x86, MRMSrcMem, (outs GR8:$dst), (ins GR8:$val, i8mem:$ptr),
                "xchg{b}\t{$val, $ptr|$ptr, $val}",
                [(set GR8:$dst, (atomic_swap_8 addr:$ptr, GR8:$val))]>;
-def XCHG16rm : I<0x87, MRMSrcMem, (outs GR16:$dst),
-                 (ins GR16:$val, i16mem:$ptr),
+def XCHG16rm : I<0x87, MRMSrcMem, (outs GR16:$dst),(ins GR16:$val, i16mem:$ptr),
                "xchg{w}\t{$val, $ptr|$ptr, $val}",
                [(set GR16:$dst, (atomic_swap_16 addr:$ptr, GR16:$val))]>,
                 OpSize;
-def XCHG32rm : I<0x87, MRMSrcMem, (outs GR32:$dst),
-                 (ins GR32:$val, i32mem:$ptr),
+def XCHG32rm : I<0x87, MRMSrcMem, (outs GR32:$dst),(ins GR32:$val, i32mem:$ptr),
                "xchg{l}\t{$val, $ptr|$ptr, $val}",
                [(set GR32:$dst, (atomic_swap_32 addr:$ptr, GR32:$val))]>;
-def XCHG64rm : RI<0x87, MRMSrcMem, (outs GR64:$dst),
-                  (ins GR64:$val,i64mem:$ptr),
+def XCHG64rm : RI<0x87, MRMSrcMem, (outs GR64:$dst),(ins GR64:$val,i64mem:$ptr),
                   "xchg{q}\t{$val, $ptr|$ptr, $val}",
                   [(set GR64:$dst, (atomic_swap_64 addr:$ptr, GR64:$val))]>;
 
@@ -1370,52 +1367,115 @@ defm : IntegerCondCodeMnemonicAlias<"cmov", "q">;
 // Assembler Instruction Aliases
 //===----------------------------------------------------------------------===//
 
+// aad/aam default to base 10 if no operand is specified.
+def : InstAlias<"aad", (AAD8i8 10)>;
+def : InstAlias<"aam", (AAM8i8 10)>;
+
+// clr aliases.
+def : InstAlias<"clrb $reg", (XOR8rr  GR8 :$reg, GR8 :$reg)>;
+def : InstAlias<"clrw $reg", (XOR16rr GR16:$reg, GR16:$reg)>;
+def : InstAlias<"clrl $reg", (XOR32rr GR32:$reg, GR32:$reg)>;
+def : InstAlias<"clrq $reg", (XOR64rr GR64:$reg, GR64:$reg)>;
+
+// Default arguments for various fp stack instructions.
+def : InstAlias<"fucom",        (UCOM_Fr   ST1)>;
+def : InstAlias<"fucomp",       (UCOM_FPr  ST1)>;
+def : InstAlias<"fcomi",        (COM_FIr   ST1)>;
+def : InstAlias<"fcomi   $reg", (COM_FIr   RST:$reg)>;
+def : InstAlias<"fcomip",       (COM_FIPr  ST1)>;
+def : InstAlias<"fcomip  $reg", (COM_FIPr  RST:$reg)>;
+def : InstAlias<"fucomi",       (UCOM_FIr  ST1)>;
+def : InstAlias<"fucomi  $reg", (UCOM_FIr  RST:$reg)>;
+def : InstAlias<"fucomip",      (UCOM_FIPr ST1)>;
+def : InstAlias<"fucomip $reg", (UCOM_FIPr RST:$reg)>;
+
+
+// We accepts "fnstsw %eax" even though it only writes %ax.
+def : InstAlias<"fnstsw %eax", (FNSTSW8r)>;
+def : InstAlias<"fnstsw %al" , (FNSTSW8r)>;
+def : InstAlias<"fnstsw"     , (FNSTSW8r)>;
+
+// lcall and ljmp aliases.  This seems to be an odd mapping in 64-bit mode, but
+// this is compatible with what GAS does.
+def : InstAlias<"lcall $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>;
+def : InstAlias<"ljmp $seg, $off",  (FARJMP32i  i32imm:$off, i16imm:$seg)>;
+def : InstAlias<"lcall *$dst",      (FARCALL32m opaque48mem:$dst)>;
+def : InstAlias<"ljmp *$dst",       (FARJMP32m  opaque48mem:$dst)>;
+
+// "imul <imm>, B" is an alias for "imul <imm>, B, B".
+def : InstAlias<"imulw $imm, $r", (IMUL16rri  GR16:$r, GR16:$r, i16imm:$imm)>;
+def : InstAlias<"imulw $imm, $r", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm)>;
+def : InstAlias<"imull $imm, $r", (IMUL32rri  GR32:$r, GR32:$r, i32imm:$imm)>;
+def : InstAlias<"imull $imm, $r", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm)>;
+def : InstAlias<"imulq $imm, $r",(IMUL64rri32 GR64:$r, GR64:$r,i64i32imm:$imm)>;
+def : InstAlias<"imulq $imm, $r", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm)>;
+
+// inb %dx -> inb %al, %dx
+def : InstAlias<"inb %dx", (IN8rr)>;
+def : InstAlias<"inw %dx", (IN16rr)>;
+def : InstAlias<"inl %dx", (IN32rr)>;
+def : InstAlias<"inb $port", (IN8ri i8imm:$port)>;
+def : InstAlias<"inw $port", (IN16ri i8imm:$port)>;
+def : InstAlias<"inl $port", (IN32ri i8imm:$port)>;
+
+
+// jmp and call aliases for lcall and ljmp.  jmp $42,$5 -> ljmp
+def : InstAlias<"call $seg, $off",  (FARCALL32i i32imm:$off, i16imm:$seg)>;
+def : InstAlias<"jmp $seg, $off",   (FARJMP32i  i32imm:$off, i16imm:$seg)>;
+def : InstAlias<"callw $seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>;
+def : InstAlias<"jmpw $seg, $off",  (FARJMP16i  i16imm:$off, i16imm:$seg)>;
+def : InstAlias<"calll $seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>;
+def : InstAlias<"jmpl $seg, $off",  (FARJMP32i  i32imm:$off, i16imm:$seg)>;
+
+
+// Match 'movq <largeimm>, <reg>' as an alias for movabsq.
+def : InstAlias<"movq $imm, $reg", (MOV64ri GR64:$reg, i64imm:$imm)>;
+
+// movsd with no operands (as opposed to the SSE scalar move of a double) is an
+// alias for movsl. (as in rep; movsd)
+def : InstAlias<"movsd", (MOVSD)>;
+
 // movsx aliases
-def : InstAlias<(outs GR16:$dst), (ins GR8 :$src),
-                "movsx $src, $dst",
-                (MOVSX16rr8W GR16:$dst, GR8:$src)>;
-def : InstAlias<(outs GR16:$dst), (ins i8mem:$src),
-                "movsx $src, $dst",
-                (MOVSX16rm8W GR16:$dst, i8mem:$src)>;
-
-def : InstAlias<(outs GR32:$dst), (ins GR8 :$src),
-                "movsx $src, $dst",
-                (MOVSX32rr8 GR32:$dst, GR8:$src)>;
-def : InstAlias<(outs GR32:$dst), (ins GR16:$src),
-                "movsx $src, $dst",
-                (MOVSX32rr16 GR32:$dst, GR16:$src)>;
-
-def : InstAlias<(outs GR64:$dst), (ins GR8 :$src),
-                "movsx $src, $dst",
-                (MOVSX64rr8 GR64:$dst, GR8:$src)>;
-def : InstAlias<(outs GR64:$dst), (ins GR16:$src),
-                "movsx $src, $dst",
-                (MOVSX64rr16 GR64:$dst, GR16:$src)>;
-def : InstAlias<(outs GR64:$dst), (ins GR32:$src),
-                "movsx $src, $dst",
-                (MOVSX64rr32 GR64:$dst, GR32:$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX16rr8W GR16:$dst, GR8:$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX16rm8W GR16:$dst, i8mem:$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX32rr8 GR32:$dst, GR8:$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX32rr16 GR32:$dst, GR16:$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX64rr8 GR64:$dst, GR8:$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX64rr16 GR64:$dst, GR16:$src)>;
+def : InstAlias<"movsx $src, $dst", (MOVSX64rr32 GR64:$dst, GR32:$src)>;
 
 // movzx aliases
-def : InstAlias<(outs GR16:$dst), (ins GR8 :$src),
-                "movzx $src, $dst",
-                (MOVZX16rr8W GR16:$dst, GR8:$src)>;
-def : InstAlias<(outs GR16:$dst), (ins i8mem:$src),
-                "movzx $src, $dst",
-                (MOVZX16rm8W GR16:$dst, i8mem:$src)>;
-
-def : InstAlias<(outs GR32:$dst), (ins GR8 :$src),
-                "movzx $src, $dst",
-                (MOVZX32rr8 GR32:$dst, GR8:$src)>;
-def : InstAlias<(outs GR32:$dst), (ins GR16:$src),
-                "movzx $src, $dst",
-                (MOVZX32rr16 GR32:$dst, GR16:$src)>;
-
-def : InstAlias<(outs GR64:$dst), (ins GR8 :$src),
-                "movzx $src, $dst",
-                (MOVZX64rr8_Q GR64:$dst, GR8:$src)>;
-def : InstAlias<(outs GR64:$dst), (ins GR16:$src),
-                "movzx $src, $dst",
-                (MOVZX64rr16_Q GR64:$dst, GR16:$src)>;
+def : InstAlias<"movzx $src, $dst", (MOVZX16rr8W GR16:$dst, GR8:$src)>;
+def : InstAlias<"movzx $src, $dst", (MOVZX16rm8W GR16:$dst, i8mem:$src)>;
+def : InstAlias<"movzx $src, $dst", (MOVZX32rr8 GR32:$dst, GR8:$src)>;
+def : InstAlias<"movzx $src, $dst", (MOVZX32rr16 GR32:$dst, GR16:$src)>;
+def : InstAlias<"movzx $src, $dst", (MOVZX64rr8_Q GR64:$dst, GR8:$src)>;
+def : InstAlias<"movzx $src, $dst", (MOVZX64rr16_Q GR64:$dst, GR16:$src)>;
 // Note: No GR32->GR64 movzx form.
 
+// outb %dx -> outb %al, %dx
+def : InstAlias<"outb %dx", (OUT8rr)>;
+def : InstAlias<"outw %dx", (OUT16rr)>;
+def : InstAlias<"outl %dx", (OUT32rr)>;
+def : InstAlias<"outb $port", (OUT8ir i8imm:$port)>;
+def : InstAlias<"outw $port", (OUT16ir i8imm:$port)>;
+def : InstAlias<"outl $port", (OUT32ir i8imm:$port)>;
+
+// 'sldt <mem>' can be encoded with either sldtw or sldtq with the same
+// effect (both store to a 16-bit mem).  Force to sldtw to avoid ambiguity
+// errors, since its encoding is the most compact.
+def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem)>;
+
+
+// test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms.
+def : InstAlias<"testb $val, $mem", (TEST8rm  GR8 :$val, i8mem :$mem)>;
+def : InstAlias<"testw $val, $mem", (TEST16rm GR16:$val, i16mem:$mem)>;
+def : InstAlias<"testl $val, $mem", (TEST32rm GR32:$val, i32mem:$mem)>;
+def : InstAlias<"testq $val, $mem", (TEST64rm GR64:$val, i64mem:$mem)>;
+
+// xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms.
+def : InstAlias<"xchgb $mem, $val", (XCHG8rm  GR8 :$val, i8mem :$mem)>;
+def : InstAlias<"xchgw $mem, $val", (XCHG16rm GR16:$val, i16mem:$mem)>;
+def : InstAlias<"xchgl $mem, $val", (XCHG32rm GR32:$val, i32mem:$mem)>;
+def : InstAlias<"xchgq $mem, $val", (XCHG64rm GR64:$val, i64mem:$mem)>;