brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.0 KiB · a1d0aa0 Raw
883 lines · cpp
1//===-- MipsSEInstrInfo.cpp - Mips32/64 Instruction 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 the TargetInstrInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "MipsSEInstrInfo.h"14#include "MipsAnalyzeImmediate.h"15#include "MipsTargetMachine.h"16#include "llvm/CodeGen/MachineInstrBuilder.h"17#include "llvm/CodeGen/MachineRegisterInfo.h"18#include "llvm/MC/TargetRegistry.h"19#include "llvm/Support/ErrorHandling.h"20#include "llvm/Support/MathExtras.h"21 22using namespace llvm;23 24static unsigned getUnconditionalBranch(const MipsSubtarget &STI) {25  if (STI.inMicroMipsMode())26    return STI.isPositionIndependent() ? Mips::B_MM : Mips::J_MM;27  return STI.isPositionIndependent() ? Mips::B : Mips::J;28}29 30MipsSEInstrInfo::MipsSEInstrInfo(const MipsSubtarget &STI)31    : MipsInstrInfo(STI, RI, getUnconditionalBranch(STI)), RI(STI) {}32 33/// isLoadFromStackSlot - If the specified machine instruction is a direct34/// load from a stack slot, return the virtual or physical register number of35/// the destination along with the FrameIndex of the loaded stack slot.  If36/// not, return 0.  This predicate must return 0 if the instruction has37/// any side effects other than loading from the stack slot.38Register MipsSEInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,39                                              int &FrameIndex) const {40  unsigned Opc = MI.getOpcode();41 42  if ((Opc == Mips::LW)   || (Opc == Mips::LD)   ||43      (Opc == Mips::LWC1) || (Opc == Mips::LDC1) || (Opc == Mips::LDC164)) {44    if ((MI.getOperand(1).isFI()) &&  // is a stack slot45        (MI.getOperand(2).isImm()) && // the imm is zero46        (isZeroImm(MI.getOperand(2)))) {47      FrameIndex = MI.getOperand(1).getIndex();48      return MI.getOperand(0).getReg();49    }50  }51 52  return 0;53}54 55/// isStoreToStackSlot - If the specified machine instruction is a direct56/// store to a stack slot, return the virtual or physical register number of57/// the source reg along with the FrameIndex of the loaded stack slot.  If58/// not, return 0.  This predicate must return 0 if the instruction has59/// any side effects other than storing to the stack slot.60Register MipsSEInstrInfo::isStoreToStackSlot(const MachineInstr &MI,61                                             int &FrameIndex) const {62  unsigned Opc = MI.getOpcode();63 64  if ((Opc == Mips::SW)   || (Opc == Mips::SD)   ||65      (Opc == Mips::SWC1) || (Opc == Mips::SDC1) || (Opc == Mips::SDC164)) {66    if ((MI.getOperand(1).isFI()) &&  // is a stack slot67        (MI.getOperand(2).isImm()) && // the imm is zero68        (isZeroImm(MI.getOperand(2)))) {69      FrameIndex = MI.getOperand(1).getIndex();70      return MI.getOperand(0).getReg();71    }72  }73  return 0;74}75 76void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,77                                  MachineBasicBlock::iterator I,78                                  const DebugLoc &DL, Register DestReg,79                                  Register SrcReg, bool KillSrc,80                                  bool RenamableDest, bool RenamableSrc) const {81  unsigned Opc = 0, ZeroReg = 0;82  bool isMicroMips = Subtarget.inMicroMipsMode();83 84  if (Mips::GPR32RegClass.contains(DestReg)) { // Copy to CPU Reg.85    if (Mips::GPR32RegClass.contains(SrcReg)) {86      if (isMicroMips)87        Opc = Mips::MOVE16_MM;88      else89        Opc = Mips::OR, ZeroReg = Mips::ZERO;90    } else if (Mips::CCRRegClass.contains(SrcReg))91      Opc = Mips::CFC1;92    else if (Mips::FGR32RegClass.contains(SrcReg))93      Opc = Mips::MFC1;94    else if (Mips::HI32RegClass.contains(SrcReg)) {95      Opc = isMicroMips ? Mips::MFHI16_MM : Mips::MFHI;96      SrcReg = 0;97    } else if (Mips::LO32RegClass.contains(SrcReg)) {98      Opc = isMicroMips ? Mips::MFLO16_MM : Mips::MFLO;99      SrcReg = 0;100    } else if (Mips::HI32DSPRegClass.contains(SrcReg))101      Opc = Mips::MFHI_DSP;102    else if (Mips::LO32DSPRegClass.contains(SrcReg))103      Opc = Mips::MFLO_DSP;104    else if (Mips::DSPCCRegClass.contains(SrcReg)) {105      BuildMI(MBB, I, DL, get(Mips::RDDSP), DestReg).addImm(1 << 4)106        .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc));107      return;108    }109    else if (Mips::MSACtrlRegClass.contains(SrcReg))110      Opc = Mips::CFCMSA;111  }112  else if (Mips::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg.113    if (Mips::CCRRegClass.contains(DestReg))114      Opc = Mips::CTC1;115    else if (Mips::FGR32RegClass.contains(DestReg))116      Opc = Mips::MTC1;117    else if (Mips::HI32RegClass.contains(DestReg))118      Opc = Mips::MTHI, DestReg = 0;119    else if (Mips::LO32RegClass.contains(DestReg))120      Opc = Mips::MTLO, DestReg = 0;121    else if (Mips::HI32DSPRegClass.contains(DestReg))122      Opc = Mips::MTHI_DSP;123    else if (Mips::LO32DSPRegClass.contains(DestReg))124      Opc = Mips::MTLO_DSP;125    else if (Mips::DSPCCRegClass.contains(DestReg)) {126      BuildMI(MBB, I, DL, get(Mips::WRDSP))127        .addReg(SrcReg, getKillRegState(KillSrc)).addImm(1 << 4)128        .addReg(DestReg, RegState::ImplicitDefine);129      return;130    } else if (Mips::MSACtrlRegClass.contains(DestReg)) {131      BuildMI(MBB, I, DL, get(Mips::CTCMSA))132          .addReg(DestReg)133          .addReg(SrcReg, getKillRegState(KillSrc));134      return;135    }136  }137  else if (Mips::FGR32RegClass.contains(DestReg, SrcReg))138    Opc = Mips::FMOV_S;139  else if (Mips::AFGR64RegClass.contains(DestReg, SrcReg))140    Opc = Mips::FMOV_D32;141  else if (Mips::FGR64RegClass.contains(DestReg, SrcReg))142    Opc = Mips::FMOV_D64;143  else if (Mips::GPR64RegClass.contains(DestReg)) { // Copy to CPU64 Reg.144    if (Mips::GPR64RegClass.contains(SrcReg))145      Opc = Mips::OR64, ZeroReg = Mips::ZERO_64;146    else if (Mips::HI64RegClass.contains(SrcReg))147      Opc = Mips::MFHI64, SrcReg = 0;148    else if (Mips::LO64RegClass.contains(SrcReg))149      Opc = Mips::MFLO64, SrcReg = 0;150    else if (Mips::FGR64RegClass.contains(SrcReg))151      Opc = Mips::DMFC1;152  }153  else if (Mips::GPR64RegClass.contains(SrcReg)) { // Copy from CPU64 Reg.154    if (Mips::HI64RegClass.contains(DestReg))155      Opc = Mips::MTHI64, DestReg = 0;156    else if (Mips::LO64RegClass.contains(DestReg))157      Opc = Mips::MTLO64, DestReg = 0;158    else if (Mips::FGR64RegClass.contains(DestReg))159      Opc = Mips::DMTC1;160  }161  else if (Mips::MSA128BRegClass.contains(DestReg)) { // Copy to MSA reg162    if (Mips::MSA128BRegClass.contains(SrcReg))163      Opc = Mips::MOVE_V;164  }165 166  assert(Opc && "Cannot copy registers");167 168  MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc));169 170  if (DestReg)171    MIB.addReg(DestReg, RegState::Define);172 173  if (SrcReg)174    MIB.addReg(SrcReg, getKillRegState(KillSrc));175 176  if (ZeroReg)177    MIB.addReg(ZeroReg);178}179 180static bool isORCopyInst(const MachineInstr &MI) {181  switch (MI.getOpcode()) {182  default:183    break;184  case Mips::OR_MM:185  case Mips::OR:186    if (MI.getOperand(2).getReg() == Mips::ZERO)187      return true;188    break;189  case Mips::OR64:190    if (MI.getOperand(2).getReg() == Mips::ZERO_64)191      return true;192    break;193  }194  return false;195}196 197/// We check for the common case of 'or', as it's MIPS' preferred instruction198/// for GPRs but we have to check the operands to ensure that is the case.199/// Other move instructions for MIPS are directly identifiable.200std::optional<DestSourcePair>201MipsSEInstrInfo::isCopyInstrImpl(const MachineInstr &MI) const {202  if (MI.isMoveReg() || isORCopyInst(MI))203    return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};204 205  return std::nullopt;206}207 208void MipsSEInstrInfo::storeRegToStack(MachineBasicBlock &MBB,209                                      MachineBasicBlock::iterator I,210                                      Register SrcReg, bool isKill, int FI,211                                      const TargetRegisterClass *RC,212                                      int64_t Offset,213                                      MachineInstr::MIFlag Flags) const {214  DebugLoc DL;215  MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore);216 217  unsigned Opc = 0;218 219  if (Mips::GPR32RegClass.hasSubClassEq(RC))220    Opc = Mips::SW;221  else if (Mips::GPR64RegClass.hasSubClassEq(RC))222    Opc = Mips::SD;223  else if (Mips::ACC64RegClass.hasSubClassEq(RC))224    Opc = Mips::STORE_ACC64;225  else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC))226    Opc = Mips::STORE_ACC64DSP;227  else if (Mips::ACC128RegClass.hasSubClassEq(RC))228    Opc = Mips::STORE_ACC128;229  else if (Mips::DSPCCRegClass.hasSubClassEq(RC))230    Opc = Mips::STORE_CCOND_DSP;231  else if (Mips::FGR32RegClass.hasSubClassEq(RC))232    Opc = Mips::SWC1;233  else if (Mips::AFGR64RegClass.hasSubClassEq(RC))234    Opc = Mips::SDC1;235  else if (Mips::FGR64RegClass.hasSubClassEq(RC))236    Opc = Mips::SDC164;237  else if (RI.isTypeLegalForClass(*RC, MVT::v16i8))238    Opc = Mips::ST_B;239  else if (RI.isTypeLegalForClass(*RC, MVT::v8i16) ||240           RI.isTypeLegalForClass(*RC, MVT::v8f16))241    Opc = Mips::ST_H;242  else if (RI.isTypeLegalForClass(*RC, MVT::v4i32) ||243           RI.isTypeLegalForClass(*RC, MVT::v4f32))244    Opc = Mips::ST_W;245  else if (RI.isTypeLegalForClass(*RC, MVT::v2i64) ||246           RI.isTypeLegalForClass(*RC, MVT::v2f64))247    Opc = Mips::ST_D;248  else if (Mips::LO32RegClass.hasSubClassEq(RC))249    Opc = Mips::SW;250  else if (Mips::LO64RegClass.hasSubClassEq(RC))251    Opc = Mips::SD;252  else if (Mips::HI32RegClass.hasSubClassEq(RC))253    Opc = Mips::SW;254  else if (Mips::HI64RegClass.hasSubClassEq(RC))255    Opc = Mips::SD;256  else if (Mips::DSPRRegClass.hasSubClassEq(RC))257    Opc = Mips::SWDSP;258 259  // Hi, Lo are normally caller save but they are callee save260  // for interrupt handling.261  const Function &Func = MBB.getParent()->getFunction();262  if (Func.hasFnAttribute("interrupt")) {263    if (Mips::HI32RegClass.hasSubClassEq(RC)) {264      BuildMI(MBB, I, DL, get(Mips::MFHI), Mips::K0);265      SrcReg = Mips::K0;266    } else if (Mips::HI64RegClass.hasSubClassEq(RC)) {267      BuildMI(MBB, I, DL, get(Mips::MFHI64), Mips::K0_64);268      SrcReg = Mips::K0_64;269    } else if (Mips::LO32RegClass.hasSubClassEq(RC)) {270      BuildMI(MBB, I, DL, get(Mips::MFLO), Mips::K0);271      SrcReg = Mips::K0;272    } else if (Mips::LO64RegClass.hasSubClassEq(RC)) {273      BuildMI(MBB, I, DL, get(Mips::MFLO64), Mips::K0_64);274      SrcReg = Mips::K0_64;275    }276  }277 278  assert(Opc && "Register class not handled!");279  BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill))280    .addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);281}282 283void MipsSEInstrInfo::loadRegFromStack(MachineBasicBlock &MBB,284                                       MachineBasicBlock::iterator I,285                                       Register DestReg, int FI,286                                       const TargetRegisterClass *RC,287                                       int64_t Offset,288                                       MachineInstr::MIFlag Flags) const {289  DebugLoc DL;290  if (I != MBB.end()) DL = I->getDebugLoc();291  MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad);292  unsigned Opc = 0;293 294  const Function &Func = MBB.getParent()->getFunction();295  bool ReqIndirectLoad = Func.hasFnAttribute("interrupt") &&296                         (DestReg == Mips::LO0 || DestReg == Mips::LO0_64 ||297                          DestReg == Mips::HI0 || DestReg == Mips::HI0_64);298 299  if (Mips::GPR32RegClass.hasSubClassEq(RC))300    Opc = Mips::LW;301  else if (Mips::GPR64RegClass.hasSubClassEq(RC))302    Opc = Mips::LD;303  else if (Mips::ACC64RegClass.hasSubClassEq(RC))304    Opc = Mips::LOAD_ACC64;305  else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC))306    Opc = Mips::LOAD_ACC64DSP;307  else if (Mips::ACC128RegClass.hasSubClassEq(RC))308    Opc = Mips::LOAD_ACC128;309  else if (Mips::DSPCCRegClass.hasSubClassEq(RC))310    Opc = Mips::LOAD_CCOND_DSP;311  else if (Mips::FGR32RegClass.hasSubClassEq(RC))312    Opc = Mips::LWC1;313  else if (Mips::AFGR64RegClass.hasSubClassEq(RC))314    Opc = Mips::LDC1;315  else if (Mips::FGR64RegClass.hasSubClassEq(RC))316    Opc = Mips::LDC164;317  else if (RI.isTypeLegalForClass(*RC, MVT::v16i8))318    Opc = Mips::LD_B;319  else if (RI.isTypeLegalForClass(*RC, MVT::v8i16) ||320           RI.isTypeLegalForClass(*RC, MVT::v8f16))321    Opc = Mips::LD_H;322  else if (RI.isTypeLegalForClass(*RC, MVT::v4i32) ||323           RI.isTypeLegalForClass(*RC, MVT::v4f32))324    Opc = Mips::LD_W;325  else if (RI.isTypeLegalForClass(*RC, MVT::v2i64) ||326           RI.isTypeLegalForClass(*RC, MVT::v2f64))327    Opc = Mips::LD_D;328  else if (Mips::HI32RegClass.hasSubClassEq(RC))329    Opc = Mips::LW;330  else if (Mips::HI64RegClass.hasSubClassEq(RC))331    Opc = Mips::LD;332  else if (Mips::LO32RegClass.hasSubClassEq(RC))333    Opc = Mips::LW;334  else if (Mips::LO64RegClass.hasSubClassEq(RC))335    Opc = Mips::LD;336  else if (Mips::DSPRRegClass.hasSubClassEq(RC))337    Opc = Mips::LWDSP;338 339  assert(Opc && "Register class not handled!");340 341  if (!ReqIndirectLoad)342    BuildMI(MBB, I, DL, get(Opc), DestReg)343        .addFrameIndex(FI)344        .addImm(Offset)345        .addMemOperand(MMO);346  else {347    // Load HI/LO through K0. Notably the DestReg is encoded into the348    // instruction itself.349    unsigned Reg = Mips::K0;350    unsigned LdOp = Mips::MTLO;351    if (DestReg == Mips::HI0)352      LdOp = Mips::MTHI;353 354    if (Subtarget.getABI().ArePtrs64bit()) {355      Reg = Mips::K0_64;356      if (DestReg == Mips::HI0_64)357        LdOp = Mips::MTHI64;358      else359        LdOp = Mips::MTLO64;360    }361 362    BuildMI(MBB, I, DL, get(Opc), Reg)363        .addFrameIndex(FI)364        .addImm(Offset)365        .addMemOperand(MMO);366    BuildMI(MBB, I, DL, get(LdOp)).addReg(Reg);367  }368}369 370bool MipsSEInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {371  MachineBasicBlock &MBB = *MI.getParent();372  bool isMicroMips = Subtarget.inMicroMipsMode();373  unsigned Opc;374 375  switch (MI.getDesc().getOpcode()) {376  default:377    return false;378  case Mips::RetRA:379    expandRetRA(MBB, MI);380    break;381  case Mips::ERet:382    expandERet(MBB, MI);383    break;384  case Mips::PseudoMFHI:385    expandPseudoMFHiLo(MBB, MI, Mips::MFHI);386    break;387  case Mips::PseudoMFHI_MM:388    expandPseudoMFHiLo(MBB, MI, Mips::MFHI16_MM);389    break;390  case Mips::PseudoMFLO:391    expandPseudoMFHiLo(MBB, MI, Mips::MFLO);392    break;393  case Mips::PseudoMFLO_MM:394    expandPseudoMFHiLo(MBB, MI, Mips::MFLO16_MM);395    break;396  case Mips::PseudoMFHI64:397    expandPseudoMFHiLo(MBB, MI, Mips::MFHI64);398    break;399  case Mips::PseudoMFLO64:400    expandPseudoMFHiLo(MBB, MI, Mips::MFLO64);401    break;402  case Mips::PseudoMTLOHI:403    expandPseudoMTLoHi(MBB, MI, Mips::MTLO, Mips::MTHI, false);404    break;405  case Mips::PseudoMTLOHI64:406    expandPseudoMTLoHi(MBB, MI, Mips::MTLO64, Mips::MTHI64, false);407    break;408  case Mips::PseudoMTLOHI_DSP:409    expandPseudoMTLoHi(MBB, MI, Mips::MTLO_DSP, Mips::MTHI_DSP, true);410    break;411  case Mips::PseudoMTLOHI_MM:412    expandPseudoMTLoHi(MBB, MI, Mips::MTLO_MM, Mips::MTHI_MM, false);413    break;414  case Mips::PseudoCVT_S_W:415    expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false);416    break;417  case Mips::PseudoCVT_D32_W:418    Opc = isMicroMips ? Mips::CVT_D32_W_MM : Mips::CVT_D32_W;419    expandCvtFPInt(MBB, MI, Opc, Mips::MTC1, false);420    break;421  case Mips::PseudoCVT_S_L:422    expandCvtFPInt(MBB, MI, Mips::CVT_S_L, Mips::DMTC1, true);423    break;424  case Mips::PseudoCVT_D64_W:425    Opc = isMicroMips ? Mips::CVT_D64_W_MM : Mips::CVT_D64_W;426    expandCvtFPInt(MBB, MI, Opc, Mips::MTC1, true);427    break;428  case Mips::PseudoCVT_D64_L:429    expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true);430    break;431  case Mips::BuildPairF64:432    expandBuildPairF64(MBB, MI, isMicroMips, false);433    break;434  case Mips::BuildPairF64_64:435    expandBuildPairF64(MBB, MI, isMicroMips, true);436    break;437  case Mips::ExtractElementF64:438    expandExtractElementF64(MBB, MI, isMicroMips, false);439    break;440  case Mips::ExtractElementF64_64:441    expandExtractElementF64(MBB, MI, isMicroMips, true);442    break;443  case Mips::MIPSeh_return32:444  case Mips::MIPSeh_return64:445    expandEhReturn(MBB, MI);446    break;447  }448 449  MBB.erase(MI);450  return true;451}452 453/// isBranchWithImm - Return true if the branch contains an immediate454/// operand (\see lib/Target/Mips/MipsBranchExpansion.cpp).455bool MipsSEInstrInfo::isBranchWithImm(unsigned Opc) const {456  switch (Opc) {457  default:458    return false;459  case Mips::BBIT0:460  case Mips::BBIT1:461  case Mips::BBIT032:462  case Mips::BBIT132:463    return true;464  }465}466 467/// getOppositeBranchOpc - Return the inverse of the specified468/// opcode, e.g. turning BEQ to BNE.469unsigned MipsSEInstrInfo::getOppositeBranchOpc(unsigned Opc) const {470  switch (Opc) {471  default:           llvm_unreachable("Illegal opcode!");472  case Mips::BEQ:    return Mips::BNE;473  case Mips::BEQ_MM: return Mips::BNE_MM;474  case Mips::BNE:    return Mips::BEQ;475  case Mips::BNE_MM: return Mips::BEQ_MM;476  case Mips::BGTZ:   return Mips::BLEZ;477  case Mips::BGEZ:   return Mips::BLTZ;478  case Mips::BLTZ:   return Mips::BGEZ;479  case Mips::BLEZ:   return Mips::BGTZ;480  case Mips::BGTZ_MM:   return Mips::BLEZ_MM;481  case Mips::BGEZ_MM:   return Mips::BLTZ_MM;482  case Mips::BLTZ_MM:   return Mips::BGEZ_MM;483  case Mips::BLEZ_MM:   return Mips::BGTZ_MM;484  case Mips::BEQ64:  return Mips::BNE64;485  case Mips::BNE64:  return Mips::BEQ64;486  case Mips::BGTZ64: return Mips::BLEZ64;487  case Mips::BGEZ64: return Mips::BLTZ64;488  case Mips::BLTZ64: return Mips::BGEZ64;489  case Mips::BLEZ64: return Mips::BGTZ64;490  case Mips::BC1T:   return Mips::BC1F;491  case Mips::BC1F:   return Mips::BC1T;492  case Mips::BC1T_MM:   return Mips::BC1F_MM;493  case Mips::BC1F_MM:   return Mips::BC1T_MM;494  case Mips::BEQZ16_MM: return Mips::BNEZ16_MM;495  case Mips::BNEZ16_MM: return Mips::BEQZ16_MM;496  case Mips::BEQZC_MM:  return Mips::BNEZC_MM;497  case Mips::BNEZC_MM:  return Mips::BEQZC_MM;498  case Mips::BEQZC:  return Mips::BNEZC;499  case Mips::BNEZC:  return Mips::BEQZC;500  case Mips::BLEZC:  return Mips::BGTZC;501  case Mips::BGEZC:  return Mips::BLTZC;502  case Mips::BGEC:   return Mips::BLTC;503  case Mips::BGTZC:  return Mips::BLEZC;504  case Mips::BLTZC:  return Mips::BGEZC;505  case Mips::BLTC:   return Mips::BGEC;506  case Mips::BGEUC:  return Mips::BLTUC;507  case Mips::BLTUC:  return Mips::BGEUC;508  case Mips::BEQC:   return Mips::BNEC;509  case Mips::BNEC:   return Mips::BEQC;510  case Mips::BC1EQZ: return Mips::BC1NEZ;511  case Mips::BC1NEZ: return Mips::BC1EQZ;512  case Mips::BEQZC_MMR6:  return Mips::BNEZC_MMR6;513  case Mips::BNEZC_MMR6:  return Mips::BEQZC_MMR6;514  case Mips::BLEZC_MMR6:  return Mips::BGTZC_MMR6;515  case Mips::BGEZC_MMR6:  return Mips::BLTZC_MMR6;516  case Mips::BGEC_MMR6:   return Mips::BLTC_MMR6;517  case Mips::BGTZC_MMR6:  return Mips::BLEZC_MMR6;518  case Mips::BLTZC_MMR6:  return Mips::BGEZC_MMR6;519  case Mips::BLTC_MMR6:   return Mips::BGEC_MMR6;520  case Mips::BGEUC_MMR6:  return Mips::BLTUC_MMR6;521  case Mips::BLTUC_MMR6:  return Mips::BGEUC_MMR6;522  case Mips::BEQC_MMR6:   return Mips::BNEC_MMR6;523  case Mips::BNEC_MMR6:   return Mips::BEQC_MMR6;524  case Mips::BC1EQZC_MMR6: return Mips::BC1NEZC_MMR6;525  case Mips::BC1NEZC_MMR6: return Mips::BC1EQZC_MMR6;526  case Mips::BEQZC64:  return Mips::BNEZC64;527  case Mips::BNEZC64:  return Mips::BEQZC64;528  case Mips::BEQC64:   return Mips::BNEC64;529  case Mips::BNEC64:   return Mips::BEQC64;530  case Mips::BGEC64:   return Mips::BLTC64;531  case Mips::BGEUC64:  return Mips::BLTUC64;532  case Mips::BLTC64:   return Mips::BGEC64;533  case Mips::BLTUC64:  return Mips::BGEUC64;534  case Mips::BGTZC64:  return Mips::BLEZC64;535  case Mips::BGEZC64:  return Mips::BLTZC64;536  case Mips::BLTZC64:  return Mips::BGEZC64;537  case Mips::BLEZC64:  return Mips::BGTZC64;538  case Mips::BBIT0:  return Mips::BBIT1;539  case Mips::BBIT1:  return Mips::BBIT0;540  case Mips::BBIT032:  return Mips::BBIT132;541  case Mips::BBIT132:  return Mips::BBIT032;542  case Mips::BZ_B:   return Mips::BNZ_B;543  case Mips::BZ_H:   return Mips::BNZ_H;544  case Mips::BZ_W:   return Mips::BNZ_W;545  case Mips::BZ_D:   return Mips::BNZ_D;546  case Mips::BZ_V:   return Mips::BNZ_V;547  case Mips::BNZ_B:  return Mips::BZ_B;548  case Mips::BNZ_H:  return Mips::BZ_H;549  case Mips::BNZ_W:  return Mips::BZ_W;550  case Mips::BNZ_D:  return Mips::BZ_D;551  case Mips::BNZ_V:  return Mips::BZ_V;552  }553}554 555/// Adjust SP by Amount bytes.556void MipsSEInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,557                                     MachineBasicBlock &MBB,558                                     MachineBasicBlock::iterator I) const {559  MipsABIInfo ABI = Subtarget.getABI();560  DebugLoc DL;561  unsigned ADDiu = ABI.GetPtrAddiuOp();562 563  if (Amount == 0)564    return;565 566  if (isInt<16>(Amount)) {567    // addi sp, sp, amount568    BuildMI(MBB, I, DL, get(ADDiu), SP).addReg(SP).addImm(Amount);569  } else {570    // For numbers which are not 16bit integers we synthesize Amount inline571    // then add or subtract it from sp.572    unsigned Opc = ABI.GetPtrAdduOp();573    if (Amount < 0) {574      Opc = ABI.GetPtrSubuOp();575      Amount = -Amount;576    }577    unsigned Reg = loadImmediate(Amount, MBB, I, DL, nullptr);578    BuildMI(MBB, I, DL, get(Opc), SP).addReg(SP).addReg(Reg, RegState::Kill);579  }580}581 582/// This function generates the sequence of instructions needed to get the583/// result of adding register REG and immediate IMM.584unsigned MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB,585                                        MachineBasicBlock::iterator II,586                                        const DebugLoc &DL,587                                        unsigned *NewImm) const {588  MipsAnalyzeImmediate AnalyzeImm;589  const MipsSubtarget &STI = Subtarget;590  MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();591  unsigned Size = STI.isABI_N64() ? 64 : 32;592  unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi;593  unsigned ZEROReg = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;594  const TargetRegisterClass *RC = STI.isABI_N64() ?595    &Mips::GPR64RegClass : &Mips::GPR32RegClass;596  bool LastInstrIsADDiu = NewImm;597 598  const MipsAnalyzeImmediate::InstSeq &Seq =599    AnalyzeImm.Analyze(Imm, Size, LastInstrIsADDiu);600  MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();601 602  assert(Seq.size() && (!LastInstrIsADDiu || (Seq.size() > 1)));603 604  // The first instruction can be a LUi, which is different from other605  // instructions (ADDiu, ORI and SLL) in that it does not have a register606  // operand.607  Register Reg = RegInfo.createVirtualRegister(RC);608 609  if (Inst->Opc == LUi)610    BuildMI(MBB, II, DL, get(LUi), Reg).addImm(SignExtend64<16>(Inst->ImmOpnd));611  else612    BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(ZEROReg)613      .addImm(SignExtend64<16>(Inst->ImmOpnd));614 615  // Build the remaining instructions in Seq.616  for (++Inst; Inst != Seq.end() - LastInstrIsADDiu; ++Inst)617    BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(Reg, RegState::Kill)618      .addImm(SignExtend64<16>(Inst->ImmOpnd));619 620  if (LastInstrIsADDiu)621    *NewImm = Inst->ImmOpnd;622 623  return Reg;624}625 626unsigned MipsSEInstrInfo::getAnalyzableBrOpc(unsigned Opc) const {627  return (Opc == Mips::BEQ    || Opc == Mips::BEQ_MM || Opc == Mips::BNE    ||628          Opc == Mips::BNE_MM || Opc == Mips::BGTZ   || Opc == Mips::BGEZ   ||629          Opc == Mips::BLTZ   || Opc == Mips::BLEZ   || Opc == Mips::BEQ64  ||630          Opc == Mips::BNE64  || Opc == Mips::BGTZ64 || Opc == Mips::BGEZ64 ||631          Opc == Mips::BLTZ64 || Opc == Mips::BLEZ64 || Opc == Mips::BC1T   ||632          Opc == Mips::BC1F   || Opc == Mips::B      || Opc == Mips::J      ||633          Opc == Mips::J_MM   || Opc == Mips::B_MM   || Opc == Mips::BEQZC_MM ||634          Opc == Mips::BNEZC_MM || Opc == Mips::BEQC || Opc == Mips::BNEC   ||635          Opc == Mips::BLTC   || Opc == Mips::BGEC   || Opc == Mips::BLTUC  ||636          Opc == Mips::BGEUC  || Opc == Mips::BGTZC  || Opc == Mips::BLEZC  ||637          Opc == Mips::BGEZC  || Opc == Mips::BLTZC  || Opc == Mips::BEQZC  ||638          Opc == Mips::BNEZC  || Opc == Mips::BEQZC64 || Opc == Mips::BNEZC64 ||639          Opc == Mips::BEQC64 || Opc == Mips::BNEC64 || Opc == Mips::BGEC64 ||640          Opc == Mips::BGEUC64 || Opc == Mips::BLTC64 || Opc == Mips::BLTUC64 ||641          Opc == Mips::BGTZC64 || Opc == Mips::BGEZC64 ||642          Opc == Mips::BLTZC64 || Opc == Mips::BLEZC64 || Opc == Mips::BC ||643          Opc == Mips::BBIT0 || Opc == Mips::BBIT1 || Opc == Mips::BBIT032 ||644          Opc == Mips::BBIT132 ||  Opc == Mips::BC_MMR6 ||645          Opc == Mips::BEQC_MMR6 || Opc == Mips::BNEC_MMR6 ||646          Opc == Mips::BLTC_MMR6 || Opc == Mips::BGEC_MMR6 ||647          Opc == Mips::BLTUC_MMR6 || Opc == Mips::BGEUC_MMR6 ||648          Opc == Mips::BGTZC_MMR6 || Opc == Mips::BLEZC_MMR6 ||649          Opc == Mips::BGEZC_MMR6 || Opc == Mips::BLTZC_MMR6 ||650          Opc == Mips::BEQZC_MMR6 || Opc == Mips::BNEZC_MMR6) ? Opc : 0;651}652 653void MipsSEInstrInfo::expandRetRA(MachineBasicBlock &MBB,654                                  MachineBasicBlock::iterator I) const {655 656  MachineInstrBuilder MIB;657  if (Subtarget.isGP64bit())658    MIB = BuildMI(MBB, I, I->getDebugLoc(), get(Mips::PseudoReturn64))659              .addReg(Mips::RA_64, RegState::Undef);660  else661    MIB = BuildMI(MBB, I, I->getDebugLoc(), get(Mips::PseudoReturn))662              .addReg(Mips::RA, RegState::Undef);663 664  // Retain any imp-use flags.665  for (auto & MO : I->operands()) {666    if (MO.isImplicit())667      MIB.add(MO);668  }669}670 671void MipsSEInstrInfo::expandERet(MachineBasicBlock &MBB,672                                 MachineBasicBlock::iterator I) const {673  BuildMI(MBB, I, I->getDebugLoc(), get(Mips::ERET));674}675 676std::pair<bool, bool>677MipsSEInstrInfo::compareOpndSize(unsigned Opc,678                                 const MachineFunction &MF) const {679  const MCInstrDesc &Desc = get(Opc);680  assert(Desc.NumOperands == 2 && "Unary instruction expected.");681  const MipsRegisterInfo *RI = &getRegisterInfo();682  unsigned DstRegSize = RI->getRegSizeInBits(*getRegClass(Desc, 0));683  unsigned SrcRegSize = RI->getRegSizeInBits(*getRegClass(Desc, 1));684 685  return std::make_pair(DstRegSize > SrcRegSize, DstRegSize < SrcRegSize);686}687 688void MipsSEInstrInfo::expandPseudoMFHiLo(MachineBasicBlock &MBB,689                                         MachineBasicBlock::iterator I,690                                         unsigned NewOpc) const {691  BuildMI(MBB, I, I->getDebugLoc(), get(NewOpc), I->getOperand(0).getReg());692}693 694void MipsSEInstrInfo::expandPseudoMTLoHi(MachineBasicBlock &MBB,695                                         MachineBasicBlock::iterator I,696                                         unsigned LoOpc,697                                         unsigned HiOpc,698                                         bool HasExplicitDef) const {699  // Expand700  //  lo_hi pseudomtlohi $gpr0, $gpr1701  // to these two instructions:702  //  mtlo $gpr0703  //  mthi $gpr1704 705  DebugLoc DL = I->getDebugLoc();706  const MachineOperand &SrcLo = I->getOperand(1), &SrcHi = I->getOperand(2);707  MachineInstrBuilder LoInst = BuildMI(MBB, I, DL, get(LoOpc));708  MachineInstrBuilder HiInst = BuildMI(MBB, I, DL, get(HiOpc));709 710  // Add lo/hi registers if the mtlo/hi instructions created have explicit711  // def registers.712  if (HasExplicitDef) {713    Register DstReg = I->getOperand(0).getReg();714    Register DstLo = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);715    Register DstHi = getRegisterInfo().getSubReg(DstReg, Mips::sub_hi);716    LoInst.addReg(DstLo, RegState::Define);717    HiInst.addReg(DstHi, RegState::Define);718  }719 720  LoInst.addReg(SrcLo.getReg(), getKillRegState(SrcLo.isKill()));721  HiInst.addReg(SrcHi.getReg(), getKillRegState(SrcHi.isKill()));722}723 724void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB,725                                     MachineBasicBlock::iterator I,726                                     unsigned CvtOpc, unsigned MovOpc,727                                     bool IsI64) const {728  const MCInstrDesc &CvtDesc = get(CvtOpc), &MovDesc = get(MovOpc);729  const MachineOperand &Dst = I->getOperand(0), &Src = I->getOperand(1);730  unsigned DstReg = Dst.getReg(), SrcReg = Src.getReg(), TmpReg = DstReg;731  unsigned KillSrc =  getKillRegState(Src.isKill());732  DebugLoc DL = I->getDebugLoc();733  bool DstIsLarger, SrcIsLarger;734 735  std::tie(DstIsLarger, SrcIsLarger) =736      compareOpndSize(CvtOpc, *MBB.getParent());737 738  if (DstIsLarger)739    TmpReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);740 741  if (SrcIsLarger)742    DstReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);743 744  BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc);745  BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill);746}747 748void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB,749                                              MachineBasicBlock::iterator I,750                                              bool isMicroMips,751                                              bool FP64) const {752  Register DstReg = I->getOperand(0).getReg();753  Register SrcReg = I->getOperand(1).getReg();754  unsigned N = I->getOperand(2).getImm();755  DebugLoc dl = I->getDebugLoc();756 757  assert(N < 2 && "Invalid immediate");758  unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo;759  Register SubReg = getRegisterInfo().getSubReg(SrcReg, SubIdx);760 761  // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload762  // in MipsSEFrameLowering.cpp.763  assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2()));764 765  // FP64A (FP64 with nooddspreg) should have been handled with a spill/reload766  // in MipsSEFrameLowering.cpp.767  assert(!(Subtarget.isFP64bit() && !Subtarget.useOddSPReg()));768 769  if (SubIdx == Mips::sub_hi && Subtarget.hasMTHC1()) {770    // FIXME: Strictly speaking MFHC1 only reads the top 32-bits however, we771    //        claim to read the whole 64-bits as part of a white lie used to772    //        temporarily work around a widespread bug in the -mfp64 support.773    //        The problem is that none of the 32-bit fpu ops mention the fact774    //        that they clobber the upper 32-bits of the 64-bit FPR. Fixing that775    //        requires a major overhaul of the FPU implementation which can't776    //        be done right now due to time constraints.777    //        MFHC1 is one of two instructions that are affected since they are778    //        the only instructions that don't read the lower 32-bits.779    //        We therefore pretend that it reads the bottom 32-bits to780    //        artificially create a dependency and prevent the scheduler781    //        changing the behaviour of the code.782    BuildMI(MBB, I, dl,783            get(isMicroMips ? (FP64 ? Mips::MFHC1_D64_MM : Mips::MFHC1_D32_MM)784                            : (FP64 ? Mips::MFHC1_D64 : Mips::MFHC1_D32)),785            DstReg)786        .addReg(SrcReg);787  } else788    BuildMI(MBB, I, dl, get(Mips::MFC1), DstReg).addReg(SubReg);789}790 791void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,792                                         MachineBasicBlock::iterator I,793                                         bool isMicroMips, bool FP64) const {794  Register DstReg = I->getOperand(0).getReg();795  unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg();796  const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1);797  DebugLoc dl = I->getDebugLoc();798  const TargetRegisterInfo &TRI = getRegisterInfo();799 800  // When mthc1 is available, use:801  //   mtc1 Lo, $fp802  //   mthc1 Hi, $fp803  //804  // Otherwise, for O32 FPXX ABI:805  //   spill + reload via ldc1806  // This case is handled by the frame lowering code.807  //808  // Otherwise, for FP32:809  //   mtc1 Lo, $fp810  //   mtc1 Hi, $fp + 1811  //812  // The case where dmtc1 is available doesn't need to be handled here813  // because it never creates a BuildPairF64 node.814 815  // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload816  // in MipsSEFrameLowering.cpp.817  assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2()));818 819  // FP64A (FP64 with nooddspreg) should have been handled with a spill/reload820  // in MipsSEFrameLowering.cpp.821  assert(!(Subtarget.isFP64bit() && !Subtarget.useOddSPReg()));822 823  BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo))824    .addReg(LoReg);825 826  if (Subtarget.hasMTHC1()) {827    // FIXME: The .addReg(DstReg) is a white lie used to temporarily work828    //        around a widespread bug in the -mfp64 support.829    //        The problem is that none of the 32-bit fpu ops mention the fact830    //        that they clobber the upper 32-bits of the 64-bit FPR. Fixing that831    //        requires a major overhaul of the FPU implementation which can't832    //        be done right now due to time constraints.833    //        MTHC1 is one of two instructions that are affected since they are834    //        the only instructions that don't read the lower 32-bits.835    //        We therefore pretend that it reads the bottom 32-bits to836    //        artificially create a dependency and prevent the scheduler837    //        changing the behaviour of the code.838    BuildMI(MBB, I, dl,839            get(isMicroMips ? (FP64 ? Mips::MTHC1_D64_MM : Mips::MTHC1_D32_MM)840                            : (FP64 ? Mips::MTHC1_D64 : Mips::MTHC1_D32)),841            DstReg)842        .addReg(DstReg)843        .addReg(HiReg);844  } else if (Subtarget.isABI_FPXX())845    llvm_unreachable("BuildPairF64 not expanded in frame lowering code!");846  else847    BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_hi))848      .addReg(HiReg);849}850 851void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB,852                                     MachineBasicBlock::iterator I) const {853  // This pseudo instruction is generated as part of the lowering of854  // ISD::EH_RETURN. We convert it to a stack increment by OffsetReg, and855  // indirect jump to TargetReg856  MipsABIInfo ABI = Subtarget.getABI();857  unsigned ADDU = ABI.GetPtrAdduOp();858  unsigned SP = Subtarget.isGP64bit() ? Mips::SP_64 : Mips::SP;859  unsigned RA = Subtarget.isGP64bit() ? Mips::RA_64 : Mips::RA;860  unsigned T9 = Subtarget.isGP64bit() ? Mips::T9_64 : Mips::T9;861  unsigned ZERO = Subtarget.isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;862  Register OffsetReg = I->getOperand(0).getReg();863  Register TargetReg = I->getOperand(1).getReg();864 865  // addu $ra, $v0, $zero866  // addu $sp, $sp, $v1867  // jr   $ra (via RetRA)868  const TargetMachine &TM = MBB.getParent()->getTarget();869  if (TM.isPositionIndependent())870    BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), T9)871        .addReg(TargetReg)872        .addReg(ZERO);873  BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), RA)874      .addReg(TargetReg)875      .addReg(ZERO);876  BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), SP).addReg(SP).addReg(OffsetReg);877  expandRetRA(MBB, I);878}879 880const MipsInstrInfo *llvm::createMipsSEInstrInfo(const MipsSubtarget &STI) {881  return new MipsSEInstrInfo(STI);882}883