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