LLVM API Documentation

SparcRegisterInfo.cpp

Go to the documentation of this file.
00001 //===- SparcRegisterInfo.cpp - SPARC 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 SPARC implementation of the MRegisterInfo class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "Sparc.h"
00015 #include "SparcRegisterInfo.h"
00016 #include "SparcSubtarget.h"
00017 #include "llvm/CodeGen/MachineInstrBuilder.h"
00018 #include "llvm/CodeGen/MachineFunction.h"
00019 #include "llvm/CodeGen/MachineFrameInfo.h"
00020 #include "llvm/CodeGen/MachineLocation.h"
00021 #include "llvm/Type.h"
00022 #include "llvm/ADT/STLExtras.h"
00023 #include <iostream>
00024 using namespace llvm;
00025 
00026 SparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st)
00027   : SparcGenRegisterInfo(SP::ADJCALLSTACKDOWN, SP::ADJCALLSTACKUP),
00028     Subtarget(st) {
00029 }
00030 
00031 void SparcRegisterInfo::
00032 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00033                     unsigned SrcReg, int FI,
00034                     const TargetRegisterClass *RC) const {
00035   // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
00036   if (RC == SP::IntRegsRegisterClass)
00037     BuildMI(MBB, I, SP::STri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg);
00038   else if (RC == SP::FPRegsRegisterClass)
00039     BuildMI(MBB, I, SP::STFri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg);
00040   else if (RC == SP::DFPRegsRegisterClass)
00041     BuildMI(MBB, I, SP::STDFri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg);
00042   else
00043     assert(0 && "Can't store this register to stack slot");
00044 }
00045 
00046 void SparcRegisterInfo::
00047 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
00048                      unsigned DestReg, int FI,
00049                      const TargetRegisterClass *RC) const {
00050   if (RC == SP::IntRegsRegisterClass)
00051     BuildMI(MBB, I, SP::LDri, 2, DestReg).addFrameIndex(FI).addImm(0);
00052   else if (RC == SP::FPRegsRegisterClass)
00053     BuildMI(MBB, I, SP::LDFri, 2, DestReg).addFrameIndex(FI).addImm (0);
00054   else if (RC == SP::DFPRegsRegisterClass)
00055     BuildMI(MBB, I, SP::LDDFri, 2, DestReg).addFrameIndex(FI).addImm(0);
00056   else
00057     assert(0 && "Can't load this register from stack slot");
00058 }
00059 
00060 void SparcRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
00061                                      MachineBasicBlock::iterator I,
00062                                      unsigned DestReg, unsigned SrcReg,
00063                                      const TargetRegisterClass *RC) const {
00064   if (RC == SP::IntRegsRegisterClass)
00065     BuildMI(MBB, I, SP::ORrr, 2, DestReg).addReg(SP::G0).addReg(SrcReg);
00066   else if (RC == SP::FPRegsRegisterClass)
00067     BuildMI(MBB, I, SP::FMOVS, 1, DestReg).addReg(SrcReg);
00068   else if (RC == SP::DFPRegsRegisterClass)
00069     BuildMI(MBB, I, Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD,
00070             1, DestReg).addReg(SrcReg);
00071   else
00072     assert (0 && "Can't copy this register");
00073 }
00074 
00075 MachineInstr *SparcRegisterInfo::foldMemoryOperand(MachineInstr* MI,
00076                                                    unsigned OpNum,
00077                                                    int FI) const {
00078   bool isFloat = false;
00079   switch (MI->getOpcode()) {
00080   case SP::ORrr:
00081     if (MI->getOperand(1).isRegister() && MI->getOperand(1).getReg() == SP::G0&&
00082         MI->getOperand(0).isRegister() && MI->getOperand(2).isRegister()) {
00083       if (OpNum == 0)    // COPY -> STORE
00084         return BuildMI(SP::STri, 3).addFrameIndex(FI).addImm(0)
00085                                    .addReg(MI->getOperand(2).getReg());
00086       else               // COPY -> LOAD
00087         return BuildMI(SP::LDri, 2, MI->getOperand(0).getReg())
00088                       .addFrameIndex(FI).addImm(0);
00089     }
00090     break;
00091   case SP::FMOVS:
00092     isFloat = true;
00093     // FALLTHROUGH
00094   case SP::FMOVD:
00095     if (OpNum == 0)  // COPY -> STORE
00096       return BuildMI(isFloat ? SP::STFri : SP::STDFri, 3)
00097                .addFrameIndex(FI).addImm(0).addReg(MI->getOperand(1).getReg());
00098     else             // COPY -> LOAD
00099       return BuildMI(isFloat ? SP::LDFri : SP::LDDFri, 2, 
00100                      MI->getOperand(0).getReg()).addFrameIndex(FI).addImm(0);
00101     break;
00102   }
00103   return 0;
00104 }
00105 
00106 void SparcRegisterInfo::
00107 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
00108                               MachineBasicBlock::iterator I) const {
00109   MachineInstr &MI = *I;
00110   int Size = MI.getOperand(0).getImmedValue();
00111   if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)
00112     Size = -Size;
00113   if (Size)
00114     BuildMI(MBB, I, SP::ADDri, 2, SP::O6).addReg(SP::O6).addSImm(Size);
00115   MBB.erase(I);
00116 }
00117 
00118 void
00119 SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
00120   unsigned i = 0;
00121   MachineInstr &MI = *II;
00122   while (!MI.getOperand(i).isFrameIndex()) {
00123     ++i;
00124     assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
00125   }
00126 
00127   int FrameIndex = MI.getOperand(i).getFrameIndex();
00128 
00129   // Addressable stack objects are accessed using neg. offsets from %fp
00130   MachineFunction &MF = *MI.getParent()->getParent();
00131   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
00132                MI.getOperand(i+1).getImmedValue();
00133 
00134   // Replace frame index with a frame pointer reference.
00135   if (Offset >= -4096 && Offset <= 4095) {
00136     // If the offset is small enough to fit in the immediate field, directly
00137     // encode it.
00138     MI.SetMachineOperandReg(i, SP::I6);
00139     MI.SetMachineOperandConst(i+1, MachineOperand::MO_SignExtendedImmed,Offset);
00140   } else {
00141     // Otherwise, emit a G1 = SETHI %hi(offset).  FIXME: it would be better to 
00142     // scavenge a register here instead of reserving G1 all of the time.
00143     unsigned OffHi = (unsigned)Offset >> 10U;
00144     BuildMI(*MI.getParent(), II, SP::SETHIi, 1, SP::G1).addImm(OffHi);
00145     // Emit G1 = G1 + I6
00146     BuildMI(*MI.getParent(), II, SP::ADDrr, 2, 
00147             SP::G1).addReg(SP::G1).addReg(SP::I6);
00148     // Insert: G1+%lo(offset) into the user.
00149     MI.SetMachineOperandReg(i, SP::G1);
00150     MI.SetMachineOperandConst(i+1, MachineOperand::MO_SignExtendedImmed,
00151                               Offset & ((1 << 10)-1));
00152   }
00153 }
00154 
00155 void SparcRegisterInfo::
00156 processFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
00157 
00158 void SparcRegisterInfo::emitPrologue(MachineFunction &MF) const {
00159   MachineBasicBlock &MBB = MF.front();
00160   MachineFrameInfo *MFI = MF.getFrameInfo();
00161 
00162   // Get the number of bytes to allocate from the FrameInfo
00163   int NumBytes = (int) MFI->getStackSize();
00164 
00165   // Emit the correct save instruction based on the number of bytes in
00166   // the frame. Minimum stack frame size according to V8 ABI is:
00167   //   16 words for register window spill
00168   //    1 word for address of returned aggregate-value
00169   // +  6 words for passing parameters on the stack
00170   // ----------
00171   //   23 words * 4 bytes per word = 92 bytes
00172   NumBytes += 92;
00173   // Round up to next doubleword boundary -- a double-word boundary
00174   // is required by the ABI.
00175   NumBytes = (NumBytes + 7) & ~7;
00176   NumBytes = -NumBytes;
00177   
00178   if (NumBytes >= -4096) {
00179     BuildMI(MBB, MBB.begin(), SP::SAVEri, 2,
00180             SP::O6).addImm(NumBytes).addReg(SP::O6);
00181   } else {
00182     MachineBasicBlock::iterator InsertPt = MBB.begin();
00183     // Emit this the hard way.  This clobbers G1 which we always know is 
00184     // available here.
00185     unsigned OffHi = (unsigned)NumBytes >> 10U;
00186     BuildMI(MBB, InsertPt, SP::SETHIi, 1, SP::G1).addImm(OffHi);
00187     // Emit G1 = G1 + I6
00188     BuildMI(MBB, InsertPt, SP::ORri, 2, SP::G1)
00189       .addReg(SP::G1).addImm(NumBytes & ((1 << 10)-1));
00190     BuildMI(MBB, InsertPt, SP::SAVErr, 2,
00191             SP::O6).addReg(SP::O6).addReg(SP::G1);
00192   }
00193 }
00194 
00195 void SparcRegisterInfo::emitEpilogue(MachineFunction &MF,
00196                                      MachineBasicBlock &MBB) const {
00197   MachineBasicBlock::iterator MBBI = prior(MBB.end());
00198   assert(MBBI->getOpcode() == SP::RETL &&
00199          "Can only put epilog before 'retl' instruction!");
00200   BuildMI(MBB, MBBI, SP::RESTORErr, 2, SP::G0).addReg(SP::G0).addReg(SP::G0);
00201 }
00202 
00203 unsigned SparcRegisterInfo::getRARegister() const {
00204   assert(0 && "What is the return address register");
00205   return 0;
00206 }
00207 
00208 unsigned SparcRegisterInfo::getFrameRegister(MachineFunction &MF) const {
00209   assert(0 && "What is the frame register");
00210   return SP::G1;
00211 }
00212 
00213 #include "SparcGenRegisterInfo.inc"
00214