X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FPowerPC%2FPPCRegisterInfo.cpp;h=679b233bc684907ed8a1122a7a7726f9c4999679;hb=ef698ca30d96baf4ec843740396187b722a63e69;hp=8d2037cc6b577399d1bd5f95cd312ecefa0b7e94;hpb=408396014742a05cad1c91949d2226169e3f9d80;p=oota-llvm.git diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 8d2037cc6b5..679b233bc68 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineLocation.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -50,6 +51,9 @@ PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, unsigned SrcReg, int FrameIdx, const TargetRegisterClass *RC) const { if (SrcReg == PPC::LR) { + // 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, PPC::MFLR, 1, PPC::R11); addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx); } else if (RC == PPC::CRRCRegisterClass) { @@ -63,6 +67,15 @@ PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx); } else if (RC == PPC::F4RCRegisterClass) { addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx); + } else if (RC == PPC::VRRCRegisterClass) { + // We don't have indexed addressing for vector loads. Emit: + // R11 = ADDI FI# + // Dest = LVX R0, R11 + // + // FIXME: We use R0 here, because it isn't available for RA. + addFrameReference(BuildMI(MBB, MI, PPC::ADDI, 1, PPC::R0), FrameIdx, 0, 0); + BuildMI(MBB, MI, PPC::STVX, 3) + .addReg(SrcReg).addReg(PPC::R0).addReg(PPC::R0); } else { assert(0 && "Unknown regclass!"); abort(); @@ -88,6 +101,14 @@ PPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx); } else if (RC == PPC::F4RCRegisterClass) { addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx); + } else if (RC == PPC::VRRCRegisterClass) { + // We don't have indexed addressing for vector loads. Emit: + // R11 = ADDI FI# + // Dest = LVX R0, R11 + // + // FIXME: We use R0 here, because it isn't available for RA. + addFrameReference(BuildMI(MBB, MI, PPC::ADDI, 1, PPC::R0), FrameIdx, 0, 0); + BuildMI(MBB, MI, PPC::LVX, 2, DestReg).addReg(PPC::R0).addReg(PPC::R0); } else { assert(0 && "Unknown regclass!"); abort(); @@ -98,8 +119,6 @@ void PPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const { - MachineInstr *I; - if (RC == PPC::GPRCRegisterClass) { BuildMI(MBB, MI, PPC::OR4, 2, DestReg).addReg(SrcReg).addReg(SrcReg); } else if (RC == PPC::G8RCRegisterClass) { @@ -110,6 +129,8 @@ void PPCRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, BuildMI(MBB, MI, PPC::FMRD, 1, DestReg).addReg(SrcReg); } else if (RC == PPC::CRRCRegisterClass) { BuildMI(MBB, MI, PPC::MCRF, 1, DestReg).addReg(SrcReg); + } else if (RC == PPC::VRRCRegisterClass) { + BuildMI(MBB, MI, PPC::VOR, 2, DestReg).addReg(SrcReg).addReg(SrcReg); } else { std::cerr << "Attempt to copy register that is not GPR or FPR"; abort(); @@ -256,7 +277,7 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { case PPC::LWA: case PPC::LD: case PPC::STD: - case PPC::STDU: + case PPC::STD_32: assert((Offset & 3) == 0 && "Invalid frame offset!"); Offset >>= 2; // The actual encoded value has the low two bits zero. break; @@ -266,12 +287,63 @@ PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { } } +// HandleVRSaveUpdate - MI is the UPDATE_VRSAVE instruction introduced by the +// instruction selector. Based on the vector registers that have been used, +// transform this into the appropriate ORI instruction. +static void HandleVRSaveUpdate(MachineInstr *MI, const bool *UsedRegs) { + unsigned UsedRegMask = 0; +#define HANDLEREG(N) if (UsedRegs[PPC::V##N]) UsedRegMask |= 1 << (31-N) + HANDLEREG( 0); HANDLEREG( 1); HANDLEREG( 2); HANDLEREG( 3); + HANDLEREG( 4); HANDLEREG( 5); HANDLEREG( 6); HANDLEREG( 7); + HANDLEREG( 8); HANDLEREG( 9); HANDLEREG(10); HANDLEREG(11); + HANDLEREG(12); HANDLEREG(13); HANDLEREG(14); HANDLEREG(15); + HANDLEREG(16); HANDLEREG(17); HANDLEREG(18); HANDLEREG(19); + HANDLEREG(20); HANDLEREG(21); HANDLEREG(22); HANDLEREG(23); + HANDLEREG(24); HANDLEREG(25); HANDLEREG(26); HANDLEREG(27); + HANDLEREG(28); HANDLEREG(29); HANDLEREG(30); HANDLEREG(31); +#undef HANDLEREG + unsigned SrcReg = MI->getOperand(1).getReg(); + unsigned DstReg = MI->getOperand(0).getReg(); + // If no registers are used, turn this into a copy. + if (UsedRegMask == 0) { + if (SrcReg != DstReg) + BuildMI(*MI->getParent(), MI, PPC::OR4, 2, DstReg) + .addReg(SrcReg).addReg(SrcReg); + } else if ((UsedRegMask & 0xFFFF) == UsedRegMask) { + BuildMI(*MI->getParent(), MI, PPC::ORI, 2, DstReg) + .addReg(SrcReg).addImm(UsedRegMask); + } else if ((UsedRegMask & 0xFFFF0000) == UsedRegMask) { + BuildMI(*MI->getParent(), MI, PPC::ORIS, 2, DstReg) + .addReg(SrcReg).addImm(UsedRegMask >> 16); + } else { + BuildMI(*MI->getParent(), MI, PPC::ORIS, 2, DstReg) + .addReg(SrcReg).addImm(UsedRegMask >> 16); + BuildMI(*MI->getParent(), MI, PPC::ORI, 2, DstReg) + .addReg(DstReg).addImm(UsedRegMask & 0xFFFF); + } + + // Remove the old UPDATE_VRSAVE instruction. + MI->getParent()->erase(MI); +} + void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB MachineBasicBlock::iterator MBBI = MBB.begin(); MachineFrameInfo *MFI = MF.getFrameInfo(); + // Scan the first few instructions of the prolog, looking for an UPDATE_VRSAVE + // instruction. If we find it, process it. + for (unsigned i = 0; MBBI != MBB.end(); ++i, ++MBBI) { + if (MBBI->getOpcode() == PPC::UPDATE_VRSAVE) { + HandleVRSaveUpdate(MBBI, MF.getUsedPhysregs()); + break; + } + } + + // Move MBBI back to the beginning of the function. + MBBI = MBB.begin(); + // Get the number of bytes to allocate from the FrameInfo unsigned NumBytes = MFI->getStackSize(); @@ -375,5 +447,9 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF, } } +unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const { + return getDwarfRegNum(hasFP(MF) ? PPC::R31 : PPC::R1); +} + #include "PPCGenRegisterInfo.inc"