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-exception 6 // 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 24 using namespace llvm; 25 26 XtensaFrameLowering::XtensaFrameLowering(const XtensaSubtarget &STI) 27 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(4), 0, 28 Align(4)), 29 TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {} 30 31 bool XtensaFrameLowering::hasFPImpl(const MachineFunction &MF) const { 32 const MachineFrameInfo &MFI = MF.getFrameInfo(); 33 return MF.getTarget().Options.DisableFramePointerElim(MF) || 34 MFI.hasVarSizedObjects(); 35 } 36 37 void XtensaFrameLowering::emitPrologue(MachineFunction &MF, 38 MachineBasicBlock &MBB) const { 39 assert(&MBB == &MF.front() && "Shrink-wrapping not yet implemented"); 40 MachineFrameInfo &MFI = MF.getFrameInfo(); 41 MachineBasicBlock::iterator MBBI = MBB.begin(); 42 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 43 MCRegister SP = Xtensa::SP; 44 MCRegister FP = TRI->getFrameRegister(MF); 45 const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo(); 46 47 // First, compute final stack size. 48 uint64_t StackSize = MFI.getStackSize(); 49 uint64_t PrevStackSize = StackSize; 50 51 // Round up StackSize to 16*N 52 StackSize += (16 - StackSize) & 0xf; 53 54 // No need to allocate space on the stack. 55 if (StackSize == 0 && !MFI.adjustsStack()) 56 return; 57 58 // Adjust stack. 59 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI); 60 61 // emit ".cfi_def_cfa_offset StackSize" 62 unsigned CFIIndex = 63 MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize)); 64 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) 65 .addCFIIndex(CFIIndex); 66 67 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 68 69 if (!CSI.empty()) { 70 // Find the instruction past the last instruction that saves a 71 // callee-saved register to the stack. The callee-saved store 72 // instructions are placed at the begin of basic block, so 73 // iterate over instruction sequence and check that 74 // save instructions are placed correctly. 75 for (unsigned i = 0, e = CSI.size(); i < e; ++i) { 76 #ifndef NDEBUG 77 const CalleeSavedInfo &Info = CSI[i]; 78 int FI = Info.getFrameIdx(); 79 int StoreFI = 0; 80 81 // Checking that the instruction is exactly as expected 82 bool IsStoreInst = false; 83 if (MBBI->getOpcode() == TargetOpcode::COPY && Info.isSpilledToReg()) { 84 Register DstReg = MBBI->getOperand(0).getReg(); 85 Register Reg = MBBI->getOperand(1).getReg(); 86 IsStoreInst = (Info.getDstReg() == DstReg) && (Info.getReg() == Reg); 87 } else { 88 Register Reg = TII.isStoreToStackSlot(*MBBI, StoreFI); 89 IsStoreInst = (Reg == Info.getReg()) && (StoreFI == FI); 90 } 91 assert(IsStoreInst && 92 "Unexpected callee-saved register store instruction"); 93 #endif 94 ++MBBI; 95 } 96 97 // Iterate over list of callee-saved registers and emit .cfi_offset 98 // directives. 99 for (const auto &I : CSI) { 100 int64_t Offset = MFI.getObjectOffset(I.getFrameIdx()); 101 Register Reg = I.getReg(); 102 103 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 104 nullptr, MRI->getDwarfRegNum(Reg, 1), Offset)); 105 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) 106 .addCFIIndex(CFIIndex); 107 } 108 } 109 110 // if framepointer enabled, set it to point to the stack pointer. 111 if (hasFP(MF)) { 112 // Insert instruction "move $fp, $sp" at this location. 113 BuildMI(MBB, MBBI, DL, TII.get(Xtensa::OR), FP) 114 .addReg(SP) 115 .addReg(SP) 116 .setMIFlag(MachineInstr::FrameSetup); 117 118 // emit ".cfi_def_cfa_register $fp" 119 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfaRegister( 120 nullptr, MRI->getDwarfRegNum(FP, true))); 121 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) 122 .addCFIIndex(CFIIndex); 123 } 124 125 if (StackSize != PrevStackSize) { 126 MFI.setStackSize(StackSize); 127 128 for (int i = MFI.getObjectIndexBegin(); i < MFI.getObjectIndexEnd(); i++) { 129 if (!MFI.isDeadObjectIndex(i)) { 130 int64_t SPOffset = MFI.getObjectOffset(i); 131 132 if (SPOffset < 0) 133 MFI.setObjectOffset(i, SPOffset - StackSize + PrevStackSize); 134 } 135 } 136 } 137 } 138 139 void XtensaFrameLowering::emitEpilogue(MachineFunction &MF, 140 MachineBasicBlock &MBB) const { 141 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 142 MachineFrameInfo &MFI = MF.getFrameInfo(); 143 DebugLoc DL = MBBI->getDebugLoc(); 144 MCRegister SP = Xtensa::SP; 145 MCRegister FP = TRI->getFrameRegister(MF); 146 147 // if framepointer enabled, restore the stack pointer. 148 if (hasFP(MF)) { 149 // We should place restore stack pointer instruction just before 150 // sequence of instructions which restores callee-saved registers. 151 // This sequence is placed at the end of the basic block, 152 // so we should find first instruction of the sequence. 153 MachineBasicBlock::iterator I = MBBI; 154 155 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 156 157 // Find the first instruction at the end that restores a callee-saved 158 // register. 159 for (unsigned i = 0, e = CSI.size(); i < e; ++i) { 160 --I; 161 #ifndef NDEBUG 162 const CalleeSavedInfo &Info = CSI[i]; 163 int FI = Info.getFrameIdx(); 164 int LoadFI = 0; 165 166 // Checking that the instruction is exactly as expected 167 bool IsRestoreInst = false; 168 if (I->getOpcode() == TargetOpcode::COPY && Info.isSpilledToReg()) { 169 Register Reg = I->getOperand(0).getReg(); 170 Register DstReg = I->getOperand(1).getReg(); 171 IsRestoreInst = (Info.getDstReg() == DstReg) && (Info.getReg() == Reg); 172 } else { 173 Register Reg = TII.isLoadFromStackSlot(*I, LoadFI); 174 IsRestoreInst = (Info.getReg() == Reg) && (LoadFI == FI); 175 } 176 assert(IsRestoreInst && 177 "Unexpected callee-saved register restore instruction"); 178 #endif 179 } 180 181 BuildMI(MBB, I, DL, TII.get(Xtensa::OR), SP).addReg(FP).addReg(FP); 182 } 183 184 // Get the number of bytes from FrameInfo 185 uint64_t StackSize = MFI.getStackSize(); 186 187 if (!StackSize) 188 return; 189 190 // Adjust stack. 191 TII.adjustStackPtr(SP, StackSize, MBB, MBBI); 192 } 193 194 bool XtensaFrameLowering::spillCalleeSavedRegisters( 195 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 196 ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { 197 MachineFunction *MF = MBB.getParent(); 198 MachineBasicBlock &EntryBlock = *(MF->begin()); 199 200 for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 201 // Add the callee-saved register as live-in. Do not add if the register is 202 // A0 and return address is taken, because it will be implemented in 203 // method XtensaTargetLowering::LowerRETURNADDR. 204 // It's killed at the spill, unless the register is RA and return address 205 // is taken. 206 Register Reg = CSI[i].getReg(); 207 bool IsA0AndRetAddrIsTaken = 208 (Reg == Xtensa::A0) && MF->getFrameInfo().isReturnAddressTaken(); 209 if (!IsA0AndRetAddrIsTaken) 210 EntryBlock.addLiveIn(Reg); 211 212 // Insert the spill to the stack frame. 213 bool IsKill = !IsA0AndRetAddrIsTaken; 214 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 215 TII.storeRegToStackSlot(EntryBlock, MI, Reg, IsKill, CSI[i].getFrameIdx(), 216 RC, TRI, Register()); 217 } 218 219 return true; 220 } 221 222 bool XtensaFrameLowering::restoreCalleeSavedRegisters( 223 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 224 MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { 225 return TargetFrameLowering::restoreCalleeSavedRegisters(MBB, MI, CSI, TRI); 226 } 227 228 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions 229 MachineBasicBlock::iterator XtensaFrameLowering::eliminateCallFramePseudoInstr( 230 MachineFunction &MF, MachineBasicBlock &MBB, 231 MachineBasicBlock::iterator I) const { 232 const XtensaInstrInfo &TII = 233 *static_cast<const XtensaInstrInfo *>(MF.getSubtarget().getInstrInfo()); 234 235 if (!hasReservedCallFrame(MF)) { 236 int64_t Amount = I->getOperand(0).getImm(); 237 238 if (I->getOpcode() == Xtensa::ADJCALLSTACKDOWN) 239 Amount = -Amount; 240 241 TII.adjustStackPtr(Xtensa::SP, Amount, MBB, I); 242 } 243 244 return MBB.erase(I); 245 } 246 247 void XtensaFrameLowering::determineCalleeSaves(MachineFunction &MF, 248 BitVector &SavedRegs, 249 RegScavenger *RS) const { 250 unsigned FP = TRI->getFrameRegister(MF); 251 252 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 253 254 // Mark $fp as used if function has dedicated frame pointer. 255 if (hasFP(MF)) 256 SavedRegs.set(FP); 257 } 258 259 void XtensaFrameLowering::processFunctionBeforeFrameFinalized( 260 MachineFunction &MF, RegScavenger *RS) const { 261 // Set scavenging frame index if necessary. 262 MachineFrameInfo &MFI = MF.getFrameInfo(); 263 uint64_t MaxSPOffset = MFI.estimateStackSize(MF); 264 auto *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>(); 265 unsigned ScavSlotsNum = 0; 266 267 if (!isInt<12>(MaxSPOffset)) 268 ScavSlotsNum = 1; 269 270 // Far branches over 18-bit offset require a spill slot for scratch register. 271 bool IsLargeFunction = !isInt<18>(MF.estimateFunctionSizeInBytes()); 272 if (IsLargeFunction) 273 ScavSlotsNum = std::max(ScavSlotsNum, 1u); 274 275 const TargetRegisterClass &RC = Xtensa::ARRegClass; 276 unsigned Size = TRI->getSpillSize(RC); 277 Align Alignment = TRI->getSpillAlign(RC); 278 for (unsigned I = 0; I < ScavSlotsNum; I++) { 279 int FI = MFI.CreateSpillStackObject(Size, Alignment); 280 RS->addScavengingFrameIndex(FI); 281 282 if (IsLargeFunction && 283 XtensaFI->getBranchRelaxationScratchFrameIndex() == -1) 284 XtensaFI->setBranchRelaxationScratchFrameIndex(FI); 285 } 286 } 287