LLVM API Documentation
00001 //===- AlphaRegisterInfo.cpp - Alpha 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 Alpha implementation of the MRegisterInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #define DEBUG_TYPE "reginfo" 00015 #include "Alpha.h" 00016 #include "AlphaRegisterInfo.h" 00017 #include "llvm/Constants.h" 00018 #include "llvm/Type.h" 00019 #include "llvm/Function.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/CodeGen/MachineLocation.h" 00025 #include "llvm/Target/TargetFrameInfo.h" 00026 #include "llvm/Target/TargetMachine.h" 00027 #include "llvm/Target/TargetOptions.h" 00028 #include "llvm/Support/CommandLine.h" 00029 #include "llvm/Support/Debug.h" 00030 #include "llvm/ADT/STLExtras.h" 00031 #include <cstdlib> 00032 #include <iostream> 00033 using namespace llvm; 00034 00035 //These describe LDAx 00036 static const int IMM_LOW = -32768; 00037 static const int IMM_HIGH = 32767; 00038 static const int IMM_MULT = 65536; 00039 00040 static long getUpper16(long l) 00041 { 00042 long y = l / IMM_MULT; 00043 if (l % IMM_MULT > IMM_HIGH) 00044 ++y; 00045 return y; 00046 } 00047 00048 static long getLower16(long l) 00049 { 00050 long h = getUpper16(l); 00051 return l - h * IMM_MULT; 00052 } 00053 00054 static int getUID() 00055 { 00056 static int id = 0; 00057 return ++id; 00058 } 00059 00060 AlphaRegisterInfo::AlphaRegisterInfo() 00061 : AlphaGenRegisterInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP) 00062 { 00063 } 00064 00065 void 00066 AlphaRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 00067 MachineBasicBlock::iterator MI, 00068 unsigned SrcReg, int FrameIdx, 00069 const TargetRegisterClass *RC) const { 00070 //std::cerr << "Trying to store " << getPrettyName(SrcReg) << " to " << FrameIdx << "\n"; 00071 //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg); 00072 if (RC == Alpha::F4RCRegisterClass) 00073 BuildMI(MBB, MI, Alpha::STS, 3).addReg(SrcReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); 00074 else if (RC == Alpha::F8RCRegisterClass) 00075 BuildMI(MBB, MI, Alpha::STT, 3).addReg(SrcReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); 00076 else if (RC == Alpha::GPRCRegisterClass) 00077 BuildMI(MBB, MI, Alpha::STQ, 3).addReg(SrcReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); 00078 else 00079 abort(); 00080 } 00081 00082 void 00083 AlphaRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 00084 MachineBasicBlock::iterator MI, 00085 unsigned DestReg, int FrameIdx, 00086 const TargetRegisterClass *RC) const { 00087 //std::cerr << "Trying to load " << getPrettyName(DestReg) << " to " << FrameIdx << "\n"; 00088 if (RC == Alpha::F4RCRegisterClass) 00089 BuildMI(MBB, MI, Alpha::LDS, 2, DestReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); 00090 else if (RC == Alpha::F8RCRegisterClass) 00091 BuildMI(MBB, MI, Alpha::LDT, 2, DestReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); 00092 else if (RC == Alpha::GPRCRegisterClass) 00093 BuildMI(MBB, MI, Alpha::LDQ, 2, DestReg).addFrameIndex(FrameIdx).addReg(Alpha::F31); 00094 else 00095 abort(); 00096 } 00097 00098 MachineInstr *AlphaRegisterInfo::foldMemoryOperand(MachineInstr *MI, 00099 unsigned OpNum, 00100 int FrameIndex) const { 00101 // Make sure this is a reg-reg copy. 00102 unsigned Opc = MI->getOpcode(); 00103 00104 switch(Opc) { 00105 default: 00106 break; 00107 case Alpha::BIS: 00108 case Alpha::CPYSS: 00109 case Alpha::CPYST: 00110 if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { 00111 if (OpNum == 0) { // move -> store 00112 unsigned InReg = MI->getOperand(1).getReg(); 00113 Opc = (Opc == Alpha::BIS) ? Alpha::STQ : 00114 ((Opc == Alpha::CPYSS) ? Alpha::STS : Alpha::STT); 00115 return BuildMI(Opc, 3).addReg(InReg).addFrameIndex(FrameIndex) 00116 .addReg(Alpha::F31); 00117 } else { // load -> move 00118 unsigned OutReg = MI->getOperand(0).getReg(); 00119 Opc = (Opc == Alpha::BIS) ? Alpha::LDQ : 00120 ((Opc == Alpha::CPYSS) ? Alpha::LDS : Alpha::LDT); 00121 return BuildMI(Opc, 2, OutReg).addFrameIndex(FrameIndex) 00122 .addReg(Alpha::F31); 00123 } 00124 } 00125 break; 00126 } 00127 return 0; 00128 } 00129 00130 00131 void AlphaRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, 00132 MachineBasicBlock::iterator MI, 00133 unsigned DestReg, unsigned SrcReg, 00134 const TargetRegisterClass *RC) const { 00135 // std::cerr << "copyRegToReg " << DestReg << " <- " << SrcReg << "\n"; 00136 if (RC == Alpha::GPRCRegisterClass) { 00137 BuildMI(MBB, MI, Alpha::BIS, 2, DestReg).addReg(SrcReg).addReg(SrcReg); 00138 } else if (RC == Alpha::F4RCRegisterClass) { 00139 BuildMI(MBB, MI, Alpha::CPYSS, 2, DestReg).addReg(SrcReg).addReg(SrcReg); 00140 } else if (RC == Alpha::F8RCRegisterClass) { 00141 BuildMI(MBB, MI, Alpha::CPYST, 2, DestReg).addReg(SrcReg).addReg(SrcReg); 00142 } else { 00143 std::cerr << "Attempt to copy register that is not GPR or FPR"; 00144 abort(); 00145 } 00146 } 00147 00148 const unsigned* AlphaRegisterInfo::getCalleeSaveRegs() const { 00149 static const unsigned CalleeSaveRegs[] = { 00150 Alpha::R9, Alpha::R10, 00151 Alpha::R11, Alpha::R12, 00152 Alpha::R13, Alpha::R14, 00153 Alpha::F2, Alpha::F3, 00154 Alpha::F4, Alpha::F5, 00155 Alpha::F6, Alpha::F7, 00156 Alpha::F8, Alpha::F9, 0 00157 }; 00158 return CalleeSaveRegs; 00159 } 00160 00161 const TargetRegisterClass* const* 00162 AlphaRegisterInfo::getCalleeSaveRegClasses() const { 00163 static const TargetRegisterClass * const CalleeSaveRegClasses[] = { 00164 &Alpha::GPRCRegClass, &Alpha::GPRCRegClass, 00165 &Alpha::GPRCRegClass, &Alpha::GPRCRegClass, 00166 &Alpha::GPRCRegClass, &Alpha::GPRCRegClass, 00167 &Alpha::F8RCRegClass, &Alpha::F8RCRegClass, 00168 &Alpha::F8RCRegClass, &Alpha::F8RCRegClass, 00169 &Alpha::F8RCRegClass, &Alpha::F8RCRegClass, 00170 &Alpha::F8RCRegClass, &Alpha::F8RCRegClass, 0 00171 }; 00172 return CalleeSaveRegClasses; 00173 } 00174 00175 //===----------------------------------------------------------------------===// 00176 // Stack Frame Processing methods 00177 //===----------------------------------------------------------------------===// 00178 00179 // hasFP - Return true if the specified function should have a dedicated frame 00180 // pointer register. This is true if the function has variable sized allocas or 00181 // if frame pointer elimination is disabled. 00182 // 00183 static bool hasFP(MachineFunction &MF) { 00184 MachineFrameInfo *MFI = MF.getFrameInfo(); 00185 return MFI->hasVarSizedObjects(); 00186 } 00187 00188 void AlphaRegisterInfo:: 00189 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 00190 MachineBasicBlock::iterator I) const { 00191 if (hasFP(MF)) { 00192 // If we have a frame pointer, turn the adjcallstackup instruction into a 00193 // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP, 00194 // <amt>' 00195 MachineInstr *Old = I; 00196 uint64_t Amount = Old->getOperand(0).getImmedValue(); 00197 if (Amount != 0) { 00198 // We need to keep the stack aligned properly. To do this, we round the 00199 // amount of space needed for the outgoing arguments up to the next 00200 // alignment boundary. 00201 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 00202 Amount = (Amount+Align-1)/Align*Align; 00203 00204 MachineInstr *New; 00205 if (Old->getOpcode() == Alpha::ADJUSTSTACKDOWN) { 00206 New=BuildMI(Alpha::LDA, 2, Alpha::R30) 00207 .addImm(-Amount).addReg(Alpha::R30); 00208 } else { 00209 assert(Old->getOpcode() == Alpha::ADJUSTSTACKUP); 00210 New=BuildMI(Alpha::LDA, 2, Alpha::R30) 00211 .addImm(Amount).addReg(Alpha::R30); 00212 } 00213 00214 // Replace the pseudo instruction with a new instruction... 00215 MBB.insert(I, New); 00216 } 00217 } 00218 00219 MBB.erase(I); 00220 } 00221 00222 //Alpha has a slightly funny stack: 00223 //Args 00224 //<- incoming SP 00225 //fixed locals (and spills, callee saved, etc) 00226 //<- FP 00227 //variable locals 00228 //<- SP 00229 00230 void 00231 AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { 00232 unsigned i = 0; 00233 MachineInstr &MI = *II; 00234 MachineBasicBlock &MBB = *MI.getParent(); 00235 MachineFunction &MF = *MBB.getParent(); 00236 bool FP = hasFP(MF); 00237 00238 while (!MI.getOperand(i).isFrameIndex()) { 00239 ++i; 00240 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 00241 } 00242 00243 int FrameIndex = MI.getOperand(i).getFrameIndex(); 00244 00245 // Add the base register of R30 (SP) or R15 (FP). 00246 MI.getOperand(i + 1).ChangeToRegister(FP ? Alpha::R15 : Alpha::R30); 00247 00248 // Now add the frame object offset to the offset from the virtual frame index. 00249 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 00250 00251 DEBUG(std::cerr << "FI: " << FrameIndex << " Offset: " << Offset << "\n"); 00252 00253 Offset += MF.getFrameInfo()->getStackSize(); 00254 00255 DEBUG(std::cerr << "Corrected Offset " << Offset << 00256 " for stack size: " << MF.getFrameInfo()->getStackSize() << "\n"); 00257 00258 if (Offset > IMM_HIGH || Offset < IMM_LOW) { 00259 DEBUG(std::cerr << "Unconditionally using R28 for evil purposes Offset: " << Offset << "\n"); 00260 //so in this case, we need to use a temporary register, and move the original 00261 //inst off the SP/FP 00262 //fix up the old: 00263 MI.getOperand(i + 1).ChangeToRegister(Alpha::R28); 00264 MI.getOperand(i).ChangeToImmediate(getLower16(Offset)); 00265 //insert the new 00266 MachineInstr* nMI=BuildMI(Alpha::LDAH, 2, Alpha::R28) 00267 .addImm(getUpper16(Offset)).addReg(FP ? Alpha::R15 : Alpha::R30); 00268 MBB.insert(II, nMI); 00269 } else { 00270 MI.getOperand(i).ChangeToImmediate(Offset); 00271 } 00272 } 00273 00274 00275 void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const { 00276 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 00277 MachineBasicBlock::iterator MBBI = MBB.begin(); 00278 MachineFrameInfo *MFI = MF.getFrameInfo(); 00279 bool FP = hasFP(MF); 00280 00281 static int curgpdist = 0; 00282 00283 //handle GOP offset 00284 BuildMI(MBB, MBBI, Alpha::LDAHg, 3, Alpha::R29) 00285 .addGlobalAddress(const_cast<Function*>(MF.getFunction())) 00286 .addReg(Alpha::R27).addImm(++curgpdist); 00287 BuildMI(MBB, MBBI, Alpha::LDAg, 3, Alpha::R29) 00288 .addGlobalAddress(const_cast<Function*>(MF.getFunction())) 00289 .addReg(Alpha::R29).addImm(curgpdist); 00290 00291 //evil const_cast until MO stuff setup to handle const 00292 BuildMI(MBB, MBBI, Alpha::ALTENT, 1) 00293 .addGlobalAddress(const_cast<Function*>(MF.getFunction())); 00294 00295 // Get the number of bytes to allocate from the FrameInfo 00296 long NumBytes = MFI->getStackSize(); 00297 00298 if (MFI->hasCalls() && !FP) { 00299 // We reserve argument space for call sites in the function immediately on 00300 // entry to the current function. This eliminates the need for add/sub 00301 // brackets around call sites. 00302 //If there is a frame pointer, then we don't do this 00303 NumBytes += MFI->getMaxCallFrameSize(); 00304 DEBUG(std::cerr << "Added " << MFI->getMaxCallFrameSize() 00305 << " to the stack due to calls\n"); 00306 } 00307 00308 if (FP) 00309 NumBytes += 8; //reserve space for the old FP 00310 00311 // Do we need to allocate space on the stack? 00312 if (NumBytes == 0) return; 00313 00314 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 00315 NumBytes = (NumBytes+Align-1)/Align*Align; 00316 00317 // Update frame info to pretend that this is part of the stack... 00318 MFI->setStackSize(NumBytes); 00319 00320 // adjust stack pointer: r30 -= numbytes 00321 NumBytes = -NumBytes; 00322 if (NumBytes >= IMM_LOW) { 00323 BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30).addImm(NumBytes) 00324 .addReg(Alpha::R30); 00325 } else if (getUpper16(NumBytes) >= IMM_LOW) { 00326 BuildMI(MBB, MBBI, Alpha::LDAH, 2, Alpha::R30).addImm(getUpper16(NumBytes)) 00327 .addReg(Alpha::R30); 00328 BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30).addImm(getLower16(NumBytes)) 00329 .addReg(Alpha::R30); 00330 } else { 00331 std::cerr << "Too big a stack frame at " << NumBytes << "\n"; 00332 abort(); 00333 } 00334 00335 //now if we need to, save the old FP and set the new 00336 if (FP) 00337 { 00338 BuildMI(MBB, MBBI, Alpha::STQ, 3).addReg(Alpha::R15).addImm(0).addReg(Alpha::R30); 00339 //this must be the last instr in the prolog 00340 BuildMI(MBB, MBBI, Alpha::BIS, 2, Alpha::R15).addReg(Alpha::R30).addReg(Alpha::R30); 00341 } 00342 00343 } 00344 00345 void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF, 00346 MachineBasicBlock &MBB) const { 00347 const MachineFrameInfo *MFI = MF.getFrameInfo(); 00348 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 00349 assert(MBBI->getOpcode() == Alpha::RETDAG || MBBI->getOpcode() == Alpha::RETDAGp 00350 && "Can only insert epilog into returning blocks"); 00351 00352 bool FP = hasFP(MF); 00353 00354 // Get the number of bytes allocated from the FrameInfo... 00355 long NumBytes = MFI->getStackSize(); 00356 00357 //now if we need to, restore the old FP 00358 if (FP) 00359 { 00360 //copy the FP into the SP (discards allocas) 00361 BuildMI(MBB, MBBI, Alpha::BIS, 2, Alpha::R30).addReg(Alpha::R15) 00362 .addReg(Alpha::R15); 00363 //restore the FP 00364 BuildMI(MBB, MBBI, Alpha::LDQ, 2, Alpha::R15).addImm(0).addReg(Alpha::R15); 00365 } 00366 00367 if (NumBytes != 0) 00368 { 00369 if (NumBytes <= IMM_HIGH) { 00370 BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30).addImm(NumBytes) 00371 .addReg(Alpha::R30); 00372 } else if (getUpper16(NumBytes) <= IMM_HIGH) { 00373 BuildMI(MBB, MBBI, Alpha::LDAH, 2, Alpha::R30) 00374 .addImm(getUpper16(NumBytes)).addReg(Alpha::R30); 00375 BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30) 00376 .addImm(getLower16(NumBytes)).addReg(Alpha::R30); 00377 } else { 00378 std::cerr << "Too big a stack frame at " << NumBytes << "\n"; 00379 abort(); 00380 } 00381 } 00382 } 00383 00384 unsigned AlphaRegisterInfo::getRARegister() const { 00385 assert(0 && "What is the return address register"); 00386 return 0; 00387 } 00388 00389 unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const { 00390 return hasFP(MF) ? Alpha::R15 : Alpha::R30; 00391 } 00392 00393 #include "AlphaGenRegisterInfo.inc" 00394 00395 std::string AlphaRegisterInfo::getPrettyName(unsigned reg) 00396 { 00397 std::string s(RegisterDescriptors[reg].Name); 00398 return s; 00399 }