def lea64mem : Operand<i64> {
let PrintMethod = "printi64mem";
- let NumMIOperands = 4;
let MIOperandInfo = (ops GR64, i8imm, GR64, i32imm);
}
def lea64_32mem : Operand<i32> {
let PrintMethod = "printlea64_32mem";
- let NumMIOperands = 4;
let MIOperandInfo = (ops GR32, i8imm, GR32, i32imm);
}
// Complex Pattern Definitions...
//
def lea64addr : ComplexPattern<i64, 4, "SelectLEAAddr",
- [add, mul, shl, or, frameindex, X86Wrapper]>;
+ [add, mul, shl, or, frameindex, X86Wrapper],
+ []>;
//===----------------------------------------------------------------------===//
// Instruction templates...
: SSI<o, F, ops, asm, pattern>, REX_W;
class RSDI<bits<8> o, Format F, dag ops, string asm, list<dag> pattern>
: SDI<o, F, ops, asm, pattern>, REX_W;
+class RPDI<bits<8> o, Format F, dag ops, string asm, list<dag> pattern>
+ : PDI<o, F, ops, asm, pattern>, REX_W;
//===----------------------------------------------------------------------===//
// Pattern fragments...
return (int64_t)N->getValue() == (int8_t)N->getValue();
}]>;
-def sextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (sextload node:$ptr, i1))>;
-def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextload node:$ptr, i8))>;
-def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextload node:$ptr, i16))>;
-def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextload node:$ptr, i32))>;
+def sextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (sextloadi1 node:$ptr))>;
+def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>;
+def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>;
+def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>;
-def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextload node:$ptr, i1))>;
-def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextload node:$ptr, i8))>;
-def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextload node:$ptr, i16))>;
-def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextload node:$ptr, i32))>;
+def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>;
+def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>;
+def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>;
+def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>;
-def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extload node:$ptr, i1))>;
-def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extload node:$ptr, i8))>;
-def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extload node:$ptr, i16))>;
-def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extload node:$ptr, i32))>;
+def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>;
+def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>;
+def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>;
+def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>;
//===----------------------------------------------------------------------===//
// Instruction list...
// All calls clobber the non-callee saved registers...
let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
+ MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15] in {
def CALL64pcrel32 : I<0xE8, RawFrm, (ops i64imm:$dst, variable_ops),
(ops), "leave", []>, Imp<[RBP,RSP],[RBP,RSP]>;
def POP64r : I<0x58, AddRegFrm,
(ops GR64:$reg), "pop{q} $reg", []>, Imp<[RSP],[RSP]>;
+def PUSH64r : I<0x50, AddRegFrm,
+ (ops GR64:$reg), "push{q} $reg", []>, Imp<[RSP],[RSP]>;
def LEA64_32r : I<0x8D, MRMSrcMem,
(ops GR32:$dst, lea64_32mem:$src),
def SHL64mi : RIi8<0xC1, MRM4m, (ops i64mem:$dst, i8imm:$src),
"shl{q} {$src, $dst|$dst, $src}",
[(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
-def SHL64m1 : RI<0xC1, MRM4m, (ops i64mem:$dst),
+def SHL64m1 : RI<0xD1, MRM4m, (ops i64mem:$dst),
"shl{q} $dst",
[(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
def SHR64mi : RIi8<0xC1, MRM5m, (ops i64mem:$dst, i8imm:$src),
"shr{q} {$src, $dst|$dst, $src}",
[(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
-def SHR64m1 : RI<0xC1, MRM5m, (ops i64mem:$dst),
+def SHR64m1 : RI<0xD1, MRM5m, (ops i64mem:$dst),
"shr{q} $dst",
[(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
def SAR64mi : RIi8<0xC1, MRM7m, (ops i64mem:$dst, i8imm:$src),
"sar{q} {$src, $dst|$dst, $src}",
[(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
-def SAR64m1 : RI<0xC1, MRM7m, (ops i64mem:$dst),
+def SAR64m1 : RI<0xD1, MRM7m, (ops i64mem:$dst),
"sar{q} $dst",
[(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>;
def ROL64ri : RIi8<0xC1, MRM0r, (ops GR64:$dst, GR64:$src1, i8imm:$src2),
"rol{q} {$src2, $dst|$dst, $src2}",
[(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>;
-def ROL64r1 : RI<0xC1, MRM0r, (ops GR64:$dst, GR64:$src1),
+def ROL64r1 : RI<0xD1, MRM0r, (ops GR64:$dst, GR64:$src1),
"rol{q} $dst",
[(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>;
} // isTwoAddress
def ROR64ri : RIi8<0xC1, MRM1r, (ops GR64:$dst, GR64:$src1, i8imm:$src2),
"ror{q} {$src2, $dst|$dst, $src2}",
[(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))]>;
-def ROR64r1 : RI<0xC1, MRM1r, (ops GR64:$dst, GR64:$src1),
+def ROR64r1 : RI<0xD1, MRM1r, (ops GR64:$dst, GR64:$src1),
"ror{q} $dst",
[(set GR64:$dst, (rotr GR64:$src1, (i8 1)))]>;
} // isTwoAddress
def TEST64rr : RI<0x85, MRMDestReg, (ops GR64:$src1, GR64:$src2),
"test{q} {$src2, $src1|$src1, $src2}",
[(X86cmp (and GR64:$src1, GR64:$src2), 0)]>;
-def TEST64mr : RI<0x85, MRMDestMem, (ops i64mem:$src1, GR64:$src2),
- "test{q} {$src2, $src1|$src1, $src2}",
- [/*(X86cmp (and (loadi64 addr:$src1), GR64:$src2), 0)*/]>;
def TEST64rm : RI<0x85, MRMSrcMem, (ops GR64:$src1, i64mem:$src2),
"test{q} {$src2, $src1|$src1, $src2}",
- [/*(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0)*/]>;
+ [(X86cmp (and GR64:$src1, (loadi64 addr:$src2)), 0)]>;
def TEST64ri32 : RIi32<0xF7, MRM0r, (ops GR64:$src1, i64i32imm:$src2),
"test{q} {$src2, $src1|$src1, $src2}",
[(X86cmp (and GR64:$src1, i64immSExt32:$src2), 0)]>;
def TEST64mi32 : RIi32<0xF7, MRM0m, (ops i64mem:$src1, i64i32imm:$src2),
"test{q} {$src2, $src1|$src1, $src2}",
- [/*(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2),
- 0)*/]>;
+ [(X86cmp (and (loadi64 addr:$src1), i64immSExt32:$src2), 0)]>;
def CMP64rr : RI<0x39, MRMDestReg, (ops GR64:$src1, GR64:$src2),
"cmp{q} {$src2, $src1|$src1, $src2}",
// Non-Instruction Patterns
//===----------------------------------------------------------------------===//
+// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
+def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
+ (MOV64ri tconstpool :$dst)>, Requires<[NotSmallCode]>;
+def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
+ (MOV64ri tjumptable :$dst)>, Requires<[NotSmallCode]>;
+def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
+ (MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>;
+def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
+ (MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>;
+
+def : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst),
+ (MOV64mi32 addr:$dst, tconstpool:$src)>,
+ Requires<[SmallCode, IsStatic]>;
+def : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst),
+ (MOV64mi32 addr:$dst, tjumptable:$src)>,
+ Requires<[SmallCode, IsStatic]>;
+def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
+ (MOV64mi32 addr:$dst, tglobaladdr:$src)>,
+ Requires<[SmallCode, IsStatic]>;
+def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
+ (MOV64mi32 addr:$dst, texternalsym:$src)>,
+ Requires<[SmallCode, IsStatic]>;
+
// Calls
// Direct PC relative function call for small code model. 32-bit displacement
// sign extended to 64-bit.
def : Pat<(store (or (shl (loadi64 addr:$dst), CL:$amt),
(srl GR64:$src2, (sub 64, CL:$amt))), addr:$dst),
(SHLD64mrCL addr:$dst, GR64:$src2)>;
+
+// X86 specific add which produces a flag.
+def : Pat<(addc GR64:$src1, GR64:$src2),
+ (ADD64rr GR64:$src1, GR64:$src2)>;
+def : Pat<(addc GR64:$src1, (load addr:$src2)),
+ (ADD64rm GR64:$src1, addr:$src2)>;
+def : Pat<(addc GR64:$src1, i64immSExt32:$src2),
+ (ADD64ri32 GR64:$src1, imm:$src2)>;
+def : Pat<(addc GR64:$src1, i64immSExt8:$src2),
+ (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
+
+def : Pat<(subc GR64:$src1, GR64:$src2),
+ (SUB64rr GR64:$src1, GR64:$src2)>;
+def : Pat<(subc GR64:$src1, (load addr:$src2)),
+ (SUB64rm GR64:$src1, addr:$src2)>;
+def : Pat<(subc GR64:$src1, imm:$src2),
+ (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
+def : Pat<(subc GR64:$src1, i64immSExt8:$src2),
+ (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
+
+
+//===----------------------------------------------------------------------===//
+// X86-64 SSE Instructions
+//===----------------------------------------------------------------------===//
+
+// Move instructions...
+
+def MOV64toPQIrr : RPDI<0x6E, MRMSrcReg, (ops VR128:$dst, GR64:$src),
+ "mov{d|q} {$src, $dst|$dst, $src}",
+ [(set VR128:$dst,
+ (v2i64 (scalar_to_vector GR64:$src)))]>;
+def MOV64toPQIrm : RPDI<0x6E, MRMSrcMem, (ops VR128:$dst, i64mem:$src),
+ "mov{d|q} {$src, $dst|$dst, $src}",
+ [(set VR128:$dst,
+ (v2i64 (scalar_to_vector (loadi64 addr:$src))))]>;
+
+def MOVPQIto64rr : RPDI<0x7E, MRMDestReg, (ops GR64:$dst, VR128:$src),
+ "mov{d|q} {$src, $dst|$dst, $src}",
+ [(set GR64:$dst, (vector_extract (v2i64 VR128:$src),
+ (iPTR 0)))]>;
+def MOVPQIto64mr : RPDI<0x7E, MRMDestMem, (ops i64mem:$dst, VR128:$src),
+ "mov{d|q} {$src, $dst|$dst, $src}",
+ [(store (i64 (vector_extract (v2i64 VR128:$src),
+ (iPTR 0))), addr:$dst)]>;
+
+def MOV64toSDrr : RPDI<0x6E, MRMSrcReg, (ops FR64:$dst, GR64:$src),
+ "mov{d|q} {$src, $dst|$dst, $src}",
+ [(set FR64:$dst, (bitconvert GR64:$src))]>;
+def MOV64toSDrm : RPDI<0x6E, MRMSrcMem, (ops FR64:$dst, i64mem:$src),
+ "mov{d|q} {$src, $dst|$dst, $src}",
+ [(set FR64:$dst, (bitconvert (loadi64 addr:$src)))]>;
+
+def MOVSDto64rr : RPDI<0x7E, MRMDestReg, (ops GR64:$dst, FR64:$src),
+ "mov{d|q} {$src, $dst|$dst, $src}",
+ [(set GR64:$dst, (bitconvert FR64:$src))]>;
+def MOVSDto64mr : RPDI<0x7E, MRMDestMem, (ops i64mem:$dst, FR64:$src),
+ "mov{d|q} {$src, $dst|$dst, $src}",
+ [(store (i64 (bitconvert FR64:$src)), addr:$dst)]>;