LLVM API Documentation

AlphaRegisterInfo.cpp

Go to the documentation of this file.
00001 //===- AlphaRegisterInfo.cpp - Alpha Register Information -------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the Alpha implementation of the TargetRegisterInfo 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/Target/TargetInstrInfo.h"
00029 #include "llvm/Support/CommandLine.h"
00030 #include "llvm/Support/Debug.h"
00031 #include "llvm/ADT/BitVector.h"
00032 #include "llvm/ADT/STLExtras.h"
00033 #include <cstdlib>
00034 using namespace llvm;
00035 
00036 //These describe LDAx
00037 static const int IMM_LOW  = -32768;
00038 static const int IMM_HIGH = 32767;
00039 static const int IMM_MULT = 65536;
00040 
00041 static long getUpper16(long l)
00042 {
00043   long y = l / IMM_MULT;
00044   if (l % IMM_MULT > IMM_HIGH)
00045     ++y;
00046   return y;
00047 }
00048 
00049 static long getLower16(long l)
00050 {
00051   long h = getUpper16(l);
00052   return l - h * IMM_MULT;
00053 }
00054 
00055 AlphaRegisterInfo::AlphaRegisterInfo(const TargetInstrInfo &tii)
00056   : AlphaGenRegisterInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP),
00057     TII(tii)
00058 {
00059 }
00060 
00061 const unsigned* AlphaRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
00062                                                                          const {
00063   static const unsigned CalleeSavedRegs[] = {
00064     Alpha::R9, Alpha::R10,
00065     Alpha::R11, Alpha::R12,
00066     Alpha::R13, Alpha::R14,
00067     Alpha::F2, Alpha::F3,
00068     Alpha::F4, Alpha::F5,
00069     Alpha::F6, Alpha::F7,
00070     Alpha::F8, Alpha::F9,  0
00071   };
00072   return CalleeSavedRegs;
00073 }
00074 
00075 const TargetRegisterClass* const*
00076 AlphaRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
00077   static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
00078     &Alpha::GPRCRegClass, &Alpha::GPRCRegClass,
00079     &Alpha::GPRCRegClass, &Alpha::GPRCRegClass,
00080     &Alpha::GPRCRegClass, &Alpha::GPRCRegClass,
00081     &Alpha::F8RCRegClass, &Alpha::F8RCRegClass,
00082     &Alpha::F8RCRegClass, &Alpha::F8RCRegClass,
00083     &Alpha::F8RCRegClass, &Alpha::F8RCRegClass,
00084     &Alpha::F8RCRegClass, &Alpha::F8RCRegClass,  0
00085   };
00086   return CalleeSavedRegClasses;
00087 }
00088 
00089 BitVector AlphaRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
00090   BitVector Reserved(getNumRegs());
00091   Reserved.set(Alpha::R15);
00092   Reserved.set(Alpha::R30);
00093   Reserved.set(Alpha::R31);
00094   return Reserved;
00095 }
00096 
00097 //===----------------------------------------------------------------------===//
00098 // Stack Frame Processing methods
00099 //===----------------------------------------------------------------------===//
00100 
00101 // hasFP - Return true if the specified function should have a dedicated frame
00102 // pointer register.  This is true if the function has variable sized allocas or
00103 // if frame pointer elimination is disabled.
00104 //
00105 bool AlphaRegisterInfo::hasFP(const MachineFunction &MF) const {
00106   const MachineFrameInfo *MFI = MF.getFrameInfo();
00107   return MFI->hasVarSizedObjects();
00108 }
00109 
00110 void AlphaRegisterInfo::
00111 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
00112                               MachineBasicBlock::iterator I) const {
00113   if (hasFP(MF)) {
00114     // If we have a frame pointer, turn the adjcallstackup instruction into a
00115     // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP,
00116     // <amt>'
00117     MachineInstr *Old = I;
00118     uint64_t Amount = Old->getOperand(0).getImm();
00119     if (Amount != 0) {
00120       // We need to keep the stack aligned properly.  To do this, we round the
00121       // amount of space needed for the outgoing arguments up to the next
00122       // alignment boundary.
00123       unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
00124       Amount = (Amount+Align-1)/Align*Align;
00125 
00126       MachineInstr *New;
00127       if (Old->getOpcode() == Alpha::ADJUSTSTACKDOWN) {
00128         New=BuildMI(MF, TII.get(Alpha::LDA), Alpha::R30)
00129           .addImm(-Amount).addReg(Alpha::R30);
00130       } else {
00131          assert(Old->getOpcode() == Alpha::ADJUSTSTACKUP);
00132          New=BuildMI(MF, TII.get(Alpha::LDA), Alpha::R30)
00133           .addImm(Amount).addReg(Alpha::R30);
00134       }
00135 
00136       // Replace the pseudo instruction with a new instruction...
00137       MBB.insert(I, New);
00138     }
00139   }
00140 
00141   MBB.erase(I);
00142 }
00143 
00144 //Alpha has a slightly funny stack:
00145 //Args
00146 //<- incoming SP
00147 //fixed locals (and spills, callee saved, etc)
00148 //<- FP
00149 //variable locals
00150 //<- SP
00151 
00152 void AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
00153                                             int SPAdj, RegScavenger *RS) const {
00154   assert(SPAdj == 0 && "Unexpected");
00155 
00156   unsigned i = 0;
00157   MachineInstr &MI = *II;
00158   MachineBasicBlock &MBB = *MI.getParent();
00159   MachineFunction &MF = *MBB.getParent();
00160   bool FP = hasFP(MF);
00161 
00162   while (!MI.getOperand(i).isFI()) {
00163     ++i;
00164     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
00165   }
00166 
00167   int FrameIndex = MI.getOperand(i).getIndex();
00168 
00169   // Add the base register of R30 (SP) or R15 (FP).
00170   MI.getOperand(i + 1).ChangeToRegister(FP ? Alpha::R15 : Alpha::R30, false);
00171 
00172   // Now add the frame object offset to the offset from the virtual frame index.
00173   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
00174 
00175   DOUT << "FI: " << FrameIndex << " Offset: " << Offset << "\n";
00176 
00177   Offset += MF.getFrameInfo()->getStackSize();
00178 
00179   DOUT << "Corrected Offset " << Offset
00180        << " for stack size: " << MF.getFrameInfo()->getStackSize() << "\n";
00181 
00182   if (Offset > IMM_HIGH || Offset < IMM_LOW) {
00183     DOUT << "Unconditionally using R28 for evil purposes Offset: "
00184          << Offset << "\n";
00185     //so in this case, we need to use a temporary register, and move the
00186     //original inst off the SP/FP
00187     //fix up the old:
00188     MI.getOperand(i + 1).ChangeToRegister(Alpha::R28, false);
00189     MI.getOperand(i).ChangeToImmediate(getLower16(Offset));
00190     //insert the new
00191     MachineInstr* nMI=BuildMI(MF, TII.get(Alpha::LDAH), Alpha::R28)
00192       .addImm(getUpper16(Offset)).addReg(FP ? Alpha::R15 : Alpha::R30);
00193     MBB.insert(II, nMI);
00194   } else {
00195     MI.getOperand(i).ChangeToImmediate(Offset);
00196   }
00197 }
00198 
00199 
00200 void AlphaRegisterInfo::emitPrologue(MachineFunction &MF) const {
00201   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
00202   MachineBasicBlock::iterator MBBI = MBB.begin();
00203   MachineFrameInfo *MFI = MF.getFrameInfo();
00204   bool FP = hasFP(MF);
00205 
00206   static int curgpdist = 0;
00207 
00208   //handle GOP offset
00209   BuildMI(MBB, MBBI, TII.get(Alpha::LDAHg), Alpha::R29)
00210     .addGlobalAddress(const_cast<Function*>(MF.getFunction()))
00211     .addReg(Alpha::R27).addImm(++curgpdist);
00212   BuildMI(MBB, MBBI, TII.get(Alpha::LDAg), Alpha::R29)
00213     .addGlobalAddress(const_cast<Function*>(MF.getFunction()))
00214     .addReg(Alpha::R29).addImm(curgpdist);
00215 
00216   //evil const_cast until MO stuff setup to handle const
00217   BuildMI(MBB, MBBI, TII.get(Alpha::ALTENT))
00218     .addGlobalAddress(const_cast<Function*>(MF.getFunction()));
00219 
00220   // Get the number of bytes to allocate from the FrameInfo
00221   long NumBytes = MFI->getStackSize();
00222 
00223   if (FP)
00224     NumBytes += 8; //reserve space for the old FP
00225 
00226   // Do we need to allocate space on the stack?
00227   if (NumBytes == 0) return;
00228 
00229   unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
00230   NumBytes = (NumBytes+Align-1)/Align*Align;
00231 
00232   // Update frame info to pretend that this is part of the stack...
00233   MFI->setStackSize(NumBytes);
00234 
00235   // adjust stack pointer: r30 -= numbytes
00236   NumBytes = -NumBytes;
00237   if (NumBytes >= IMM_LOW) {
00238     BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes)
00239       .addReg(Alpha::R30);
00240   } else if (getUpper16(NumBytes) >= IMM_LOW) {
00241     BuildMI(MBB, MBBI, TII.get(Alpha::LDAH), Alpha::R30).addImm(getUpper16(NumBytes))
00242       .addReg(Alpha::R30);
00243     BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30).addImm(getLower16(NumBytes))
00244       .addReg(Alpha::R30);
00245   } else {
00246     cerr << "Too big a stack frame at " << NumBytes << "\n";
00247     abort();
00248   }
00249 
00250   //now if we need to, save the old FP and set the new
00251   if (FP)
00252   {
00253     BuildMI(MBB, MBBI, TII.get(Alpha::STQ))
00254       .addReg(Alpha::R15).addImm(0).addReg(Alpha::R30);
00255     //this must be the last instr in the prolog
00256     BuildMI(MBB, MBBI, TII.get(Alpha::BISr), Alpha::R15)
00257       .addReg(Alpha::R30).addReg(Alpha::R30);
00258   }
00259 
00260 }
00261 
00262 void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF,
00263                                      MachineBasicBlock &MBB) const {
00264   const MachineFrameInfo *MFI = MF.getFrameInfo();
00265   MachineBasicBlock::iterator MBBI = prior(MBB.end());
00266   assert((MBBI->getOpcode() == Alpha::RETDAG ||
00267           MBBI->getOpcode() == Alpha::RETDAGp)
00268          && "Can only insert epilog into returning blocks");
00269 
00270   bool FP = hasFP(MF);
00271 
00272   // Get the number of bytes allocated from the FrameInfo...
00273   long NumBytes = MFI->getStackSize();
00274 
00275   //now if we need to, restore the old FP
00276   if (FP) {
00277     //copy the FP into the SP (discards allocas)
00278     BuildMI(MBB, MBBI, TII.get(Alpha::BISr), Alpha::R30).addReg(Alpha::R15)
00279       .addReg(Alpha::R15);
00280     //restore the FP
00281     BuildMI(MBB, MBBI, TII.get(Alpha::LDQ), Alpha::R15).addImm(0).addReg(Alpha::R15);
00282   }
00283 
00284   if (NumBytes != 0) {
00285     if (NumBytes <= IMM_HIGH) {
00286       BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30).addImm(NumBytes)
00287         .addReg(Alpha::R30);
00288     } else if (getUpper16(NumBytes) <= IMM_HIGH) {
00289       BuildMI(MBB, MBBI, TII.get(Alpha::LDAH), Alpha::R30)
00290         .addImm(getUpper16(NumBytes)).addReg(Alpha::R30);
00291       BuildMI(MBB, MBBI, TII.get(Alpha::LDA), Alpha::R30)
00292         .addImm(getLower16(NumBytes)).addReg(Alpha::R30);
00293     } else {
00294       cerr << "Too big a stack frame at " << NumBytes << "\n";
00295       abort();
00296     }
00297   }
00298 }
00299 
00300 unsigned AlphaRegisterInfo::getRARegister() const {
00301   assert(0 && "What is the return address register");
00302   return 0;
00303 }
00304 
00305 unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const {
00306   return hasFP(MF) ? Alpha::R15 : Alpha::R30;
00307 }
00308 
00309 unsigned AlphaRegisterInfo::getEHExceptionRegister() const {
00310   assert(0 && "What is the exception register");
00311   return 0;
00312 }
00313 
00314 unsigned AlphaRegisterInfo::getEHHandlerRegister() const {
00315   assert(0 && "What is the exception handler register");
00316   return 0;
00317 }
00318 
00319 int AlphaRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
00320   assert(0 && "What is the dwarf register number");
00321   return -1;
00322 }
00323 
00324 #include "AlphaGenRegisterInfo.inc"
00325 
00326 std::string AlphaRegisterInfo::getPrettyName(unsigned reg)
00327 {
00328   std::string s(RegisterDescriptors[reg].Name);
00329   return s;
00330 }