brintos

brintos / llvm-project-archived public Read only

0
0
Text · 36.3 KiB · 78f2e5d Raw
1113 lines · cpp
1//===-- MipsExpandPseudoInsts.cpp - Expand pseudo instructions ------------===//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 a pass that expands pseudo instructions into target10// instructions to allow proper scheduling, if-conversion, and other late11// optimizations. This pass should be run after register allocation but before12// the post-regalloc scheduling pass.13//14// This is currently only used for expanding atomic pseudos after register15// allocation. We do this to avoid the fast register allocator introducing16// spills between ll and sc. These stores cause some MIPS implementations to17// abort the atomic RMW sequence.18//19//===----------------------------------------------------------------------===//20 21#include "Mips.h"22#include "MipsInstrInfo.h"23#include "MipsSubtarget.h"24#include "llvm/CodeGen/LivePhysRegs.h"25#include "llvm/CodeGen/MachineFunctionPass.h"26#include "llvm/CodeGen/MachineInstrBuilder.h"27 28using namespace llvm;29 30#define DEBUG_TYPE "mips-pseudo"31 32namespace {33  class MipsExpandPseudo : public MachineFunctionPass {34  public:35    static char ID;36    MipsExpandPseudo() : MachineFunctionPass(ID) {}37 38    const MipsInstrInfo *TII;39    const MipsSubtarget *STI;40 41    bool runOnMachineFunction(MachineFunction &Fn) override;42 43    MachineFunctionProperties getRequiredProperties() const override {44      return MachineFunctionProperties().setNoVRegs();45    }46 47    StringRef getPassName() const override {48      return "Mips pseudo instruction expansion pass";49    }50 51  private:52    bool expandAtomicCmpSwap(MachineBasicBlock &MBB,53                             MachineBasicBlock::iterator MBBI,54                             MachineBasicBlock::iterator &NextMBBI);55    bool expandAtomicCmpSwapSubword(MachineBasicBlock &MBB,56                                    MachineBasicBlock::iterator MBBI,57                                    MachineBasicBlock::iterator &NextMBBI);58 59    bool expandAtomicBinOp(MachineBasicBlock &BB,60                           MachineBasicBlock::iterator I,61                           MachineBasicBlock::iterator &NMBBI, unsigned Size);62    bool expandAtomicBinOpSubword(MachineBasicBlock &BB,63                                  MachineBasicBlock::iterator I,64                                  MachineBasicBlock::iterator &NMBBI);65 66    bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,67                  MachineBasicBlock::iterator &NMBB);68    bool expandMBB(MachineBasicBlock &MBB);69   };70  char MipsExpandPseudo::ID = 0;71}72 73bool MipsExpandPseudo::expandAtomicCmpSwapSubword(74    MachineBasicBlock &BB, MachineBasicBlock::iterator I,75    MachineBasicBlock::iterator &NMBBI) {76 77  MachineFunction *MF = BB.getParent();78 79  const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();80  DebugLoc DL = I->getDebugLoc();81  unsigned LL, SC;82 83  unsigned ZERO = Mips::ZERO;84  unsigned BNE = Mips::BNE;85  unsigned BEQ = Mips::BEQ;86  unsigned SEOp =87      I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I8_POSTRA ? Mips::SEB : Mips::SEH;88 89  if (STI->inMicroMipsMode()) {90      LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;91      SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;92      BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;93      BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;94  } else {95    LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)96                            : (ArePtrs64bit ? Mips::LL64 : Mips::LL);97    SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)98                            : (ArePtrs64bit ? Mips::SC64 : Mips::SC);99  }100 101  Register Dest = I->getOperand(0).getReg();102  Register Ptr = I->getOperand(1).getReg();103  Register Mask = I->getOperand(2).getReg();104  Register ShiftCmpVal = I->getOperand(3).getReg();105  Register Mask2 = I->getOperand(4).getReg();106  Register ShiftNewVal = I->getOperand(5).getReg();107  Register ShiftAmnt = I->getOperand(6).getReg();108  Register Scratch = I->getOperand(7).getReg();109  Register Scratch2 = I->getOperand(8).getReg();110 111  // insert new blocks after the current block112  const BasicBlock *LLVM_BB = BB.getBasicBlock();113  MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);114  MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);115  MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);116  MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);117  MachineFunction::iterator It = ++BB.getIterator();118  MF->insert(It, loop1MBB);119  MF->insert(It, loop2MBB);120  MF->insert(It, sinkMBB);121  MF->insert(It, exitMBB);122 123  // Transfer the remainder of BB and its successor edges to exitMBB.124  exitMBB->splice(exitMBB->begin(), &BB,125                  std::next(MachineBasicBlock::iterator(I)), BB.end());126  exitMBB->transferSuccessorsAndUpdatePHIs(&BB);127 128  //  thisMBB:129  //    ...130  //    fallthrough --> loop1MBB131  BB.addSuccessor(loop1MBB, BranchProbability::getOne());132  loop1MBB->addSuccessor(sinkMBB);133  loop1MBB->addSuccessor(loop2MBB);134  loop1MBB->normalizeSuccProbs();135  loop2MBB->addSuccessor(loop1MBB);136  loop2MBB->addSuccessor(sinkMBB);137  loop2MBB->normalizeSuccProbs();138  sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());139 140  // loop1MBB:141  //   ll dest, 0(ptr)142  //   and Mask', dest, Mask143  //   bne Mask', ShiftCmpVal, exitMBB144  BuildMI(loop1MBB, DL, TII->get(LL), Scratch).addReg(Ptr).addImm(0);145  BuildMI(loop1MBB, DL, TII->get(Mips::AND), Scratch2)146      .addReg(Scratch)147      .addReg(Mask);148  BuildMI(loop1MBB, DL, TII->get(BNE))149    .addReg(Scratch2).addReg(ShiftCmpVal).addMBB(sinkMBB);150 151  // loop2MBB:152  //   and dest, dest, mask2153  //   or dest, dest, ShiftNewVal154  //   sc dest, dest, 0(ptr)155  //   beq dest, $0, loop1MBB156  BuildMI(loop2MBB, DL, TII->get(Mips::AND), Scratch)157      .addReg(Scratch, RegState::Kill)158      .addReg(Mask2);159  BuildMI(loop2MBB, DL, TII->get(Mips::OR), Scratch)160      .addReg(Scratch, RegState::Kill)161      .addReg(ShiftNewVal);162  BuildMI(loop2MBB, DL, TII->get(SC), Scratch)163      .addReg(Scratch, RegState::Kill)164      .addReg(Ptr)165      .addImm(0);166  BuildMI(loop2MBB, DL, TII->get(BEQ))167      .addReg(Scratch, RegState::Kill)168      .addReg(ZERO)169      .addMBB(loop1MBB);170 171  //  sinkMBB:172  //    srl     srlres, Mask', shiftamt173  //    sign_extend dest,srlres174  BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)175      .addReg(Scratch2)176      .addReg(ShiftAmnt);177  if (STI->hasMips32r2()) {178    BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);179  } else {180    const unsigned ShiftImm =181        I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I16_POSTRA ? 16 : 24;182    BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)183        .addReg(Dest, RegState::Kill)184        .addImm(ShiftImm);185    BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)186        .addReg(Dest, RegState::Kill)187        .addImm(ShiftImm);188  }189 190  LivePhysRegs LiveRegs;191  computeAndAddLiveIns(LiveRegs, *loop1MBB);192  computeAndAddLiveIns(LiveRegs, *loop2MBB);193  computeAndAddLiveIns(LiveRegs, *sinkMBB);194  computeAndAddLiveIns(LiveRegs, *exitMBB);195 196  NMBBI = BB.end();197  I->eraseFromParent();198  return true;199}200 201bool MipsExpandPseudo::expandAtomicCmpSwap(MachineBasicBlock &BB,202                                           MachineBasicBlock::iterator I,203                                           MachineBasicBlock::iterator &NMBBI) {204 205  const unsigned Size =206      I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I32_POSTRA ? 4 : 8;207  MachineFunction *MF = BB.getParent();208 209  const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();210  DebugLoc DL = I->getDebugLoc();211 212  unsigned LL, SC, ZERO, BNE, BEQ, MOVE;213 214  if (Size == 4) {215    if (STI->inMicroMipsMode()) {216      LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;217      SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;218      BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;219      BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;220    } else {221      LL = STI->hasMips32r6()222               ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)223               : (ArePtrs64bit ? Mips::LL64 : Mips::LL);224      SC = STI->hasMips32r6()225               ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)226               : (ArePtrs64bit ? Mips::SC64 : Mips::SC);227      BNE = Mips::BNE;228      BEQ = Mips::BEQ;229    }230 231    ZERO = Mips::ZERO;232    MOVE = Mips::OR;233  } else {234    LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;235    SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;236    ZERO = Mips::ZERO_64;237    BNE = Mips::BNE64;238    BEQ = Mips::BEQ64;239    MOVE = Mips::OR64;240  }241 242  Register Dest = I->getOperand(0).getReg();243  Register Ptr = I->getOperand(1).getReg();244  Register OldVal = I->getOperand(2).getReg();245  Register NewVal = I->getOperand(3).getReg();246  Register Scratch = I->getOperand(4).getReg();247 248  // insert new blocks after the current block249  const BasicBlock *LLVM_BB = BB.getBasicBlock();250  MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);251  MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);252  MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);253  MachineFunction::iterator It = ++BB.getIterator();254  MF->insert(It, loop1MBB);255  MF->insert(It, loop2MBB);256  MF->insert(It, exitMBB);257 258  // Transfer the remainder of BB and its successor edges to exitMBB.259  exitMBB->splice(exitMBB->begin(), &BB,260                  std::next(MachineBasicBlock::iterator(I)), BB.end());261  exitMBB->transferSuccessorsAndUpdatePHIs(&BB);262 263  //  thisMBB:264  //    ...265  //    fallthrough --> loop1MBB266  BB.addSuccessor(loop1MBB, BranchProbability::getOne());267  loop1MBB->addSuccessor(exitMBB);268  loop1MBB->addSuccessor(loop2MBB);269  loop1MBB->normalizeSuccProbs();270  loop2MBB->addSuccessor(loop1MBB);271  loop2MBB->addSuccessor(exitMBB);272  loop2MBB->normalizeSuccProbs();273 274  // loop1MBB:275  //   ll dest, 0(ptr)276  //   bne dest, oldval, exitMBB277  BuildMI(loop1MBB, DL, TII->get(LL), Dest).addReg(Ptr).addImm(0);278  BuildMI(loop1MBB, DL, TII->get(BNE))279    .addReg(Dest, RegState::Kill).addReg(OldVal).addMBB(exitMBB);280 281  // loop2MBB:282  //   move scratch, NewVal283  //   sc Scratch, Scratch, 0(ptr)284  //   beq Scratch, $0, loop1MBB285  BuildMI(loop2MBB, DL, TII->get(MOVE), Scratch).addReg(NewVal).addReg(ZERO);286  BuildMI(loop2MBB, DL, TII->get(SC), Scratch)287    .addReg(Scratch).addReg(Ptr).addImm(0);288  BuildMI(loop2MBB, DL, TII->get(BEQ))289    .addReg(Scratch, RegState::Kill).addReg(ZERO).addMBB(loop1MBB);290 291  LivePhysRegs LiveRegs;292  computeAndAddLiveIns(LiveRegs, *loop1MBB);293  computeAndAddLiveIns(LiveRegs, *loop2MBB);294  computeAndAddLiveIns(LiveRegs, *exitMBB);295 296  NMBBI = BB.end();297  I->eraseFromParent();298  return true;299}300 301bool MipsExpandPseudo::expandAtomicBinOpSubword(302    MachineBasicBlock &BB, MachineBasicBlock::iterator I,303    MachineBasicBlock::iterator &NMBBI) {304 305  MachineFunction *MF = BB.getParent();306 307  const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();308  DebugLoc DL = I->getDebugLoc();309 310  unsigned LL, SC, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;311  unsigned BEQ = Mips::BEQ;312  unsigned SEOp = Mips::SEH;313 314  if (STI->inMicroMipsMode()) {315      LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;316      SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;317      BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;318      SLT = Mips::SLT_MM;319      SLTu = Mips::SLTu_MM;320      OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;321      MOVN = Mips::MOVN_I_MM;322      MOVZ = Mips::MOVZ_I_MM;323      SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;324      SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;325  } else {326    LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)327                            : (ArePtrs64bit ? Mips::LL64 : Mips::LL);328    SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)329                            : (ArePtrs64bit ? Mips::SC64 : Mips::SC);330    SLT = Mips::SLT;331    SLTu = Mips::SLTu;332    OR = Mips::OR;333    MOVN = Mips::MOVN_I_I;334    MOVZ = Mips::MOVZ_I_I;335    SELNEZ = Mips::SELNEZ;336    SELEQZ = Mips::SELEQZ;337  }338 339  bool IsSwap = false;340  bool IsNand = false;341  bool IsMin = false;342  bool IsMax = false;343  bool IsUnsigned = false;344  bool DestOK = false;345 346  unsigned Opcode = 0;347  switch (I->getOpcode()) {348  case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:349    SEOp = Mips::SEB;350    [[fallthrough]];351  case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:352    IsNand = true;353    break;354  case Mips::ATOMIC_SWAP_I8_POSTRA:355    SEOp = Mips::SEB;356    [[fallthrough]];357  case Mips::ATOMIC_SWAP_I16_POSTRA:358    IsSwap = true;359    break;360  case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:361    SEOp = Mips::SEB;362    [[fallthrough]];363  case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:364    Opcode = Mips::ADDu;365    break;366  case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:367    SEOp = Mips::SEB;368    [[fallthrough]];369  case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:370    Opcode = Mips::SUBu;371    break;372  case Mips::ATOMIC_LOAD_AND_I8_POSTRA:373    SEOp = Mips::SEB;374    [[fallthrough]];375  case Mips::ATOMIC_LOAD_AND_I16_POSTRA:376    Opcode = Mips::AND;377    break;378  case Mips::ATOMIC_LOAD_OR_I8_POSTRA:379    SEOp = Mips::SEB;380    [[fallthrough]];381  case Mips::ATOMIC_LOAD_OR_I16_POSTRA:382    Opcode = Mips::OR;383    break;384  case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:385    SEOp = Mips::SEB;386    [[fallthrough]];387  case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:388    Opcode = Mips::XOR;389    break;390  case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:391    SEOp = Mips::SEB;392    IsUnsigned = true;393    IsMin = true;394    break;395  case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:396    IsUnsigned = true;397    IsMin = true;398    break;399  case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:400    SEOp = Mips::SEB;401    IsMin = true;402    break;403  case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:404    IsMin = true;405    break;406  case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:407    SEOp = Mips::SEB;408    IsUnsigned = true;409    IsMax = true;410    break;411  case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:412    IsUnsigned = true;413    IsMax = true;414    break;415  case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:416    SEOp = Mips::SEB;417    IsMax = true;418    break;419  case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:420    IsMax = true;421    break;422  default:423    llvm_unreachable("Unknown subword atomic pseudo for expansion!");424  }425 426  Register Dest = I->getOperand(0).getReg();427  Register Ptr = I->getOperand(1).getReg();428  Register Incr = I->getOperand(2).getReg();429  Register Mask = I->getOperand(3).getReg();430  Register Mask2 = I->getOperand(4).getReg();431  Register ShiftAmnt = I->getOperand(5).getReg();432  Register OldVal = I->getOperand(6).getReg();433  Register BinOpRes = I->getOperand(7).getReg();434  Register StoreVal = I->getOperand(8).getReg();435  bool NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4() && !STI->hasMips32();436 437  const BasicBlock *LLVM_BB = BB.getBasicBlock();438  MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);439  MachineBasicBlock *loop1MBB = nullptr;440  MachineBasicBlock *loop2MBB = nullptr;441  if (NoMovnInstr) {442    loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);443    loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);444  }445  MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);446  MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);447  MachineFunction::iterator It = ++BB.getIterator();448  MF->insert(It, loopMBB);449  if (NoMovnInstr) {450    MF->insert(It, loop1MBB);451    MF->insert(It, loop2MBB);452  }453  MF->insert(It, sinkMBB);454  MF->insert(It, exitMBB);455 456  exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end());457  exitMBB->transferSuccessorsAndUpdatePHIs(&BB);458 459  BB.addSuccessor(loopMBB, BranchProbability::getOne());460  if (NoMovnInstr) {461    loopMBB->addSuccessor(loop1MBB);462    loopMBB->addSuccessor(loop2MBB);463  } else {464    loopMBB->addSuccessor(sinkMBB);465    loopMBB->addSuccessor(loopMBB);466    loopMBB->normalizeSuccProbs();467  }468  if (NoMovnInstr) {469    loop1MBB->addSuccessor(loop2MBB);470    loop2MBB->addSuccessor(loopMBB);471    loop2MBB->addSuccessor(sinkMBB);472  }473 474  BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);475  if (IsNand) {476    //  and andres, oldval, incr2477    //  nor binopres, $0, andres478    //  and newval, binopres, mask479    BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)480        .addReg(OldVal)481        .addReg(Incr);482    BuildMI(loopMBB, DL, TII->get(Mips::NOR), BinOpRes)483        .addReg(Mips::ZERO)484        .addReg(BinOpRes);485    BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)486        .addReg(BinOpRes)487        .addReg(Mask);488  } else if (IsMin || IsMax) {489 490    assert(I->getNumOperands() == 10 &&491           "Atomics min|max|umin|umax use an additional register");492    Register Scratch4 = I->getOperand(9).getReg();493 494    unsigned SLTScratch4 = IsUnsigned ? SLTu : SLT;495    unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;496    unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;497    unsigned MOVIncr = IsMax ? MOVN : MOVZ;498 499    BuildMI(loopMBB, DL, TII->get(Mips::SRAV), StoreVal)500        .addReg(OldVal)501        .addReg(ShiftAmnt);502    if (IsUnsigned) {503      const unsigned OpMask = SEOp == Mips::SEH ? 0xffff : 0xff;504      BuildMI(loopMBB, DL, TII->get(Mips::ANDi), StoreVal)505          .addReg(StoreVal)506          .addImm(OpMask);507    } else if (STI->hasMips32r2()) {508      BuildMI(loopMBB, DL, TII->get(SEOp), StoreVal).addReg(StoreVal);509    } else {510      const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;511      const unsigned SROp = IsUnsigned ? Mips::SRL : Mips::SRA;512      BuildMI(loopMBB, DL, TII->get(Mips::SLL), StoreVal)513          .addReg(StoreVal, RegState::Kill)514          .addImm(ShiftImm);515      BuildMI(loopMBB, DL, TII->get(SROp), StoreVal)516          .addReg(StoreVal, RegState::Kill)517          .addImm(ShiftImm);518    }519    BuildMI(loopMBB, DL, TII->get(Mips::OR), Dest)520        .addReg(Mips::ZERO)521        .addReg(StoreVal);522    DestOK = true;523    BuildMI(loopMBB, DL, TII->get(Mips::SLLV), StoreVal)524        .addReg(StoreVal)525        .addReg(ShiftAmnt);526 527    // unsigned: sltu Scratch4, StoreVal, Incr528    // signed:   slt Scratch4, StoreVal, Incr529    BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4)530        .addReg(StoreVal)531        .addReg(Incr);532 533    if (STI->hasMips64r6() || STI->hasMips32r6()) {534      // max: seleqz BinOpRes, OldVal, Scratch4535      //      selnez Scratch4, Incr, Scratch4536      //      or BinOpRes, BinOpRes, Scratch4537      // min: selnqz BinOpRes, OldVal, Scratch4538      //      seleqz Scratch4, Incr, Scratch4539      //      or BinOpRes, BinOpRes, Scratch4540      BuildMI(loopMBB, DL, TII->get(SELOldVal), BinOpRes)541          .addReg(StoreVal)542          .addReg(Scratch4);543      BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch4)544          .addReg(Incr)545          .addReg(Scratch4);546      BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)547          .addReg(BinOpRes)548          .addReg(Scratch4);549    } else if (STI->hasMips4() || STI->hasMips32()) {550      // max: move BinOpRes, StoreVal551      //      movn BinOpRes, Incr, Scratch4, BinOpRes552      // min: move BinOpRes, StoreVal553      //      movz BinOpRes, Incr, Scratch4, BinOpRes554      BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)555          .addReg(StoreVal)556          .addReg(Mips::ZERO);557      BuildMI(loopMBB, DL, TII->get(MOVIncr), BinOpRes)558          .addReg(Incr)559          .addReg(Scratch4)560          .addReg(BinOpRes);561    } else {562      // if min:563      // loopMBB:  move BinOpRes, StoreVal564      //           beq Scratch4, 0, loop1MBB565      //           j loop2MBB566      // loop1MBB: move BinOpRes, Incr567      // loop2MBB: and BinOpRes, BinOpRes, Mask568      //           and StoreVal, OlddVal, Mask2569      //           or StoreVal, StoreVal, BinOpRes570      //           StoreVal<tied1> = sc StoreVal, 0(Ptr)571      //           beq StoreVal, zero, loopMBB572      //573      // if max:574      // loopMBB:  move BinOpRes, Incr575      //           beq Scratch4, 0, loop1MBB576      //           j loop2MBB577      // loop1MBB: move BinOpRes, StoreVal578      // loop2MBB: and BinOpRes, BinOpRes, Mask579      //           and StoreVal, OlddVal, Mask2580      //           or StoreVal, StoreVal, BinOpRes581      //           StoreVal<tied1> = sc StoreVal, 0(Ptr)582      //           beq StoreVal, zero, loopMBB583      if (IsMin) {584        BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)585            .addReg(StoreVal)586            .addReg(Mips::ZERO);587        BuildMI(loop1MBB, DL, TII->get(OR), BinOpRes)588            .addReg(Incr)589            .addReg(Mips::ZERO);590      } else {591        BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)592            .addReg(Incr)593            .addReg(Mips::ZERO);594        BuildMI(loop1MBB, DL, TII->get(OR), BinOpRes)595            .addReg(StoreVal)596            .addReg(Mips::ZERO);597      }598      BuildMI(loopMBB, DL, TII->get(BEQ))599          .addReg(Scratch4)600          .addReg(Mips::ZERO)601          .addMBB(loop1MBB);602      BuildMI(loopMBB, DL, TII->get(Mips::J)).addMBB(loop2MBB);603    }604 605    //  and BinOpRes, BinOpRes, Mask606    if (NoMovnInstr)607      BuildMI(loop2MBB, DL, TII->get(Mips::AND), BinOpRes)608          .addReg(BinOpRes)609          .addReg(Mask);610    else611      BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)612          .addReg(BinOpRes)613          .addReg(Mask);614 615  } else if (!IsSwap) {616    //  <binop> binopres, oldval, incr2617    //  and newval, binopres, mask618    BuildMI(loopMBB, DL, TII->get(Opcode), BinOpRes)619        .addReg(OldVal)620        .addReg(Incr);621    BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)622        .addReg(BinOpRes)623        .addReg(Mask);624  } else { // atomic.swap625    //  and newval, incr2, mask626    BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)627        .addReg(Incr)628        .addReg(Mask);629  }630 631  // and StoreVal, OlddVal, Mask2632  // or StoreVal, StoreVal, BinOpRes633  // StoreVal<tied1> = sc StoreVal, 0(Ptr)634  // beq StoreVal, zero, loopMBB635  if (NoMovnInstr) {636    BuildMI(loop2MBB, DL, TII->get(Mips::AND), StoreVal)637        .addReg(OldVal)638        .addReg(Mask2);639    BuildMI(loop2MBB, DL, TII->get(Mips::OR), StoreVal)640        .addReg(StoreVal)641        .addReg(BinOpRes);642    BuildMI(loop2MBB, DL, TII->get(SC), StoreVal)643        .addReg(StoreVal)644        .addReg(Ptr)645        .addImm(0);646    BuildMI(loop2MBB, DL, TII->get(BEQ))647        .addReg(StoreVal)648        .addReg(Mips::ZERO)649        .addMBB(loopMBB);650  } else {651    BuildMI(loopMBB, DL, TII->get(Mips::AND), StoreVal)652        .addReg(OldVal)653        .addReg(Mask2);654    BuildMI(loopMBB, DL, TII->get(Mips::OR), StoreVal)655        .addReg(StoreVal)656        .addReg(BinOpRes);657    BuildMI(loopMBB, DL, TII->get(SC), StoreVal)658        .addReg(StoreVal)659        .addReg(Ptr)660        .addImm(0);661    BuildMI(loopMBB, DL, TII->get(BEQ))662        .addReg(StoreVal)663        .addReg(Mips::ZERO)664        .addMBB(loopMBB);665  }666 667  //  sinkMBB:668  //    and     maskedoldval1,oldval,mask669  //    srl     srlres,maskedoldval1,shiftamt670  //    sign_extend dest,srlres671 672  if (!DestOK) {673    sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());674    BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest).addReg(OldVal).addReg(Mask);675    BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)676        .addReg(Dest)677        .addReg(ShiftAmnt);678 679    if (STI->hasMips32r2()) {680      BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);681    } else {682      const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;683      BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)684          .addReg(Dest, RegState::Kill)685          .addImm(ShiftImm);686      BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)687          .addReg(Dest, RegState::Kill)688          .addImm(ShiftImm);689    }690  }691 692  LivePhysRegs LiveRegs;693  computeAndAddLiveIns(LiveRegs, *loopMBB);694  if (loop1MBB) {695    assert(loop2MBB && "should have 2 loop blocks");696    computeAndAddLiveIns(LiveRegs, *loop1MBB);697    computeAndAddLiveIns(LiveRegs, *loop2MBB);698  }699  computeAndAddLiveIns(LiveRegs, *sinkMBB);700  computeAndAddLiveIns(LiveRegs, *exitMBB);701 702  NMBBI = BB.end();703  I->eraseFromParent();704 705  return true;706}707 708bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,709                                         MachineBasicBlock::iterator I,710                                         MachineBasicBlock::iterator &NMBBI,711                                         unsigned Size) {712  MachineFunction *MF = BB.getParent();713 714  const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();715  DebugLoc DL = I->getDebugLoc();716 717  unsigned LL, SC, ZERO, BEQ, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;718 719  if (Size == 4) {720    if (STI->inMicroMipsMode()) {721      LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;722      SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;723      BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;724      SLT = Mips::SLT_MM;725      SLTu = Mips::SLTu_MM;726      OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;727      MOVN = Mips::MOVN_I_MM;728      MOVZ = Mips::MOVZ_I_MM;729      SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;730      SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;731    } else {732      LL = STI->hasMips32r6()733               ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)734               : (ArePtrs64bit ? Mips::LL64 : Mips::LL);735      SC = STI->hasMips32r6()736               ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)737               : (ArePtrs64bit ? Mips::SC64 : Mips::SC);738      BEQ = Mips::BEQ;739      SLT = Mips::SLT;740      SLTu = Mips::SLTu;741      OR = Mips::OR;742      MOVN = Mips::MOVN_I_I;743      MOVZ = Mips::MOVZ_I_I;744      SELNEZ = Mips::SELNEZ;745      SELEQZ = Mips::SELEQZ;746    }747 748    ZERO = Mips::ZERO;749  } else {750    LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;751    SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;752    ZERO = Mips::ZERO_64;753    BEQ = Mips::BEQ64;754    SLT = Mips::SLT64;755    SLTu = Mips::SLTu64;756    OR = Mips::OR64;757    MOVN = Mips::MOVN_I64_I64;758    MOVZ = Mips::MOVZ_I64_I64;759    SELNEZ = Mips::SELNEZ64;760    SELEQZ = Mips::SELEQZ64;761  }762 763  Register OldVal = I->getOperand(0).getReg();764  Register Ptr = I->getOperand(1).getReg();765  Register Incr = I->getOperand(2).getReg();766  Register Scratch = I->getOperand(3).getReg();767 768  unsigned Opcode = 0;769  unsigned AND = 0;770  unsigned NOR = 0;771 772  bool IsOr = false;773  bool IsNand = false;774  bool IsMin = false;775  bool IsMax = false;776  bool IsUnsigned = false;777 778  switch (I->getOpcode()) {779  case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:780    Opcode = Mips::ADDu;781    break;782  case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:783    Opcode = Mips::SUBu;784    break;785  case Mips::ATOMIC_LOAD_AND_I32_POSTRA:786    Opcode = Mips::AND;787    break;788  case Mips::ATOMIC_LOAD_OR_I32_POSTRA:789    Opcode = Mips::OR;790    break;791  case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:792    Opcode = Mips::XOR;793    break;794  case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:795    IsNand = true;796    AND = Mips::AND;797    NOR = Mips::NOR;798    break;799  case Mips::ATOMIC_SWAP_I32_POSTRA:800    IsOr = true;801    break;802  case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:803    Opcode = Mips::DADDu;804    break;805  case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:806    Opcode = Mips::DSUBu;807    break;808  case Mips::ATOMIC_LOAD_AND_I64_POSTRA:809    Opcode = Mips::AND64;810    break;811  case Mips::ATOMIC_LOAD_OR_I64_POSTRA:812    Opcode = Mips::OR64;813    break;814  case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:815    Opcode = Mips::XOR64;816    break;817  case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:818    IsNand = true;819    AND = Mips::AND64;820    NOR = Mips::NOR64;821    break;822  case Mips::ATOMIC_SWAP_I64_POSTRA:823    IsOr = true;824    break;825  case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:826  case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:827    IsUnsigned = true;828    [[fallthrough]];829  case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:830  case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:831    IsMin = true;832    break;833  case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:834  case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:835    IsUnsigned = true;836    [[fallthrough]];837  case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:838  case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:839    IsMax = true;840    break;841  default:842    llvm_unreachable("Unknown pseudo atomic!");843  }844 845  bool NoMovnInstr = (IsMin || IsMax) && !STI->hasMips4() && !STI->hasMips32();846  const BasicBlock *LLVM_BB = BB.getBasicBlock();847  MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);848  MachineBasicBlock *loop1MBB = nullptr;849  MachineBasicBlock *loop2MBB = nullptr;850  if (NoMovnInstr) {851    loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);852    loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);853  }854  MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);855  MachineFunction::iterator It = ++BB.getIterator();856  MF->insert(It, loopMBB);857  if (NoMovnInstr) {858    MF->insert(It, loop1MBB);859    MF->insert(It, loop2MBB);860  }861  MF->insert(It, exitMBB);862 863  exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end());864  exitMBB->transferSuccessorsAndUpdatePHIs(&BB);865 866  BB.addSuccessor(loopMBB, BranchProbability::getOne());867  if (NoMovnInstr) {868    loopMBB->addSuccessor(loop1MBB);869    loopMBB->addSuccessor(loop2MBB);870  } else {871    loopMBB->addSuccessor(exitMBB);872    loopMBB->addSuccessor(loopMBB);873  }874  loopMBB->normalizeSuccProbs();875  if (NoMovnInstr) {876    loop1MBB->addSuccessor(loop2MBB);877    loop2MBB->addSuccessor(loopMBB);878    loop2MBB->addSuccessor(exitMBB);879  }880 881  BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);882  assert((OldVal != Ptr) && "Clobbered the wrong ptr reg!");883  assert((OldVal != Incr) && "Clobbered the wrong reg!");884  if (IsMin || IsMax) {885 886    assert(I->getNumOperands() == 5 &&887           "Atomics min|max|umin|umax use an additional register");888    MCRegister Scratch2 = I->getOperand(4).getReg().asMCReg();889 890    // On Mips64 result of slt is GPR32.891    MCRegister Scratch2_32 =892        (Size == 8) ? STI->getRegisterInfo()->getSubReg(Scratch2, Mips::sub_32)893                    : Scratch2;894 895    unsigned SLTScratch2 = IsUnsigned ? SLTu : SLT;896    unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;897    unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;898    unsigned MOVIncr = IsMax ? MOVN : MOVZ;899 900    // unsigned: sltu Scratch2, oldVal, Incr901    // signed:   slt Scratch2, oldVal, Incr902    BuildMI(loopMBB, DL, TII->get(SLTScratch2), Scratch2_32)903        .addReg(OldVal)904        .addReg(Incr);905 906    if (STI->hasMips64r6() || STI->hasMips32r6()) {907      // max: seleqz Scratch, OldVal, Scratch2908      //      selnez Scratch2, Incr, Scratch2909      //      or Scratch, Scratch, Scratch2910      // min: selnez Scratch, OldVal, Scratch2911      //      seleqz Scratch2, Incr, Scratch2912      //      or Scratch, Scratch, Scratch2913      BuildMI(loopMBB, DL, TII->get(SELOldVal), Scratch)914          .addReg(OldVal)915          .addReg(Scratch2);916      BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch2)917          .addReg(Incr)918          .addReg(Scratch2);919      BuildMI(loopMBB, DL, TII->get(OR), Scratch)920          .addReg(Scratch)921          .addReg(Scratch2);922    } else if (STI->hasMips4() || STI->hasMips32()) {923      // max: move Scratch, OldVal924      //      movn Scratch, Incr, Scratch2, Scratch925      // min: move Scratch, OldVal926      //      movz Scratch, Incr, Scratch2, Scratch927      BuildMI(loopMBB, DL, TII->get(OR), Scratch)928          .addReg(OldVal)929          .addReg(ZERO);930      BuildMI(loopMBB, DL, TII->get(MOVIncr), Scratch)931          .addReg(Incr)932          .addReg(Scratch2)933          .addReg(Scratch);934    } else {935      // if min:936      // loopMBB:  move Scratch, OldVal937      //           beq Scratch2_32, 0, loop1MBB938      //           j loop2MBB939      // loop1MBB: move Scratch, Incr940      // loop2MBB: sc $2, 0($4)941      //           beqz	$2, $BB0_1942      //           nop943      //944      // if max:945      // loopMBB:  move Scratch, Incr946      //           beq Scratch2_32, 0, loop1MBB947      //           j loop2MBB948      // loop1MBB: move Scratch, OldVal949      // loop2MBB: sc $2, 0($4)950      //           beqz	$2, $BB0_1951      //           nop952      if (IsMin) {953        BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(OldVal).addReg(ZERO);954        BuildMI(loop1MBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);955      } else {956        BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);957        BuildMI(loop1MBB, DL, TII->get(OR), Scratch)958            .addReg(OldVal)959            .addReg(ZERO);960      }961      BuildMI(loopMBB, DL, TII->get(BEQ))962          .addReg(Scratch2_32)963          .addReg(ZERO)964          .addMBB(loop1MBB);965      BuildMI(loopMBB, DL, TII->get(Mips::J)).addMBB(loop2MBB);966    }967 968  } else if (Opcode) {969    BuildMI(loopMBB, DL, TII->get(Opcode), Scratch).addReg(OldVal).addReg(Incr);970  } else if (IsNand) {971    assert(AND && NOR &&972           "Unknown nand instruction for atomic pseudo expansion");973    BuildMI(loopMBB, DL, TII->get(AND), Scratch).addReg(OldVal).addReg(Incr);974    BuildMI(loopMBB, DL, TII->get(NOR), Scratch).addReg(ZERO).addReg(Scratch);975  } else {976    assert(IsOr && OR && "Unknown instruction for atomic pseudo expansion!");977    (void)IsOr;978    BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);979  }980 981  if (NoMovnInstr) {982    BuildMI(loop2MBB, DL, TII->get(SC), Scratch)983        .addReg(Scratch)984        .addReg(Ptr)985        .addImm(0);986    BuildMI(loop2MBB, DL, TII->get(BEQ))987        .addReg(Scratch)988        .addReg(ZERO)989        .addMBB(loopMBB);990  } else {991    BuildMI(loopMBB, DL, TII->get(SC), Scratch)992        .addReg(Scratch)993        .addReg(Ptr)994        .addImm(0);995    BuildMI(loopMBB, DL, TII->get(BEQ))996        .addReg(Scratch)997        .addReg(ZERO)998        .addMBB(loopMBB);999  }1000 1001  NMBBI = BB.end();1002  I->eraseFromParent();1003 1004  LivePhysRegs LiveRegs;1005  computeAndAddLiveIns(LiveRegs, *loopMBB);1006  if (loop1MBB) {1007    assert(loop2MBB && "should have 2 loop blocks");1008    computeAndAddLiveIns(LiveRegs, *loop1MBB);1009    computeAndAddLiveIns(LiveRegs, *loop2MBB);1010  }1011  computeAndAddLiveIns(LiveRegs, *exitMBB);1012 1013  return true;1014}1015 1016bool MipsExpandPseudo::expandMI(MachineBasicBlock &MBB,1017                                MachineBasicBlock::iterator MBBI,1018                                MachineBasicBlock::iterator &NMBB) {1019 1020  bool Modified = false;1021 1022  switch (MBBI->getOpcode()) {1023  case Mips::ATOMIC_CMP_SWAP_I32_POSTRA:1024  case Mips::ATOMIC_CMP_SWAP_I64_POSTRA:1025    return expandAtomicCmpSwap(MBB, MBBI, NMBB);1026  case Mips::ATOMIC_CMP_SWAP_I8_POSTRA:1027  case Mips::ATOMIC_CMP_SWAP_I16_POSTRA:1028    return expandAtomicCmpSwapSubword(MBB, MBBI, NMBB);1029  case Mips::ATOMIC_SWAP_I8_POSTRA:1030  case Mips::ATOMIC_SWAP_I16_POSTRA:1031  case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:1032  case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:1033  case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:1034  case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:1035  case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:1036  case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:1037  case Mips::ATOMIC_LOAD_AND_I8_POSTRA:1038  case Mips::ATOMIC_LOAD_AND_I16_POSTRA:1039  case Mips::ATOMIC_LOAD_OR_I8_POSTRA:1040  case Mips::ATOMIC_LOAD_OR_I16_POSTRA:1041  case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:1042  case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:1043  case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:1044  case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:1045  case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:1046  case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:1047  case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:1048  case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:1049  case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:1050  case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:1051    return expandAtomicBinOpSubword(MBB, MBBI, NMBB);1052  case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:1053  case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:1054  case Mips::ATOMIC_LOAD_AND_I32_POSTRA:1055  case Mips::ATOMIC_LOAD_OR_I32_POSTRA:1056  case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:1057  case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:1058  case Mips::ATOMIC_SWAP_I32_POSTRA:1059  case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:1060  case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:1061  case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:1062  case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:1063    return expandAtomicBinOp(MBB, MBBI, NMBB, 4);1064  case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:1065  case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:1066  case Mips::ATOMIC_LOAD_AND_I64_POSTRA:1067  case Mips::ATOMIC_LOAD_OR_I64_POSTRA:1068  case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:1069  case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:1070  case Mips::ATOMIC_SWAP_I64_POSTRA:1071  case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:1072  case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:1073  case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:1074  case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:1075    return expandAtomicBinOp(MBB, MBBI, NMBB, 8);1076  default:1077    return Modified;1078  }1079}1080 1081bool MipsExpandPseudo::expandMBB(MachineBasicBlock &MBB) {1082  bool Modified = false;1083 1084  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();1085  while (MBBI != E) {1086    MachineBasicBlock::iterator NMBBI = std::next(MBBI);1087    Modified |= expandMI(MBB, MBBI, NMBBI);1088    MBBI = NMBBI;1089  }1090 1091  return Modified;1092}1093 1094bool MipsExpandPseudo::runOnMachineFunction(MachineFunction &MF) {1095  STI = &MF.getSubtarget<MipsSubtarget>();1096  TII = STI->getInstrInfo();1097 1098  bool Modified = false;1099  for (MachineBasicBlock &MBB : MF)1100    Modified |= expandMBB(MBB);1101 1102  if (Modified)1103    MF.RenumberBlocks();1104 1105  return Modified;1106}1107 1108/// createMipsExpandPseudoPass - returns an instance of the pseudo instruction1109/// expansion pass.1110FunctionPass *llvm::createMipsExpandPseudoPass() {1111  return new MipsExpandPseudo();1112}1113