diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 3d9f8aa6ee5..00eebb83f12 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -712,8 +712,9 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) { if (PPCSubTarget.isGigaProcessor() && OtherCondIdx == -1) IntCR = SDValue(CurDAG->getMachineNode(PPC::MFOCRF, dl, MVT::i32, CR7Reg, CCReg), 0); - else - IntCR = SDValue(CurDAG->getMachineNode(PPC::MFCR, dl, MVT::i32, CCReg), 0); + else + IntCR = SDValue(CurDAG->getMachineNode(PPC::MFCRpseud, dl, MVT::i32, + CR7Reg, CCReg), 0); SDValue Ops[] = { IntCR, getI32Imm((32-(3-Idx)) & 31), getI32Imm(31), getI32Imm(31) }; @@ -848,7 +849,8 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) { return CurDAG->getMachineNode(PPC::MFOCRF, dl, MVT::i32, N->getOperand(0), InFlag); else - return CurDAG->getMachineNode(PPC::MFCR, dl, MVT::i32, InFlag); + return CurDAG->getMachineNode(PPC::MFCRpseud, dl, MVT::i32, + N->getOperand(0), InFlag); } case ISD::SDIV: { diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 1d05f3d4ea6..6dcaf1e1a2c 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -111,9 +111,10 @@ namespace llvm { /// Return with a flag operand, matched by 'blr' RET_FLAG, - /// R32 = MFCR(CRREG, INFLAG) - Represents the MFCR/MFOCRF instructions. - /// This copies the bits corresponding to the specified CRREG into the - /// resultant GPR. Bits corresponding to other CR regs are undefined. + /// R32 = MFCR(CRREG, INFLAG) - Represents the MFCRpseud/MFOCRF + /// instructions. This copies the bits corresponding to the specified + /// CRREG into the resultant GPR. Bits corresponding to other CR regs + /// are undefined. MFCR, /// RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index ae95ae47712..1b7a7783b23 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -442,7 +442,8 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, // issue a MFCR to save all of the CRBits. unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ? PPC::R2 : PPC::R0; - NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFCR), ScratchReg)); + NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFCRpseud), ScratchReg) + .addReg(SrcReg, getKillRegState(isKill))); // If the saved register wasn't CR0, shift the bits left so that they are // in CR0's slot. diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 4d153c46e53..63b4581a37f 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -1117,14 +1117,17 @@ def MFVRSAVE : XFXForm_1_ext<31, 339, 256, (outs GPRC:$rT), (ins), def MTCRF : XFXForm_5<31, 144, (outs), (ins crbitm:$FXM, GPRC:$rS), "mtcrf $FXM, $rS", BrMCRX>, PPC970_MicroCode, PPC970_Unit_CRU; -// FIXME: this Uses all the CR registers. Marking it as such is -// necessary for DeadMachineInstructionElim to do the right thing. -// However, marking it also exposes PR 2964, and causes crashes in -// the Local RA because it doesn't like this sequence: + +// This is a pseudo for MFCR, which implicitly uses all 8 of its subregisters; +// declaring that here gives the local register allocator problems with this: // vreg = MCRF CR0 // MFCR -// For now DeadMachineInstructionElim is turned off, so don't do the marking. -def MFCR : XFXForm_3<31, 19, (outs GPRC:$rT), (ins), "mfcr $rT", SprMFCR>, +// while not declaring it breaks DeadMachineInstructionElimination. +// As it turns out, in all cases where we currently use this, +// we're only interested in one subregister of it. Represent this in the +// instruction to keep the register allocator from becoming confused. +def MFCRpseud: XFXForm_3<31, 19, (outs GPRC:$rT), (ins crbitm:$FXM), + "mfcr $rT ${:comment} $FXM", SprMFCR>, PPC970_MicroCode, PPC970_Unit_CRU; def MFOCRF: XFXForm_5a<31, 19, (outs GPRC:$rT), (ins crbitm:$FXM), "mfcr $rT, $FXM", SprMFCR>, diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 0bccf15c6ac..0ff852cf15a 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -689,19 +689,15 @@ void PPCRegisterInfo::lowerCRSpilling(MachineBasicBlock::iterator II, const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; const TargetRegisterClass *RC = Subtarget.isPPC64() ? G8RC : GPRC; unsigned Reg = findScratchRegister(II, RS, RC, SPAdj); + unsigned SrcReg = MI.getOperand(0).getReg(); // We need to store the CR in the low 4-bits of the saved value. First, issue - // an MFCR to save all of the CRBits. Add an implicit kill of the CR. - if (!MI.getOperand(0).isKill()) - BuildMI(MBB, II, dl, TII.get(PPC::MFCR), Reg); - else - // Implicitly kill the CR register. - BuildMI(MBB, II, dl, TII.get(PPC::MFCR), Reg) - .addReg(MI.getOperand(0).getReg(), RegState::ImplicitKill); + // an MFCRpsued to save all of the CRBits and, if needed, kill the SrcReg. + BuildMI(MBB, II, dl, TII.get(PPC::MFCRpseud), Reg) + .addReg(SrcReg, getKillRegState(MI.getOperand(0).isKill())); // If the saved register wasn't CR0, shift the bits left so that they are in // CR0's slot. - unsigned SrcReg = MI.getOperand(0).getReg(); if (SrcReg != PPC::CR0) // rlwinm rA, rA, ShiftBits, 0, 31. BuildMI(MBB, II, dl, TII.get(PPC::RLWINM), Reg)