LLVM API Documentation
00001 //===- PPC64RegisterInfo.cpp - PowerPC64 Register Information ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the PowerPC64 implementation of the MRegisterInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #define DEBUG_TYPE "reginfo" 00015 #include "PowerPC.h" 00016 #include "PowerPCInstrBuilder.h" 00017 #include "PPC64RegisterInfo.h" 00018 #include "llvm/Constants.h" 00019 #include "llvm/Type.h" 00020 #include "llvm/CodeGen/ValueTypes.h" 00021 #include "llvm/CodeGen/MachineInstrBuilder.h" 00022 #include "llvm/CodeGen/MachineFunction.h" 00023 #include "llvm/CodeGen/MachineFrameInfo.h" 00024 #include "llvm/Target/TargetFrameInfo.h" 00025 #include "llvm/Target/TargetMachine.h" 00026 #include "llvm/Target/TargetOptions.h" 00027 #include "llvm/Support/CommandLine.h" 00028 #include "llvm/Support/Debug.h" 00029 #include "llvm/ADT/STLExtras.h" 00030 #include <cstdlib> 00031 #include <iostream> 00032 using namespace llvm; 00033 00034 namespace llvm { 00035 // Switch toggling compilation for AIX 00036 extern cl::opt<bool> AIX; 00037 } 00038 00039 PPC64RegisterInfo::PPC64RegisterInfo() 00040 : PPC64GenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP) { 00041 ImmToIdxMap[PPC::LD] = PPC::LDX; ImmToIdxMap[PPC::STD] = PPC::STDX; 00042 ImmToIdxMap[PPC::LBZ] = PPC::LBZX; ImmToIdxMap[PPC::STB] = PPC::STBX; 00043 ImmToIdxMap[PPC::LHZ] = PPC::LHZX; ImmToIdxMap[PPC::LHA] = PPC::LHAX; 00044 ImmToIdxMap[PPC::LWZ] = PPC::LWZX; ImmToIdxMap[PPC::LWA] = PPC::LWAX; 00045 ImmToIdxMap[PPC::LFS] = PPC::LFSX; ImmToIdxMap[PPC::LFD] = PPC::LFDX; 00046 ImmToIdxMap[PPC::STH] = PPC::STHX; ImmToIdxMap[PPC::STW] = PPC::STWX; 00047 ImmToIdxMap[PPC::STFS] = PPC::STFSX; ImmToIdxMap[PPC::STFD] = PPC::STFDX; 00048 ImmToIdxMap[PPC::ADDI] = PPC::ADD; 00049 } 00050 00051 static const TargetRegisterClass *getClass(unsigned SrcReg) { 00052 if (PPC64::FPRCRegisterClass->contains(SrcReg)) 00053 return PPC64::FPRCRegisterClass; 00054 assert(PPC64::GPRCRegisterClass->contains(SrcReg) && "Reg not FPR or GPR"); 00055 return PPC64::GPRCRegisterClass; 00056 } 00057 00058 static unsigned getIdx(const TargetRegisterClass *RC) { 00059 if (RC == PPC64::GPRCRegisterClass) { 00060 switch (RC->getSize()) { 00061 default: assert(0 && "Invalid data size!"); 00062 case 1: return 0; 00063 case 2: return 1; 00064 case 4: return 2; 00065 case 8: return 3; 00066 } 00067 } else if (RC == PPC64::FPRCRegisterClass) { 00068 switch (RC->getSize()) { 00069 default: assert(0 && "Invalid data size!"); 00070 case 4: return 4; 00071 case 8: return 5; 00072 } 00073 } 00074 std::cerr << "Invalid register class to getIdx()!\n"; 00075 abort(); 00076 } 00077 00078 void 00079 PPC64RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 00080 MachineBasicBlock::iterator MI, 00081 unsigned SrcReg, int FrameIdx) const { 00082 static const unsigned Opcode[] = { 00083 PPC::STB, PPC::STH, PPC::STW, PPC::STD, PPC::STFS, PPC::STFD 00084 }; 00085 unsigned OC = Opcode[getIdx(getClass(SrcReg))]; 00086 if (SrcReg == PPC::LR) { 00087 BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11).addReg(PPC::LR); 00088 BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); 00089 addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx); 00090 } else { 00091 BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); 00092 addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(SrcReg),FrameIdx); 00093 } 00094 } 00095 00096 void 00097 PPC64RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 00098 MachineBasicBlock::iterator MI, 00099 unsigned DestReg, int FrameIdx) const{ 00100 static const unsigned Opcode[] = { 00101 PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LD, PPC::LFS, PPC::LFD 00102 }; 00103 unsigned OC = Opcode[getIdx(getClass(DestReg))]; 00104 if (DestReg == PPC::LR) { 00105 BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); 00106 addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx); 00107 BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11); 00108 } else { 00109 BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0); 00110 addFrameReference(BuildMI(MBB, MI, OC, 2, DestReg), FrameIdx); 00111 } 00112 } 00113 00114 void PPC64RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, 00115 MachineBasicBlock::iterator MI, 00116 unsigned DestReg, unsigned SrcReg, 00117 const TargetRegisterClass *RC) const { 00118 MachineInstr *I; 00119 00120 if (RC == PPC64::GPRCRegisterClass) { 00121 BuildMI(MBB, MI, PPC::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg); 00122 } else if (RC == PPC64::FPRCRegisterClass) { 00123 BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg); 00124 } else { 00125 std::cerr << "Attempt to copy register that is not GPR or FPR"; 00126 abort(); 00127 } 00128 } 00129 00130 //===----------------------------------------------------------------------===// 00131 // Stack Frame Processing methods 00132 //===----------------------------------------------------------------------===// 00133 00134 // hasFP - Return true if the specified function should have a dedicated frame 00135 // pointer register. This is true if the function has variable sized allocas or 00136 // if frame pointer elimination is disabled. 00137 // 00138 static bool hasFP(MachineFunction &MF) { 00139 MachineFrameInfo *MFI = MF.getFrameInfo(); 00140 return MFI->hasVarSizedObjects(); 00141 } 00142 00143 void PPC64RegisterInfo:: 00144 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 00145 MachineBasicBlock::iterator I) const { 00146 if (hasFP(MF)) { 00147 // If we have a frame pointer, convert as follows: 00148 // ADJCALLSTACKDOWN -> addi, r1, r1, -amount 00149 // ADJCALLSTACKUP -> addi, r1, r1, amount 00150 MachineInstr *Old = I; 00151 unsigned Amount = Old->getOperand(0).getImmedValue(); 00152 if (Amount != 0) { 00153 // We need to keep the stack aligned properly. To do this, we round the 00154 // amount of space needed for the outgoing arguments up to the next 00155 // alignment boundary. 00156 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 00157 Amount = (Amount+Align-1)/Align*Align; 00158 00159 // Replace the pseudo instruction with a new instruction... 00160 if (Old->getOpcode() == PPC::ADJCALLSTACKDOWN) { 00161 MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1) 00162 .addSImm(-Amount)); 00163 } else { 00164 assert(Old->getOpcode() == PPC::ADJCALLSTACKUP); 00165 MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1) 00166 .addSImm(Amount)); 00167 } 00168 } 00169 } 00170 MBB.erase(I); 00171 } 00172 00173 void 00174 PPC64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { 00175 unsigned i = 0; 00176 MachineInstr &MI = *II; 00177 MachineBasicBlock &MBB = *MI.getParent(); 00178 MachineFunction &MF = *MBB.getParent(); 00179 00180 while (!MI.getOperand(i).isFrameIndex()) { 00181 ++i; 00182 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 00183 } 00184 00185 int FrameIndex = MI.getOperand(i).getFrameIndex(); 00186 00187 // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP). 00188 MI.SetMachineOperandReg(i, hasFP(MF) ? PPC::R31 : PPC::R1); 00189 00190 // Take into account whether it's an add or mem instruction 00191 unsigned OffIdx = (i == 2) ? 1 : 2; 00192 00193 // Now add the frame object offset to the offset from r1. 00194 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 00195 MI.getOperand(OffIdx).getImmedValue(); 00196 00197 // If we're not using a Frame Pointer that has been set to the value of the 00198 // SP before having the stack size subtracted from it, then add the stack size 00199 // to Offset to get the correct offset. 00200 Offset += MF.getFrameInfo()->getStackSize(); 00201 00202 if (Offset > 32767 || Offset < -32768) { 00203 // Insert a set of r0 with the full offset value before the ld, st, or add 00204 MachineBasicBlock *MBB = MI.getParent(); 00205 MBB->insert(II, BuildMI(PPC::LIS, 1, PPC::R0).addSImm(Offset >> 16)); 00206 MBB->insert(II, BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0) 00207 .addImm(Offset)); 00208 // convert into indexed form of the instruction 00209 // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0 00210 // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0 00211 unsigned NewOpcode = 00212 const_cast<std::map<unsigned, unsigned>& >(ImmToIdxMap)[MI.getOpcode()]; 00213 assert(NewOpcode && "No indexed form of load or store available!"); 00214 MI.setOpcode(NewOpcode); 00215 MI.SetMachineOperandReg(1, MI.getOperand(i).getReg()); 00216 MI.SetMachineOperandReg(2, PPC::R0); 00217 } else { 00218 MI.SetMachineOperandConst(OffIdx, MachineOperand::MO_SignExtendedImmed, 00219 Offset); 00220 } 00221 } 00222 00223 00224 void PPC64RegisterInfo::emitPrologue(MachineFunction &MF) const { 00225 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 00226 MachineBasicBlock::iterator MBBI = MBB.begin(); 00227 MachineFrameInfo *MFI = MF.getFrameInfo(); 00228 MachineInstr *MI; 00229 00230 // Get the number of bytes to allocate from the FrameInfo 00231 unsigned NumBytes = MFI->getStackSize(); 00232 00233 // If we have calls, we cannot use the red zone to store callee save registers 00234 // and we must set up a stack frame, so calculate the necessary size here. 00235 if (MFI->hasCalls()) { 00236 // We reserve argument space for call sites in the function immediately on 00237 // entry to the current function. This eliminates the need for add/sub 00238 // brackets around call sites. 00239 NumBytes += MFI->getMaxCallFrameSize(); 00240 } 00241 00242 // Do we need to allocate space on the stack? 00243 if (NumBytes == 0) return; 00244 00245 // Add the size of R1 to NumBytes size for the store of R1 to the bottom 00246 // of the stack and round the size to a multiple of the alignment. 00247 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 00248 unsigned GPRSize = getSpillSize(PPC::R1)/8; 00249 unsigned Size = hasFP(MF) ? GPRSize + GPRSize : GPRSize; 00250 NumBytes = (NumBytes+Size+Align-1)/Align*Align; 00251 00252 // Update frame info to pretend that this is part of the stack... 00253 MFI->setStackSize(NumBytes); 00254 00255 // adjust stack pointer: r1 -= numbytes 00256 if (NumBytes <= 32768) { 00257 MI=BuildMI(PPC::STDU,3).addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1); 00258 MBB.insert(MBBI, MI); 00259 } else { 00260 int NegNumbytes = -NumBytes; 00261 MI = BuildMI(PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16); 00262 MBB.insert(MBBI, MI); 00263 MI = BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0) 00264 .addImm(NegNumbytes & 0xFFFF); 00265 MBB.insert(MBBI, MI); 00266 MI = BuildMI(PPC::STDUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0); 00267 MBB.insert(MBBI, MI); 00268 } 00269 00270 if (hasFP(MF)) { 00271 MI = BuildMI(PPC::STD, 3).addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1); 00272 MBB.insert(MBBI, MI); 00273 MI = BuildMI(PPC::OR, 2, PPC::R31).addReg(PPC::R1).addReg(PPC::R1); 00274 MBB.insert(MBBI, MI); 00275 } 00276 } 00277 00278 void PPC64RegisterInfo::emitEpilogue(MachineFunction &MF, 00279 MachineBasicBlock &MBB) const { 00280 const MachineFrameInfo *MFI = MF.getFrameInfo(); 00281 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 00282 MachineInstr *MI; 00283 assert(MBBI->getOpcode() == PPC::BLR && 00284 "Can only insert epilog into returning blocks"); 00285 00286 // Get the number of bytes allocated from the FrameInfo... 00287 unsigned NumBytes = MFI->getStackSize(); 00288 00289 if (NumBytes != 0) { 00290 if (hasFP(MF)) { 00291 MI = BuildMI(PPC::OR, 2, PPC::R1).addReg(PPC::R31).addReg(PPC::R31); 00292 MBB.insert(MBBI, MI); 00293 MI = BuildMI(PPC::LD, 2, PPC::R31).addSImm(4).addReg(PPC::R31); 00294 MBB.insert(MBBI, MI); 00295 } 00296 MI = BuildMI(PPC::LD, 2, PPC::R1).addSImm(0).addReg(PPC::R1); 00297 MBB.insert(MBBI, MI); 00298 } 00299 } 00300 00301 #include "PPC64GenRegisterInfo.inc" 00302 00303 const TargetRegisterClass* 00304 PPC64RegisterInfo::getRegClassForType(const Type* Ty) const { 00305 switch (Ty->getTypeID()) { 00306 default: assert(0 && "Invalid type to getClass!"); 00307 case Type::BoolTyID: 00308 case Type::SByteTyID: 00309 case Type::UByteTyID: 00310 case Type::ShortTyID: 00311 case Type::UShortTyID: 00312 case Type::IntTyID: 00313 case Type::UIntTyID: 00314 case Type::PointerTyID: 00315 case Type::LongTyID: 00316 case Type::ULongTyID: return &GPRCInstance; 00317 00318 case Type::FloatTyID: 00319 case Type::DoubleTyID: return &FPRCInstance; 00320 } 00321 } 00322