876 lines · cpp
1//===- MipsSEFrameLowering.cpp - Mips32/64 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 Mips32/64 implementation of TargetFrameLowering class.10//11//===----------------------------------------------------------------------===//12 13#include "MipsSEFrameLowering.h"14#include "MCTargetDesc/MipsABIInfo.h"15#include "MipsMachineFunction.h"16#include "MipsRegisterInfo.h"17#include "MipsSEInstrInfo.h"18#include "MipsSubtarget.h"19#include "llvm/ADT/BitVector.h"20#include "llvm/ADT/StringRef.h"21#include "llvm/ADT/StringSwitch.h"22#include "llvm/CodeGen/CFIInstBuilder.h"23#include "llvm/CodeGen/MachineBasicBlock.h"24#include "llvm/CodeGen/MachineFrameInfo.h"25#include "llvm/CodeGen/MachineFunction.h"26#include "llvm/CodeGen/MachineInstr.h"27#include "llvm/CodeGen/MachineInstrBuilder.h"28#include "llvm/CodeGen/MachineModuleInfo.h"29#include "llvm/CodeGen/MachineOperand.h"30#include "llvm/CodeGen/MachineRegisterInfo.h"31#include "llvm/CodeGen/RegisterScavenging.h"32#include "llvm/CodeGen/TargetInstrInfo.h"33#include "llvm/CodeGen/TargetRegisterInfo.h"34#include "llvm/CodeGen/TargetSubtargetInfo.h"35#include "llvm/IR/DebugLoc.h"36#include "llvm/IR/Function.h"37#include "llvm/Support/CodeGen.h"38#include "llvm/Support/ErrorHandling.h"39#include "llvm/Support/MathExtras.h"40#include <cassert>41#include <cstdint>42#include <utility>43#include <vector>44 45using namespace llvm;46 47static std::pair<unsigned, unsigned> getMFHiLoOpc(unsigned Src) {48 if (Mips::ACC64RegClass.contains(Src))49 return std::make_pair((unsigned)Mips::PseudoMFHI,50 (unsigned)Mips::PseudoMFLO);51 52 if (Mips::ACC64DSPRegClass.contains(Src))53 return std::make_pair((unsigned)Mips::MFHI_DSP, (unsigned)Mips::MFLO_DSP);54 55 if (Mips::ACC128RegClass.contains(Src))56 return std::make_pair((unsigned)Mips::PseudoMFHI64,57 (unsigned)Mips::PseudoMFLO64);58 59 return std::make_pair(0, 0);60}61 62namespace {63 64/// Helper class to expand pseudos.65class ExpandPseudo {66public:67 ExpandPseudo(MachineFunction &MF);68 bool expand();69 70private:71 using Iter = MachineBasicBlock::iterator;72 73 bool expandInstr(MachineBasicBlock &MBB, Iter I);74 void expandLoadCCond(MachineBasicBlock &MBB, Iter I);75 void expandStoreCCond(MachineBasicBlock &MBB, Iter I);76 void expandLoadACC(MachineBasicBlock &MBB, Iter I, unsigned RegSize);77 void expandStoreACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc,78 unsigned MFLoOpc, unsigned RegSize);79 bool expandCopy(MachineBasicBlock &MBB, Iter I);80 bool expandCopyACC(MachineBasicBlock &MBB, Iter I, unsigned MFHiOpc,81 unsigned MFLoOpc);82 bool expandBuildPairF64(MachineBasicBlock &MBB,83 MachineBasicBlock::iterator I, bool FP64) const;84 bool expandExtractElementF64(MachineBasicBlock &MBB,85 MachineBasicBlock::iterator I, bool FP64) const;86 87 MachineFunction &MF;88 MachineRegisterInfo &MRI;89 const MipsSubtarget &Subtarget;90 const MipsSEInstrInfo &TII;91 const MipsRegisterInfo &RegInfo;92};93 94} // end anonymous namespace95 96ExpandPseudo::ExpandPseudo(MachineFunction &MF_)97 : MF(MF_), MRI(MF.getRegInfo()),98 Subtarget(MF.getSubtarget<MipsSubtarget>()),99 TII(*static_cast<const MipsSEInstrInfo *>(Subtarget.getInstrInfo())),100 RegInfo(*Subtarget.getRegisterInfo()) {}101 102bool ExpandPseudo::expand() {103 bool Expanded = false;104 105 for (auto &MBB : MF) {106 for (Iter I = MBB.begin(), End = MBB.end(); I != End;)107 Expanded |= expandInstr(MBB, I++);108 }109 110 return Expanded;111}112 113bool ExpandPseudo::expandInstr(MachineBasicBlock &MBB, Iter I) {114 switch(I->getOpcode()) {115 case Mips::LOAD_CCOND_DSP:116 expandLoadCCond(MBB, I);117 break;118 case Mips::STORE_CCOND_DSP:119 expandStoreCCond(MBB, I);120 break;121 case Mips::LOAD_ACC64:122 case Mips::LOAD_ACC64DSP:123 expandLoadACC(MBB, I, 4);124 break;125 case Mips::LOAD_ACC128:126 expandLoadACC(MBB, I, 8);127 break;128 case Mips::STORE_ACC64:129 expandStoreACC(MBB, I, Mips::PseudoMFHI, Mips::PseudoMFLO, 4);130 break;131 case Mips::STORE_ACC64DSP:132 expandStoreACC(MBB, I, Mips::MFHI_DSP, Mips::MFLO_DSP, 4);133 break;134 case Mips::STORE_ACC128:135 expandStoreACC(MBB, I, Mips::PseudoMFHI64, Mips::PseudoMFLO64, 8);136 break;137 case Mips::BuildPairF64:138 if (expandBuildPairF64(MBB, I, false))139 MBB.erase(I);140 return false;141 case Mips::BuildPairF64_64:142 if (expandBuildPairF64(MBB, I, true))143 MBB.erase(I);144 return false;145 case Mips::ExtractElementF64:146 if (expandExtractElementF64(MBB, I, false))147 MBB.erase(I);148 return false;149 case Mips::ExtractElementF64_64:150 if (expandExtractElementF64(MBB, I, true))151 MBB.erase(I);152 return false;153 case TargetOpcode::COPY:154 if (!expandCopy(MBB, I))155 return false;156 break;157 default:158 return false;159 }160 161 MBB.erase(I);162 return true;163}164 165void ExpandPseudo::expandLoadCCond(MachineBasicBlock &MBB, Iter I) {166 // load $vr, FI167 // copy ccond, $vr168 169 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());170 171 const TargetRegisterClass *RC = RegInfo.intRegClass(4);172 Register VR = MRI.createVirtualRegister(RC);173 Register Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();174 175 TII.loadRegFromStack(MBB, I, VR, FI, RC, 0);176 BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), Dst)177 .addReg(VR, RegState::Kill);178}179 180void ExpandPseudo::expandStoreCCond(MachineBasicBlock &MBB, Iter I) {181 // copy $vr, ccond182 // store $vr, FI183 184 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());185 186 const TargetRegisterClass *RC = RegInfo.intRegClass(4);187 Register VR = MRI.createVirtualRegister(RC);188 Register Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();189 190 BuildMI(MBB, I, I->getDebugLoc(), TII.get(TargetOpcode::COPY), VR)191 .addReg(Src, getKillRegState(I->getOperand(0).isKill()));192 TII.storeRegToStack(MBB, I, VR, true, FI, RC, 0);193}194 195void ExpandPseudo::expandLoadACC(MachineBasicBlock &MBB, Iter I,196 unsigned RegSize) {197 // load $vr0, FI198 // copy lo, $vr0199 // load $vr1, FI + 4200 // copy hi, $vr1201 202 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());203 204 const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);205 Register VR0 = MRI.createVirtualRegister(RC);206 Register VR1 = MRI.createVirtualRegister(RC);207 Register Dst = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();208 Register Lo = RegInfo.getSubReg(Dst, Mips::sub_lo);209 Register Hi = RegInfo.getSubReg(Dst, Mips::sub_hi);210 DebugLoc DL = I->getDebugLoc();211 const MCInstrDesc &Desc = TII.get(TargetOpcode::COPY);212 213 TII.loadRegFromStack(MBB, I, VR0, FI, RC, 0);214 BuildMI(MBB, I, DL, Desc, Lo).addReg(VR0, RegState::Kill);215 TII.loadRegFromStack(MBB, I, VR1, FI, RC, RegSize);216 BuildMI(MBB, I, DL, Desc, Hi).addReg(VR1, RegState::Kill);217}218 219void ExpandPseudo::expandStoreACC(MachineBasicBlock &MBB, Iter I,220 unsigned MFHiOpc, unsigned MFLoOpc,221 unsigned RegSize) {222 // mflo $vr0, src223 // store $vr0, FI224 // mfhi $vr1, src225 // store $vr1, FI + 4226 227 assert(I->getOperand(0).isReg() && I->getOperand(1).isFI());228 229 const TargetRegisterClass *RC = RegInfo.intRegClass(RegSize);230 Register VR0 = MRI.createVirtualRegister(RC);231 Register VR1 = MRI.createVirtualRegister(RC);232 Register Src = I->getOperand(0).getReg(), FI = I->getOperand(1).getIndex();233 unsigned SrcKill = getKillRegState(I->getOperand(0).isKill());234 DebugLoc DL = I->getDebugLoc();235 236 BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src);237 TII.storeRegToStack(MBB, I, VR0, true, FI, RC, 0);238 BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);239 TII.storeRegToStack(MBB, I, VR1, true, FI, RC, RegSize);240}241 242bool ExpandPseudo::expandCopy(MachineBasicBlock &MBB, Iter I) {243 Register Src = I->getOperand(1).getReg();244 std::pair<unsigned, unsigned> Opcodes = getMFHiLoOpc(Src);245 246 if (!Opcodes.first)247 return false;248 249 return expandCopyACC(MBB, I, Opcodes.first, Opcodes.second);250}251 252bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I,253 unsigned MFHiOpc, unsigned MFLoOpc) {254 // mflo $vr0, src255 // copy dst_lo, $vr0256 // mfhi $vr1, src257 // copy dst_hi, $vr1258 259 unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg();260 const TargetRegisterClass *DstRC = RegInfo.getMinimalPhysRegClass(Dst);261 unsigned VRegSize = RegInfo.getRegSizeInBits(*DstRC) / 16;262 const TargetRegisterClass *RC = RegInfo.intRegClass(VRegSize);263 Register VR0 = MRI.createVirtualRegister(RC);264 Register VR1 = MRI.createVirtualRegister(RC);265 unsigned SrcKill = getKillRegState(I->getOperand(1).isKill());266 Register DstLo = RegInfo.getSubReg(Dst, Mips::sub_lo);267 Register DstHi = RegInfo.getSubReg(Dst, Mips::sub_hi);268 DebugLoc DL = I->getDebugLoc();269 270 BuildMI(MBB, I, DL, TII.get(MFLoOpc), VR0).addReg(Src);271 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstLo)272 .addReg(VR0, RegState::Kill);273 BuildMI(MBB, I, DL, TII.get(MFHiOpc), VR1).addReg(Src, SrcKill);274 BuildMI(MBB, I, DL, TII.get(TargetOpcode::COPY), DstHi)275 .addReg(VR1, RegState::Kill);276 return true;277}278 279/// This method expands the same instruction that MipsSEInstrInfo::280/// expandBuildPairF64 does, for the case when ABI is fpxx and mthc1 is not281/// available and the case where the ABI is FP64A. It is implemented here282/// because frame indexes are eliminated before MipsSEInstrInfo::283/// expandBuildPairF64 is called.284bool ExpandPseudo::expandBuildPairF64(MachineBasicBlock &MBB,285 MachineBasicBlock::iterator I,286 bool FP64) const {287 // For fpxx and when mthc1 is not available, use:288 // spill + reload via ldc1289 //290 // The case where dmtc1 is available doesn't need to be handled here291 // because it never creates a BuildPairF64 node.292 //293 // The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence294 // for odd-numbered double precision values (because the lower 32-bits is295 // transferred with mtc1 which is redirected to the upper half of the even296 // register). Unfortunately, we have to make this decision before register297 // allocation so for now we use a spill/reload sequence for all298 // double-precision values in regardless of being an odd/even register.299 //300 // For the cases that should be covered here MipsSEISelDAGToDAG adds $sp as301 // implicit operand, so other passes (like ShrinkWrapping) are aware that302 // stack is used.303 if (I->getNumOperands() == 4 && I->getOperand(3).isReg()304 && I->getOperand(3).getReg() == Mips::SP) {305 Register DstReg = I->getOperand(0).getReg();306 Register LoReg = I->getOperand(1).getReg();307 Register HiReg = I->getOperand(2).getReg();308 309 // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are310 // the cases where mthc1 is not available). 64-bit architectures and311 // MIPS32r2 or later can use FGR64 though.312 assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||313 !Subtarget.isFP64bit());314 315 const TargetRegisterClass *RC = &Mips::GPR32RegClass;316 const TargetRegisterClass *RC2 =317 FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;318 319 // We re-use the same spill slot each time so that the stack frame doesn't320 // grow too much in functions with a large number of moves.321 int FI = MF.getInfo<MipsFunctionInfo>()->getMoveF64ViaSpillFI(MF, RC2);322 if (!Subtarget.isLittle())323 std::swap(LoReg, HiReg);324 TII.storeRegToStack(MBB, I, LoReg, I->getOperand(1).isKill(), FI, RC, 0);325 TII.storeRegToStack(MBB, I, HiReg, I->getOperand(2).isKill(), FI, RC, 4);326 TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, 0);327 return true;328 }329 330 return false;331}332 333/// This method expands the same instruction that MipsSEInstrInfo::334/// expandExtractElementF64 does, for the case when ABI is fpxx and mfhc1 is not335/// available and the case where the ABI is FP64A. It is implemented here336/// because frame indexes are eliminated before MipsSEInstrInfo::337/// expandExtractElementF64 is called.338bool ExpandPseudo::expandExtractElementF64(MachineBasicBlock &MBB,339 MachineBasicBlock::iterator I,340 bool FP64) const {341 const MachineOperand &Op1 = I->getOperand(1);342 const MachineOperand &Op2 = I->getOperand(2);343 344 if ((Op1.isReg() && Op1.isUndef()) || (Op2.isReg() && Op2.isUndef())) {345 Register DstReg = I->getOperand(0).getReg();346 BuildMI(MBB, I, I->getDebugLoc(), TII.get(Mips::IMPLICIT_DEF), DstReg);347 return true;348 }349 350 // For fpxx and when mfhc1 is not available, use:351 // spill + reload via ldc1352 //353 // The case where dmfc1 is available doesn't need to be handled here354 // because it never creates a ExtractElementF64 node.355 //356 // The FP64A ABI (fp64 with nooddspreg) must also use a spill/reload sequence357 // for odd-numbered double precision values (because the lower 32-bits is358 // transferred with mfc1 which is redirected to the upper half of the even359 // register). Unfortunately, we have to make this decision before register360 // allocation so for now we use a spill/reload sequence for all361 // double-precision values in regardless of being an odd/even register.362 //363 // For the cases that should be covered here MipsSEISelDAGToDAG adds $sp as364 // implicit operand, so other passes (like ShrinkWrapping) are aware that365 // stack is used.366 if (I->getNumOperands() == 4 && I->getOperand(3).isReg()367 && I->getOperand(3).getReg() == Mips::SP) {368 Register DstReg = I->getOperand(0).getReg();369 Register SrcReg = Op1.getReg();370 unsigned N = Op2.getImm();371 int64_t Offset = 4 * (Subtarget.isLittle() ? N : (1 - N));372 373 // It should be impossible to have FGR64 on MIPS-II or MIPS32r1 (which are374 // the cases where mfhc1 is not available). 64-bit architectures and375 // MIPS32r2 or later can use FGR64 though.376 assert(Subtarget.isGP64bit() || Subtarget.hasMTHC1() ||377 !Subtarget.isFP64bit());378 379 const TargetRegisterClass *RC =380 FP64 ? &Mips::FGR64RegClass : &Mips::AFGR64RegClass;381 const TargetRegisterClass *RC2 = &Mips::GPR32RegClass;382 383 // We re-use the same spill slot each time so that the stack frame doesn't384 // grow too much in functions with a large number of moves.385 int FI = MF.getInfo<MipsFunctionInfo>()->getMoveF64ViaSpillFI(MF, RC);386 TII.storeRegToStack(MBB, I, SrcReg, Op1.isKill(), FI, RC, 0);387 TII.loadRegFromStack(MBB, I, DstReg, FI, RC2, Offset);388 return true;389 }390 391 return false;392}393 394MipsSEFrameLowering::MipsSEFrameLowering(const MipsSubtarget &STI)395 : MipsFrameLowering(STI, STI.getStackAlignment()) {}396 397void MipsSEFrameLowering::emitPrologue(MachineFunction &MF,398 MachineBasicBlock &MBB) const {399 MachineFrameInfo &MFI = MF.getFrameInfo();400 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();401 402 const MipsSEInstrInfo &TII =403 *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());404 const MipsRegisterInfo &RegInfo = *STI.getRegisterInfo();405 406 MachineBasicBlock::iterator MBBI = MBB.begin();407 DebugLoc dl;408 MipsABIInfo ABI = STI.getABI();409 unsigned SP = ABI.GetStackPtr();410 unsigned FP = ABI.GetFramePtr();411 unsigned ZERO = ABI.GetNullPtr();412 unsigned MOVE = ABI.GetGPRMoveOp();413 unsigned ADDiu = ABI.GetPtrAddiuOp();414 unsigned AND = ABI.IsN64() ? Mips::AND64 : Mips::AND;415 416 const TargetRegisterClass *RC = ABI.ArePtrs64bit() ?417 &Mips::GPR64RegClass : &Mips::GPR32RegClass;418 419 // First, compute final stack size.420 uint64_t StackSize = MFI.getStackSize();421 422 // No need to allocate space on the stack.423 if (StackSize == 0 && !MFI.adjustsStack()) return;424 425 CFIInstBuilder CFIBuilder(MBB, MBBI, MachineInstr::NoFlags);426 427 // Adjust stack.428 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);429 CFIBuilder.buildDefCFAOffset(StackSize);430 431 if (MF.getFunction().hasFnAttribute("interrupt"))432 emitInterruptPrologueStub(MF, MBB);433 434 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();435 436 // Find the instruction past the last instruction that saves a callee-saved437 // register to the stack.438 std::advance(MBBI, CSI.size());439 CFIBuilder.setInsertPoint(MBBI);440 441 if (!CSI.empty()) {442 // Iterate over list of callee-saved registers and emit .cfi_offset443 // directives.444 for (const CalleeSavedInfo &I : CSI) {445 int64_t Offset = MFI.getObjectOffset(I.getFrameIdx());446 MCRegister Reg = I.getReg();447 448 // If Reg is a double precision register, emit two cfa_offsets,449 // one for each of the paired single precision registers.450 if (Mips::AFGR64RegClass.contains(Reg)) {451 MCRegister Reg0 = RegInfo.getSubReg(Reg, Mips::sub_lo);452 MCRegister Reg1 = RegInfo.getSubReg(Reg, Mips::sub_hi);453 454 if (!STI.isLittle())455 std::swap(Reg0, Reg1);456 457 CFIBuilder.buildOffset(Reg0, Offset);458 CFIBuilder.buildOffset(Reg1, Offset + 4);459 } else if (Mips::FGR64RegClass.contains(Reg)) {460 MCRegister Reg0 = Reg;461 MCRegister Reg1 = Reg + 1;462 463 if (!STI.isLittle())464 std::swap(Reg0, Reg1);465 466 CFIBuilder.buildOffset(Reg0, Offset);467 CFIBuilder.buildOffset(Reg1, Offset + 4);468 } else {469 // Reg is either in GPR32 or FGR32.470 CFIBuilder.buildOffset(Reg, Offset);471 }472 }473 }474 475 if (MipsFI->callsEhReturn()) {476 // Insert instructions that spill eh data registers.477 for (int I = 0; I < 4; ++I) {478 if (!MBB.isLiveIn(ABI.GetEhDataReg(I)))479 MBB.addLiveIn(ABI.GetEhDataReg(I));480 TII.storeRegToStackSlot(MBB, MBBI, ABI.GetEhDataReg(I), false,481 MipsFI->getEhDataRegFI(I), RC, Register());482 }483 484 // Emit .cfi_offset directives for eh data registers.485 for (int I = 0; I < 4; ++I) {486 int64_t Offset = MFI.getObjectOffset(MipsFI->getEhDataRegFI(I));487 CFIBuilder.buildOffset(ABI.GetEhDataReg(I), Offset);488 }489 }490 491 // if framepointer enabled, set it to point to the stack pointer.492 if (hasFP(MF)) {493 // Insert instruction "move $fp, $sp" at this location.494 BuildMI(MBB, MBBI, dl, TII.get(MOVE), FP).addReg(SP).addReg(ZERO)495 .setMIFlag(MachineInstr::FrameSetup);496 497 CFIBuilder.buildDefCFARegister(FP);498 499 if (RegInfo.hasStackRealignment(MF)) {500 // addiu $Reg, $zero, -MaxAlignment501 // andi $sp, $sp, $Reg502 Register VR = MF.getRegInfo().createVirtualRegister(RC);503 assert((Log2(MFI.getMaxAlign()) < 16) &&504 "Function's alignment size requirement is not supported.");505 int64_t MaxAlign = -(int64_t)MFI.getMaxAlign().value();506 507 BuildMI(MBB, MBBI, dl, TII.get(ADDiu), VR).addReg(ZERO).addImm(MaxAlign);508 BuildMI(MBB, MBBI, dl, TII.get(AND), SP).addReg(SP).addReg(VR);509 510 if (hasBP(MF)) {511 // move $s7, $sp512 unsigned BP = STI.isABI_N64() ? Mips::S7_64 : Mips::S7;513 BuildMI(MBB, MBBI, dl, TII.get(MOVE), BP)514 .addReg(SP)515 .addReg(ZERO);516 }517 }518 }519}520 521void MipsSEFrameLowering::emitInterruptPrologueStub(522 MachineFunction &MF, MachineBasicBlock &MBB) const {523 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();524 MachineBasicBlock::iterator MBBI = MBB.begin();525 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();526 527 // Report an error the target doesn't support Mips32r2 or later.528 // The epilogue relies on the use of the "ehb" to clear execution529 // hazards. Pre R2 Mips relies on an implementation defined number530 // of "ssnop"s to clear the execution hazard. Support for ssnop hazard531 // clearing is not provided so reject that configuration.532 if (!STI.hasMips32r2())533 report_fatal_error(534 "\"interrupt\" attribute is not supported on pre-MIPS32R2 or "535 "MIPS16 targets.");536 537 // The GP register contains the "user" value, so we cannot perform538 // any gp relative loads until we restore the "kernel" or "system" gp539 // value. Until support is written we shall only accept the static540 // relocation model.541 if ((STI.getRelocationModel() != Reloc::Static))542 report_fatal_error("\"interrupt\" attribute is only supported for the "543 "static relocation model on MIPS at the present time.");544 545 if (!STI.isABI_O32() || STI.hasMips64())546 report_fatal_error("\"interrupt\" attribute is only supported for the "547 "O32 ABI on MIPS32R2+ at the present time.");548 549 // Perform ISR handling like GCC550 StringRef IntKind =551 MF.getFunction().getFnAttribute("interrupt").getValueAsString();552 const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;553 554 // EIC interrupt handling needs to read the Cause register to disable555 // interrupts.556 if (IntKind == "eic") {557 // Coprocessor registers are always live per se.558 MBB.addLiveIn(Mips::COP013);559 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K0)560 .addReg(Mips::COP013)561 .addImm(0)562 .setMIFlag(MachineInstr::FrameSetup);563 564 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EXT), Mips::K0)565 .addReg(Mips::K0)566 .addImm(10)567 .addImm(6)568 .setMIFlag(MachineInstr::FrameSetup);569 }570 571 // Fetch and spill EPC572 MBB.addLiveIn(Mips::COP014);573 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)574 .addReg(Mips::COP014)575 .addImm(0)576 .setMIFlag(MachineInstr::FrameSetup);577 578 STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,579 MipsFI->getISRRegFI(0), PtrRC, 0);580 581 // Fetch and Spill Status582 MBB.addLiveIn(Mips::COP012);583 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MFC0), Mips::K1)584 .addReg(Mips::COP012)585 .addImm(0)586 .setMIFlag(MachineInstr::FrameSetup);587 588 STI.getInstrInfo()->storeRegToStack(MBB, MBBI, Mips::K1, false,589 MipsFI->getISRRegFI(1), PtrRC, 0);590 591 // Build the configuration for disabling lower priority interrupts. Non EIC592 // interrupts need to be masked off with zero, EIC from the Cause register.593 unsigned InsPosition = 8;594 unsigned InsSize = 0;595 unsigned SrcReg = Mips::ZERO;596 597 // If the interrupt we're tied to is the EIC, switch the source for the598 // masking off interrupts to the cause register.599 if (IntKind == "eic") {600 SrcReg = Mips::K0;601 InsPosition = 10;602 InsSize = 6;603 } else604 InsSize = StringSwitch<unsigned>(IntKind)605 .Case("sw0", 1)606 .Case("sw1", 2)607 .Case("hw0", 3)608 .Case("hw1", 4)609 .Case("hw2", 5)610 .Case("hw3", 6)611 .Case("hw4", 7)612 .Case("hw5", 8)613 .Default(0);614 assert(InsSize != 0 && "Unknown interrupt type!");615 616 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)617 .addReg(SrcReg)618 .addImm(InsPosition)619 .addImm(InsSize)620 .addReg(Mips::K1)621 .setMIFlag(MachineInstr::FrameSetup);622 623 // Mask off KSU, ERL, EXL624 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)625 .addReg(Mips::ZERO)626 .addImm(1)627 .addImm(4)628 .addReg(Mips::K1)629 .setMIFlag(MachineInstr::FrameSetup);630 631 // Disable the FPU as we are not spilling those register sets.632 if (!STI.useSoftFloat())633 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::INS), Mips::K1)634 .addReg(Mips::ZERO)635 .addImm(29)636 .addImm(1)637 .addReg(Mips::K1)638 .setMIFlag(MachineInstr::FrameSetup);639 640 // Set the new status641 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)642 .addReg(Mips::K1)643 .addImm(0)644 .setMIFlag(MachineInstr::FrameSetup);645}646 647void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF,648 MachineBasicBlock &MBB) const {649 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();650 MachineFrameInfo &MFI = MF.getFrameInfo();651 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();652 653 const MipsSEInstrInfo &TII =654 *static_cast<const MipsSEInstrInfo *>(STI.getInstrInfo());655 656 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();657 MipsABIInfo ABI = STI.getABI();658 unsigned SP = ABI.GetStackPtr();659 unsigned FP = ABI.GetFramePtr();660 unsigned ZERO = ABI.GetNullPtr();661 unsigned MOVE = ABI.GetGPRMoveOp();662 663 // if framepointer enabled, restore the stack pointer.664 if (hasFP(MF)) {665 // Find the first instruction that restores a callee-saved register.666 MachineBasicBlock::iterator I = MBBI;667 668 for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i)669 --I;670 671 // Insert instruction "move $sp, $fp" at this location.672 BuildMI(MBB, I, DL, TII.get(MOVE), SP).addReg(FP).addReg(ZERO);673 }674 675 if (MipsFI->callsEhReturn()) {676 const TargetRegisterClass *RC =677 ABI.ArePtrs64bit() ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;678 679 // Find first instruction that restores a callee-saved register.680 MachineBasicBlock::iterator I = MBBI;681 for (unsigned i = 0; i < MFI.getCalleeSavedInfo().size(); ++i)682 --I;683 684 // Insert instructions that restore eh data registers.685 for (int J = 0; J < 4; ++J) {686 TII.loadRegFromStackSlot(MBB, I, ABI.GetEhDataReg(J),687 MipsFI->getEhDataRegFI(J), RC, Register());688 }689 }690 691 if (MF.getFunction().hasFnAttribute("interrupt"))692 emitInterruptEpilogueStub(MF, MBB);693 694 // Get the number of bytes from FrameInfo695 uint64_t StackSize = MFI.getStackSize();696 697 if (!StackSize)698 return;699 700 // Adjust stack.701 TII.adjustStackPtr(SP, StackSize, MBB, MBBI);702}703 704void MipsSEFrameLowering::emitInterruptEpilogueStub(705 MachineFunction &MF, MachineBasicBlock &MBB) const {706 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();707 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();708 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();709 710 // Perform ISR handling like GCC711 const TargetRegisterClass *PtrRC = &Mips::GPR32RegClass;712 713 // Disable Interrupts.714 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::DI), Mips::ZERO);715 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::EHB));716 717 // Restore EPC718 STI.getInstrInfo()->loadRegFromStackSlot(719 MBB, MBBI, Mips::K1, MipsFI->getISRRegFI(0), PtrRC, Register());720 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP014)721 .addReg(Mips::K1)722 .addImm(0);723 724 // Restore Status725 STI.getInstrInfo()->loadRegFromStackSlot(726 MBB, MBBI, Mips::K1, MipsFI->getISRRegFI(1), PtrRC, Register());727 BuildMI(MBB, MBBI, DL, STI.getInstrInfo()->get(Mips::MTC0), Mips::COP012)728 .addReg(Mips::K1)729 .addImm(0);730}731 732StackOffset733MipsSEFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,734 Register &FrameReg) const {735 const MachineFrameInfo &MFI = MF.getFrameInfo();736 MipsABIInfo ABI = STI.getABI();737 738 if (MFI.isFixedObjectIndex(FI))739 FrameReg = hasFP(MF) ? ABI.GetFramePtr() : ABI.GetStackPtr();740 else741 FrameReg = hasBP(MF) ? ABI.GetBasePtr() : ABI.GetStackPtr();742 743 return StackOffset::getFixed(MFI.getObjectOffset(FI) + MFI.getStackSize() -744 getOffsetOfLocalArea() +745 MFI.getOffsetAdjustment());746}747 748bool MipsSEFrameLowering::spillCalleeSavedRegisters(749 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,750 ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {751 MachineFunction *MF = MBB.getParent();752 const TargetInstrInfo &TII = *STI.getInstrInfo();753 754 for (const CalleeSavedInfo &I : CSI) {755 // Add the callee-saved register as live-in. Do not add if the register is756 // RA and return address is taken, because it has already been added in757 // method MipsTargetLowering::lowerRETURNADDR.758 // It's killed at the spill, unless the register is RA and return address759 // is taken.760 MCRegister Reg = I.getReg();761 bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64)762 && MF->getFrameInfo().isReturnAddressTaken();763 if (!IsRAAndRetAddrIsTaken)764 MBB.addLiveIn(Reg);765 766 // ISRs require HI/LO to be spilled into kernel registers to be then767 // spilled to the stack frame.768 bool IsLOHI = (Reg == Mips::LO0 || Reg == Mips::LO0_64 ||769 Reg == Mips::HI0 || Reg == Mips::HI0_64);770 const Function &Func = MBB.getParent()->getFunction();771 if (IsLOHI && Func.hasFnAttribute("interrupt")) {772 DebugLoc DL = MI->getDebugLoc();773 774 unsigned Op = 0;775 if (!STI.getABI().ArePtrs64bit()) {776 Op = (Reg == Mips::HI0) ? Mips::MFHI : Mips::MFLO;777 Reg = Mips::K0;778 } else {779 Op = (Reg == Mips::HI0) ? Mips::MFHI64 : Mips::MFLO64;780 Reg = Mips::K0_64;781 }782 BuildMI(MBB, MI, DL, TII.get(Op), Mips::K0)783 .setMIFlag(MachineInstr::FrameSetup);784 }785 786 // Insert the spill to the stack frame.787 bool IsKill = !IsRAAndRetAddrIsTaken;788 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);789 TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, I.getFrameIdx(), RC,790 Register());791 }792 793 return true;794}795 796bool797MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {798 const MachineFrameInfo &MFI = MF.getFrameInfo();799 // Reserve call frame if the size of the maximum call frame fits into 16-bit800 // immediate field and there are no variable sized objects on the stack.801 // Make sure the second register scavenger spill slot can be accessed with one802 // instruction.803 return isInt<16>(MFI.getMaxCallFrameSize() + getStackAlignment()) &&804 !MFI.hasVarSizedObjects();805}806 807/// Mark \p Reg and all registers aliasing it in the bitset.808static void setAliasRegs(MachineFunction &MF, BitVector &SavedRegs,809 unsigned Reg) {810 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();811 for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)812 SavedRegs.set(*AI);813}814 815void MipsSEFrameLowering::determineCalleeSaves(MachineFunction &MF,816 BitVector &SavedRegs,817 RegScavenger *RS) const {818 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);819 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();820 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();821 MipsABIInfo ABI = STI.getABI();822 unsigned RA = ABI.IsN64() ? Mips::RA_64 : Mips::RA;823 unsigned FP = ABI.GetFramePtr();824 unsigned BP = ABI.IsN64() ? Mips::S7_64 : Mips::S7;825 826 // Mark $ra and $fp as used if function has dedicated frame pointer.827 if (hasFP(MF)) {828 setAliasRegs(MF, SavedRegs, RA);829 setAliasRegs(MF, SavedRegs, FP);830 }831 // Mark $s7 as used if function has dedicated base pointer.832 if (hasBP(MF))833 setAliasRegs(MF, SavedRegs, BP);834 835 // Create spill slots for eh data registers if function calls eh_return.836 if (MipsFI->callsEhReturn())837 MipsFI->createEhDataRegsFI(MF);838 839 // Create spill slots for Coprocessor 0 registers if function is an ISR.840 if (MipsFI->isISR())841 MipsFI->createISRRegFI(MF);842 843 // Expand pseudo instructions which load, store or copy accumulators.844 // Add an emergency spill slot if a pseudo was expanded.845 if (ExpandPseudo(MF).expand()) {846 // The spill slot should be half the size of the accumulator. If target have847 // general-purpose registers 64 bits wide, it should be 64-bit, otherwise848 // it should be 32-bit.849 const TargetRegisterClass &RC = STI.isGP64bit() ?850 Mips::GPR64RegClass : Mips::GPR32RegClass;851 int FI = MF.getFrameInfo().CreateSpillStackObject(TRI->getSpillSize(RC),852 TRI->getSpillAlign(RC));853 RS->addScavengingFrameIndex(FI);854 }855 856 // Set scavenging frame index if necessary.857 uint64_t MaxSPOffset = estimateStackSize(MF);858 859 // MSA has a minimum offset of 10 bits signed. If there is a variable860 // sized object on the stack, the estimation cannot account for it.861 if (isIntN(STI.hasMSA() ? 10 : 16, MaxSPOffset) &&862 !MF.getFrameInfo().hasVarSizedObjects())863 return;864 865 const TargetRegisterClass &RC =866 ABI.ArePtrs64bit() ? Mips::GPR64RegClass : Mips::GPR32RegClass;867 int FI = MF.getFrameInfo().CreateSpillStackObject(TRI->getSpillSize(RC),868 TRI->getSpillAlign(RC));869 RS->addScavengingFrameIndex(FI);870}871 872const MipsFrameLowering *873llvm::createMipsSEFrameLowering(const MipsSubtarget &ST) {874 return new MipsSEFrameLowering(ST);875}876