118334Speter//===- Mips16FrameLowering.cpp - Mips16 Frame Information -----------------===// 218334Speter// 318334Speter// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 490075Sobrien// See https://llvm.org/LICENSE.txt for license information. 590075Sobrien// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 618334Speter// 718334Speter//===----------------------------------------------------------------------===// 890075Sobrien// 918334Speter// This file contains the Mips16 implementation of TargetFrameLowering class. 1090075Sobrien// 1190075Sobrien//===----------------------------------------------------------------------===// 1290075Sobrien 1390075Sobrien#include "Mips16FrameLowering.h" 1418334Speter#include "MCTargetDesc/MipsBaseInfo.h" 1590075Sobrien#include "Mips16InstrInfo.h" 1690075Sobrien#include "MipsInstrInfo.h" 1790075Sobrien#include "MipsRegisterInfo.h" 1890075Sobrien#include "MipsSubtarget.h" 1918334Speter#include "llvm/ADT/BitVector.h" 2018334Speter#include "llvm/CodeGen/MachineBasicBlock.h" 2190075Sobrien#include "llvm/CodeGen/MachineFrameInfo.h" 2290075Sobrien#include "llvm/CodeGen/MachineFunction.h" 2390075Sobrien#include "llvm/CodeGen/MachineInstr.h" 2418334Speter#include "llvm/CodeGen/MachineInstrBuilder.h" 2518334Speter#include "llvm/CodeGen/MachineModuleInfo.h" 2650397Sobrien#include "llvm/IR/DebugLoc.h" 2752284Sobrien#include "llvm/MC/MCContext.h" 2818334Speter#include "llvm/MC/MCDwarf.h" 2918334Speter#include "llvm/MC/MCRegisterInfo.h" 3018334Speter#include "llvm/MC/MachineLocation.h" 3118334Speter#include "llvm/Support/MathExtras.h" 3218334Speter#include "llvm/CodeGen/TargetFrameLowering.h" 3318334Speter#include <cassert> 3418334Speter#include <cstdint> 3518334Speter#include <vector> 3618334Speter 3718334Speterusing namespace llvm; 3818334Speter 3918334SpeterMips16FrameLowering::Mips16FrameLowering(const MipsSubtarget &STI) 4052284Sobrien : MipsFrameLowering(STI, STI.getStackAlignment()) {} 4118334Speter 4290075Sobrienvoid Mips16FrameLowering::emitPrologue(MachineFunction &MF, 4390075Sobrien MachineBasicBlock &MBB) const { 4490075Sobrien MachineFrameInfo &MFI = MF.getFrameInfo(); 4590075Sobrien const Mips16InstrInfo &TII = 4690075Sobrien *static_cast<const Mips16InstrInfo *>(STI.getInstrInfo()); 4790075Sobrien MachineBasicBlock::iterator MBBI = MBB.begin(); 4818334Speter 4918334Speter // Debug location must be unknown since the first debug location is used 5018334Speter // to determine the end of the prologue. 5118334Speter DebugLoc dl; 5218334Speter 5318334Speter uint64_t StackSize = MFI.getStackSize(); 5418334Speter 5518334Speter // No need to allocate space on the stack. 5618334Speter if (StackSize == 0 && !MFI.adjustsStack()) return; 5718334Speter 5818334Speter MachineModuleInfo &MMI = MF.getMMI(); 5918334Speter const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 6018334Speter 6118334Speter // Adjust stack. 6218334Speter TII.makeFrame(Mips::SP, StackSize, MBB, MBBI); 6350397Sobrien 6452284Sobrien // emit ".cfi_def_cfa_offset StackSize" 6552284Sobrien unsigned CFIIndex = 6618334Speter MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize)); 6790075Sobrien BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) 6818334Speter .addCFIIndex(CFIIndex); 6918334Speter 7018334Speter const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 7118334Speter 7218334Speter if (!CSI.empty()) { 7318334Speter const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 7418334Speter 7518334Speter for (const CalleeSavedInfo &I : CSI) { 7618334Speter int64_t Offset = MFI.getObjectOffset(I.getFrameIdx()); 7718334Speter Register Reg = I.getReg(); 7818334Speter unsigned DReg = MRI->getDwarfRegNum(Reg, true); 7918334Speter unsigned CFIIndex = MF.addFrameInst( 8018334Speter MCCFIInstruction::createOffset(nullptr, DReg, Offset)); 8118334Speter BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) 8218334Speter .addCFIIndex(CFIIndex); 8318334Speter } 8418334Speter } 8518334Speter if (hasFP(MF)) 8618334Speter BuildMI(MBB, MBBI, dl, TII.get(Mips::MoveR3216), Mips::S0) 8718334Speter .addReg(Mips::SP).setMIFlag(MachineInstr::FrameSetup); 8818334Speter} 8918334Speter 9018334Spetervoid Mips16FrameLowering::emitEpilogue(MachineFunction &MF, 9118334Speter MachineBasicBlock &MBB) const { 9218334Speter MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(); 9390075Sobrien MachineFrameInfo &MFI = MF.getFrameInfo(); 9418334Speter const Mips16InstrInfo &TII = 9518334Speter *static_cast<const Mips16InstrInfo *>(STI.getInstrInfo()); 9618334Speter DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 9790075Sobrien uint64_t StackSize = MFI.getStackSize(); 9818334Speter 9990075Sobrien if (!StackSize) 10090075Sobrien return; 10118334Speter 10218334Speter if (hasFP(MF)) 10318334Speter BuildMI(MBB, MBBI, dl, TII.get(Mips::Move32R16), Mips::SP) 10418334Speter .addReg(Mips::S0); 10518334Speter 10618334Speter // Adjust stack. 10718334Speter // assumes stacksize multiple of 8 10850397Sobrien TII.restoreFrame(Mips::SP, StackSize, MBB, MBBI); 10918334Speter} 11052284Sobrien 11118334Speterbool Mips16FrameLowering::spillCalleeSavedRegisters( 11218334Speter MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 11318334Speter ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { 11418334Speter MachineFunction *MF = MBB.getParent(); 11552284Sobrien 11618334Speter // 11718334Speter // Registers RA, S0,S1 are the callee saved registers and they 11818334Speter // will be saved with the "save" instruction 11918334Speter // during emitPrologue 12018334Speter // 12118334Speter for (const CalleeSavedInfo &I : CSI) { 12218334Speter // Add the callee-saved register as live-in. Do not add if the register is 12318334Speter // RA and return address is taken, because it has already been added in 12452284Sobrien // method MipsTargetLowering::lowerRETURNADDR. 12518334Speter // It's killed at the spill, unless the register is RA and return address 12618334Speter // is taken. 12790075Sobrien Register Reg = I.getReg(); 12818334Speter bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA) 12918334Speter && MF->getFrameInfo().isReturnAddressTaken(); 13050397Sobrien if (!IsRAAndRetAddrIsTaken) 13150397Sobrien MBB.addLiveIn(Reg); 13290075Sobrien } 13390075Sobrien 13418334Speter return true; 13518334Speter} 13618334Speter 13718334Speterbool Mips16FrameLowering::restoreCalleeSavedRegisters( 13818334Speter MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 13918334Speter MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { 14018334Speter // 14118334Speter // Registers RA,S0,S1 are the callee saved registers and they will be restored 14218334Speter // with the restore instruction during emitEpilogue. 14318334Speter // We need to override this virtual function, otherwise llvm will try and 14418334Speter // restore the registers on it's on from the stack. 14518334Speter // 14618334Speter 14718334Speter return true; 14818334Speter} 14918334Speter 15018334Speterbool 15118334SpeterMips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 15218334Speter const MachineFrameInfo &MFI = MF.getFrameInfo(); 15318334Speter // Reserve call frame if the size of the maximum call frame fits into 15-bit 15418334Speter // immediate field and there are no variable sized objects on the stack. 15518334Speter return isInt<15>(MFI.getMaxCallFrameSize()) && !MFI.hasVarSizedObjects(); 15618334Speter} 15718334Speter 15818334Spetervoid Mips16FrameLowering::determineCalleeSaves(MachineFunction &MF, 15918334Speter BitVector &SavedRegs, 16018334Speter RegScavenger *RS) const { 16118334Speter TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 16218334Speter const Mips16InstrInfo &TII = 16318334Speter *static_cast<const Mips16InstrInfo *>(STI.getInstrInfo()); 16418334Speter const MipsRegisterInfo &RI = TII.getRegisterInfo(); 16518334Speter const BitVector Reserved = RI.getReservedRegs(MF); 16618334Speter bool SaveS2 = Reserved[Mips::S2]; 16718334Speter if (SaveS2) 16818334Speter SavedRegs.set(Mips::S2); 16918334Speter if (hasFP(MF)) 17018334Speter SavedRegs.set(Mips::S0); 17118334Speter} 17218334Speter 17318334Speterconst MipsFrameLowering * 17418334Speterllvm::createMips16FrameLowering(const MipsSubtarget &ST) { 17518334Speter return new Mips16FrameLowering(ST); 17618334Speter} 17718334Speter