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