Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp =================================================================== --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -265,6 +265,10 @@ SDValue zeroExtendInputIfNeeded(SDValue Input); SDValue addExtOrTrunc(SDValue NatWidthRes, bool From32Bit, bool To32Bit); + SDValue getSETGE0I32InGPR(SDValue LHS, SDLoc dl, bool IsSext); + SDValue getSETGE0I64InGPR(SDValue LHS, SDLoc dl, bool IsSext); + SDValue getSETLE0I32InGPR(SDValue LHS, SDLoc dl, bool IsSext); + SDValue getSETLE0I64InGPR(SDValue LHS, SDLoc dl, bool IsSext); void PeepholePPC64(); void PeepholePPC64ZExt(); @@ -2568,6 +2572,65 @@ return ConvOp; } +// Produces a sign/zero extended result of comparing whether a 32-bit value is +// greater than or equal to zero. +SDValue PPCDAGToDAGISel::getSETGE0I32InGPR(SDValue LHS, SDLoc dl, bool IsSext) { + SDValue Not = + SDValue(CurDAG->getMachineNode(PPC::NOR, dl, MVT::i32, LHS, LHS), 0); + if (IsSext) + return SDValue(CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, Not, + getI32Imm(31, dl)), 0); + SDValue ShiftOps[] = + { Not, getI32Imm(1, dl), getI32Imm(31, dl), getI32Imm(31, dl) }; + return SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, + ShiftOps), 0); +} + +// Produces a sign/zero extended result of comparing whether a 64-bit value is +// greater than or equal to zero. +SDValue PPCDAGToDAGISel::getSETGE0I64InGPR(SDValue LHS, SDLoc dl, bool IsSext) { + SDValue Not = + SDValue(CurDAG->getMachineNode(PPC::NOR8, dl, MVT::i64, LHS, LHS), 0); + if (IsSext) + return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, Not, + getI64Imm(31, dl)), 0); + return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Not, + getI64Imm(1, dl), getI64Imm(63, dl)), + 0); +} + +// Produces a sign/zero extended result of comparing whether a 32-bit value is +// less than or equal to zero. +SDValue PPCDAGToDAGISel::getSETLE0I32InGPR(SDValue LHS, SDLoc dl, bool IsSext) { + SDValue Neg = + SDValue(CurDAG->getMachineNode(PPC::NEG, dl, MVT::i32, LHS), 0); + SDValue Srdi = + SDValue(CurDAG->getMachineNode(PPC::RLDICL_32, dl, MVT::i32, + Neg, getI64Imm(1, dl), + getI64Imm(63, dl)), 0); + if (IsSext) + return SDValue(CurDAG->getMachineNode(PPC::ADDI, dl, MVT::i32, Srdi, + getI32Imm(-1, dl)), 0); + return SDValue(CurDAG->getMachineNode(PPC::XORI, dl, MVT::i32, Srdi, + getI32Imm(1, dl)), 0); +} + +// Produces a sign/zero extended result of comparing whether a 64-bit value is +// less than or equal to zero. +SDValue PPCDAGToDAGISel::getSETLE0I64InGPR(SDValue LHS, SDLoc dl, bool IsSext) { + SDValue Addi = + SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl, MVT::i64, LHS, + getI64Imm(~0ULL, dl)), 0); + SDValue Or = + SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64, + Addi, LHS), 0); + if (IsSext) + return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl, MVT::i64, Or, + getI64Imm(63, dl)), 0); + return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, + Or, getI64Imm(1, dl), + getI64Imm(63, dl)), 0); +} void PPCDAGToDAGISel::transferMemOperands(SDNode *N, SDNode *Result) { // Transfer memoperands. MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);