Home | History | Annotate | Download | only in Mips
      1 //===-- MipsSEFrameLowering.cpp - Mips32/64 Frame Information -------------===//
      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 Mips32/64 implementation of TargetFrameLowering class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "MipsSEFrameLowering.h"
     15 #include "MipsAnalyzeImmediate.h"
     16 #include "MipsSEInstrInfo.h"
     17 #include "MipsMachineFunction.h"
     18 #include "MCTargetDesc/MipsBaseInfo.h"
     19 #include "llvm/Function.h"
     20 #include "llvm/CodeGen/MachineFrameInfo.h"
     21 #include "llvm/CodeGen/MachineFunction.h"
     22 #include "llvm/CodeGen/MachineInstrBuilder.h"
     23 #include "llvm/CodeGen/MachineModuleInfo.h"
     24 #include "llvm/CodeGen/MachineRegisterInfo.h"
     25 #include "llvm/Target/TargetData.h"
     26 #include "llvm/Target/TargetOptions.h"
     27 #include "llvm/Support/CommandLine.h"
     28 
     29 using namespace llvm;
     30 
     31 void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const {
     32   MachineBasicBlock &MBB   = MF.front();
     33   MachineFrameInfo *MFI    = MF.getFrameInfo();
     34   const MipsRegisterInfo *RegInfo =
     35     static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo());
     36   const MipsSEInstrInfo &TII =
     37     *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
     38   MachineBasicBlock::iterator MBBI = MBB.begin();
     39   DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
     40   unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
     41   unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
     42   unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
     43   unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
     44 
     45   // First, compute final stack size.
     46   uint64_t StackSize = MFI->getStackSize();
     47 
     48   // No need to allocate space on the stack.
     49   if (StackSize == 0 && !MFI->adjustsStack()) return;
     50 
     51   MachineModuleInfo &MMI = MF.getMMI();
     52   std::vector<MachineMove> &Moves = MMI.getFrameMoves();
     53   MachineLocation DstML, SrcML;
     54 
     55   // Adjust stack.
     56   TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
     57 
     58   // emit ".cfi_def_cfa_offset StackSize"
     59   MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol();
     60   BuildMI(MBB, MBBI, dl,
     61           TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel);
     62   DstML = MachineLocation(MachineLocation::VirtualFP);
     63   SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize);
     64   Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML));
     65 
     66   const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
     67 
     68   if (CSI.size()) {
     69     // Find the instruction past the last instruction that saves a callee-saved
     70     // register to the stack.
     71     for (unsigned i = 0; i < CSI.size(); ++i)
     72       ++MBBI;
     73 
     74     // Iterate over list of callee-saved registers and emit .cfi_offset
     75     // directives.
     76     MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol();
     77     BuildMI(MBB, MBBI, dl,
     78             TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel);
     79 
     80     for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
     81            E = CSI.end(); I != E; ++I) {
     82       int64_t Offset = MFI->getObjectOffset(I->getFrameIdx());
     83       unsigned Reg = I->getReg();
     84 
     85       // If Reg is a double precision register, emit two cfa_offsets,
     86       // one for each of the paired single precision registers.
     87       if (Mips::AFGR64RegClass.contains(Reg)) {
     88         MachineLocation DstML0(MachineLocation::VirtualFP, Offset);
     89         MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4);
     90         MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven));
     91         MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd));
     92 
     93         if (!STI.isLittle())
     94           std::swap(SrcML0, SrcML1);
     95 
     96         Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0));
     97         Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1));
     98       } else {
     99         // Reg is either in CPURegs or FGR32.
    100         DstML = MachineLocation(MachineLocation::VirtualFP, Offset);
    101         SrcML = MachineLocation(Reg);
    102         Moves.push_back(MachineMove(CSLabel, DstML, SrcML));
    103       }
    104     }
    105   }
    106 
    107   // if framepointer enabled, set it to point to the stack pointer.
    108   if (hasFP(MF)) {
    109     // Insert instruction "move $fp, $sp" at this location.
    110     BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO);
    111 
    112     // emit ".cfi_def_cfa_register $fp"
    113     MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol();
    114     BuildMI(MBB, MBBI, dl,
    115             TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel);
    116     DstML = MachineLocation(FP);
    117     SrcML = MachineLocation(MachineLocation::VirtualFP);
    118     Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML));
    119   }
    120 }
    121 
    122 void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,
    123                                        MachineBasicBlock &MBB) const {
    124   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
    125   MachineFrameInfo *MFI            = MF.getFrameInfo();
    126   const MipsSEInstrInfo &TII =
    127     *static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
    128   DebugLoc dl = MBBI->getDebugLoc();
    129   unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
    130   unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
    131   unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
    132   unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
    133 
    134   // if framepointer enabled, restore the stack pointer.
    135   if (hasFP(MF)) {
    136     // Find the first instruction that restores a callee-saved register.
    137     MachineBasicBlock::iterator I = MBBI;
    138 
    139     for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i)
    140       --I;
    141 
    142     // Insert instruction "move $sp, $fp" at this location.
    143     BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO);
    144   }
    145 
    146   // Get the number of bytes from FrameInfo
    147   uint64_t StackSize = MFI->getStackSize();
    148 
    149   if (!StackSize)
    150     return;
    151 
    152   // Adjust stack.
    153   TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
    154 }
    155 
    156 bool MipsSEFrameLowering::
    157 spillCalleeSavedRegisters(MachineBasicBlock &MBB,
    158                           MachineBasicBlock::iterator MI,
    159                           const std::vector<CalleeSavedInfo> &CSI,
    160                           const TargetRegisterInfo *TRI) const {
    161   MachineFunction *MF = MBB.getParent();
    162   MachineBasicBlock *EntryBlock = MF->begin();
    163   const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
    164 
    165   for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
    166     // Add the callee-saved register as live-in. Do not add if the register is
    167     // RA and return address is taken, because it has already been added in
    168     // method MipsTargetLowering::LowerRETURNADDR.
    169     // It's killed at the spill, unless the register is RA and return address
    170     // is taken.
    171     unsigned Reg = CSI[i].getReg();
    172     bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)
    173         && MF->getFrameInfo()->isReturnAddressTaken();
    174     if (!IsRAAndRetAddrIsTaken)
    175       EntryBlock->addLiveIn(Reg);
    176 
    177     // Insert the spill to the stack frame.
    178     bool IsKill = !IsRAAndRetAddrIsTaken;
    179     const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
    180     TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill,
    181                             CSI[i].getFrameIdx(), RC, TRI);
    182   }
    183 
    184   return true;
    185 }
    186 
    187 bool
    188 MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
    189   const MachineFrameInfo *MFI = MF.getFrameInfo();
    190 
    191   // Reserve call frame if the size of the maximum call frame fits into 16-bit
    192   // immediate field and there are no variable sized objects on the stack.
    193   return isInt<16>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects();
    194 }
    195 
    196 void MipsSEFrameLowering::
    197 processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
    198                                      RegScavenger *RS) const {
    199   MachineRegisterInfo &MRI = MF.getRegInfo();
    200   unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP;
    201 
    202   // Mark $fp as used if function has dedicated frame pointer.
    203   if (hasFP(MF))
    204     MRI.setPhysRegUsed(FP);
    205 }
    206 
    207 const MipsFrameLowering *
    208 llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) {
    209   return new MipsSEFrameLowering(ST);
    210 }
    211