[llvm-commits] [llvm] r55343 - in /llvm/trunk/lib/Target: PowerPC/PPCISelLowering.cpp PowerPC/PPCISelLowering.h PowerPC/PPCInstr64Bit.td PowerPC/PPCInstrInfo.td TargetSelectionDAG.td
Dale Johannesen
dalej at apple.com
Mon Aug 25 15:34:38 PDT 2008
Author: johannes
Date: Mon Aug 25 17:34:37 2008
New Revision: 55343
URL: http://llvm.org/viewvc/llvm-project?rev=55343&view=rev
Log:
Implement 32 & 64 bit versions of PPC atomic
binary primitives.
Modified:
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
llvm/trunk/lib/Target/TargetSelectionDAG.td
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=55343&r1=55342&r2=55343&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon Aug 25 17:34:37 2008
@@ -3861,6 +3861,60 @@
//===----------------------------------------------------------------------===//
MachineBasicBlock *
+PPCTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB,
+ bool is64bit, unsigned BinOpcode) {
+ const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+
+ const BasicBlock *LLVM_BB = BB->getBasicBlock();
+ MachineFunction *F = BB->getParent();
+ MachineFunction::iterator It = BB;
+ ++It;
+
+ unsigned dest = MI->getOperand(0).getReg();
+ unsigned ptrA = MI->getOperand(1).getReg();
+ unsigned ptrB = MI->getOperand(2).getReg();
+ unsigned incr = MI->getOperand(3).getReg();
+
+ MachineBasicBlock *loopMBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB);
+ F->insert(It, loopMBB);
+ F->insert(It, exitMBB);
+ exitMBB->transferSuccessors(BB);
+
+ MachineRegisterInfo &RegInfo = F->getRegInfo();
+ unsigned TmpReg = RegInfo.createVirtualRegister(
+ is64bit ? (const TargetRegisterClass *) &PPC::GPRCRegClass :
+ (const TargetRegisterClass *) &PPC::G8RCRegClass);
+
+ // thisMBB:
+ // ...
+ // fallthrough --> loopMBB
+ BB->addSuccessor(loopMBB);
+
+ // loopMBB:
+ // l[wd]arx dest, ptr
+ // add r0, dest, incr
+ // st[wd]cx. r0, ptr
+ // bne- loopMBB
+ // fallthrough --> exitMBB
+ BB = loopMBB;
+ BuildMI(BB, TII->get(is64bit ? PPC::LDARX : PPC::LWARX), dest)
+ .addReg(ptrA).addReg(ptrB);
+ BuildMI(BB, TII->get(BinOpcode), TmpReg).addReg(incr).addReg(dest);
+ BuildMI(BB, TII->get(is64bit ? PPC::STDCX : PPC::STWCX))
+ .addReg(TmpReg).addReg(ptrA).addReg(ptrB);
+ BuildMI(BB, TII->get(PPC::BCC))
+ .addImm(PPC::PRED_NE).addReg(PPC::CR0).addMBB(loopMBB);
+ BB->addSuccessor(loopMBB);
+ BB->addSuccessor(exitMBB);
+
+ // exitMBB:
+ // ...
+ BB = exitMBB;
+ return BB;
+}
+
+MachineBasicBlock *
PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *BB) {
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
@@ -3920,53 +3974,30 @@
.addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB)
.addReg(MI->getOperand(2).getReg()).addMBB(thisMBB);
}
- else if (MI->getOpcode() == PPC::ATOMIC_LOAD_ADD_I32 ||
- MI->getOpcode() == PPC::ATOMIC_LOAD_ADD_I64) {
- bool is64bit = MI->getOpcode() == PPC::ATOMIC_LOAD_ADD_I64;
-
- unsigned dest = MI->getOperand(0).getReg();
- unsigned ptrA = MI->getOperand(1).getReg();
- unsigned ptrB = MI->getOperand(2).getReg();
- unsigned incr = MI->getOperand(3).getReg();
-
- MachineBasicBlock *loopMBB = F->CreateMachineBasicBlock(LLVM_BB);
- MachineBasicBlock *exitMBB = F->CreateMachineBasicBlock(LLVM_BB);
- F->insert(It, loopMBB);
- F->insert(It, exitMBB);
- exitMBB->transferSuccessors(BB);
-
- MachineRegisterInfo &RegInfo = F->getRegInfo();
- unsigned TmpReg = RegInfo.createVirtualRegister(
- is64bit ? (const TargetRegisterClass *) &PPC::GPRCRegClass :
- (const TargetRegisterClass *) &PPC::G8RCRegClass);
-
- // thisMBB:
- // ...
- // fallthrough --> loopMBB
- BB->addSuccessor(loopMBB);
-
- // loopMBB:
- // l[wd]arx dest, ptr
- // add r0, dest, incr
- // st[wd]cx. r0, ptr
- // bne- loopMBB
- // fallthrough --> exitMBB
- BB = loopMBB;
- BuildMI(BB, TII->get(is64bit ? PPC::LDARX : PPC::LWARX), dest)
- .addReg(ptrA).addReg(ptrB);
- BuildMI(BB, TII->get(is64bit ? PPC::ADD4 : PPC::ADD8), TmpReg)
- .addReg(incr).addReg(dest);
- BuildMI(BB, TII->get(is64bit ? PPC::STDCX : PPC::STWCX))
- .addReg(TmpReg).addReg(ptrA).addReg(ptrB);
- BuildMI(BB, TII->get(PPC::BCC))
- .addImm(PPC::PRED_NE).addReg(PPC::CR0).addMBB(loopMBB);
- BB->addSuccessor(loopMBB);
- BB->addSuccessor(exitMBB);
-
- // exitMBB:
- // ...
- BB = exitMBB;
- }
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
+ BB = EmitAtomicBinary(MI, BB, false, PPC::ADD4);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
+ BB = EmitAtomicBinary(MI, BB, true, PPC::ADD8);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
+ BB = EmitAtomicBinary(MI, BB, false, PPC::AND);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
+ BB = EmitAtomicBinary(MI, BB, true, PPC::AND8);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
+ BB = EmitAtomicBinary(MI, BB, false, PPC::OR);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
+ BB = EmitAtomicBinary(MI, BB, true, PPC::OR8);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
+ BB = EmitAtomicBinary(MI, BB, false, PPC::XOR);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
+ BB = EmitAtomicBinary(MI, BB, true, PPC::XOR8);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
+ BB = EmitAtomicBinary(MI, BB, false, PPC::NAND);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
+ BB = EmitAtomicBinary(MI, BB, true, PPC::NAND8);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
+ BB = EmitAtomicBinary(MI, BB, false, PPC::SUBF);
+ else if (MI->getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
+ BB = EmitAtomicBinary(MI, BB, true, PPC::SUBF8);
else if (MI->getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
MI->getOpcode() == PPC::ATOMIC_CMP_SWAP_I64) {
bool is64bit = MI->getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=55343&r1=55342&r2=55343&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Mon Aug 25 17:34:37 2008
@@ -282,6 +282,9 @@
virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *MBB);
+ MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI,
+ MachineBasicBlock *MBB, bool is64Bit,
+ unsigned BinOpcode);
ConstraintType getConstraintType(const std::string &Constraint) const;
std::pair<unsigned, const TargetRegisterClass*>
Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=55343&r1=55342&r2=55343&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Mon Aug 25 17:34:37 2008
@@ -123,11 +123,33 @@
(outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr),
"${:comment} ATOMIC_LOAD_ADD_I64 PSEUDO!",
[(set G8RC:$dst, (atomic_load_add_64 xoaddr:$ptr, G8RC:$incr))]>;
+ def ATOMIC_LOAD_SUB_I64 : Pseudo<
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr),
+ "${:comment} ATOMIC_LOAD_SUB_I64 PSEUDO!",
+ [(set G8RC:$dst, (atomic_load_sub_64 xoaddr:$ptr, G8RC:$incr))]>;
+ def ATOMIC_LOAD_OR_I64 : Pseudo<
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr),
+ "${:comment} ATOMIC_LOAD_OR_I64 PSEUDO!",
+ [(set G8RC:$dst, (atomic_load_or_64 xoaddr:$ptr, G8RC:$incr))]>;
+ def ATOMIC_LOAD_XOR_I64 : Pseudo<
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr),
+ "${:comment} ATOMIC_LOAD_XOR_I64 PSEUDO!",
+ [(set G8RC:$dst, (atomic_load_xor_64 xoaddr:$ptr, G8RC:$incr))]>;
+ def ATOMIC_LOAD_AND_I64 : Pseudo<
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr),
+ "${:comment} ATOMIC_LOAD_AND_I64 PSEUDO!",
+ [(set G8RC:$dst, (atomic_load_and_64 xoaddr:$ptr, G8RC:$incr))]>;
+ def ATOMIC_LOAD_NAND_I64 : Pseudo<
+ (outs G8RC:$dst), (ins memrr:$ptr, G8RC:$incr),
+ "${:comment} ATOMIC_LOAD_NAND_I64 PSEUDO!",
+ [(set G8RC:$dst, (atomic_load_nand_64 xoaddr:$ptr, G8RC:$incr))]>;
+
def ATOMIC_CMP_SWAP_I64 : Pseudo<
(outs G8RC:$dst), (ins memrr:$ptr, G8RC:$old, G8RC:$new),
"${:comment} ATOMIC_CMP_SWAP_I64 PSEUDO!",
[(set G8RC:$dst,
(atomic_cmp_swap_64 xoaddr:$ptr, G8RC:$old, G8RC:$new))]>;
+
def ATOMIC_SWAP_I64 : Pseudo<
(outs G8RC:$dst), (ins memrr:$ptr, G8RC:$new),
"${:comment} ATOMIC_SWAP_I64 PSEUDO!",
@@ -313,7 +335,6 @@
def SUBF8 : XOForm_1<31, 40, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB),
"subf $rT, $rA, $rB", IntGeneral,
[(set G8RC:$rT, (sub G8RC:$rB, G8RC:$rA))]>;
-
def SUBFC8 : XOForm_1<31, 8, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB),
"subfc $rT, $rA, $rB", IntGeneral,
[(set G8RC:$rT, (subc G8RC:$rB, G8RC:$rA))]>,
Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=55343&r1=55342&r2=55343&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Mon Aug 25 17:34:37 2008
@@ -532,11 +532,33 @@
(outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr),
"${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!",
[(set GPRC:$dst, (atomic_load_add_32 xoaddr:$ptr, GPRC:$incr))]>;
+ def ATOMIC_LOAD_SUB_I32 : Pseudo<
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr),
+ "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!",
+ [(set GPRC:$dst, (atomic_load_sub_32 xoaddr:$ptr, GPRC:$incr))]>;
+ def ATOMIC_LOAD_AND_I32 : Pseudo<
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr),
+ "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!",
+ [(set GPRC:$dst, (atomic_load_and_32 xoaddr:$ptr, GPRC:$incr))]>;
+ def ATOMIC_LOAD_OR_I32 : Pseudo<
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr),
+ "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!",
+ [(set GPRC:$dst, (atomic_load_or_32 xoaddr:$ptr, GPRC:$incr))]>;
+ def ATOMIC_LOAD_XOR_I32 : Pseudo<
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr),
+ "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!",
+ [(set GPRC:$dst, (atomic_load_xor_32 xoaddr:$ptr, GPRC:$incr))]>;
+ def ATOMIC_LOAD_NAND_I32 : Pseudo<
+ (outs GPRC:$dst), (ins memrr:$ptr, GPRC:$incr),
+ "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!",
+ [(set GPRC:$dst, (atomic_load_nand_32 xoaddr:$ptr, GPRC:$incr))]>;
+
def ATOMIC_CMP_SWAP_I32 : Pseudo<
(outs GPRC:$dst), (ins memrr:$ptr, GPRC:$old, GPRC:$new),
"${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!",
[(set GPRC:$dst,
(atomic_cmp_swap_32 xoaddr:$ptr, GPRC:$old, GPRC:$new))]>;
+
def ATOMIC_SWAP_I32 : Pseudo<
(outs GPRC:$dst), (ins memrr:$ptr, GPRC:$new),
"${:comment} ATOMIC_SWAP_I32 PSEUDO!",
Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSelectionDAG.td?rev=55343&r1=55342&r2=55343&view=diff
==============================================================================
--- llvm/trunk/lib/Target/TargetSelectionDAG.td (original)
+++ llvm/trunk/lib/Target/TargetSelectionDAG.td Mon Aug 25 17:34:37 2008
@@ -767,6 +767,111 @@
return V->getValueType(0) == MVT::i64;
}]>;
+def atomic_load_sub_8 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_sub node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i8;
+}]>;
+def atomic_load_sub_16 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_sub node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i16;
+}]>;
+def atomic_load_sub_32 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_sub node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i32;
+}]>;
+def atomic_load_sub_64 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_sub node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i64;
+}]>;
+
+def atomic_load_and_8 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_and node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i8;
+}]>;
+def atomic_load_and_16 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_and node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i16;
+}]>;
+def atomic_load_and_32 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_and node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i32;
+}]>;
+def atomic_load_and_64 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_and node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i64;
+}]>;
+
+def atomic_load_or_8 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_or node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i8;
+}]>;
+def atomic_load_or_16 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_or node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i16;
+}]>;
+def atomic_load_or_32 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_or node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i32;
+}]>;
+def atomic_load_or_64 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_or node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i64;
+}]>;
+
+def atomic_load_xor_8 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_xor node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i8;
+}]>;
+def atomic_load_xor_16 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_xor node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i16;
+}]>;
+def atomic_load_xor_32 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_xor node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i32;
+}]>;
+def atomic_load_xor_64 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_xor node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i64;
+}]>;
+
+def atomic_load_nand_8 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_nand node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i8;
+}]>;
+def atomic_load_nand_16 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_nand node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i16;
+}]>;
+def atomic_load_nand_32 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_nand node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i32;
+}]>;
+def atomic_load_nand_64 : PatFrag<(ops node:$ptr, node:$inc),
+ (atomic_load_nand node:$ptr, node:$inc), [{
+ AtomicSDNode* V = cast<AtomicSDNode>(N);
+ return V->getValueType(0) == MVT::i64;
+}]>;
+
def atomic_swap_8 : PatFrag<(ops node:$ptr, node:$inc),
(atomic_swap node:$ptr, node:$inc), [{
AtomicSDNode* V = cast<AtomicSDNode>(N);
More information about the llvm-commits
mailing list