diff options
author | Tim Northover <Tim.Northover@arm.com> | 2013-02-28 13:52:07 +0000 |
---|---|---|
committer | Tim Northover <Tim.Northover@arm.com> | 2013-02-28 13:52:07 +0000 |
commit | 279b9184c2ff4fea93b198a3519b8cb3a1d8d195 (patch) | |
tree | f5ae69ecc976e62daded9c99bbdab787c97ba17b /lib/Target/AArch64 | |
parent | 5e812139690ce077d568ef6559992b2cf74eb536 (diff) | |
download | external_llvm-279b9184c2ff4fea93b198a3519b8cb3a1d8d195.zip external_llvm-279b9184c2ff4fea93b198a3519b8cb3a1d8d195.tar.gz external_llvm-279b9184c2ff4fea93b198a3519b8cb3a1d8d195.tar.bz2 |
AArch64: Use cbnz instead of cmp/b.ne pair for atomic operations.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176253 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/AArch64')
-rw-r--r-- | lib/Target/AArch64/AArch64ISelLowering.cpp | 27 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64InstrInfo.td | 13 |
2 files changed, 17 insertions, 23 deletions
diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index cea7f91..4981fba 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -341,8 +341,7 @@ AArch64TargetLowering::emitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, // ldxr dest, ptr // <binop> scratch, dest, incr // stxr stxr_status, scratch, ptr - // cmp stxr_status, #0 - // b.ne loopMBB + // cbnz stxr_status, loopMBB // fallthrough --> exitMBB BB = loopMBB; BuildMI(BB, dl, TII->get(ldrOpc), dest).addReg(ptr); @@ -364,10 +363,8 @@ AArch64TargetLowering::emitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, MRI.constrainRegClass(stxr_status, &AArch64::GPR32wspRegClass); BuildMI(BB, dl, TII->get(strOpc), stxr_status).addReg(scratch).addReg(ptr); - BuildMI(BB, dl, TII->get(AArch64::SUBwwi_lsl0_cmp)) - .addReg(stxr_status).addImm(0); - BuildMI(BB, dl, TII->get(AArch64::Bcc)) - .addImm(A64CC::NE).addMBB(loopMBB); + BuildMI(BB, dl, TII->get(AArch64::CBNZw)) + .addReg(stxr_status).addMBB(loopMBB); BB->addSuccessor(loopMBB); BB->addSuccessor(exitMBB); @@ -437,8 +434,7 @@ AArch64TargetLowering::emitAtomicBinaryMinMax(MachineInstr *MI, // cmp incr, dest (, sign extend if necessary) // csel scratch, dest, incr, cond // stxr stxr_status, scratch, ptr - // cmp stxr_status, #0 - // b.ne loopMBB + // cbnz stxr_status, loopMBB // fallthrough --> exitMBB BB = loopMBB; BuildMI(BB, dl, TII->get(ldrOpc), dest).addReg(ptr); @@ -457,10 +453,8 @@ AArch64TargetLowering::emitAtomicBinaryMinMax(MachineInstr *MI, BuildMI(BB, dl, TII->get(strOpc), stxr_status) .addReg(scratch).addReg(ptr); - BuildMI(BB, dl, TII->get(AArch64::SUBwwi_lsl0_cmp)) - .addReg(stxr_status).addImm(0); - BuildMI(BB, dl, TII->get(AArch64::Bcc)) - .addImm(A64CC::NE).addMBB(loopMBB); + BuildMI(BB, dl, TII->get(AArch64::CBNZw)) + .addReg(stxr_status).addMBB(loopMBB); BB->addSuccessor(loopMBB); BB->addSuccessor(exitMBB); @@ -533,17 +527,14 @@ AArch64TargetLowering::emitAtomicCmpSwap(MachineInstr *MI, // loop2MBB: // strex stxr_status, newval, [ptr] - // cmp stxr_status, #0 - // b.ne loop1MBB + // cbnz stxr_status, loop1MBB BB = loop2MBB; unsigned stxr_status = MRI.createVirtualRegister(&AArch64::GPR32RegClass); MRI.constrainRegClass(stxr_status, &AArch64::GPR32wspRegClass); BuildMI(BB, dl, TII->get(strOpc), stxr_status).addReg(newval).addReg(ptr); - BuildMI(BB, dl, TII->get(AArch64::SUBwwi_lsl0_cmp)) - .addReg(stxr_status).addImm(0); - BuildMI(BB, dl, TII->get(AArch64::Bcc)) - .addImm(A64CC::NE).addMBB(loop1MBB); + BuildMI(BB, dl, TII->get(AArch64::CBNZw)) + .addReg(stxr_status).addMBB(loop1MBB); BB->addSuccessor(loop1MBB); BB->addSuccessor(exitMBB); diff --git a/lib/Target/AArch64/AArch64InstrInfo.td b/lib/Target/AArch64/AArch64InstrInfo.td index 562a7f6..78c4ad1 100644 --- a/lib/Target/AArch64/AArch64InstrInfo.td +++ b/lib/Target/AArch64/AArch64InstrInfo.td @@ -159,7 +159,7 @@ let Defs = [XSP], Uses = [XSP] in { // Atomic operation pseudo-instructions //===----------------------------------------------------------------------===// -let usesCustomInserter = 1, Defs = [NZCV] in { +let usesCustomInserter = 1 in { multiclass AtomicSizes<string opname> { def _I8 : PseudoInst<(outs GPR32:$dst), (ins GPR64:$ptr, GPR32:$incr), [(set GPR32:$dst, (!cast<SDNode>(opname # "_8") GPR64:$ptr, GPR32:$incr))]>; @@ -178,11 +178,14 @@ defm ATOMIC_LOAD_AND : AtomicSizes<"atomic_load_and">; defm ATOMIC_LOAD_OR : AtomicSizes<"atomic_load_or">; defm ATOMIC_LOAD_XOR : AtomicSizes<"atomic_load_xor">; defm ATOMIC_LOAD_NAND : AtomicSizes<"atomic_load_nand">; -defm ATOMIC_LOAD_MIN : AtomicSizes<"atomic_load_min">; -defm ATOMIC_LOAD_MAX : AtomicSizes<"atomic_load_max">; -defm ATOMIC_LOAD_UMIN : AtomicSizes<"atomic_load_umin">; -defm ATOMIC_LOAD_UMAX : AtomicSizes<"atomic_load_umax">; defm ATOMIC_SWAP : AtomicSizes<"atomic_swap">; +let Defs = [NZCV] in { + // These operations need a CMP to calculate the correct value + defm ATOMIC_LOAD_MIN : AtomicSizes<"atomic_load_min">; + defm ATOMIC_LOAD_MAX : AtomicSizes<"atomic_load_max">; + defm ATOMIC_LOAD_UMIN : AtomicSizes<"atomic_load_umin">; + defm ATOMIC_LOAD_UMAX : AtomicSizes<"atomic_load_umax">; +} let usesCustomInserter = 1, Defs = [NZCV] in { def ATOMIC_CMP_SWAP_I8 |