Correlate stubs with functions in JIT: when emitting a stub, the JIT tells the memory...
[oota-llvm.git] / lib / Target / X86 / X86InstrInfo.td
index 276468c8fd29cf49231f104c5f15e9e827831c15..1ac0519e798c24ee32a64ef2241d8af4abacd05d 100644 (file)
@@ -35,7 +35,11 @@ def SDTX86SetCC   : SDTypeProfile<1, 2,
                                   [SDTCisVT<0, i8>,
                                    SDTCisVT<1, i8>, SDTCisVT<2, i32>]>;
 
-def SDTX86Ret     : SDTypeProfile<0, 1, [SDTCisVT<0, i16>]>;
+def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>, 
+                                     SDTCisVT<2, i8>]>;
+def SDTX86cas8 : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
+
+def SDTX86Ret     : SDTypeProfile<0, -1, [SDTCisVT<0, i16>]>;
 
 def SDT_X86CallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>;
 def SDT_X86CallSeqEnd   : SDCallSeqEnd<[ SDTCisVT<0, i32>,
@@ -69,6 +73,13 @@ def X86brcond  : SDNode<"X86ISD::BRCOND",   SDTX86BrCond,
                         [SDNPHasChain]>;
 def X86setcc   : SDNode<"X86ISD::SETCC",    SDTX86SetCC>;
 
+def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas,
+                        [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore,
+                         SDNPMayLoad]>;
+def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86cas8,
+                        [SDNPHasChain, SDNPInFlag, SDNPOutFlag, SDNPMayStore,
+                         SDNPMayLoad]>;
+
 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret,
                         [SDNPHasChain, SDNPOptInFlag]>;
 
@@ -248,7 +259,7 @@ def extloadi32i16  : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;
 
 // An 'and' node with a single use.
 def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
-  return !FoldAndInTest || N->hasOneUse();
+  return N->hasOneUse();
 }]>;
 
 //===----------------------------------------------------------------------===//
@@ -258,8 +269,8 @@ def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{
 // ADJCALLSTACKDOWN/UP implicitly use/def ESP because they may be expanded into
 // a stack adjustment and the codegen must know that they may modify the stack
 // pointer before prolog-epilog rewriting occurs.
-// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become sub / add
-// which can clobber EFLAGS.
+// Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
+// sub / add which can clobber EFLAGS.
 let Defs = [ESP, EFLAGS], Uses = [ESP] in {
 def ADJCALLSTACKDOWN : I<0, Pseudo, (outs), (ins i32imm:$amt),
                          "#ADJCALLSTACKDOWN",
@@ -268,17 +279,6 @@ def ADJCALLSTACKUP   : I<0, Pseudo, (outs), (ins i32imm:$amt1, i32imm:$amt2),
                          "#ADJCALLSTACKUP",
                          [(X86callseq_end imm:$amt1, imm:$amt2)]>;
 }
-let isImplicitDef = 1 in {
-def IMPLICIT_DEF_GR8  : I<0, Pseudo, (outs GR8:$dst), (ins),
-                         "#IMPLICIT_DEF $dst",
-                         [(set GR8:$dst, (undef))]>;
-def IMPLICIT_DEF_GR16  : I<0, Pseudo, (outs GR16:$dst), (ins),
-                         "#IMPLICIT_DEF $dst",
-                         [(set GR16:$dst, (undef))]>;
-def IMPLICIT_DEF_GR32  : I<0, Pseudo, (outs GR32:$dst), (ins),
-                         "#IMPLICIT_DEF $dst",
-                         [(set GR32:$dst, (undef))]>;
-}
 
 // Nop
 let neverHasSideEffects = 1 in
@@ -295,9 +295,12 @@ let neverHasSideEffects = 1, isNotDuplicable = 1 in
 
 // Return instructions.
 let isTerminator = 1, isReturn = 1, isBarrier = 1,
-    hasCtrlDep = 1 in {
-  def RET    : I<0xC3, RawFrm, (outs), (ins), "ret", [(X86retflag 0)]>;
-  def RETI   : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt), "ret\t$amt",
+    hasCtrlDep = 1, FPForm = SpecialFP, FPFormBits = SpecialFP.Value in {
+  def RET    : I   <0xC3, RawFrm, (outs), (ins variable_ops),
+                    "ret",
+                    [/*(X86retflag 0)*/ /*FIXME: Disabled: rdar://5791600*/]>;
+  def RETI   : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),
+                    "ret\t$amt",
                     [(X86retflag imm:$amt)]>;
 }
 
