1 //===-- VEFrameLowering.cpp - VE 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 VE implementation of TargetFrameLowering class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "VEFrameLowering.h" 14 #include "VEInstrInfo.h" 15 #include "VEMachineFunctionInfo.h" 16 #include "VESubtarget.h" 17 #include "llvm/CodeGen/MachineFrameInfo.h" 18 #include "llvm/CodeGen/MachineFunction.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/CodeGen/MachineModuleInfo.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/CodeGen/RegisterScavenging.h" 23 #include "llvm/IR/DataLayout.h" 24 #include "llvm/IR/Function.h" 25 #include "llvm/Support/CommandLine.h" 26 #include "llvm/Target/TargetOptions.h" 27 #include "llvm/Support/MathExtras.h" 28 29 using namespace llvm; 30 31 VEFrameLowering::VEFrameLowering(const VESubtarget &ST) 32 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(16), 0, 33 Align(16)) {} 34 35 void VEFrameLowering::emitPrologueInsns(MachineFunction &MF, 36 MachineBasicBlock &MBB, 37 MachineBasicBlock::iterator MBBI, 38 int NumBytes, 39 bool RequireFPUpdate) const { 40 41 DebugLoc dl; 42 const VEInstrInfo &TII = 43 *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 44 // Insert following codes here as prologue 45 // 46 // st %fp, 0(,%sp) 47 // st %lr, 8(,%sp) 48 // st %got, 24(,%sp) 49 // st %plt, 32(,%sp) 50 // or %fp, 0, %sp 51 52 BuildMI(MBB, MBBI, dl, TII.get(VE::STrii)) 53 .addReg(VE::SX11) 54 .addImm(0) 55 .addImm(0) 56 .addReg(VE::SX9); 57 BuildMI(MBB, MBBI, dl, TII.get(VE::STrii)) 58 .addReg(VE::SX11) 59 .addImm(0) 60 .addImm(8) 61 .addReg(VE::SX10); 62 BuildMI(MBB, MBBI, dl, TII.get(VE::STrii)) 63 .addReg(VE::SX11) 64 .addImm(0) 65 .addImm(24) 66 .addReg(VE::SX15); 67 BuildMI(MBB, MBBI, dl, TII.get(VE::STrii)) 68 .addReg(VE::SX11) 69 .addImm(0) 70 .addImm(32) 71 .addReg(VE::SX16); 72 BuildMI(MBB, MBBI, dl, TII.get(VE::ORri), VE::SX9) 73 .addReg(VE::SX11) 74 .addImm(0); 75 } 76 77 void VEFrameLowering::emitEpilogueInsns(MachineFunction &MF, 78 MachineBasicBlock &MBB, 79 MachineBasicBlock::iterator MBBI, 80 int NumBytes, 81 bool RequireFPUpdate) const { 82 83 DebugLoc dl; 84 const VEInstrInfo &TII = 85 *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 86 // Insert following codes here as epilogue 87 // 88 // or %sp, 0, %fp 89 // ld %got, 32(,%sp) 90 // ld %plt, 24(,%sp) 91 // ld %lr, 8(,%sp) 92 // ld %fp, 0(,%sp) 93 94 BuildMI(MBB, MBBI, dl, TII.get(VE::ORri), VE::SX11) 95 .addReg(VE::SX9) 96 .addImm(0); 97 BuildMI(MBB, MBBI, dl, TII.get(VE::LDrii), VE::SX16) 98 .addReg(VE::SX11) 99 .addImm(0) 100 .addImm(32); 101 BuildMI(MBB, MBBI, dl, TII.get(VE::LDrii), VE::SX15) 102 .addReg(VE::SX11) 103 .addImm(0) 104 .addImm(24); 105 BuildMI(MBB, MBBI, dl, TII.get(VE::LDrii), VE::SX10) 106 .addReg(VE::SX11) 107 .addImm(0) 108 .addImm(8); 109 BuildMI(MBB, MBBI, dl, TII.get(VE::LDrii), VE::SX9) 110 .addReg(VE::SX11) 111 .addImm(0) 112 .addImm(0); 113 } 114 115 void VEFrameLowering::emitSPAdjustment(MachineFunction &MF, 116 MachineBasicBlock &MBB, 117 MachineBasicBlock::iterator MBBI, 118 int NumBytes) const { 119 DebugLoc dl; 120 const VEInstrInfo &TII = 121 *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 122 123 if (NumBytes >= -64 && NumBytes < 63) { 124 BuildMI(MBB, MBBI, dl, TII.get(VE::ADDSLri), VE::SX11) 125 .addReg(VE::SX11) 126 .addImm(NumBytes); 127 return; 128 } 129 130 // Emit following codes. This clobbers SX13 which we always know is 131 // available here. 132 // lea %s13,%lo(NumBytes) 133 // and %s13,%s13,(32)0 134 // lea.sl %sp,%hi(NumBytes)(%sp, %s13) 135 BuildMI(MBB, MBBI, dl, TII.get(VE::LEAzii), VE::SX13) 136 .addImm(0) 137 .addImm(0) 138 .addImm(Lo_32(NumBytes)); 139 BuildMI(MBB, MBBI, dl, TII.get(VE::ANDrm), VE::SX13) 140 .addReg(VE::SX13) 141 .addImm(M0(32)); 142 BuildMI(MBB, MBBI, dl, TII.get(VE::LEASLrri), VE::SX11) 143 .addReg(VE::SX11) 144 .addReg(VE::SX13) 145 .addImm(Hi_32(NumBytes)); 146 } 147 148 void VEFrameLowering::emitSPExtend(MachineFunction &MF, MachineBasicBlock &MBB, 149 MachineBasicBlock::iterator MBBI, 150 int NumBytes) const { 151 DebugLoc dl; 152 const VEInstrInfo &TII = 153 *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo()); 154 155 // Emit following codes. It is not possible to insert multiple 156 // BasicBlocks in PEI pass, so we emit two pseudo instructions here. 157 // 158 // EXTEND_STACK // pseudo instrcution 159 // EXTEND_STACK_GUARD // pseudo instrcution 160 // 161 // EXTEND_STACK pseudo will be converted by ExpandPostRA pass into 162 // following instructions with multiple basic blocks later. 163 // 164 // thisBB: 165 // brge.l.t %sp, %sl, sinkBB 166 // syscallBB: 167 // ld %s61, 0x18(, %tp) // load param area 168 // or %s62, 0, %s0 // spill the value of %s0 169 // lea %s63, 0x13b // syscall # of grow 170 // shm.l %s63, 0x0(%s61) // store syscall # at addr:0 171 // shm.l %sl, 0x8(%s61) // store old limit at addr:8 172 // shm.l %sp, 0x10(%s61) // store new limit at addr:16 173 // monc // call monitor 174 // or %s0, 0, %s62 // restore the value of %s0 175 // sinkBB: 176 // 177 // EXTEND_STACK_GUARD pseudo will be simply eliminated by ExpandPostRA 178 // pass. This pseudo is required to be at the next of EXTEND_STACK 179 // pseudo in order to protect iteration loop in ExpandPostRA. 180 181 BuildMI(MBB, MBBI, dl, TII.get(VE::EXTEND_STACK)); 182 BuildMI(MBB, MBBI, dl, TII.get(VE::EXTEND_STACK_GUARD)); 183 } 184 185 void VEFrameLowering::emitPrologue(MachineFunction &MF, 186 MachineBasicBlock &MBB) const { 187 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); 188 MachineFrameInfo &MFI = MF.getFrameInfo(); 189 const VESubtarget &Subtarget = MF.getSubtarget<VESubtarget>(); 190 const VEInstrInfo &TII = 191 *static_cast<const VEInstrInfo *>(Subtarget.getInstrInfo()); 192 const VERegisterInfo &RegInfo = 193 *static_cast<const VERegisterInfo *>(Subtarget.getRegisterInfo()); 194 MachineBasicBlock::iterator MBBI = MBB.begin(); 195 // Debug location must be unknown since the first debug location is used 196 // to determine the end of the prologue. 197 DebugLoc dl; 198 bool NeedsStackRealignment = RegInfo.needsStackRealignment(MF); 199 200 // FIXME: unfortunately, returning false from canRealignStack 201 // actually just causes needsStackRealignment to return false, 202 // rather than reporting an error, as would be sensible. This is 203 // poor, but fixing that bogosity is going to be a large project. 204 // For now, just see if it's lied, and report an error here. 205 if (!NeedsStackRealignment && MFI.getMaxAlign() > getStackAlign()) 206 report_fatal_error("Function \"" + Twine(MF.getName()) + 207 "\" required " 208 "stack re-alignment, but LLVM couldn't handle it " 209 "(probably because it has a dynamic alloca)."); 210 211 // Get the number of bytes to allocate from the FrameInfo 212 int NumBytes = (int)MFI.getStackSize(); 213 // The VE ABI requires a reserved 176-byte area in the user's stack, starting 214 // at %sp + 16. This is for the callee Register Save Area (RSA). 215 // 216 // We therefore need to add that offset to the total stack size 217 // after all the stack objects are placed by 218 // PrologEpilogInserter calculateFrameObjectOffsets. However, since the stack 219 // needs to be aligned *after* the extra size is added, we need to disable 220 // calculateFrameObjectOffsets's built-in stack alignment, by having 221 // targetHandlesStackFrameRounding return true. 222 223 // Add the extra call frame stack size, if needed. (This is the same 224 // code as in PrologEpilogInserter, but also gets disabled by 225 // targetHandlesStackFrameRounding) 226 if (MFI.adjustsStack() && hasReservedCallFrame(MF)) 227 NumBytes += MFI.getMaxCallFrameSize(); 228 229 // Adds the VE subtarget-specific spill area to the stack 230 // size. Also ensures target-required alignment. 231 NumBytes = Subtarget.getAdjustedFrameSize(NumBytes); 232 233 // Finally, ensure that the size is sufficiently aligned for the 234 // data on the stack. 235 NumBytes = alignTo(NumBytes, MFI.getMaxAlign().value()); 236 237 // Update stack size with corrected value. 238 MFI.setStackSize(NumBytes); 239 240 // Emit Prologue instructions to save %lr 241 emitPrologueInsns(MF, MBB, MBBI, NumBytes, true); 242 243 // Emit stack adjust instructions 244 emitSPAdjustment(MF, MBB, MBBI, -NumBytes); 245 246 // Emit stack extend instructions 247 emitSPExtend(MF, MBB, MBBI, -NumBytes); 248 249 unsigned regFP = RegInfo.getDwarfRegNum(VE::SX9, true); 250 251 // Emit ".cfi_def_cfa_register 30". 252 unsigned CFIIndex = 253 MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, regFP)); 254 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) 255 .addCFIIndex(CFIIndex); 256 257 // Emit ".cfi_window_save". 258 CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); 259 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) 260 .addCFIIndex(CFIIndex); 261 } 262 263 MachineBasicBlock::iterator VEFrameLowering::eliminateCallFramePseudoInstr( 264 MachineFunction &MF, MachineBasicBlock &MBB, 265 MachineBasicBlock::iterator I) const { 266 if (!hasReservedCallFrame(MF)) { 267 MachineInstr &MI = *I; 268 int Size = MI.getOperand(0).getImm(); 269 if (MI.getOpcode() == VE::ADJCALLSTACKDOWN) 270 Size = -Size; 271 272 if (Size) 273 emitSPAdjustment(MF, MBB, I, Size); 274 } 275 return MBB.erase(I); 276 } 277 278 void VEFrameLowering::emitEpilogue(MachineFunction &MF, 279 MachineBasicBlock &MBB) const { 280 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 281 DebugLoc dl = MBBI->getDebugLoc(); 282 MachineFrameInfo &MFI = MF.getFrameInfo(); 283 284 int NumBytes = (int)MFI.getStackSize(); 285 286 // Emit Epilogue instructions to restore %lr 287 emitEpilogueInsns(MF, MBB, MBBI, NumBytes, true); 288 } 289 290 bool VEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 291 // Reserve call frame if there are no variable sized objects on the stack. 292 return !MF.getFrameInfo().hasVarSizedObjects(); 293 } 294 295 // hasFP - Return true if the specified function should have a dedicated frame 296 // pointer register. This is true if the function has variable sized allocas or 297 // if frame pointer elimination is disabled. 298 bool VEFrameLowering::hasFP(const MachineFunction &MF) const { 299 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 300 301 const MachineFrameInfo &MFI = MF.getFrameInfo(); 302 return MF.getTarget().Options.DisableFramePointerElim(MF) || 303 RegInfo->needsStackRealignment(MF) || MFI.hasVarSizedObjects() || 304 MFI.isFrameAddressTaken(); 305 } 306 307 int VEFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, 308 Register &FrameReg) const { 309 const VESubtarget &Subtarget = MF.getSubtarget<VESubtarget>(); 310 const MachineFrameInfo &MFI = MF.getFrameInfo(); 311 const VERegisterInfo *RegInfo = Subtarget.getRegisterInfo(); 312 const VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>(); 313 bool isFixed = MFI.isFixedObjectIndex(FI); 314 315 // Addressable stack objects are accessed using neg. offsets from 316 // %fp, or positive offsets from %sp. 317 bool UseFP = true; 318 319 // VE uses FP-based references in general, even when "hasFP" is 320 // false. That function is rather a misnomer, because %fp is 321 // actually always available, unless isLeafProc. 322 if (FuncInfo->isLeafProc()) { 323 // If there's a leaf proc, all offsets need to be %sp-based, 324 // because we haven't caused %fp to actually point to our frame. 325 UseFP = false; 326 } else if (isFixed) { 327 // Otherwise, argument access should always use %fp. 328 UseFP = true; 329 } else if (RegInfo->needsStackRealignment(MF)) { 330 // If there is dynamic stack realignment, all local object 331 // references need to be via %sp, to take account of the 332 // re-alignment. 333 UseFP = false; 334 } 335 336 int64_t FrameOffset = MF.getFrameInfo().getObjectOffset(FI); 337 338 if (UseFP) { 339 FrameReg = RegInfo->getFrameRegister(MF); 340 return FrameOffset; 341 } 342 343 FrameReg = VE::SX11; // %sp 344 return FrameOffset + MF.getFrameInfo().getStackSize(); 345 } 346 347 bool VEFrameLowering::isLeafProc(MachineFunction &MF) const { 348 349 MachineRegisterInfo &MRI = MF.getRegInfo(); 350 MachineFrameInfo &MFI = MF.getFrameInfo(); 351 352 return !MFI.hasCalls() // No calls 353 && !MRI.isPhysRegUsed(VE::SX18) // Registers within limits 354 // (s18 is first CSR) 355 && !MRI.isPhysRegUsed(VE::SX11) // %sp un-used 356 && !hasFP(MF); // Don't need %fp 357 } 358 359 void VEFrameLowering::determineCalleeSaves(MachineFunction &MF, 360 BitVector &SavedRegs, 361 RegScavenger *RS) const { 362 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 363 364 if (isLeafProc(MF)) { 365 VEMachineFunctionInfo *MFI = MF.getInfo<VEMachineFunctionInfo>(); 366 MFI->setLeafProc(true); 367 } 368 } 369