Home | History | Annotate | Download | only in MBlaze
      1 //===- MBlazeRegisterInfo.cpp - MBlaze Register Information -== -*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains the MBlaze implementation of the TargetRegisterInfo
     11 // class.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #define DEBUG_TYPE "mblaze-frame-info"
     16 
     17 #include "MBlaze.h"
     18 #include "MBlazeSubtarget.h"
     19 #include "MBlazeRegisterInfo.h"
     20 #include "MBlazeMachineFunction.h"
     21 #include "llvm/Constants.h"
     22 #include "llvm/Type.h"
     23 #include "llvm/Function.h"
     24 #include "llvm/CodeGen/ValueTypes.h"
     25 #include "llvm/CodeGen/MachineInstrBuilder.h"
     26 #include "llvm/CodeGen/MachineFunction.h"
     27 #include "llvm/CodeGen/MachineFrameInfo.h"
     28 #include "llvm/Target/TargetFrameLowering.h"
     29 #include "llvm/Target/TargetMachine.h"
     30 #include "llvm/Target/TargetOptions.h"
     31 #include "llvm/Target/TargetInstrInfo.h"
     32 #include "llvm/Support/CommandLine.h"
     33 #include "llvm/Support/Debug.h"
     34 #include "llvm/Support/ErrorHandling.h"
     35 #include "llvm/Support/raw_ostream.h"
     36 #include "llvm/ADT/BitVector.h"
     37 #include "llvm/ADT/STLExtras.h"
     38 
     39 #define GET_REGINFO_TARGET_DESC
     40 #include "MBlazeGenRegisterInfo.inc"
     41 
     42 using namespace llvm;
     43 
     44 MBlazeRegisterInfo::
     45 MBlazeRegisterInfo(const MBlazeSubtarget &ST, const TargetInstrInfo &tii)
     46   : MBlazeGenRegisterInfo(MBlaze::R15), Subtarget(ST), TII(tii) {}
     47 
     48 unsigned MBlazeRegisterInfo::getPICCallReg() {
     49   return MBlaze::R20;
     50 }
     51 
     52 //===----------------------------------------------------------------------===//
     53 // Callee Saved Registers methods
     54 //===----------------------------------------------------------------------===//
     55 
     56 /// MBlaze Callee Saved Registers
     57 const unsigned* MBlazeRegisterInfo::
     58 getCalleeSavedRegs(const MachineFunction *MF) const {
     59   // MBlaze callee-save register range is R20 - R31
     60   static const unsigned CalleeSavedRegs[] = {
     61     MBlaze::R20, MBlaze::R21, MBlaze::R22, MBlaze::R23,
     62     MBlaze::R24, MBlaze::R25, MBlaze::R26, MBlaze::R27,
     63     MBlaze::R28, MBlaze::R29, MBlaze::R30, MBlaze::R31,
     64     0
     65   };
     66 
     67   return CalleeSavedRegs;
     68 }
     69 
     70 BitVector MBlazeRegisterInfo::
     71 getReservedRegs(const MachineFunction &MF) const {
     72   BitVector Reserved(getNumRegs());
     73   Reserved.set(MBlaze::R0);
     74   Reserved.set(MBlaze::R1);
     75   Reserved.set(MBlaze::R2);
     76   Reserved.set(MBlaze::R13);
     77   Reserved.set(MBlaze::R14);
     78   Reserved.set(MBlaze::R15);
     79   Reserved.set(MBlaze::R16);
     80   Reserved.set(MBlaze::R17);
     81   Reserved.set(MBlaze::R18);
     82   Reserved.set(MBlaze::R19);
     83   return Reserved;
     84 }
     85 
     86 // This function eliminate ADJCALLSTACKDOWN/ADJCALLSTACKUP pseudo instructions
     87 void MBlazeRegisterInfo::
     88 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
     89                               MachineBasicBlock::iterator I) const {
     90   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
     91 
     92   if (!TFI->hasReservedCallFrame(MF)) {
     93     // If we have a frame pointer, turn the adjcallstackup instruction into a
     94     // 'addi r1, r1, -<amt>' and the adjcallstackdown instruction into
     95     // 'addi r1, r1, <amt>'
     96     MachineInstr *Old = I;
     97     int Amount = Old->getOperand(0).getImm() + 4;
     98     if (Amount != 0) {
     99       // We need to keep the stack aligned properly.  To do this, we round the
    100       // amount of space needed for the outgoing arguments up to the next
    101       // alignment boundary.
    102       unsigned Align = TFI->getStackAlignment();
    103       Amount = (Amount+Align-1)/Align*Align;
    104 
    105       MachineInstr *New;
    106       if (Old->getOpcode() == MBlaze::ADJCALLSTACKDOWN) {
    107         New = BuildMI(MF,Old->getDebugLoc(),TII.get(MBlaze::ADDIK),MBlaze::R1)
    108                 .addReg(MBlaze::R1).addImm(-Amount);
    109       } else {
    110         assert(Old->getOpcode() == MBlaze::ADJCALLSTACKUP);
    111         New = BuildMI(MF,Old->getDebugLoc(),TII.get(MBlaze::ADDIK),MBlaze::R1)
    112                 .addReg(MBlaze::R1).addImm(Amount);
    113       }
    114 
    115       // Replace the pseudo instruction with a new instruction...
    116       MBB.insert(I, New);
    117     }
    118   }
    119 
    120   // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
    121   MBB.erase(I);
    122 }
    123 
    124 // FrameIndex represent objects inside a abstract stack.
    125 // We must replace FrameIndex with an stack/frame pointer
    126 // direct reference.
    127 void MBlazeRegisterInfo::
    128 eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
    129                     RegScavenger *RS) const {
    130   MachineInstr &MI = *II;
    131   MachineFunction &MF = *MI.getParent()->getParent();
    132   MachineFrameInfo *MFI = MF.getFrameInfo();
    133 
    134   unsigned i = 0;
    135   while (!MI.getOperand(i).isFI()) {
    136     ++i;
    137     assert(i < MI.getNumOperands() &&
    138            "Instr doesn't have FrameIndex operand!");
    139   }
    140 
    141   unsigned oi = i == 2 ? 1 : 2;
    142 
    143   DEBUG(dbgs() << "\nFunction : " << MF.getFunction()->getName() << "\n";
    144         dbgs() << "<--------->\n" << MI);
    145 
    146   int FrameIndex = MI.getOperand(i).getIndex();
    147   int stackSize  = MFI->getStackSize();
    148   int spOffset   = MFI->getObjectOffset(FrameIndex);
    149 
    150   DEBUG(MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
    151         dbgs() << "FrameIndex : " << FrameIndex << "\n"
    152                << "spOffset   : " << spOffset << "\n"
    153                << "stackSize  : " << stackSize << "\n"
    154                << "isFixed    : " << MFI->isFixedObjectIndex(FrameIndex) << "\n"
    155                << "isLiveIn   : " << MBlazeFI->isLiveIn(FrameIndex) << "\n"
    156                << "isSpill    : " << MFI->isSpillSlotObjectIndex(FrameIndex)
    157                << "\n" );
    158 
    159   // as explained on LowerFormalArguments, detect negative offsets
    160   // and adjust SPOffsets considering the final stack size.
    161   int Offset = (spOffset < 0) ? (stackSize - spOffset) : spOffset;
    162   Offset += MI.getOperand(oi).getImm();
    163 
    164   DEBUG(dbgs() << "Offset     : " << Offset << "\n" << "<--------->\n");
    165 
    166   MI.getOperand(oi).ChangeToImmediate(Offset);
    167   MI.getOperand(i).ChangeToRegister(getFrameRegister(MF), false);
    168 }
    169 
    170 void MBlazeRegisterInfo::
    171 processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
    172   // Set the stack offset where GP must be saved/loaded from.
    173   MachineFrameInfo *MFI = MF.getFrameInfo();
    174   MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>();
    175   if (MBlazeFI->needGPSaveRestore())
    176     MFI->setObjectOffset(MBlazeFI->getGPFI(), MBlazeFI->getGPStackOffset());
    177 }
    178 
    179 unsigned MBlazeRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
    180   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
    181 
    182   return TFI->hasFP(MF) ? MBlaze::R19 : MBlaze::R1;
    183 }
    184 
    185 unsigned MBlazeRegisterInfo::getEHExceptionRegister() const {
    186   llvm_unreachable("What is the exception register");
    187   return 0;
    188 }
    189 
    190 unsigned MBlazeRegisterInfo::getEHHandlerRegister() const {
    191   llvm_unreachable("What is the exception handler register");
    192   return 0;
    193 }
    194