@@ -373,17 +376,17 @@ let isCall = 1 in
 
 // Tail call stuff.
 
-def TAILCALL : I<0, Pseudo, (outs), (ins ),
+def TAILCALL : I<0, Pseudo, (outs), (ins),
                          "#TAILCALL",
                          []>;
 
 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
-def TCRETURNdi : I<0, Pseudo, (outs), (ins i32imm:$dst, i32imm:$offset),
+def TCRETURNdi : I<0, Pseudo, (outs), (ins i32imm:$dst, i32imm:$offset, variable_ops),
                  "#TC_RETURN $dst $offset",
                  []>;
 
 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in
-def TCRETURNri : I<0, Pseudo, (outs), (ins GR32:$dst, i32imm:$offset),
+def TCRETURNri : I<0, Pseudo, (outs), (ins GR32:$dst, i32imm:$offset, variable_ops),
                  "#TC_RETURN $dst $offset",
                  []>;
 
@@ -461,6 +464,7 @@ let neverHasSideEffects = 1 in
 def LEA16r   : I<0x8D, MRMSrcMem,
                  (outs GR16:$dst), (ins i32mem:$src),
                  "lea{w}\t{$src|$dst}, {$dst|$src}", []>, OpSize;
+let isReMaterializable = 1 in
 def LEA32r   : I<0x8D, MRMSrcMem,
                  (outs GR32:$dst), (ins lea32mem:$src),
                  "lea{l}\t{$src|$dst}, {$dst|$src}",
@@ -2535,6 +2539,81 @@ def EH_RETURN   : I<0xC3, RawFrm, (outs), (ins GR32:$addr),
 
 }
 
