diff options
author | Logan Chien <loganchien@google.com> | 2011-12-16 09:08:45 +0800 |
---|---|---|
committer | Logan Chien <loganchien@google.com> | 2011-12-16 13:28:58 +0800 |
commit | a1e6e241a813f81be2d2f36ab60c950ca297574b (patch) | |
tree | cf2d7ec5c63f40e2b66d8be7737496719a0d7902 /lib/Target/PowerPC/PPCInstrInfo.cpp | |
parent | ac212abcc6d858470ad35ce7d660af0c1800364a (diff) | |
parent | ddecfe54a35ffbe0675f7f33e493734fd60b2495 (diff) | |
download | external_llvm-a1e6e241a813f81be2d2f36ab60c950ca297574b.zip external_llvm-a1e6e241a813f81be2d2f36ab60c950ca297574b.tar.gz external_llvm-a1e6e241a813f81be2d2f36ab60c950ca297574b.tar.bz2 |
Merge with LLVM upstream r146714 (Dec 16th 2011)
Change-Id: Ied458adb08bf9a69250cbcee9b14b44d17e8701a
Diffstat (limited to 'lib/Target/PowerPC/PPCInstrInfo.cpp')
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.cpp | 120 |
1 files changed, 73 insertions, 47 deletions
diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index b9a6297..6d16f1d 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -33,8 +33,8 @@ #include "PPCGenInstrInfo.inc" namespace llvm { -extern cl::opt<bool> EnablePPC32RS; // FIXME (64-bit): See PPCRegisterInfo.cpp. -extern cl::opt<bool> EnablePPC64RS; // FIXME (64-bit): See PPCRegisterInfo.cpp. +extern cl::opt<bool> DisablePPC32RS; +extern cl::opt<bool> DisablePPC64RS; } using namespace llvm; @@ -48,25 +48,32 @@ PPCInstrInfo::PPCInstrInfo(PPCTargetMachine &tm) ScheduleHazardRecognizer *PPCInstrInfo::CreateTargetHazardRecognizer( const TargetMachine *TM, const ScheduleDAG *DAG) const { - // Should use subtarget info to pick the right hazard recognizer. For - // now, always return a PPC970 recognizer. - const TargetInstrInfo *TII = TM->getInstrInfo(); - (void)TII; - assert(TII && "No InstrInfo?"); - unsigned Directive = TM->getSubtarget<PPCSubtarget>().getDarwinDirective(); if (Directive == PPC::DIR_440) { const InstrItineraryData *II = TM->getInstrItineraryData(); return new PPCHazardRecognizer440(II, DAG); } - else { - // Disable the hazard recognizer for now, as it doesn't support - // bottom-up scheduling. - //return new PPCHazardRecognizer970(*TII); - return new ScheduleHazardRecognizer(); - } + + return TargetInstrInfoImpl::CreateTargetHazardRecognizer(TM, DAG); } +/// CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer +/// to use for this target when scheduling the DAG. +ScheduleHazardRecognizer *PPCInstrInfo::CreateTargetPostRAHazardRecognizer( + const InstrItineraryData *II, + const ScheduleDAG *DAG) const { + unsigned Directive = TM.getSubtarget<PPCSubtarget>().getDarwinDirective(); + + // Most subtargets use a PPC970 recognizer. + if (Directive != PPC::DIR_440) { + const TargetInstrInfo *TII = TM.getInstrInfo(); + assert(TII && "No InstrInfo?"); + + return new PPCHazardRecognizer970(*TII); + } + + return TargetInstrInfoImpl::CreateTargetPostRAHazardRecognizer(II, DAG); +} unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { @@ -338,6 +345,7 @@ void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB, BuildMI(MBB, I, DL, MCID, DestReg).addReg(SrcReg, getKillRegState(KillSrc)); } +// This function returns true if a CR spill is necessary and false otherwise. bool PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, unsigned SrcReg, bool isKill, @@ -369,7 +377,7 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, FrameIdx)); } else { // FIXME: this spills LR immediately to memory in one step. To do this, - // we use R11, which we know cannot be used in the prolog/epilog. This is + // we use X11, which we know cannot be used in the prolog/epilog. This is // a hack. NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFLR8), PPC::X11)); NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STD)) @@ -388,9 +396,8 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, getKillRegState(isKill)), FrameIdx)); } else if (PPC::CRRCRegisterClass->hasSubClassEq(RC)) { - if ((EnablePPC32RS && !TM.getSubtargetImpl()->isPPC64()) || - (EnablePPC64RS && TM.getSubtargetImpl()->isPPC64())) { - // FIXME (64-bit): Enable + if ((!DisablePPC32RS && !TM.getSubtargetImpl()->isPPC64()) || + (!DisablePPC64RS && TM.getSubtargetImpl()->isPPC64())) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILL_CR)) .addReg(SrcReg, getKillRegState(isKill)), @@ -403,11 +410,14 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, // We hack this on Darwin by reserving R2. It's probably broken on Linux // at the moment. + bool is64Bit = TM.getSubtargetImpl()->isPPC64(); // We need to store the CR in the low 4-bits of the saved value. First, // 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::MFCRpseud), ScratchReg) + (is64Bit ? PPC::X2 : PPC::R2) : + (is64Bit ? PPC::X0 : PPC::R0); + NewMIs.push_back(BuildMI(MF, DL, get(is64Bit ? PPC::MFCR8pseud : + PPC::MFCRpseud), ScratchReg) .addReg(SrcReg, getKillRegState(isKill))); // If the saved register wasn't CR0, shift the bits left so that they are @@ -415,12 +425,14 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, if (SrcReg != PPC::CR0) { unsigned ShiftBits = getPPCRegisterNumbering(SrcReg)*4; // rlwinm scratch, scratch, ShiftBits, 0, 31. - NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg) + NewMIs.push_back(BuildMI(MF, DL, get(is64Bit ? PPC::RLWINM8 : + PPC::RLWINM), ScratchReg) .addReg(ScratchReg).addImm(ShiftBits) .addImm(0).addImm(31)); } - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW)) + NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(is64Bit ? + PPC::STW8 : PPC::STW)) .addReg(ScratchReg, getKillRegState(isKill)), FrameIdx)); @@ -504,7 +516,7 @@ PPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, NewMIs.back()->addMemOperand(MF, MMO); } -void +bool PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, @@ -524,8 +536,8 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, FrameIdx)); } else { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LD), - PPC::R11), FrameIdx)); - NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTLR8)).addReg(PPC::R11)); + PPC::X11), FrameIdx)); + NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTLR8)).addReg(PPC::X11)); } } else if (PPC::F8RCRegisterClass->hasSubClassEq(RC)) { NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFD), DestReg), @@ -534,28 +546,37 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg), FrameIdx)); } else if (PPC::CRRCRegisterClass->hasSubClassEq(RC)) { - // FIXME: We need a scatch reg here. The trouble with using R0 is that - // it's possible for the stack frame to be so big the save location is - // out of range of immediate offsets, necessitating another register. - // We hack this on Darwin by reserving R2. It's probably broken on Linux - // at the moment. - unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ? - PPC::R2 : PPC::R0; - NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), - ScratchReg), FrameIdx)); - - // If the reloaded register isn't CR0, shift the bits right so that they are - // in the right CR's slot. - if (DestReg != PPC::CR0) { - unsigned ShiftBits = getPPCRegisterNumbering(DestReg)*4; - // rlwinm r11, r11, 32-ShiftBits, 0, 31. - NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg) - .addReg(ScratchReg).addImm(32-ShiftBits).addImm(0) - .addImm(31)); + if ((!DisablePPC32RS && !TM.getSubtargetImpl()->isPPC64()) || + (!DisablePPC64RS && TM.getSubtargetImpl()->isPPC64())) { + NewMIs.push_back(addFrameReference(BuildMI(MF, DL, + get(PPC::RESTORE_CR), DestReg) + , FrameIdx)); + return true; + } else { + // FIXME: We need a scatch reg here. The trouble with using R0 is that + // it's possible for the stack frame to be so big the save location is + // out of range of immediate offsets, necessitating another register. + // We hack this on Darwin by reserving R2. It's probably broken on Linux + // at the moment. + unsigned ScratchReg = TM.getSubtargetImpl()->isDarwinABI() ? + PPC::R2 : PPC::R0; + NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), + ScratchReg), FrameIdx)); + + // If the reloaded register isn't CR0, shift the bits right so that they are + // in the right CR's slot. + if (DestReg != PPC::CR0) { + unsigned ShiftBits = getPPCRegisterNumbering(DestReg)*4; + // rlwinm r11, r11, 32-ShiftBits, 0, 31. + NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), ScratchReg) + .addReg(ScratchReg).addImm(32-ShiftBits).addImm(0) + .addImm(31)); + } + + NewMIs.push_back(BuildMI(MF, DL, get(TM.getSubtargetImpl()->isPPC64() ? + PPC::MTCRF8 : PPC::MTCRF), DestReg) + .addReg(ScratchReg)); } - - NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg) - .addReg(ScratchReg)); } else if (PPC::CRBITRCRegisterClass->hasSubClassEq(RC)) { unsigned Reg = 0; @@ -600,6 +621,8 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, } else { llvm_unreachable("Unknown regclass!"); } + + return false; } void @@ -612,7 +635,10 @@ PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, SmallVector<MachineInstr*, 4> NewMIs; DebugLoc DL; if (MI != MBB.end()) DL = MI->getDebugLoc(); - LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs); + if (LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs)) { + PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); + FuncInfo->setSpillsCR(); + } for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) MBB.insert(MI, NewMIs[i]); |