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 //===----------------------------------------------------------------------===// 00149 // Stack Frame Processing methods 00150 //===----------------------------------------------------------------------===// 00151 00152 // hasFP - Return true if the specified function should have a dedicated frame 00153 // pointer register. This is true if the function has variable sized allocas or 00154 // if frame pointer elimination is disabled. 00155 // 00156 static bool hasFP(MachineFunction &MF) { 00157 MachineFrameInfo *MFI = MF.getFrameInfo(); 00158 return MFI->hasVarSizedObjects(); 00159 } 00160 00161 void AlphaRegisterInfo:: 00162 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 00163 MachineBasicBlock::iterator I) const { 00164 if (hasFP(MF)) { 00165 // If we have a frame pointer, turn the adjcallstackup instruction into a 00166 // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP, 00167 // <amt>' 00168 MachineInstr *Old = I; 00169 unsigned Amount = Old->getOperand(0).getImmedValue(); 00170 if (Amount != 0) { 00171 // We need to keep the stack aligned properly. To do this, we round the 00172 // amount of space needed for the outgoing arguments up to the next 00173 // alignment boundary. 00174 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 00175 Amount = (Amount+Align-1)/Align*Align; 00176 00177 MachineInstr *New; 00178 if (Old->getOpcode() == Alpha::ADJUSTSTACKDOWN) { 00179 New=BuildMI(Alpha::LDA, 2, Alpha::R30) 00180 .addImm(-Amount).addReg(Alpha::R30); 00181 } else { 00182 assert(Old->getOpcode() == Alpha::ADJUSTSTACKUP); 00183 New=BuildMI(Alpha::LDA, 2, Alpha::R30) 00184 .addImm(Amount).addReg(Alpha::R30); 00185 } 00186 00187 // Replace the pseudo instruction with a new instruction... 00188 MBB.insert(I, New); 00189 } 00190 } 00191 00192 MBB.erase(I); 00193 } 00194 00195 //Alpha has a slightly funny stack: 00196 //Args 00197 //<- incoming SP 00198 //fixed locals (and spills, callee saved, etc) 00199 //<- FP 00200 //variable locals 00201 //<- SP 00202 00203 void 00204 AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { 00205 unsigned i = 0; 00206 MachineInstr &MI = *II; 00207 MachineBasicBlock &MBB = *MI.getParent(); 00208 MachineFunction &MF = *MBB.getParent(); 00209 bool FP = hasFP(MF); 00210 00211 while (!MI.getOperand(i).isFrameIndex()) { 00212 ++i; 00213 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 00214 } 00215 00216 int FrameIndex = MI.getOperand(i).getFrameIndex(); 00217 00218 // Add the base register of R30 (SP) or R15 (FP). 00219 MI.SetMachineOperandReg(i + 1, FP ? Alpha::R15 : Alpha::R30); 00220 00221 // Now add the frame object offset to the offset from the virtual frame index. 00222 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 00223 00224 DEBUG(std::cerr << "FI: " << FrameIndex << " Offset: " << Offset << "\n"); 00225 00226 Offset += MF.getFrameInfo()->getStackSize(); 00227 00228 DEBUG(std::cerr << "Corrected Offset " << Offset << 00229 " for stack size: " << MF.getFrameInfo()->getStackSize() << "\n"); 00230 00231 if (Offset > IMM_HIGH || Offset < IMM_LOW) { 00232 DEBUG(std::cerr << "Unconditionally using R28 for evil purposes Offset: " << Offset << "\n"); 00233 //so in this case, we need to use a temporary register, and move the original 00234 //inst off the SP/FP 00235 //fix up the old: 00236 MI.SetMachineOperandReg(i + 1, Alpha::R28); 00237 MI.SetMachineOperandConst(i, MachineOperand::MO_SignExtendedImmed, 00238 getLower16(Offset)); 00239 //insert the new 00240 MachineInstr* nMI=BuildMI(Alpha::LDAH, 2, Alpha::R28) 00241 .addImm(getUpper16(Offset)).addReg(FP ? Alpha::R15 : Alpha::R30); 00242 MBB.insert(II, nMI); 00243 } else { 00244 MI.SetMachineOperandConst(i, MachineOperand::MO_SignExtendedImmed, Offset); 00245 } 00246 } 00247 00248 00249 void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const { 00250 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 00251 MachineBasicBlock::iterator MBBI = MBB.begin(); 00252 MachineFrameInfo *MFI = MF.getFrameInfo(); 00253 bool FP = hasFP(MF); 00254 00255 static int curgpdist = 0; 00256 00257 //handle GOP offset 00258 BuildMI(MBB, MBBI, Alpha::LDAHg, 3, Alpha::R29) 00259 .addGlobalAddress(const_cast<Function*>(MF.getFunction())) 00260 .addReg(Alpha::R27).addImm(++curgpdist); 00261 BuildMI(MBB, MBBI, Alpha::LDAg, 3, Alpha::R29) 00262 .addGlobalAddress(const_cast<Function*>(MF.getFunction())) 00263 .addReg(Alpha::R29).addImm(curgpdist); 00264 00265 //evil const_cast until MO stuff setup to handle const 00266 BuildMI(MBB, MBBI, Alpha::ALTENT, 1).addGlobalAddress(const_cast<Function*>(MF.getFunction()), true); 00267 00268 // Get the number of bytes to allocate from the FrameInfo 00269 long NumBytes = MFI->getStackSize(); 00270 00271 if (MFI->hasCalls() && !FP) { 00272 // We reserve argument space for call sites in the function immediately on 00273 // entry to the current function. This eliminates the need for add/sub 00274 // brackets around call sites. 00275 //If there is a frame pointer, then we don't do this 00276 NumBytes += MFI->getMaxCallFrameSize(); 00277 DEBUG(std::cerr << "Added " << MFI->getMaxCallFrameSize() 00278 << " to the stack due to calls\n"); 00279 } 00280 00281 if (FP) 00282 NumBytes += 8; //reserve space for the old FP 00283 00284 // Do we need to allocate space on the stack? 00285 if (NumBytes == 0) return; 00286 00287 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); 00288 NumBytes = (NumBytes+Align-1)/Align*Align; 00289 00290 // Update frame info to pretend that this is part of the stack... 00291 MFI->setStackSize(NumBytes); 00292 00293 // adjust stack pointer: r30 -= numbytes 00294 NumBytes = -NumBytes; 00295 if (NumBytes >= IMM_LOW) { 00296 BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30).addImm(NumBytes) 00297 .addReg(Alpha::R30); 00298 } else if (getUpper16(NumBytes) >= IMM_LOW) { 00299 BuildMI(MBB, MBBI, Alpha::LDAH, 2, Alpha::R30).addImm(getUpper16(NumBytes)) 00300 .addReg(Alpha::R30); 00301 BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30).addImm(getLower16(NumBytes)) 00302 .addReg(Alpha::R30); 00303 } else { 00304 std::cerr << "Too big a stack frame at " << NumBytes << "\n"; 00305 abort(); 00306 } 00307 00308 //now if we need to, save the old FP and set the new 00309 if (FP) 00310 { 00311 BuildMI(MBB, MBBI, Alpha::STQ, 3).addReg(Alpha::R15).addImm(0).addReg(Alpha::R30); 00312 //this must be the last instr in the prolog 00313 BuildMI(MBB, MBBI, Alpha::BIS, 2, Alpha::R15).addReg(Alpha::R30).addReg(Alpha::R30); 00314 } 00315 00316 } 00317 00318 void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF, 00319 MachineBasicBlock &MBB) const { 00320 const MachineFrameInfo *MFI = MF.getFrameInfo(); 00321 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 00322 assert(MBBI->getOpcode() == Alpha::RETDAG 00323 && "Can only insert epilog into returning blocks"); 00324 00325 bool FP = hasFP(MF); 00326 00327 // Get the number of bytes allocated from the FrameInfo... 00328 long NumBytes = MFI->getStackSize(); 00329 00330 //now if we need to, restore the old FP 00331 if (FP) 00332 { 00333 //copy the FP into the SP (discards allocas) 00334 BuildMI(MBB, MBBI, Alpha::BIS, 2, Alpha::R30).addReg(Alpha::R15) 00335 .addReg(Alpha::R15); 00336 //restore the FP 00337 BuildMI(MBB, MBBI, Alpha::LDQ, 2, Alpha::R15).addImm(0).addReg(Alpha::R15); 00338 } 00339 00340 if (NumBytes != 0) 00341 { 00342 if (NumBytes <= IMM_HIGH) { 00343 BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30).addImm(NumBytes) 00344 .addReg(Alpha::R30); 00345 } else if (getUpper16(NumBytes) <= IMM_HIGH) { 00346 BuildMI(MBB, MBBI, Alpha::LDAH, 2, Alpha::R30) 00347 .addImm(getUpper16(NumBytes)).addReg(Alpha::R30); 00348 BuildMI(MBB, MBBI, Alpha::LDA, 2, Alpha::R30) 00349 .addImm(getLower16(NumBytes)).addReg(Alpha::R30); 00350 } else { 00351 std::cerr << "Too big a stack frame at " << NumBytes << "\n"; 00352 abort(); 00353 } 00354 } 00355 } 00356 00357 unsigned AlphaRegisterInfo::getRARegister() const { 00358 assert(0 && "What is the return address register"); 00359 return 0; 00360 } 00361 00362 unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const { 00363 return hasFP(MF) ? Alpha::R15 : Alpha::R30; 00364 } 00365 00366 #include "AlphaGenRegisterInfo.inc" 00367 00368 std::string AlphaRegisterInfo::getPrettyName(unsigned reg) 00369 { 00370 std::string s(RegisterDescriptors[reg].Name); 00371 return s; 00372 }