+//===----------------------------------------------------------------------===//
+// Atomic support
+//
+
+//FIXME: Please check the format Pseudo is certainly wrong, but the opcode and
+//       prefixes should be correct
+
+let Defs = [EAX, EFLAGS], Uses = [EAX] in {
+def CMPXCHG32 : I<0xB1, Pseudo, (outs), (ins i32mem:$ptr, GR32:$swap),
+               "cmpxchgl $swap,$ptr", []>, TB;
+def LCMPXCHG32 : I<0xB1, Pseudo, (outs), (ins i32mem:$ptr, GR32:$swap),
+               "lock cmpxchgl $swap,$ptr",
+               [(X86cas addr:$ptr, GR32:$swap, 4)]>, TB, LOCK;
+}
+let Defs = [EAX, EBX, ECX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in {
+def CMPXCHG8B : I<0xC7, Pseudo, (outs), (ins i32mem:$ptr),
+               "cmpxchg8b $ptr", []>, TB;
+def LCMPXCHG8B : I<0xC7, Pseudo, (outs), (ins i32mem:$ptr),
+               "lock cmpxchg8b $ptr",
+               [(X86cas8 addr:$ptr)]>, TB, LOCK;
+}
+
+let Defs = [AX, EFLAGS], Uses = [AX] in {
+def CMPXCHG16 : I<0xB1, Pseudo, (outs), (ins i16mem:$ptr, GR16:$swap),
+               "cmpxchgw $swap,($ptr)", []>, TB, OpSize;
+def LCMPXCHG16 : I<0xB1, Pseudo, (outs), (ins i16mem:$ptr, GR16:$swap),
+               "lock cmpxchgw $swap,$ptr",
+               [(X86cas addr:$ptr, GR16:$swap, 2)]>, TB, OpSize, LOCK;
+}
+let Defs = [AL, EFLAGS], Uses = [AL] in {
+def CMPXCHG8 : I<0xB0, Pseudo, (outs), (ins i8mem:$ptr, GR8:$swap),
+               "cmpxchgb $swap,($ptr)", []>, TB;
+def LCMPXCHG8 : I<0xB0, Pseudo, (outs), (ins i8mem:$ptr, GR8:$swap),
+               "lock cmpxchgb $swap,$ptr",
+               [(X86cas addr:$ptr, GR8:$swap, 1)]>, TB, LOCK;
+}
+
+let Constraints = "$val = $dst", Defs = [EFLAGS] in {
+def LXADD32 : I<0xC1, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),
+               "lock xadd $val, $ptr", 
+               [(set GR32:$dst, (atomic_las_32 addr:$ptr, GR32:$val))]>,
+                TB, LOCK;
+def LXADD16 : I<0xC1, Pseudo, (outs GR16:$dst), (ins i16mem:$ptr, GR16:$val),
+               "lock xadd $val, $ptr", 
+               [(set GR16:$dst, (atomic_las_16 addr:$ptr, GR16:$val))]>,
+                TB, OpSize, LOCK;
+def LXADD8  : I<0xC0, Pseudo, (outs GR8:$dst), (ins i8mem:$ptr, GR8:$val),
+               "lock xadd $val, $ptr", 
+               [(set GR8:$dst, (atomic_las_8 addr:$ptr, GR8:$val))]>,
+                TB, LOCK;
+def XADD32 : I<0xC1, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),
+               "xadd $val, $ptr", []>, TB;
+def XADD16 : I<0xC1, Pseudo, (outs GR16:$dst), (ins i16mem:$ptr, GR16:$val),
+               "xadd $val, $ptr", []>, TB, OpSize;
+def XADD8  : I<0xC0, Pseudo, (outs GR8:$dst), (ins i8mem:$ptr, GR8:$val),
+               "xadd $val, $ptr", []>, TB;
+
+def LXCHG32 : I<0x87, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),
+               "lock xchg $val, $ptr", 
+               [(set GR32:$dst, (atomic_swap_32 addr:$ptr, GR32:$val))]>, LOCK;
+def LXCHG16 : I<0x87, Pseudo, (outs GR16:$dst), (ins i16mem:$ptr, GR16:$val),
+               "lock xchg $val, $ptr", 
+               [(set GR16:$dst, (atomic_swap_16 addr:$ptr, GR16:$val))]>, 
+                OpSize, LOCK;
+def LXCHG8  : I<0x86, Pseudo, (outs GR8:$dst), (ins i8mem:$ptr, GR8:$val),
+               "lock xchg $val, $ptr", 
+               [(set GR8:$dst, (atomic_swap_8 addr:$ptr, GR8:$val))]>, LOCK;
+def XCHG32 : I<0x87, Pseudo, (outs GR32:$dst), (ins i32mem:$ptr, GR32:$val),
+               "xchg $val, $ptr", []>;
+def XCHG16 : I<0x87, Pseudo, (outs GR16:$dst), (ins i16mem:$ptr, GR16:$val),
+               "xchg $val, $ptr", []>, OpSize;
+def XCHG8  : I<0x86, Pseudo, (outs GR8:$dst), (ins i8mem:$ptr, GR8:$val),
+               "xchg $val, $ptr", []>;
+}
+
 //===----------------------------------------------------------------------===//
 // Non-Instruction Patterns
 //===----------------------------------------------------------------------===//
@@ -2542,7 +2621,7 @@ def EH_RETURN   : I<0xC3, RawFrm, (outs), (ins GR32:$addr),
 // ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
 def : Pat<(i32 (X86Wrapper tconstpool  :$dst)), (MOV32ri tconstpool  :$dst)>;
 def : Pat<(i32 (X86Wrapper tjumptable  :$dst)), (MOV32ri tjumptable  :$dst)>;
-def : Pat<(i32 (X86Wrapper tglobaltlsaddr:$dst)), (MOV32ri tglobaltlsaddr:$dst)>;
+def : Pat<(i32 (X86Wrapper tglobaltlsaddr:$dst)),(MOV32ri tglobaltlsaddr:$dst)>;
 def : Pat<(i32 (X86Wrapper tglobaladdr :$dst)), (MOV32ri tglobaladdr :$dst)>;
 def : Pat<(i32 (X86Wrapper texternalsym:$dst)), (MOV32ri texternalsym:$dst)>;
 
@@ -2683,7 +2762,6 @@ def : Pat<(store (or (shl (loadi16 addr:$dst), CL:$amt),
                      (srl GR16:$src2, (sub 16, CL:$amt))), addr:$dst),
           (SHLD16mrCL addr:$dst, GR16:$src2)>;
 
-
 //===----------------------------------------------------------------------===//
 // Floating Point Stack Support
 //===----------------------------------------------------------------------===//