x86-64 atomics
authorAndrew Lenharth <andrewl@lenharth.org>
Tue, 4 Mar 2008 21:13:33 +0000 (21:13 +0000)
committerAndrew Lenharth <andrewl@lenharth.org>
Tue, 4 Mar 2008 21:13:33 +0000 (21:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47903 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86Instr64bit.td

index 665c5f4ff8d096ee577f5c1b160133d926074f6b..a2143ee16864f85fe154060843428bf16011edc7 100644 (file)
@@ -291,6 +291,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::ATOMIC_LCS     , MVT::i8, Custom);
   setOperationAction(ISD::ATOMIC_LCS     , MVT::i16, Custom);
   setOperationAction(ISD::ATOMIC_LCS     , MVT::i32, Custom);
+  setOperationAction(ISD::ATOMIC_LCS     , MVT::i64, Custom);
 
   // Use the default ISD::LOCATION, ISD::DECLARE expansion.
   setOperationAction(ISD::LOCATION, MVT::Other, Expand);
@@ -5356,12 +5357,13 @@ SDOperand X86TargetLowering::LowerCTTZ(SDOperand Op, SelectionDAG &DAG) {
 
 SDOperand X86TargetLowering::LowerCAS(SDOperand Op, SelectionDAG &DAG) {
   MVT::ValueType T = cast<AtomicSDNode>(Op.Val)->getVT();
-  unsigned Reg;
-  unsigned size;
+  unsigned Reg = 0;
+  unsigned size = 0;
   switch(T) {
   case MVT::i8:  Reg = X86::AL;  size = 1; break;
   case MVT::i16: Reg = X86::AX;  size = 2; break;
   case MVT::i32: Reg = X86::EAX; size = 4; break;
+  case MVT::i64: Reg = X86::RAX; size = 8; break;
   };
   SDOperand cpIn = DAG.getCopyToReg(Op.getOperand(0), Reg,
                                     Op.getOperand(3), SDOperand());
index 04a76d5d17a5e9b2a84cf2a729819d5577b3a9a8..3002b2c21082d20e2003bb397130fb5d282d656c 100644 (file)
@@ -1122,6 +1122,37 @@ def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
                         "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
                         [(set GR64:$dst, i64immZExt32:$src)]>;
 
+
+//===----------------------------------------------------------------------===//
+// Atomic Instructions
+//===----------------------------------------------------------------------===//
+
+//FIXME: Please check the format Pseudo is certainly wrong, but the opcode and
+//       prefixes should be correct
+
+let Defs = [RAX, EFLAGS], Uses = [RAX] in {
+def CMPXCHG64 : RI<0xB1, Pseudo, (outs), (ins i64mem:$ptr, GR64:$swap),
+               "cmpxchgq $swap,$ptr", []>, TB;
+def LCMPXCHG64 : RI<0xB1, Pseudo, (outs), (ins i64mem:$ptr, GR64:$swap),
+               "lock cmpxchgq $swap,$ptr",
+               [(X86cas addr:$ptr, GR64:$swap, 8)]>, TB, LOCK;
+}
+
+let Constraints = "$val = $dst", Defs = [EFLAGS] in {
+def LXADD64 : RI<0xC1, Pseudo, (outs GR64:$dst), (ins i64mem:$ptr, GR64:$val),
+               "lock xadd $val, $ptr", 
+               [(set GR64:$dst, (atomic_las_64 addr:$ptr, GR64:$val))]>,
+                TB, LOCK;
+def XADD64 : RI<0xC1, Pseudo, (outs GR64:$dst), (ins i64mem:$ptr, GR64:$val),
+               "xadd $val, $ptr", []>, TB;
+def LXCHG64 : RI<0x87, Pseudo, (outs GR64:$dst), (ins i64mem:$ptr, GR64:$val),
+               "lock xchg $val, $ptr", 
+               [(set GR64:$dst, (atomic_swap_64 addr:$ptr, GR64:$val))]>, LOCK;
+def XCHG64 : RI<0x87, Pseudo, (outs GR64:$dst), (ins i64mem:$ptr, GR64:$val),
+               "xchg $val, $ptr", []>;
+}
+
+
 //===----------------------------------------------------------------------===//
 // Non-Instruction Patterns
 //===----------------------------------------------------------------------===//