[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Thu Aug 25 13:08:30 PDT 2005
Changes in directory llvm/lib/Target/PowerPC:
PPC32ISelDAGToDAG.cpp updated: 1.30 -> 1.31
---
Log message:
implement setcc on the G5. We're still missing the non-g5 specific bits, but
they will come later.
---
Diffs of the changes: (+121 -0)
PPC32ISelDAGToDAG.cpp | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 121 insertions(+)
Index: llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.30 llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.31
--- llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp:1.30 Thu Aug 25 12:50:06 2005
+++ llvm/lib/Target/PowerPC/PPC32ISelDAGToDAG.cpp Thu Aug 25 15:08:18 2005
@@ -460,6 +460,25 @@
return 0;
}
+/// getCRIdxForSetCC - Return the index of the condition register field
+/// associated with the SetCC condition, and whether or not the field is
+/// treated as inverted. That is, lt = 0; ge = 0 inverted.
+static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool& Inv) {
+ switch (CC) {
+ default: assert(0 && "Unknown condition!"); abort();
+ case ISD::SETULT:
+ case ISD::SETLT: Inv = false; return 0;
+ case ISD::SETUGE:
+ case ISD::SETGE: Inv = true; return 0;
+ case ISD::SETUGT:
+ case ISD::SETGT: Inv = false; return 1;
+ case ISD::SETULE:
+ case ISD::SETLE: Inv = true; return 1;
+ case ISD::SETEQ: Inv = false; return 2;
+ case ISD::SETNE: Inv = true; return 2;
+ }
+ return 0;
+}
// Select - Convert the specified operand from a target-independent to a
// target-specific node if it hasn't already been changed.
@@ -990,6 +1009,108 @@
AddrOp1, AddrOp2, Select(N->getOperand(0)));
break;
}
+
+ case ISD::SETCC: {
+ unsigned Imm;
+ ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
+ if (isIntImmediate(N->getOperand(1), Imm)) {
+ // We can codegen setcc op, imm very efficiently compared to a brcond.
+ // Check for those cases here.
+ // setcc op, 0
+ if (Imm == 0) {
+ SDOperand Op = Select(N->getOperand(0));
+ switch (CC) {
+ default: assert(0 && "Unhandled SetCC condition"); abort();
+ case ISD::SETEQ:
+ Op = CurDAG->getTargetNode(PPC::CNTLZW, MVT::i32, Op);
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::RLWINM, Op, getI32Imm(27),
+ getI32Imm(5), getI32Imm(31));
+ break;
+ case ISD::SETNE: {
+ SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
+ Op, getI32Imm(~0U));
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::SUBFE, AD, Op, AD.getValue(1));
+ break;
+ }
+ case ISD::SETLT:
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::RLWINM, Op, getI32Imm(1),
+ getI32Imm(31), getI32Imm(31));
+ break;
+ case ISD::SETGT: {
+ SDOperand T = CurDAG->getTargetNode(PPC::NEG, MVT::i32, Op);
+ T = CurDAG->getTargetNode(PPC::ANDC, MVT::i32, T, Op);;
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::RLWINM, T, getI32Imm(1),
+ getI32Imm(31), getI32Imm(31));
+ break;
+ }
+ }
+ break;
+ } else if (Imm == ~0U) { // setcc op, -1
+ SDOperand Op = Select(N->getOperand(0));
+ switch (CC) {
+ default: assert(0 && "Unhandled SetCC condition"); abort();
+ case ISD::SETEQ:
+ Op = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
+ Op, getI32Imm(1));
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::ADDZE,
+ CurDAG->getTargetNode(PPC::LI, MVT::i32,
+ getI32Imm(0)),
+ Op.getValue(1));
+ break;
+ case ISD::SETNE: {
+ Op = CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op);
+ SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, Op,
+ getI32Imm(~0U));
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::SUBFE, AD, Op, AD.getValue(1));
+ break;
+ }
+ case ISD::SETLT: {
+ SDOperand AD = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op,
+ getI32Imm(1));
+ SDOperand AN = CurDAG->getTargetNode(PPC::AND, MVT::i32, AD, Op);
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::RLWINM, AN, getI32Imm(1),
+ getI32Imm(31), getI32Imm(31));
+ break;
+ }
+ case ISD::SETGT:
+ Op = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Op, getI32Imm(1),
+ getI32Imm(31), getI32Imm(31));
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::XORI, Op, getI32Imm(1));
+ break;
+ }
+ break;
+ }
+ }
+
+ bool Inv;
+ unsigned Idx = getCRIdxForSetCC(CC, Inv);
+ SDOperand CCReg =
+ SelectCC(Select(N->getOperand(0)), Select(N->getOperand(1)), CC);
+ SDOperand IntCR;
+ if (TLI.getTargetMachine().getSubtarget<PPCSubtarget>().isGigaProcessor()) {
+ IntCR = CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, CCReg);
+ } else {
+ assert(0 && "Not imp yet!");
+ // FIXME: HOW DO WE DO THIS??
+#if 0
+ //SDOperand CR7Op = CurDAG->getCopyToReg();
+ BuildMI(BB, PPC::MCRF, 1, PPC::CR7).addReg(CCReg);
+ BuildMI(BB, PPC::MFCR, 0, IntCR);
+#endif
+ }
+
+ if (!Inv) {
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::RLWINM, IntCR,
+ getI32Imm(32-(3-Idx)), getI32Imm(31), getI32Imm(31));
+ } else {
+ SDOperand Tmp =
+ CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, IntCR,
+ getI32Imm(32-(3-Idx)), getI32Imm(31),getI32Imm(31));
+ CurDAG->SelectNodeTo(N, MVT::i32, PPC::XORI, Tmp, getI32Imm(1));
+ }
+
+ break;
+ }
case ISD::CALLSEQ_START:
case ISD::CALLSEQ_END: {
More information about the llvm-commits
mailing list