X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FPowerPC%2FPPCISelDAGToDAG.cpp;h=87c698b4b13186c84111685055fc3d9c08f0a3e6;hb=69244300b8a0112efb44b6273ecea4ca6264b8cf;hp=49427aaf7cc796ba163475ca1eba364b7332120f;hpb=df4ed6350b2a51f71c0980e86c9078f4046ea706;p=oota-llvm.git diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 49427aaf7cc..87c698b4b13 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Chris Lattner and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "ppc-codegen" #include "PPC.h" #include "PPCPredicates.h" #include "PPCTargetMachine.h" @@ -19,25 +20,21 @@ #include "PPCHazardRecognizers.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/SSARegMap.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/ADT/Statistic.h" #include "llvm/Constants.h" #include "llvm/GlobalValue.h" #include "llvm/Intrinsics.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Compiler.h" -#include #include #include using namespace llvm; namespace { - Statistic<> FrameOff("ppc-codegen", "Number of frame idx offsets collapsed"); - //===--------------------------------------------------------------------===// /// PPCDAGToDAGISel - PPC specific code to select PPC machine /// instructions for SelectionDAG operations. @@ -45,11 +42,13 @@ namespace { class VISIBILITY_HIDDEN PPCDAGToDAGISel : public SelectionDAGISel { PPCTargetMachine &TM; PPCTargetLowering PPCLowering; + const PPCSubtarget &PPCSubTarget; unsigned GlobalBaseReg; public: PPCDAGToDAGISel(PPCTargetMachine &tm) : SelectionDAGISel(PPCLowering), TM(tm), - PPCLowering(*TM.getTargetLowering()) {} + PPCLowering(*TM.getTargetLowering()), + PPCSubTarget(*TM.getSubtargetImpl()) {} virtual bool runOnFunction(Function &Fn) { // Make sure we re-emit a set of the global base reg if necessary @@ -225,11 +224,10 @@ void PPCDAGToDAGISel::InsertVRSaveCode(Function &F) { // In this case, there will be virtual registers of vector type type created // by the scheduler. Detect them now. MachineFunction &Fn = MachineFunction::get(&F); - SSARegMap *RegMap = Fn.getSSARegMap(); bool HasVectorVReg = false; for (unsigned i = MRegisterInfo::FirstVirtualRegister, - e = RegMap->getLastVirtReg()+1; i != e; ++i) - if (RegMap->getRegClass(i) == &PPC::VRRCRegClass) { + e = RegInfo->getLastVirtReg()+1; i != e; ++i) + if (RegInfo->getRegClass(i) == &PPC::VRRCRegClass) { HasVectorVReg = true; break; } @@ -247,21 +245,22 @@ void PPCDAGToDAGISel::InsertVRSaveCode(Function &F) { // Create two vregs - one to hold the VRSAVE register that is live-in to the // function and one for the value after having bits or'd into it. - unsigned InVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass); - unsigned UpdatedVRSAVE = RegMap->createVirtualRegister(&PPC::GPRCRegClass); + unsigned InVRSAVE = RegInfo->createVirtualRegister(&PPC::GPRCRegClass); + unsigned UpdatedVRSAVE = RegInfo->createVirtualRegister(&PPC::GPRCRegClass); + const TargetInstrInfo &TII = *TM.getInstrInfo(); MachineBasicBlock &EntryBB = *Fn.begin(); // Emit the following code into the entry block: // InVRSAVE = MFVRSAVE // UpdatedVRSAVE = UPDATE_VRSAVE InVRSAVE // MTVRSAVE UpdatedVRSAVE MachineBasicBlock::iterator IP = EntryBB.begin(); // Insert Point - BuildMI(EntryBB, IP, PPC::MFVRSAVE, 0, InVRSAVE); - BuildMI(EntryBB, IP, PPC::UPDATE_VRSAVE, 1, UpdatedVRSAVE).addReg(InVRSAVE); - BuildMI(EntryBB, IP, PPC::MTVRSAVE, 1).addReg(UpdatedVRSAVE); + BuildMI(EntryBB, IP, TII.get(PPC::MFVRSAVE), InVRSAVE); + BuildMI(EntryBB, IP, TII.get(PPC::UPDATE_VRSAVE), + UpdatedVRSAVE).addReg(InVRSAVE); + BuildMI(EntryBB, IP, TII.get(PPC::MTVRSAVE)).addReg(UpdatedVRSAVE); // Find all return blocks, outputting a restore in each epilog. - const TargetInstrInfo &TII = *TM.getInstrInfo(); for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { if (!BB->empty() && TII.isReturn(BB->back().getOpcode())) { IP = BB->end(); --IP; @@ -269,11 +268,11 @@ void PPCDAGToDAGISel::InsertVRSaveCode(Function &F) { // Skip over all terminator instructions, which are part of the return // sequence. MachineBasicBlock::iterator I2 = IP; - while (I2 != BB->begin() && TII.isTerminatorInstr((--I2)->getOpcode())) + while (I2 != BB->begin() && (--I2)->getDesc()->isTerminator()) IP = I2; // Emit: MTVRSAVE InVRSave - BuildMI(*BB, IP, PPC::MTVRSAVE, 1).addReg(InVRSAVE); + BuildMI(*BB, IP, TII.get(PPC::MTVRSAVE)).addReg(InVRSAVE); } } } @@ -284,19 +283,19 @@ void PPCDAGToDAGISel::InsertVRSaveCode(Function &F) { /// SDNode *PPCDAGToDAGISel::getGlobalBaseReg() { if (!GlobalBaseReg) { + const TargetInstrInfo &TII = *TM.getInstrInfo(); // Insert the set of GlobalBaseReg into the first MBB of the function MachineBasicBlock &FirstMBB = BB->getParent()->front(); MachineBasicBlock::iterator MBBI = FirstMBB.begin(); - SSARegMap *RegMap = BB->getParent()->getSSARegMap(); if (PPCLowering.getPointerTy() == MVT::i32) { - GlobalBaseReg = RegMap->createVirtualRegister(PPC::GPRCRegisterClass); - BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR); - BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg); + GlobalBaseReg = RegInfo->createVirtualRegister(PPC::GPRCRegisterClass); + BuildMI(FirstMBB, MBBI, TII.get(PPC::MovePCtoLR), PPC::LR); + BuildMI(FirstMBB, MBBI, TII.get(PPC::MFLR), GlobalBaseReg); } else { - GlobalBaseReg = RegMap->createVirtualRegister(PPC::G8RCRegisterClass); - BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR8, 0, PPC::LR8); - BuildMI(FirstMBB, MBBI, PPC::MFLR8, 1, GlobalBaseReg); + GlobalBaseReg = RegInfo->createVirtualRegister(PPC::G8RCRegisterClass); + BuildMI(FirstMBB, MBBI, TII.get(PPC::MovePCtoLR8), PPC::LR8); + BuildMI(FirstMBB, MBBI, TII.get(PPC::MFLR8), GlobalBaseReg); } } return CurDAG->getRegister(GlobalBaseReg, PPCLowering.getPointerTy()).Val; @@ -426,8 +425,8 @@ SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) { SDOperand Op1 = N->getOperand(1); uint64_t LKZ, LKO, RKZ, RKO; - TLI.ComputeMaskedBits(Op0, 0xFFFFFFFFULL, LKZ, LKO); - TLI.ComputeMaskedBits(Op1, 0xFFFFFFFFULL, RKZ, RKO); + CurDAG->ComputeMaskedBits(Op0, 0xFFFFFFFFULL, LKZ, LKO); + CurDAG->ComputeMaskedBits(Op1, 0xFFFFFFFFULL, RKZ, RKO); unsigned TargetMask = LKZ; unsigned InsertMask = RKZ; @@ -510,7 +509,7 @@ SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS, return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, LHS, getI32Imm(Imm & 0xFFFF)), 0); // If this is a 16-bit signed immediate, fold it. - if (isInt16(Imm)) + if (isInt16((int)Imm)) return SDOperand(CurDAG->getTargetNode(PPC::CMPWI, MVT::i32, LHS, getI32Imm(Imm & 0xFFFF)), 0); @@ -738,7 +737,7 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDOperand Op) { CCReg = CurDAG->getCopyToReg(CurDAG->getEntryNode(), CR7Reg, CCReg, InFlag).getValue(1); - if (TLI.getTargetMachine().getSubtarget().isGigaProcessor()) + if (PPCSubTarget.isGigaProcessor()) IntCR = SDOperand(CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, CR7Reg, CCReg), 0); else @@ -766,6 +765,81 @@ SDNode *PPCDAGToDAGISel::Select(SDOperand Op) { switch (N->getOpcode()) { default: break; + + case ISD::Constant: { + if (N->getValueType(0) == MVT::i64) { + // Get 64 bit value. + int64_t Imm = cast(N)->getValue(); + // Assume no remaining bits. + unsigned Remainder = 0; + // Assume no shift required. + unsigned Shift = 0; + + // If it can't be represented as a 32 bit value. + if (!isInt32(Imm)) { + Shift = CountTrailingZeros_64(Imm); + int64_t ImmSh = static_cast(Imm) >> Shift; + + // If the shifted value fits 32 bits. + if (isInt32(ImmSh)) { + // Go with the shifted value. + Imm = ImmSh; + } else { + // Still stuck with a 64 bit value. + Remainder = Imm; + Shift = 32; + Imm >>= 32; + } + } + + // Intermediate operand. + SDNode *Result; + + // Handle first 32 bits. + unsigned Lo = Imm & 0xFFFF; + unsigned Hi = (Imm >> 16) & 0xFFFF; + + // Simple value. + if (isInt16(Imm)) { + // Just the Lo bits. + Result = CurDAG->getTargetNode(PPC::LI8, MVT::i64, getI32Imm(Lo)); + } else if (Lo) { + // Handle the Hi bits. + unsigned OpC = Hi ? PPC::LIS8 : PPC::LI8; + Result = CurDAG->getTargetNode(OpC, MVT::i64, getI32Imm(Hi)); + // And Lo bits. + Result = CurDAG->getTargetNode(PPC::ORI8, MVT::i64, + SDOperand(Result, 0), getI32Imm(Lo)); + } else { + // Just the Hi bits. + Result = CurDAG->getTargetNode(PPC::LIS8, MVT::i64, getI32Imm(Hi)); + } + + // If no shift, we're done. + if (!Shift) return Result; + + // Shift for next step if the upper 32-bits were not zero. + if (Imm) { + Result = CurDAG->getTargetNode(PPC::RLDICR, MVT::i64, + SDOperand(Result, 0), + getI32Imm(Shift), getI32Imm(63 - Shift)); + } + + // Add in the last bits as required. + if ((Hi = (Remainder >> 16) & 0xFFFF)) { + Result = CurDAG->getTargetNode(PPC::ORIS8, MVT::i64, + SDOperand(Result, 0), getI32Imm(Hi)); + } + if ((Lo = Remainder & 0xFFFF)) { + Result = CurDAG->getTargetNode(PPC::ORI8, MVT::i64, + SDOperand(Result, 0), getI32Imm(Lo)); + } + + return Result; + } + break; + } + case ISD::SETCC: return SelectSETCC(Op); case PPCISD::GlobalBaseReg: @@ -786,7 +860,7 @@ SDNode *PPCDAGToDAGISel::Select(SDOperand Op) { SDOperand InFlag = N->getOperand(1); AddToISelQueue(InFlag); // Use MFOCRF if supported. - if (TLI.getTargetMachine().getSubtarget().isGigaProcessor()) + if (PPCSubTarget.isGigaProcessor()) return CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, N->getOperand(0), InFlag); else @@ -1001,13 +1075,26 @@ SDNode *PPCDAGToDAGISel::Select(SDOperand Op) { getI32Imm(BROpc) }; return CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), Ops, 4); } + case PPCISD::COND_BRANCH: { + AddToISelQueue(N->getOperand(0)); // Op #0 is the Chain. + // Op #1 is the PPC::PRED_* number. + // Op #2 is the CR# + // Op #3 is the Dest MBB + AddToISelQueue(N->getOperand(4)); // Op #4 is the Flag. + // Prevent PPC::PRED_* from being selected into LI. + SDOperand Pred = + getI32Imm(cast(N->getOperand(1))->getValue()); + SDOperand Ops[] = { Pred, N->getOperand(2), N->getOperand(3), + N->getOperand(0), N->getOperand(4) }; + return CurDAG->SelectNodeTo(N, PPC::BCC, MVT::Other, Ops, 5); + } case ISD::BR_CC: { AddToISelQueue(N->getOperand(0)); ISD::CondCode CC = cast(N->getOperand(1))->get(); SDOperand CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC); - SDOperand Ops[] = { CondCode, getI32Imm(getPredicateForSetCC(CC)), + SDOperand Ops[] = { getI32Imm(getPredicateForSetCC(CC)), CondCode, N->getOperand(4), N->getOperand(0) }; - return CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other, Ops, 4); + return CurDAG->SelectNodeTo(N, PPC::BCC, MVT::Other, Ops, 4); } case ISD::BRIND: { // FIXME: Should custom lower this.