diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h index bc58080a5ec..f13823382f6 100644 --- a/include/llvm/Target/MRegisterInfo.h +++ b/include/llvm/Target/MRegisterInfo.h @@ -16,6 +16,7 @@ #ifndef LLVM_TARGET_MREGISTERINFO_H #define LLVM_TARGET_MREGISTERINFO_H +#include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/ValueTypes.h" #include @@ -30,6 +31,9 @@ class MachineInstr; class MachineLocation; class MachineMove; class RegScavenger; +class SDNode; +class SelectionDAG; +class SSARegMap; class TargetRegisterClass; class Type; @@ -503,11 +507,21 @@ public: unsigned SrcReg, int FrameIndex, const TargetRegisterClass *RC) const = 0; + virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const = 0; + virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const = 0; + virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const = 0; + virtual void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, @@ -550,6 +564,20 @@ public: return 0; } + /// unfoldMemoryOperand - Separate a single instruction which folded a load or a + /// a store or a load and a store into two or more instruction. If this is + /// possible, returns true as well as the new instructions by reference. + virtual bool unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, + SSARegMap *RegMap, + SmallVector &NewMIs) const { + return false; + } + + virtual bool unfoldMemoryOperand(SelectionDAG &DAG, SDNode *N, + SmallVector &NewNodes) const { + return false; + } + /// targetHandlesStackFrameRounding - Returns true if the target is responsible /// for rounding up the stack frame (probably at emitPrologue time). virtual bool targetHandlesStackFrameRounding() const { diff --git a/lib/Target/ARM/ARMRegisterInfo.cpp b/lib/Target/ARM/ARMRegisterInfo.cpp index e6d99e590c6..02446e91a9f 100644 --- a/lib/Target/ARM/ARMRegisterInfo.cpp +++ b/lib/Target/ARM/ARMRegisterInfo.cpp @@ -132,6 +132,30 @@ bool ARMRegisterInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, return true; } +static inline +const MachineInstrBuilder &AddDefaultPred(const MachineInstrBuilder &MIB) { + return MIB.addImm((int64_t)ARMCC::AL).addReg(0); +} + +static inline +const MachineInstrBuilder &AddDefaultCC(const MachineInstrBuilder &MIB) { + return MIB.addReg(0); +} + +static const MachineInstrBuilder &ARMInstrAddOperand(MachineInstrBuilder &MIB, + MachineOperand &MO) { + if (MO.isRegister()) + MIB = MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit()); + else if (MO.isImmediate()) + MIB = MIB.addImm(MO.getImm()); + else if (MO.isFrameIndex()) + MIB = MIB.addFrameIndex(MO.getFrameIndex()); + else + assert(0 && "Unknown operand for ARMInstrAddOperand!"); + + return MIB; +} + void ARMRegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned SrcReg, int FI, @@ -143,19 +167,54 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, BuildMI(MBB, I, TII.get(ARM::tSpill)).addReg(SrcReg, false, false, true) .addFrameIndex(FI).addImm(0); else - BuildMI(MBB, I, TII.get(ARM::STR)).addReg(SrcReg, false, false, true) - .addFrameIndex(FI).addReg(0).addImm(0).addImm((int64_t)ARMCC::AL) - .addReg(0); + AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::STR)) + .addReg(SrcReg, false, false, true) + .addFrameIndex(FI).addReg(0).addImm(0)); } else if (RC == ARM::DPRRegisterClass) { - BuildMI(MBB, I, TII.get(ARM::FSTD)).addReg(SrcReg, false, false, true) - .addFrameIndex(FI).addImm(0).addImm((int64_t)ARMCC::AL).addReg(0); + AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::FSTD)) + .addReg(SrcReg, false, false, true) + .addFrameIndex(FI).addImm(0)); } else { assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); - BuildMI(MBB, I, TII.get(ARM::FSTS)).addReg(SrcReg, false, false, true) - .addFrameIndex(FI).addImm(0).addImm((int64_t)ARMCC::AL).addReg(0); + AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::FSTS)) + .addReg(SrcReg, false, false, true) + .addFrameIndex(FI).addImm(0)); } } +void ARMRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + unsigned Opc = 0; + if (RC == ARM::GPRRegisterClass) { + ARMFunctionInfo *AFI = MF.getInfo(); + if (AFI->isThumbFunction()) { + Opc = Addr[0].isFrameIndex() ? ARM::tSpill : ARM::tSTR; + MachineInstrBuilder MIB = + BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, true); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) + MIB = ARMInstrAddOperand(MIB, Addr[i]); + NewMIs.push_back(MIB); + return; + } + Opc = ARM::STR; + } else if (RC == ARM::DPRRegisterClass) { + Opc = ARM::FSTD; + } else { + assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); + Opc = ARM::FSTS; + } + + MachineInstrBuilder MIB = + BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, true); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) + MIB = ARMInstrAddOperand(MIB, Addr[i]); + AddDefaultPred(MIB); + NewMIs.push_back(MIB); + return; +} + void ARMRegisterInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FI, @@ -167,19 +226,49 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, BuildMI(MBB, I, TII.get(ARM::tRestore), DestReg) .addFrameIndex(FI).addImm(0); else - BuildMI(MBB, I, TII.get(ARM::LDR), DestReg) - .addFrameIndex(FI).addReg(0).addImm(0).addImm((int64_t)ARMCC::AL) - .addReg(0); + AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::LDR), DestReg) + .addFrameIndex(FI).addReg(0).addImm(0)); } else if (RC == ARM::DPRRegisterClass) { - BuildMI(MBB, I, TII.get(ARM::FLDD), DestReg) - .addFrameIndex(FI).addImm(0).addImm((int64_t)ARMCC::AL).addReg(0); + AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::FLDD), DestReg) + .addFrameIndex(FI).addImm(0)); } else { assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); - BuildMI(MBB, I, TII.get(ARM::FLDS), DestReg) - .addFrameIndex(FI).addImm(0).addImm((int64_t)ARMCC::AL).addReg(0); + AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::FLDS), DestReg) + .addFrameIndex(FI).addImm(0)); } } +void ARMRegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + unsigned Opc = 0; + if (RC == ARM::GPRRegisterClass) { + ARMFunctionInfo *AFI = MF.getInfo(); + if (AFI->isThumbFunction()) { + Opc = Addr[0].isFrameIndex() ? ARM::tRestore : ARM::tLDR; + MachineInstrBuilder MIB = BuildMI(TII.get(Opc), DestReg); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) + MIB = ARMInstrAddOperand(MIB, Addr[i]); + NewMIs.push_back(MIB); + return; + } + Opc = ARM::LDR; + } else if (RC == ARM::DPRRegisterClass) { + Opc = ARM::FLDD; + } else { + assert(RC == ARM::SPRRegisterClass && "Unknown regclass!"); + Opc = ARM::FLDS; + } + + MachineInstrBuilder MIB = BuildMI(TII.get(Opc), DestReg); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) + MIB = ARMInstrAddOperand(MIB, Addr[i]); + AddDefaultPred(MIB); + NewMIs.push_back(MIB); + return; +} + void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, unsigned SrcReg, @@ -196,14 +285,14 @@ void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, if (AFI->isThumbFunction()) BuildMI(MBB, I, TII.get(ARM::tMOVr), DestReg).addReg(SrcReg); else - BuildMI(MBB, I, TII.get(ARM::MOVr), DestReg).addReg(SrcReg) - .addImm((int64_t)ARMCC::AL).addReg(0).addReg(0); + AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::MOVr), DestReg) + .addReg(SrcReg))); } else if (DestRC == ARM::SPRRegisterClass) - BuildMI(MBB, I, TII.get(ARM::FCPYS), DestReg).addReg(SrcReg) - .addImm((int64_t)ARMCC::AL).addReg(0); + AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::FCPYS), DestReg) + .addReg(SrcReg)); else if (DestRC == ARM::DPRRegisterClass) - BuildMI(MBB, I, TII.get(ARM::FCPYD), DestReg).addReg(SrcReg) - .addImm((int64_t)ARMCC::AL).addReg(0); + AddDefaultPred(BuildMI(MBB, I, TII.get(ARM::FCPYD), DestReg) + .addReg(SrcReg)); else abort(); } @@ -1390,7 +1479,7 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const { MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri),FramePtr) .addFrameIndex(FramePtrSpillFI).addImm(0); - if (!isThumb) MIB.addImm(ARMCC::AL).addReg(0).addReg(0); + if (!isThumb) AddDefaultCC(AddDefaultPred(MIB)); } if (!isThumb) { diff --git a/lib/Target/ARM/ARMRegisterInfo.h b/lib/Target/ARM/ARMRegisterInfo.h index 7a2fd2c6cbc..cd32eb63dbf 100644 --- a/lib/Target/ARM/ARMRegisterInfo.h +++ b/lib/Target/ARM/ARMRegisterInfo.h @@ -51,11 +51,21 @@ public: unsigned SrcReg, int FrameIndex, const TargetRegisterClass *RC) const; + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const; + void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *DestRC, diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp index 08c4c94c031..7959483cb59 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.cpp +++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp @@ -82,6 +82,31 @@ AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, abort(); } +void AlphaRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + unsigned Opc = 0; + if (RC == Alpha::F4RCRegisterClass) + Opc = Alpha::STS; + else if (RC == Alpha::F8RCRegisterClass) + Opc = Alpha::STT; + else if (RC == Alpha::GPRCRegisterClass) + Opc = Alpha::STQ; + else + abort(); + MachineInstrBuilder MIB = + BuildMI(TII.get(Opc)).addReg(SrcReg, false, false, true); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) { + MachineOperand &MO = Addr[i]; + if (MO.isRegister()) + MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit()); + else + MIB.addImm(MO.getImm()); + } + NewMIs.push_back(MIB); +} + void AlphaRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, @@ -102,6 +127,31 @@ AlphaRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, abort(); } +void AlphaRegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + unsigned Opc = 0; + if (RC == Alpha::F4RCRegisterClass) + Opc = Alpha::LDS; + else if (RC == Alpha::F8RCRegisterClass) + Opc = Alpha::LDT; + else if (RC == Alpha::GPRCRegisterClass) + Opc = Alpha::LDQ; + else + abort(); + MachineInstrBuilder MIB = + BuildMI(TII.get(Opc), DestReg); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) { + MachineOperand &MO = Addr[i]; + if (MO.isRegister()) + MIB.addReg(MO.getReg(), MO.isDef(), MO.isImplicit()); + else + MIB.addImm(MO.getImm()); + } + NewMIs.push_back(MIB); +} + MachineInstr *AlphaRegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum, int FrameIndex) const { diff --git a/lib/Target/Alpha/AlphaRegisterInfo.h b/lib/Target/Alpha/AlphaRegisterInfo.h index 573d6eb54da..c9bb2dd5393 100644 --- a/lib/Target/Alpha/AlphaRegisterInfo.h +++ b/lib/Target/Alpha/AlphaRegisterInfo.h @@ -33,11 +33,21 @@ struct AlphaRegisterInfo : public AlphaGenRegisterInfo { unsigned SrcReg, int FrameIndex, const TargetRegisterClass *RC) const; + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const; + void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + MachineInstr* foldMemoryOperand(MachineInstr *MI, unsigned OpNum, int FrameIndex) const; diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index 68ad38aed49..8ab5e0e0880 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -95,6 +95,27 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, assert(0 && "Can't store this register to stack slot"); } +void MipsRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + if (RC != Mips::CPURegsRegisterClass) + assert(0 && "Can't store this register"); + MachineInstrBuilder MIB = BuildMI(TII.get(Mips::SW)) + .addReg(SrcReg, false, false, true); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) { + MachineOperand &MO = Addr[i]; + if (MO.isRegister()) + MIB.addReg(MO.getReg()); + else if (MO.isImmediate()) + MIB.addImm(MO.getImmedValue()); + else + MIB.addFrameIndex(MO.getFrameIndex()); + } + NewMIs.push_back(MIB); + return; +} + void MipsRegisterInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FI, @@ -106,6 +127,26 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, assert(0 && "Can't load this register from stack slot"); } +void MipsRegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + if (RC != Mips::CPURegsRegisterClass) + assert(0 && "Can't load this register"); + MachineInstrBuilder MIB = BuildMI(TII.get(Mips::LW), DestReg); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) { + MachineOperand &MO = Addr[i]; + if (MO.isRegister()) + MIB.addReg(MO.getReg()); + else if (MO.isImmediate()) + MIB.addImm(MO.getImmedValue()); + else + MIB.addFrameIndex(MO.getFrameIndex()); + } + NewMIs.push_back(MIB); + return; +} + void MipsRegisterInfo:: copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, unsigned SrcReg, diff --git a/lib/Target/Mips/MipsRegisterInfo.h b/lib/Target/Mips/MipsRegisterInfo.h index b992e2e16d6..47d1fc2b33b 100644 --- a/lib/Target/Mips/MipsRegisterInfo.h +++ b/lib/Target/Mips/MipsRegisterInfo.h @@ -37,11 +37,21 @@ struct MipsRegisterInfo : public MipsGenRegisterInfo { unsigned SrcReg, int FrameIndex, const TargetRegisterClass *RC) const; + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const; + void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, const MachineInstr *Orig) const; diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 158111b2847..76ad6fd0be3 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -103,68 +103,176 @@ PPCRegisterInfo::PPCRegisterInfo(const PPCSubtarget &ST, ImmToIdxMap[PPC::ADDI8] = PPC::ADD8; ImmToIdxMap[PPC::STD_32] = PPC::STDX_32; } -void -PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - unsigned SrcReg, int FrameIdx, - const TargetRegisterClass *RC) const { +static void StoreRegToStackSlot(const TargetInstrInfo &TII, + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *RC, + SmallVector &NewMIs) { if (RC == PPC::GPRCRegisterClass) { if (SrcReg != PPC::LR) { - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STW)) - .addReg(SrcReg, false, false, true), FrameIdx); + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STW)) + .addReg(SrcReg, false, false, true), 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 // a hack. - BuildMI(MBB, MI, TII.get(PPC::MFLR), PPC::R11); - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STW)) - .addReg(PPC::R11, false, false, true), FrameIdx); + NewMIs.push_back(BuildMI(TII.get(PPC::MFLR), PPC::R11)); + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STW)) + .addReg(PPC::R11, false, false, true), FrameIdx)); } } else if (RC == PPC::G8RCRegisterClass) { if (SrcReg != PPC::LR8) { - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STD)) - .addReg(SrcReg, false, false, true), FrameIdx); + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STD)) + .addReg(SrcReg, false, false, true), 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 // a hack. - BuildMI(MBB, MI, TII.get(PPC::MFLR8), PPC::X11); - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STD)) - .addReg(PPC::X11, false, false, true), FrameIdx); + NewMIs.push_back(BuildMI(TII.get(PPC::MFLR8), PPC::X11)); + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STD)) + .addReg(PPC::X11, false, false, true), FrameIdx)); } } else if (RC == PPC::F8RCRegisterClass) { - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STFD)) - .addReg(SrcReg, false, false, true), FrameIdx); + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STFD)) + .addReg(SrcReg, false, false, true), FrameIdx)); } else if (RC == PPC::F4RCRegisterClass) { - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STFS)) - .addReg(SrcReg, false, false, true), FrameIdx); + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STFS)) + .addReg(SrcReg, false, false, true), FrameIdx)); } else if (RC == PPC::CRRCRegisterClass) { // FIXME: We use R0 here, because it isn't available for RA. // 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. - BuildMI(MBB, MI, TII.get(PPC::MFCR), PPC::R0); + NewMIs.push_back(BuildMI(TII.get(PPC::MFCR), PPC::R0)); // If the saved register wasn't CR0, shift the bits left so that they are in // CR0's slot. if (SrcReg != PPC::CR0) { unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(SrcReg)*4; // rlwinm r0, r0, ShiftBits, 0, 31. - BuildMI(MBB, MI, TII.get(PPC::RLWINM), PPC::R0) - .addReg(PPC::R0).addImm(ShiftBits).addImm(0).addImm(31); + NewMIs.push_back(BuildMI(TII.get(PPC::RLWINM), PPC::R0) + .addReg(PPC::R0).addImm(ShiftBits).addImm(0).addImm(31)); } - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::STW)) - .addReg(PPC::R0, false, false, true), FrameIdx); + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::STW)) + .addReg(PPC::R0, false, false, true), FrameIdx)); } else if (RC == PPC::VRRCRegisterClass) { // We don't have indexed addressing for vector loads. Emit: // R0 = ADDI FI# // STVX VAL, 0, R0 // // FIXME: We use R0 here, because it isn't available for RA. - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::ADDI), PPC::R0), - FrameIdx, 0, 0); - BuildMI(MBB, MI, TII.get(PPC::STVX)) - .addReg(SrcReg, false, false, true).addReg(PPC::R0).addReg(PPC::R0); + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::ADDI), PPC::R0), + FrameIdx, 0, 0)); + NewMIs.push_back(BuildMI(TII.get(PPC::STVX)) + .addReg(SrcReg, false, false, true).addReg(PPC::R0).addReg(PPC::R0)); + } else { + assert(0 && "Unknown regclass!"); + abort(); + } +} + +void +PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned SrcReg, int FrameIdx, + const TargetRegisterClass *RC) const { + SmallVector NewMIs; + StoreRegToStackSlot(TII, SrcReg, FrameIdx, RC, NewMIs); + for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) + MBB.insert(MI, NewMIs[i]); +} + +void PPCRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + if (Addr[0].isFrameIndex()) { + StoreRegToStackSlot(TII, SrcReg, Addr[0].getFrameIndex(), RC, NewMIs); + return; + } + + unsigned Opc = 0; + if (RC == PPC::GPRCRegisterClass) { + Opc = PPC::STW; + } else if (RC == PPC::G8RCRegisterClass) { + Opc = PPC::STD; + } else if (RC == PPC::F8RCRegisterClass) { + Opc = PPC::STFD; + } else if (RC == PPC::F4RCRegisterClass) { + Opc = PPC::STFS; + } else if (RC == PPC::VRRCRegisterClass) { + Opc = PPC::STVX; + } else { + assert(0 && "Unknown regclass!"); + abort(); + } + MachineInstrBuilder MIB = BuildMI(TII.get(Opc)) + .addReg(SrcReg, false, false, true); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) { + MachineOperand &MO = Addr[i]; + if (MO.isRegister()) + MIB.addReg(MO.getReg()); + else if (MO.isImmediate()) + MIB.addImm(MO.getImmedValue()); + else + MIB.addFrameIndex(MO.getFrameIndex()); + } + NewMIs.push_back(MIB); + return; +} + +static void LoadRegFromStackSlot(const TargetInstrInfo &TII, + unsigned DestReg, int FrameIdx, + const TargetRegisterClass *RC, + SmallVector &NewMIs) { + if (RC == PPC::GPRCRegisterClass) { + if (DestReg != PPC::LR) { + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::LWZ), DestReg), + FrameIdx)); + } else { + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::LWZ), PPC::R11), + FrameIdx)); + NewMIs.push_back(BuildMI(TII.get(PPC::MTLR)).addReg(PPC::R11)); + } + } else if (RC == PPC::G8RCRegisterClass) { + if (DestReg != PPC::LR8) { + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::LD), DestReg), + FrameIdx)); + } else { + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::LD), PPC::R11), + FrameIdx)); + NewMIs.push_back(BuildMI(TII.get(PPC::MTLR8)).addReg(PPC::R11)); + } + } else if (RC == PPC::F8RCRegisterClass) { + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::LFD), DestReg), + FrameIdx)); + } else if (RC == PPC::F4RCRegisterClass) { + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::LFS), DestReg), + FrameIdx)); + } else if (RC == PPC::CRRCRegisterClass) { + // FIXME: We use R0 here, because it isn't available for RA. + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::LWZ), PPC::R0), + 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 = PPCRegisterInfo::getRegisterNumbering(DestReg)*4; + // rlwinm r11, r11, 32-ShiftBits, 0, 31. + NewMIs.push_back(BuildMI(TII.get(PPC::RLWINM), PPC::R0) + .addReg(PPC::R0).addImm(32-ShiftBits).addImm(0).addImm(31)); + } + + NewMIs.push_back(BuildMI(TII.get(PPC::MTCRF), DestReg).addReg(PPC::R0)); + } else if (RC == PPC::VRRCRegisterClass) { + // We don't have indexed addressing for vector loads. Emit: + // R0 = ADDI FI# + // Dest = LVX 0, R0 + // + // FIXME: We use R0 here, because it isn't available for RA. + NewMIs.push_back(addFrameReference(BuildMI(TII.get(PPC::ADDI), PPC::R0), + FrameIdx, 0, 0)); + NewMIs.push_back(BuildMI(TII.get(PPC::LVX),DestReg).addReg(PPC::R0) + .addReg(PPC::R0)); } else { assert(0 && "Unknown regclass!"); abort(); @@ -176,51 +284,50 @@ PPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC) const { + SmallVector NewMIs; + LoadRegFromStackSlot(TII, DestReg, FrameIdx, RC, NewMIs); + for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) + MBB.insert(MI, NewMIs[i]); +} + +void PPCRegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + if (Addr[0].isFrameIndex()) { + LoadRegFromStackSlot(TII, DestReg, Addr[0].getFrameIndex(), RC, NewMIs); + return; + } + + unsigned Opc = 0; if (RC == PPC::GPRCRegisterClass) { - if (DestReg != PPC::LR) { - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LWZ), DestReg), FrameIdx); - } else { - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LWZ), PPC::R11),FrameIdx); - BuildMI(MBB, MI, TII.get(PPC::MTLR)).addReg(PPC::R11); - } + assert(DestReg != PPC::LR && "Can't handle this yet!"); + Opc = PPC::LWZ; } else if (RC == PPC::G8RCRegisterClass) { - if (DestReg != PPC::LR8) { - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LD), DestReg), FrameIdx); - } else { - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LD), PPC::R11), FrameIdx); - BuildMI(MBB, MI, TII.get(PPC::MTLR8)).addReg(PPC::R11); - } + assert(DestReg != PPC::LR8 && "Can't handle this yet!"); + Opc = PPC::LD; } else if (RC == PPC::F8RCRegisterClass) { - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LFD), DestReg), FrameIdx); + Opc = PPC::LFD; } else if (RC == PPC::F4RCRegisterClass) { - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LFS), DestReg), FrameIdx); - } else if (RC == PPC::CRRCRegisterClass) { - // FIXME: We use R0 here, because it isn't available for RA. - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::LWZ), PPC::R0), 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 = PPCRegisterInfo::getRegisterNumbering(DestReg)*4; - // rlwinm r11, r11, 32-ShiftBits, 0, 31. - BuildMI(MBB, MI, TII.get(PPC::RLWINM), PPC::R0) - .addReg(PPC::R0).addImm(32-ShiftBits).addImm(0).addImm(31); - } - - BuildMI(MBB, MI, TII.get(PPC::MTCRF), DestReg).addReg(PPC::R0); + Opc = PPC::LFS; } else if (RC == PPC::VRRCRegisterClass) { - // We don't have indexed addressing for vector loads. Emit: - // R0 = ADDI FI# - // Dest = LVX 0, R0 - // - // FIXME: We use R0 here, because it isn't available for RA. - addFrameReference(BuildMI(MBB, MI, TII.get(PPC::ADDI), PPC::R0), - FrameIdx, 0, 0); - BuildMI(MBB, MI, TII.get(PPC::LVX),DestReg).addReg(PPC::R0).addReg(PPC::R0); + Opc = PPC::LVX; } else { assert(0 && "Unknown regclass!"); abort(); } + MachineInstrBuilder MIB = BuildMI(TII.get(Opc), DestReg); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) { + MachineOperand &MO = Addr[i]; + if (MO.isRegister()) + MIB.addReg(MO.getReg()); + else if (MO.isImmediate()) + MIB.addImm(MO.getImmedValue()); + else + MIB.addFrameIndex(MO.getFrameIndex()); + } + NewMIs.push_back(MIB); + return; } void PPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, diff --git a/lib/Target/PowerPC/PPCRegisterInfo.h b/lib/Target/PowerPC/PPCRegisterInfo.h index 097d60cc9d2..e986c1b8d56 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/lib/Target/PowerPC/PPCRegisterInfo.h @@ -40,11 +40,21 @@ public: unsigned SrcReg, int FrameIndex, const TargetRegisterClass *RC) const; + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const; + void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *DestRC, diff --git a/lib/Target/Sparc/SparcRegisterInfo.cpp b/lib/Target/Sparc/SparcRegisterInfo.cpp index d3ea07b1215..7129f43712d 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.cpp +++ b/lib/Target/Sparc/SparcRegisterInfo.cpp @@ -48,6 +48,34 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, assert(0 && "Can't store this register to stack slot"); } +void SparcRegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + unsigned Opc = 0; + if (RC == SP::IntRegsRegisterClass) + Opc = SP::STri; + else if (RC == SP::FPRegsRegisterClass) + Opc = SP::STFri; + else if (RC == SP::DFPRegsRegisterClass) + Opc = SP::STDFri; + else + assert(0 && "Can't load this register"); + MachineInstrBuilder MIB = BuildMI(TII.get(Opc)); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) { + MachineOperand &MO = Addr[i]; + if (MO.isRegister()) + MIB.addReg(MO.getReg()); + else if (MO.isImmediate()) + MIB.addImm(MO.getImmedValue()); + else + MIB.addFrameIndex(MO.getFrameIndex()); + } + MIB.addReg(SrcReg, false, false, true); + NewMIs.push_back(MIB); + return; +} + void SparcRegisterInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FI, @@ -62,6 +90,33 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, assert(0 && "Can't load this register from stack slot"); } +void SparcRegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const { + unsigned Opc = 0; + if (RC == SP::IntRegsRegisterClass) + Opc = SP::LDri; + else if (RC == SP::FPRegsRegisterClass) + Opc = SP::LDFri; + else if (RC == SP::DFPRegsRegisterClass) + Opc = SP::LDDFri; + else + assert(0 && "Can't load this register"); + MachineInstrBuilder MIB = BuildMI(TII.get(Opc), DestReg); + for (unsigned i = 0, e = Addr.size(); i != e; ++i) { + MachineOperand &MO = Addr[i]; + if (MO.isRegister()) + MIB.addReg(MO.getReg()); + else if (MO.isImmediate()) + MIB.addImm(MO.getImmedValue()); + else + MIB.addFrameIndex(MO.getFrameIndex()); + } + NewMIs.push_back(MIB); + return; +} + void SparcRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, unsigned SrcReg, diff --git a/lib/Target/Sparc/SparcRegisterInfo.h b/lib/Target/Sparc/SparcRegisterInfo.h index a0e6fc239d5..39cf6160d6c 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.h +++ b/lib/Target/Sparc/SparcRegisterInfo.h @@ -35,11 +35,21 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo { unsigned SrcReg, int FrameIndex, const TargetRegisterClass *RC) const; + void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const; + void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, + SmallVector Addr, + const TargetRegisterClass *RC, + SmallVector &NewMIs) const; + void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *DestRC,