391 lines · cpp
1//===- XtensaFrameLowering.cpp - Xtensa Frame Information -----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the Xtensa implementation of TargetFrameLowering class.10//11//===----------------------------------------------------------------------===//12 13#include "XtensaFrameLowering.h"14#include "XtensaInstrInfo.h"15#include "XtensaMachineFunctionInfo.h"16#include "XtensaSubtarget.h"17#include "llvm/CodeGen/MachineFrameInfo.h"18#include "llvm/CodeGen/MachineInstrBuilder.h"19#include "llvm/CodeGen/MachineModuleInfo.h"20#include "llvm/CodeGen/MachineRegisterInfo.h"21#include "llvm/CodeGen/RegisterScavenging.h"22#include "llvm/IR/Function.h"23 24using namespace llvm;25 26// Minimum frame = reg save area (4 words) plus static chain (1 word)27// and the total number of words must be a multiple of 128 bits.28// Width of a word, in units (bytes).29#define UNITS_PER_WORD 430#define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)31 32XtensaFrameLowering::XtensaFrameLowering(const XtensaSubtarget &STI)33 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(4), 0,34 Align(4)),35 STI(STI), TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}36 37bool XtensaFrameLowering::hasFPImpl(const MachineFunction &MF) const {38 const MachineFrameInfo &MFI = MF.getFrameInfo();39 return MF.getTarget().Options.DisableFramePointerElim(MF) ||40 MFI.hasVarSizedObjects();41}42 43void XtensaFrameLowering::emitPrologue(MachineFunction &MF,44 MachineBasicBlock &MBB) const {45 assert(&MBB == &MF.front() && "Shrink-wrapping not yet implemented");46 MachineFrameInfo &MFI = MF.getFrameInfo();47 MachineBasicBlock::iterator MBBI = MBB.begin();48 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();49 MCRegister SP = Xtensa::SP;50 MCRegister FP = TRI->getFrameRegister(MF);51 const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo();52 XtensaMachineFunctionInfo *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();53 54 // First, compute final stack size.55 uint64_t StackSize = MFI.getStackSize();56 uint64_t PrevStackSize = StackSize;57 58 // Round up StackSize to 16*N59 StackSize += (16 - StackSize) & 0xf;60 61 if (STI.isWindowedABI()) {62 StackSize += 32;63 uint64_t MaxAlignment = MFI.getMaxAlign().value();64 if (MaxAlignment > 32)65 StackSize += MaxAlignment;66 67 if (StackSize <= 32760) {68 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::ENTRY))69 .addReg(SP)70 .addImm(StackSize);71 } else {72 // Use a8 as a temporary since a0-a7 may be live.73 MCRegister TmpReg = Xtensa::A8;74 75 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::ENTRY))76 .addReg(SP)77 .addImm(MIN_FRAME_SIZE);78 TII.loadImmediate(MBB, MBBI, &TmpReg, StackSize - MIN_FRAME_SIZE);79 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::SUB), TmpReg)80 .addReg(SP)81 .addReg(TmpReg);82 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::MOVSP), SP).addReg(TmpReg);83 }84 85 // Calculate how much is needed to have the correct alignment.86 // Change offset to: alignment + difference.87 // For example, in case of alignment of 128:88 // diff_to_128_aligned_address = (128 - (SP & 127))89 // new_offset = SP + diff_to_128_aligned_address90 // This is safe to do because we increased the stack size by MaxAlignment.91 MCRegister Reg, RegMisAlign;92 if (MaxAlignment > 32) {93 TII.loadImmediate(MBB, MBBI, &RegMisAlign, MaxAlignment - 1);94 TII.loadImmediate(MBB, MBBI, &Reg, MaxAlignment);95 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::AND))96 .addReg(RegMisAlign, RegState::Define)97 .addReg(FP)98 .addReg(RegMisAlign);99 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::SUB), RegMisAlign)100 .addReg(Reg)101 .addReg(RegMisAlign);102 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::ADD), SP)103 .addReg(SP)104 .addReg(RegMisAlign, RegState::Kill);105 }106 107 // Store FP register in A8, because FP may be used to pass function108 // arguments109 if (XtensaFI->isSaveFrameRegister()) {110 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::OR), Xtensa::A8)111 .addReg(FP)112 .addReg(FP);113 }114 115 // if framepointer enabled, set it to point to the stack pointer.116 if (hasFP(MF)) {117 // Insert instruction "move $fp, $sp" at this location.118 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::OR), FP)119 .addReg(SP)120 .addReg(SP)121 .setMIFlag(MachineInstr::FrameSetup);122 123 MCCFIInstruction Inst = MCCFIInstruction::cfiDefCfa(124 nullptr, MRI->getDwarfRegNum(FP, true), StackSize);125 unsigned CFIIndex = MF.addFrameInst(Inst);126 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))127 .addCFIIndex(CFIIndex);128 } else {129 // emit ".cfi_def_cfa_offset StackSize"130 unsigned CFIIndex = MF.addFrameInst(131 MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize));132 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))133 .addCFIIndex(CFIIndex);134 }135 } else {136 // No need to allocate space on the stack.137 if (StackSize == 0 && !MFI.adjustsStack())138 return;139 140 // Adjust stack.141 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);142 143 // emit ".cfi_def_cfa_offset StackSize"144 unsigned CFIIndex =145 MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize));146 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))147 .addCFIIndex(CFIIndex);148 149 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();150 151 if (!CSI.empty()) {152 // Find the instruction past the last instruction that saves a153 // callee-saved register to the stack. The callee-saved store154 // instructions are placed at the begin of basic block, so155 // iterate over instruction sequence and check that156 // save instructions are placed correctly.157 for (unsigned i = 0, e = CSI.size(); i < e; ++i) {158#ifndef NDEBUG159 const CalleeSavedInfo &Info = CSI[i];160 int FI = Info.getFrameIdx();161 int StoreFI = 0;162 163 // Checking that the instruction is exactly as expected164 bool IsStoreInst = false;165 if (MBBI->getOpcode() == TargetOpcode::COPY && Info.isSpilledToReg()) {166 Register DstReg = MBBI->getOperand(0).getReg();167 Register Reg = MBBI->getOperand(1).getReg();168 IsStoreInst = Info.getDstReg() == DstReg.asMCReg() &&169 Info.getReg() == Reg.asMCReg();170 } else {171 Register Reg = TII.isStoreToStackSlot(*MBBI, StoreFI);172 IsStoreInst = Reg.asMCReg() == Info.getReg() && StoreFI == FI;173 }174 assert(IsStoreInst &&175 "Unexpected callee-saved register store instruction");176#endif177 ++MBBI;178 }179 180 // Iterate over list of callee-saved registers and emit .cfi_offset181 // directives.182 for (const auto &I : CSI) {183 int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());184 MCRegister Reg = I.getReg();185 186 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(187 nullptr, MRI->getDwarfRegNum(Reg, 1), Offset));188 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))189 .addCFIIndex(CFIIndex);190 }191 }192 193 // if framepointer enabled, set it to point to the stack pointer.194 if (hasFP(MF)) {195 // Insert instruction "move $fp, $sp" at this location.196 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::OR), FP)197 .addReg(SP)198 .addReg(SP)199 .setMIFlag(MachineInstr::FrameSetup);200 201 // emit ".cfi_def_cfa_register $fp"202 unsigned CFIIndex =203 MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(204 nullptr, MRI->getDwarfRegNum(FP, true)));205 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))206 .addCFIIndex(CFIIndex);207 }208 }209 210 if (StackSize != PrevStackSize) {211 MFI.setStackSize(StackSize);212 213 for (int i = MFI.getObjectIndexBegin(); i < MFI.getObjectIndexEnd(); i++) {214 if (!MFI.isDeadObjectIndex(i)) {215 int64_t SPOffset = MFI.getObjectOffset(i);216 217 if (SPOffset < 0)218 MFI.setObjectOffset(i, SPOffset - StackSize + PrevStackSize);219 }220 }221 }222}223 224void XtensaFrameLowering::emitEpilogue(MachineFunction &MF,225 MachineBasicBlock &MBB) const {226 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();227 MachineFrameInfo &MFI = MF.getFrameInfo();228 DebugLoc DL = MBBI->getDebugLoc();229 MCRegister SP = Xtensa::SP;230 MCRegister FP = TRI->getFrameRegister(MF);231 232 // if framepointer enabled, restore the stack pointer.233 if (hasFP(MF)) {234 // We should place restore stack pointer instruction just before235 // sequence of instructions which restores callee-saved registers.236 // This sequence is placed at the end of the basic block,237 // so we should find first instruction of the sequence.238 MachineBasicBlock::iterator I = MBBI;239 240 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();241 242 // Find the first instruction at the end that restores a callee-saved243 // register.244 for (unsigned i = 0, e = CSI.size(); i < e; ++i) {245 --I;246#ifndef NDEBUG247 const CalleeSavedInfo &Info = CSI[i];248 int FI = Info.getFrameIdx();249 int LoadFI = 0;250 251 // Checking that the instruction is exactly as expected252 bool IsRestoreInst = false;253 if (I->getOpcode() == TargetOpcode::COPY && Info.isSpilledToReg()) {254 Register Reg = I->getOperand(0).getReg();255 Register DstReg = I->getOperand(1).getReg();256 IsRestoreInst = Info.getDstReg() == DstReg.asMCReg() &&257 Info.getReg() == Reg.asMCReg();258 } else {259 Register Reg = TII.isLoadFromStackSlot(*I, LoadFI);260 IsRestoreInst = Info.getReg() == Reg.asMCReg() && LoadFI == FI;261 }262 assert(IsRestoreInst &&263 "Unexpected callee-saved register restore instruction");264#endif265 }266 if (STI.isWindowedABI()) {267 // In most architectures, we need to explicitly restore the stack pointer268 // before returning.269 //270 // For Xtensa Windowed Register option, it is not needed to explicitly271 // restore the stack pointer. Reason being is that on function return,272 // the window of the caller (including the old stack pointer) gets273 // restored anyways.274 } else {275 BuildMI(MBB, I, DL, TII.get(Xtensa::OR), SP).addReg(FP).addReg(FP);276 }277 }278 279 if (STI.isWindowedABI())280 return;281 282 // Get the number of bytes from FrameInfo283 uint64_t StackSize = MFI.getStackSize();284 285 if (!StackSize)286 return;287 288 // Adjust stack.289 TII.adjustStackPtr(SP, StackSize, MBB, MBBI);290}291 292bool XtensaFrameLowering::spillCalleeSavedRegisters(293 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,294 ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {295 MachineFunction *MF = MBB.getParent();296 MachineBasicBlock &EntryBlock = *(MF->begin());297 298 if (STI.isWindowedABI())299 return true;300 301 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {302 // Add the callee-saved register as live-in. Do not add if the register is303 // A0 and return address is taken, because it will be implemented in304 // method XtensaTargetLowering::LowerRETURNADDR.305 // It's killed at the spill, unless the register is RA and return address306 // is taken.307 MCRegister Reg = CSI[i].getReg();308 bool IsA0AndRetAddrIsTaken =309 (Reg == Xtensa::A0) && MF->getFrameInfo().isReturnAddressTaken();310 if (!IsA0AndRetAddrIsTaken)311 EntryBlock.addLiveIn(Reg);312 313 // Insert the spill to the stack frame.314 bool IsKill = !IsA0AndRetAddrIsTaken;315 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);316 TII.storeRegToStackSlot(EntryBlock, MI, Reg, IsKill, CSI[i].getFrameIdx(),317 RC, Register());318 }319 320 return true;321}322 323bool XtensaFrameLowering::restoreCalleeSavedRegisters(324 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,325 MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {326 if (STI.isWindowedABI())327 return true;328 return TargetFrameLowering::restoreCalleeSavedRegisters(MBB, MI, CSI, TRI);329}330 331// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions332MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr(333 MachineFunction &MF, MachineBasicBlock &MBB,334 MachineBasicBlock::iterator I) const {335 if (!hasReservedCallFrame(MF)) {336 int64_t Amount = I->getOperand(0).getImm();337 338 if (I->getOpcode() == Xtensa::ADJCALLSTACKDOWN)339 Amount = -Amount;340 341 TII.adjustStackPtr(Xtensa::SP, Amount, MBB, I);342 }343 344 return MBB.erase(I);345}346 347void XtensaFrameLowering::determineCalleeSaves(MachineFunction &MF,348 BitVector &SavedRegs,349 RegScavenger *RS) const {350 MCRegister FP = TRI->getFrameRegister(MF);351 352 if (STI.isWindowedABI()) {353 return;354 }355 356 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);357 358 // Mark $fp as used if function has dedicated frame pointer.359 if (hasFP(MF))360 SavedRegs.set(FP);361}362 363void XtensaFrameLowering::processFunctionBeforeFrameFinalized(364 MachineFunction &MF, RegScavenger *RS) const {365 // Set scavenging frame index if necessary.366 MachineFrameInfo &MFI = MF.getFrameInfo();367 uint64_t MaxSPOffset = MFI.estimateStackSize(MF);368 auto *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();369 unsigned ScavSlotsNum = 0;370 371 if (!isInt<12>(MaxSPOffset))372 ScavSlotsNum = 1;373 374 // Far branches over 18-bit offset require a spill slot for scratch register.375 bool IsLargeFunction = !isInt<18>(MF.estimateFunctionSizeInBytes());376 if (IsLargeFunction)377 ScavSlotsNum = std::max(ScavSlotsNum, 1u);378 379 const TargetRegisterClass &RC = Xtensa::ARRegClass;380 unsigned Size = TRI->getSpillSize(RC);381 Align Alignment = TRI->getSpillAlign(RC);382 for (unsigned I = 0; I < ScavSlotsNum; I++) {383 int FI = MFI.CreateSpillStackObject(Size, Alignment);384 RS->addScavengingFrameIndex(FI);385 386 if (IsLargeFunction &&387 XtensaFI->getBranchRelaxationScratchFrameIndex() == -1)388 XtensaFI->setBranchRelaxationScratchFrameIndex(FI);389 }390}391