diff options
author | dim <dim@FreeBSD.org> | 2014-02-20 22:31:45 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-02-20 22:31:45 +0000 |
commit | 7a21bf645bb41c26775d255b7045211cef4e3ff2 (patch) | |
tree | a78704753fdd360efde13b71967bbf053e33c9a7 /contrib/llvm | |
parent | fed0da0559f6d100f3a8ca53c35eb632fef51560 (diff) | |
download | FreeBSD-src-7a21bf645bb41c26775d255b7045211cef4e3ff2.zip FreeBSD-src-7a21bf645bb41c26775d255b7045211cef4e3ff2.tar.gz |
Pull in r200453 from upstream llvm trunk:
Implement SPARCv9 atomic_swap_64 with a pseudo.
The SWAP instruction only exists in a 32-bit variant, but the 64-bit
atomic swap can be implemented in terms of CASX, like the other
atomic rmw primitives.
Submitted by: rdivacky
Diffstat (limited to 'contrib/llvm')
-rw-r--r-- | contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp | 10 | ||||
-rw-r--r-- | contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td | 8 |
2 files changed, 15 insertions, 3 deletions
diff --git a/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp index a252832..9f6dc5c 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -1499,7 +1499,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM) if (Subtarget->is64Bit()) { setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i64, Legal); - setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Expand); + setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Legal); setOperationAction(ISD::ATOMIC_LOAD, MVT::i64, Custom); setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Custom); } @@ -2886,6 +2886,9 @@ SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, case SP::ATOMIC_LOAD_NAND_64: return expandAtomicRMW(MI, BB, SP::ANDXrr); + case SP::ATOMIC_SWAP_64: + return expandAtomicRMW(MI, BB, 0); + case SP::ATOMIC_LOAD_MAX_32: return expandAtomicRMW(MI, BB, SP::MOVICCrr, SPCC::ICC_G); case SP::ATOMIC_LOAD_MAX_64: @@ -3024,7 +3027,8 @@ SparcTargetLowering::expandAtomicRMW(MachineInstr *MI, // Build the loop block. unsigned ValReg = MRI.createVirtualRegister(ValueRC); - unsigned UpdReg = MRI.createVirtualRegister(ValueRC); + // Opcode == 0 means try to write Rs2Reg directly (ATOMIC_SWAP). + unsigned UpdReg = (Opcode ? MRI.createVirtualRegister(ValueRC) : Rs2Reg); BuildMI(LoopMBB, DL, TII.get(SP::PHI), ValReg) .addReg(Val0Reg).addMBB(MBB) @@ -3036,7 +3040,7 @@ SparcTargetLowering::expandAtomicRMW(MachineInstr *MI, BuildMI(LoopMBB, DL, TII.get(SP::CMPrr)).addReg(ValReg).addReg(Rs2Reg); BuildMI(LoopMBB, DL, TII.get(Opcode), UpdReg) .addReg(ValReg).addReg(Rs2Reg).addImm(CondCode); - } else { + } else if (Opcode) { BuildMI(LoopMBB, DL, TII.get(Opcode), UpdReg) .addReg(ValReg).addReg(Rs2Reg); } diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td b/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td index 59ff92b..a5b48f9 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td +++ b/contrib/llvm/lib/Target/Sparc/SparcInstr64Bit.td @@ -463,6 +463,14 @@ defm ATOMIC_LOAD_MAX : AtomicRMW<atomic_load_max_32, atomic_load_max_64>; defm ATOMIC_LOAD_UMIN : AtomicRMW<atomic_load_umin_32, atomic_load_umin_64>; defm ATOMIC_LOAD_UMAX : AtomicRMW<atomic_load_umax_32, atomic_load_umax_64>; +// There is no 64-bit variant of SWAP, so use a pseudo. +let usesCustomInserter = 1, hasCtrlDep = 1, mayLoad = 1, mayStore = 1, + Defs = [ICC], Predicates = [Is64Bit] in +def ATOMIC_SWAP_64 : Pseudo<(outs I64Regs:$rd), + (ins ptr_rc:$addr, I64Regs:$rs2), "", + [(set i64:$rd, + (atomic_swap_64 iPTR:$addr, i64:$rs2))]>; + // Global addresses, constant pool entries let Predicates = [Is64Bit] in { |