brintos

brintos / llvm-project-archived public Read only

0
0
Text · 32.1 KiB · 942194c Raw
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