Home | History | Annotate | Line # | Download | only in Mips
      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-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file contains a pass that expands pseudo instructions into target
     10 // instructions to allow proper scheduling, if-conversion, and other late
     11 // optimizations. This pass should be run after register allocation but before
     12 // the post-regalloc scheduling pass.
     13 //
     14 // This is currently only used for expanding atomic pseudos after register
     15 // allocation. We do this to avoid the fast register allocator introducing
     16 // spills between ll and sc. These stores cause some MIPS implementations to
     17 // 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 
     28 using namespace llvm;
     29 
     30 #define DEBUG_TYPE "mips-pseudo"
     31 
     32 namespace {
     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().set(
     45           MachineFunctionProperties::Property::NoVRegs);
     46     }
     47 
     48     StringRef getPassName() const override {
     49       return "Mips pseudo instruction expansion pass";
     50     }
     51 
     52   private:
     53     bool expandAtomicCmpSwap(MachineBasicBlock &MBB,
     54                              MachineBasicBlock::iterator MBBI,
     55                              MachineBasicBlock::iterator &NextMBBI);
     56     bool expandAtomicCmpSwapSubword(MachineBasicBlock &MBB,
     57                                     MachineBasicBlock::iterator MBBI,
     58                                     MachineBasicBlock::iterator &NextMBBI);
     59 
     60     bool expandAtomicBinOp(MachineBasicBlock &BB,
     61                            MachineBasicBlock::iterator I,
     62                            MachineBasicBlock::iterator &NMBBI, unsigned Size);
     63     bool expandAtomicBinOpSubword(MachineBasicBlock &BB,
     64                                   MachineBasicBlock::iterator I,
     65                                   MachineBasicBlock::iterator &NMBBI);
     66 
     67     bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
     68                   MachineBasicBlock::iterator &NMBB);
     69     bool expandMBB(MachineBasicBlock &MBB);
     70    };
     71   char MipsExpandPseudo::ID = 0;
     72 }
     73 
     74 bool MipsExpandPseudo::expandAtomicCmpSwapSubword(
     75     MachineBasicBlock &BB, MachineBasicBlock::iterator I,
     76     MachineBasicBlock::iterator &NMBBI) {
     77 
     78   MachineFunction *MF = BB.getParent();
     79 
     80   const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
     81   DebugLoc DL = I->getDebugLoc();
     82   unsigned LL, SC;
     83 
     84   unsigned ZERO = Mips::ZERO;
     85   unsigned BNE = Mips::BNE;
     86   unsigned BEQ = Mips::BEQ;
     87   unsigned SEOp =
     88       I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I8_POSTRA ? Mips::SEB : Mips::SEH;
     89 
     90   if (STI->inMicroMipsMode()) {
     91       LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
     92       SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
     93       BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
     94       BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
     95   } else {
     96     LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
     97                             : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
     98     SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
     99                             : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
    100   }
    101 
    102   Register Dest = I->getOperand(0).getReg();
    103   Register Ptr = I->getOperand(1).getReg();
    104   Register Mask = I->getOperand(2).getReg();
    105   Register ShiftCmpVal = I->getOperand(3).getReg();
    106   Register Mask2 = I->getOperand(4).getReg();
    107   Register ShiftNewVal = I->getOperand(5).getReg();
    108   Register ShiftAmnt = I->getOperand(6).getReg();
    109   Register Scratch = I->getOperand(7).getReg();
    110   Register Scratch2 = I->getOperand(8).getReg();
    111 
    112   // insert new blocks after the current block
    113   const BasicBlock *LLVM_BB = BB.getBasicBlock();
    114   MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
    115   MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
    116   MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
    117   MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
    118   MachineFunction::iterator It = ++BB.getIterator();
    119   MF->insert(It, loop1MBB);
    120   MF->insert(It, loop2MBB);
    121   MF->insert(It, sinkMBB);
    122   MF->insert(It, exitMBB);
    123 
    124   // Transfer the remainder of BB and its successor edges to exitMBB.
    125   exitMBB->splice(exitMBB->begin(), &BB,
    126                   std::next(MachineBasicBlock::iterator(I)), BB.end());
    127   exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
    128 
    129   //  thisMBB:
    130   //    ...
    131   //    fallthrough --> loop1MBB
    132   BB.addSuccessor(loop1MBB, BranchProbability::getOne());
    133   loop1MBB->addSuccessor(sinkMBB);
    134   loop1MBB->addSuccessor(loop2MBB);
    135   loop1MBB->normalizeSuccProbs();
    136   loop2MBB->addSuccessor(loop1MBB);
    137   loop2MBB->addSuccessor(sinkMBB);
    138   loop2MBB->normalizeSuccProbs();
    139   sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
    140 
    141   // loop1MBB:
    142   //   ll dest, 0(ptr)
    143   //   and Mask', dest, Mask
    144   //   bne Mask', ShiftCmpVal, exitMBB
    145   BuildMI(loop1MBB, DL, TII->get(LL), Scratch).addReg(Ptr).addImm(0);
    146   BuildMI(loop1MBB, DL, TII->get(Mips::AND), Scratch2)
    147       .addReg(Scratch)
    148       .addReg(Mask);
    149   BuildMI(loop1MBB, DL, TII->get(BNE))
    150     .addReg(Scratch2).addReg(ShiftCmpVal).addMBB(sinkMBB);
    151 
    152   // loop2MBB:
    153   //   and dest, dest, mask2
    154   //   or dest, dest, ShiftNewVal
    155   //   sc dest, dest, 0(ptr)
    156   //   beq dest, $0, loop1MBB
    157   BuildMI(loop2MBB, DL, TII->get(Mips::AND), Scratch)
    158       .addReg(Scratch, RegState::Kill)
    159       .addReg(Mask2);
    160   BuildMI(loop2MBB, DL, TII->get(Mips::OR), Scratch)
    161       .addReg(Scratch, RegState::Kill)
    162       .addReg(ShiftNewVal);
    163   BuildMI(loop2MBB, DL, TII->get(SC), Scratch)
    164       .addReg(Scratch, RegState::Kill)
    165       .addReg(Ptr)
    166       .addImm(0);
    167   BuildMI(loop2MBB, DL, TII->get(BEQ))
    168       .addReg(Scratch, RegState::Kill)
    169       .addReg(ZERO)
    170       .addMBB(loop1MBB);
    171 
    172   //  sinkMBB:
    173   //    srl     srlres, Mask', shiftamt
    174   //    sign_extend dest,srlres
    175   BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
    176       .addReg(Scratch2)
    177       .addReg(ShiftAmnt);
    178   if (STI->hasMips32r2()) {
    179     BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
    180   } else {
    181     const unsigned ShiftImm =
    182         I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I16_POSTRA ? 16 : 24;
    183     BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
    184         .addReg(Dest, RegState::Kill)
    185         .addImm(ShiftImm);
    186     BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
    187         .addReg(Dest, RegState::Kill)
    188         .addImm(ShiftImm);
    189   }
    190 
    191   LivePhysRegs LiveRegs;
    192   computeAndAddLiveIns(LiveRegs, *loop1MBB);
    193   computeAndAddLiveIns(LiveRegs, *loop2MBB);
    194   computeAndAddLiveIns(LiveRegs, *sinkMBB);
    195   computeAndAddLiveIns(LiveRegs, *exitMBB);
    196 
    197   NMBBI = BB.end();
    198   I->eraseFromParent();
    199   return true;
    200 }
    201 
    202 bool MipsExpandPseudo::expandAtomicCmpSwap(MachineBasicBlock &BB,
    203                                            MachineBasicBlock::iterator I,
    204                                            MachineBasicBlock::iterator &NMBBI) {
    205 
    206   const unsigned Size =
    207       I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I32_POSTRA ? 4 : 8;
    208   MachineFunction *MF = BB.getParent();
    209 
    210   const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
    211   DebugLoc DL = I->getDebugLoc();
    212 
    213   unsigned LL, SC, ZERO, BNE, BEQ, MOVE;
    214 
    215   if (Size == 4) {
    216     if (STI->inMicroMipsMode()) {
    217       LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
    218       SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
    219       BNE = STI->hasMips32r6() ? Mips::BNEC_MMR6 : Mips::BNE_MM;
    220       BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
    221     } else {
    222       LL = STI->hasMips32r6()
    223                ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
    224                : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
    225       SC = STI->hasMips32r6()
    226                ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
    227                : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
    228       BNE = Mips::BNE;
    229       BEQ = Mips::BEQ;
    230     }
    231 
    232     ZERO = Mips::ZERO;
    233     MOVE = Mips::OR;
    234   } else {
    235     LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
    236     SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
    237     ZERO = Mips::ZERO_64;
    238     BNE = Mips::BNE64;
    239     BEQ = Mips::BEQ64;
    240     MOVE = Mips::OR64;
    241   }
    242 
    243   Register Dest = I->getOperand(0).getReg();
    244   Register Ptr = I->getOperand(1).getReg();
    245   Register OldVal = I->getOperand(2).getReg();
    246   Register NewVal = I->getOperand(3).getReg();
    247   Register Scratch = I->getOperand(4).getReg();
    248 
    249   // insert new blocks after the current block
    250   const BasicBlock *LLVM_BB = BB.getBasicBlock();
    251   MachineBasicBlock *loop1MBB = MF->CreateMachineBasicBlock(LLVM_BB);
    252   MachineBasicBlock *loop2MBB = MF->CreateMachineBasicBlock(LLVM_BB);
    253   MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
    254   MachineFunction::iterator It = ++BB.getIterator();
    255   MF->insert(It, loop1MBB);
    256   MF->insert(It, loop2MBB);
    257   MF->insert(It, exitMBB);
    258 
    259   // Transfer the remainder of BB and its successor edges to exitMBB.
    260   exitMBB->splice(exitMBB->begin(), &BB,
    261                   std::next(MachineBasicBlock::iterator(I)), BB.end());
    262   exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
    263 
    264   //  thisMBB:
    265   //    ...
    266   //    fallthrough --> loop1MBB
    267   BB.addSuccessor(loop1MBB, BranchProbability::getOne());
    268   loop1MBB->addSuccessor(exitMBB);
    269   loop1MBB->addSuccessor(loop2MBB);
    270   loop1MBB->normalizeSuccProbs();
    271   loop2MBB->addSuccessor(loop1MBB);
    272   loop2MBB->addSuccessor(exitMBB);
    273   loop2MBB->normalizeSuccProbs();
    274 
    275   // loop1MBB:
    276   //   ll dest, 0(ptr)
    277   //   bne dest, oldval, exitMBB
    278   BuildMI(loop1MBB, DL, TII->get(LL), Dest).addReg(Ptr).addImm(0);
    279   BuildMI(loop1MBB, DL, TII->get(BNE))
    280     .addReg(Dest, RegState::Kill).addReg(OldVal).addMBB(exitMBB);
    281 
    282   // loop2MBB:
    283   //   move scratch, NewVal
    284   //   sc Scratch, Scratch, 0(ptr)
    285   //   beq Scratch, $0, loop1MBB
    286   BuildMI(loop2MBB, DL, TII->get(MOVE), Scratch).addReg(NewVal).addReg(ZERO);
    287   BuildMI(loop2MBB, DL, TII->get(SC), Scratch)
    288     .addReg(Scratch).addReg(Ptr).addImm(0);
    289   BuildMI(loop2MBB, DL, TII->get(BEQ))
    290     .addReg(Scratch, RegState::Kill).addReg(ZERO).addMBB(loop1MBB);
    291 
    292   LivePhysRegs LiveRegs;
    293   computeAndAddLiveIns(LiveRegs, *loop1MBB);
    294   computeAndAddLiveIns(LiveRegs, *loop2MBB);
    295   computeAndAddLiveIns(LiveRegs, *exitMBB);
    296 
    297   NMBBI = BB.end();
    298   I->eraseFromParent();
    299   return true;
    300 }
    301 
    302 bool MipsExpandPseudo::expandAtomicBinOpSubword(
    303     MachineBasicBlock &BB, MachineBasicBlock::iterator I,
    304     MachineBasicBlock::iterator &NMBBI) {
    305 
    306   MachineFunction *MF = BB.getParent();
    307 
    308   const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
    309   DebugLoc DL = I->getDebugLoc();
    310 
    311   unsigned LL, SC, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;
    312   unsigned BEQ = Mips::BEQ;
    313   unsigned SEOp = Mips::SEH;
    314 
    315   if (STI->inMicroMipsMode()) {
    316       LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
    317       SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
    318       BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
    319       SLT = Mips::SLT_MM;
    320       SLTu = Mips::SLTu_MM;
    321       OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
    322       MOVN = Mips::MOVN_I_MM;
    323       MOVZ = Mips::MOVZ_I_MM;
    324       SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
    325       SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
    326   } else {
    327     LL = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
    328                             : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
    329     SC = STI->hasMips32r6() ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
    330                             : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
    331     SLT = Mips::SLT;
    332     SLTu = Mips::SLTu;
    333     OR = Mips::OR;
    334     MOVN = Mips::MOVN_I_I;
    335     MOVZ = Mips::MOVZ_I_I;
    336     SELNEZ = Mips::SELNEZ;
    337     SELEQZ = Mips::SELEQZ;
    338   }
    339 
    340   bool IsSwap = false;
    341   bool IsNand = false;
    342   bool IsMin = false;
    343   bool IsMax = false;
    344   bool IsUnsigned = false;
    345 
    346   unsigned Opcode = 0;
    347   switch (I->getOpcode()) {
    348   case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
    349     SEOp = Mips::SEB;
    350     LLVM_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     LLVM_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     LLVM_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     LLVM_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     LLVM_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     LLVM_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     LLVM_FALLTHROUGH;
    387   case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
    388     Opcode = Mips::XOR;
    389     break;
    390   case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
    391   case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
    392     IsUnsigned = true;
    393     LLVM_FALLTHROUGH;
    394   case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
    395   case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
    396     IsMin = true;
    397     break;
    398   case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
    399   case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
    400     IsUnsigned = true;
    401     LLVM_FALLTHROUGH;
    402   case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
    403   case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
    404     IsMax = true;
    405     break;
    406   default:
    407     llvm_unreachable("Unknown subword atomic pseudo for expansion!");
    408   }
    409 
    410   Register Dest = I->getOperand(0).getReg();
    411   Register Ptr = I->getOperand(1).getReg();
    412   Register Incr = I->getOperand(2).getReg();
    413   Register Mask = I->getOperand(3).getReg();
    414   Register Mask2 = I->getOperand(4).getReg();
    415   Register ShiftAmnt = I->getOperand(5).getReg();
    416   Register OldVal = I->getOperand(6).getReg();
    417   Register BinOpRes = I->getOperand(7).getReg();
    418   Register StoreVal = I->getOperand(8).getReg();
    419 
    420   const BasicBlock *LLVM_BB = BB.getBasicBlock();
    421   MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
    422   MachineBasicBlock *sinkMBB = MF->CreateMachineBasicBlock(LLVM_BB);
    423   MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
    424   MachineFunction::iterator It = ++BB.getIterator();
    425   MF->insert(It, loopMBB);
    426   MF->insert(It, sinkMBB);
    427   MF->insert(It, exitMBB);
    428 
    429   exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end());
    430   exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
    431 
    432   BB.addSuccessor(loopMBB, BranchProbability::getOne());
    433   loopMBB->addSuccessor(sinkMBB);
    434   loopMBB->addSuccessor(loopMBB);
    435   loopMBB->normalizeSuccProbs();
    436 
    437   BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
    438   if (IsNand) {
    439     //  and andres, oldval, incr2
    440     //  nor binopres, $0, andres
    441     //  and newval, binopres, mask
    442     BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
    443         .addReg(OldVal)
    444         .addReg(Incr);
    445     BuildMI(loopMBB, DL, TII->get(Mips::NOR), BinOpRes)
    446         .addReg(Mips::ZERO)
    447         .addReg(BinOpRes);
    448     BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
    449         .addReg(BinOpRes)
    450         .addReg(Mask);
    451   } else if (IsMin || IsMax) {
    452 
    453     assert(I->getNumOperands() == 10 &&
    454            "Atomics min|max|umin|umax use an additional register");
    455     Register Scratch4 = I->getOperand(9).getReg();
    456 
    457     unsigned SLTScratch4 = IsUnsigned ? SLTu : SLT;
    458     unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
    459     unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
    460     unsigned MOVIncr = IsMax ? MOVN : MOVZ;
    461 
    462     // For little endian we need to clear uninterested bits.
    463     if (STI->isLittle()) {
    464       // and OldVal, OldVal, Mask
    465       // and Incr, Incr, Mask
    466       BuildMI(loopMBB, DL, TII->get(Mips::AND), OldVal)
    467           .addReg(OldVal)
    468           .addReg(Mask);
    469       BuildMI(loopMBB, DL, TII->get(Mips::AND), Incr).addReg(Incr).addReg(Mask);
    470     }
    471 
    472     // unsigned: sltu Scratch4, oldVal, Incr
    473     // signed:   slt Scratch4, oldVal, Incr
    474     BuildMI(loopMBB, DL, TII->get(SLTScratch4), Scratch4)
    475         .addReg(OldVal)
    476         .addReg(Incr);
    477 
    478     if (STI->hasMips64r6() || STI->hasMips32r6()) {
    479       // max: seleqz BinOpRes, OldVal, Scratch4
    480       //      selnez Scratch4, Incr, Scratch4
    481       //      or BinOpRes, BinOpRes, Scratch4
    482       // min: selnqz BinOpRes, OldVal, Scratch4
    483       //      seleqz Scratch4, Incr, Scratch4
    484       //      or BinOpRes, BinOpRes, Scratch4
    485       BuildMI(loopMBB, DL, TII->get(SELOldVal), BinOpRes)
    486           .addReg(OldVal)
    487           .addReg(Scratch4);
    488       BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch4)
    489           .addReg(Incr)
    490           .addReg(Scratch4);
    491       BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
    492           .addReg(BinOpRes)
    493           .addReg(Scratch4);
    494     } else {
    495       // max: move BinOpRes, OldVal
    496       //      movn BinOpRes, Incr, Scratch4, BinOpRes
    497       // min: move BinOpRes, OldVal
    498       //      movz BinOpRes, Incr, Scratch4, BinOpRes
    499       BuildMI(loopMBB, DL, TII->get(OR), BinOpRes)
    500           .addReg(OldVal)
    501           .addReg(Mips::ZERO);
    502       BuildMI(loopMBB, DL, TII->get(MOVIncr), BinOpRes)
    503           .addReg(Incr)
    504           .addReg(Scratch4)
    505           .addReg(BinOpRes);
    506     }
    507 
    508     //  and BinOpRes, BinOpRes, Mask
    509     BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
    510         .addReg(BinOpRes)
    511         .addReg(Mask);
    512 
    513   } else if (!IsSwap) {
    514     //  <binop> binopres, oldval, incr2
    515     //  and newval, binopres, mask
    516     BuildMI(loopMBB, DL, TII->get(Opcode), BinOpRes)
    517         .addReg(OldVal)
    518         .addReg(Incr);
    519     BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
    520         .addReg(BinOpRes)
    521         .addReg(Mask);
    522   } else { // atomic.swap
    523     //  and newval, incr2, mask
    524     BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
    525         .addReg(Incr)
    526         .addReg(Mask);
    527   }
    528 
    529   // and StoreVal, OlddVal, Mask2
    530   // or StoreVal, StoreVal, BinOpRes
    531   // StoreVal<tied1> = sc StoreVal, 0(Ptr)
    532   // beq StoreVal, zero, loopMBB
    533   BuildMI(loopMBB, DL, TII->get(Mips::AND), StoreVal)
    534     .addReg(OldVal).addReg(Mask2);
    535   BuildMI(loopMBB, DL, TII->get(Mips::OR), StoreVal)
    536     .addReg(StoreVal).addReg(BinOpRes);
    537   BuildMI(loopMBB, DL, TII->get(SC), StoreVal)
    538     .addReg(StoreVal).addReg(Ptr).addImm(0);
    539   BuildMI(loopMBB, DL, TII->get(BEQ))
    540     .addReg(StoreVal).addReg(Mips::ZERO).addMBB(loopMBB);
    541 
    542   //  sinkMBB:
    543   //    and     maskedoldval1,oldval,mask
    544   //    srl     srlres,maskedoldval1,shiftamt
    545   //    sign_extend dest,srlres
    546 
    547   sinkMBB->addSuccessor(exitMBB, BranchProbability::getOne());
    548 
    549   BuildMI(sinkMBB, DL, TII->get(Mips::AND), Dest)
    550     .addReg(OldVal).addReg(Mask);
    551   BuildMI(sinkMBB, DL, TII->get(Mips::SRLV), Dest)
    552       .addReg(Dest).addReg(ShiftAmnt);
    553 
    554   if (STI->hasMips32r2()) {
    555     BuildMI(sinkMBB, DL, TII->get(SEOp), Dest).addReg(Dest);
    556   } else {
    557     const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
    558     BuildMI(sinkMBB, DL, TII->get(Mips::SLL), Dest)
    559         .addReg(Dest, RegState::Kill)
    560         .addImm(ShiftImm);
    561     BuildMI(sinkMBB, DL, TII->get(Mips::SRA), Dest)
    562         .addReg(Dest, RegState::Kill)
    563         .addImm(ShiftImm);
    564   }
    565 
    566   LivePhysRegs LiveRegs;
    567   computeAndAddLiveIns(LiveRegs, *loopMBB);
    568   computeAndAddLiveIns(LiveRegs, *sinkMBB);
    569   computeAndAddLiveIns(LiveRegs, *exitMBB);
    570 
    571   NMBBI = BB.end();
    572   I->eraseFromParent();
    573 
    574   return true;
    575 }
    576 
    577 bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock &BB,
    578                                          MachineBasicBlock::iterator I,
    579                                          MachineBasicBlock::iterator &NMBBI,
    580                                          unsigned Size) {
    581   MachineFunction *MF = BB.getParent();
    582 
    583   const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
    584   DebugLoc DL = I->getDebugLoc();
    585 
    586   unsigned LL, SC, ZERO, BEQ, SLT, SLTu, OR, MOVN, MOVZ, SELNEZ, SELEQZ;
    587 
    588   if (Size == 4) {
    589     if (STI->inMicroMipsMode()) {
    590       LL = STI->hasMips32r6() ? Mips::LL_MMR6 : Mips::LL_MM;
    591       SC = STI->hasMips32r6() ? Mips::SC_MMR6 : Mips::SC_MM;
    592       BEQ = STI->hasMips32r6() ? Mips::BEQC_MMR6 : Mips::BEQ_MM;
    593       SLT = Mips::SLT_MM;
    594       SLTu = Mips::SLTu_MM;
    595       OR = STI->hasMips32r6() ? Mips::OR_MMR6 : Mips::OR_MM;
    596       MOVN = Mips::MOVN_I_MM;
    597       MOVZ = Mips::MOVZ_I_MM;
    598       SELNEZ = STI->hasMips32r6() ? Mips::SELNEZ_MMR6 : Mips::SELNEZ;
    599       SELEQZ = STI->hasMips32r6() ? Mips::SELEQZ_MMR6 : Mips::SELEQZ;
    600     } else {
    601       LL = STI->hasMips32r6()
    602                ? (ArePtrs64bit ? Mips::LL64_R6 : Mips::LL_R6)
    603                : (ArePtrs64bit ? Mips::LL64 : Mips::LL);
    604       SC = STI->hasMips32r6()
    605                ? (ArePtrs64bit ? Mips::SC64_R6 : Mips::SC_R6)
    606                : (ArePtrs64bit ? Mips::SC64 : Mips::SC);
    607       BEQ = Mips::BEQ;
    608       SLT = Mips::SLT;
    609       SLTu = Mips::SLTu;
    610       OR = Mips::OR;
    611       MOVN = Mips::MOVN_I_I;
    612       MOVZ = Mips::MOVZ_I_I;
    613       SELNEZ = Mips::SELNEZ;
    614       SELEQZ = Mips::SELEQZ;
    615     }
    616 
    617     ZERO = Mips::ZERO;
    618   } else {
    619     LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
    620     SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
    621     ZERO = Mips::ZERO_64;
    622     BEQ = Mips::BEQ64;
    623     SLT = Mips::SLT64;
    624     SLTu = Mips::SLTu64;
    625     OR = Mips::OR64;
    626     MOVN = Mips::MOVN_I64_I64;
    627     MOVZ = Mips::MOVZ_I64_I64;
    628     SELNEZ = Mips::SELNEZ64;
    629     SELEQZ = Mips::SELEQZ64;
    630   }
    631 
    632   Register OldVal = I->getOperand(0).getReg();
    633   Register Ptr = I->getOperand(1).getReg();
    634   Register Incr = I->getOperand(2).getReg();
    635   Register Scratch = I->getOperand(3).getReg();
    636 
    637   unsigned Opcode = 0;
    638   unsigned AND = 0;
    639   unsigned NOR = 0;
    640 
    641   bool IsOr = false;
    642   bool IsNand = false;
    643   bool IsMin = false;
    644   bool IsMax = false;
    645   bool IsUnsigned = false;
    646 
    647   switch (I->getOpcode()) {
    648   case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
    649     Opcode = Mips::ADDu;
    650     break;
    651   case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
    652     Opcode = Mips::SUBu;
    653     break;
    654   case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
    655     Opcode = Mips::AND;
    656     break;
    657   case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
    658     Opcode = Mips::OR;
    659     break;
    660   case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
    661     Opcode = Mips::XOR;
    662     break;
    663   case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
    664     IsNand = true;
    665     AND = Mips::AND;
    666     NOR = Mips::NOR;
    667     break;
    668   case Mips::ATOMIC_SWAP_I32_POSTRA:
    669     IsOr = true;
    670     break;
    671   case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
    672     Opcode = Mips::DADDu;
    673     break;
    674   case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
    675     Opcode = Mips::DSUBu;
    676     break;
    677   case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
    678     Opcode = Mips::AND64;
    679     break;
    680   case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
    681     Opcode = Mips::OR64;
    682     break;
    683   case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
    684     Opcode = Mips::XOR64;
    685     break;
    686   case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
    687     IsNand = true;
    688     AND = Mips::AND64;
    689     NOR = Mips::NOR64;
    690     break;
    691   case Mips::ATOMIC_SWAP_I64_POSTRA:
    692     IsOr = true;
    693     break;
    694   case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
    695   case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
    696     IsUnsigned = true;
    697     LLVM_FALLTHROUGH;
    698   case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
    699   case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
    700     IsMin = true;
    701     break;
    702   case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
    703   case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
    704     IsUnsigned = true;
    705     LLVM_FALLTHROUGH;
    706   case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
    707   case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
    708     IsMax = true;
    709     break;
    710   default:
    711     llvm_unreachable("Unknown pseudo atomic!");
    712   }
    713 
    714   const BasicBlock *LLVM_BB = BB.getBasicBlock();
    715   MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB);
    716   MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);
    717   MachineFunction::iterator It = ++BB.getIterator();
    718   MF->insert(It, loopMBB);
    719   MF->insert(It, exitMBB);
    720 
    721   exitMBB->splice(exitMBB->begin(), &BB, std::next(I), BB.end());
    722   exitMBB->transferSuccessorsAndUpdatePHIs(&BB);
    723 
    724   BB.addSuccessor(loopMBB, BranchProbability::getOne());
    725   loopMBB->addSuccessor(exitMBB);
    726   loopMBB->addSuccessor(loopMBB);
    727   loopMBB->normalizeSuccProbs();
    728 
    729   BuildMI(loopMBB, DL, TII->get(LL), OldVal).addReg(Ptr).addImm(0);
    730   assert((OldVal != Ptr) && "Clobbered the wrong ptr reg!");
    731   assert((OldVal != Incr) && "Clobbered the wrong reg!");
    732   if (IsMin || IsMax) {
    733 
    734     assert(I->getNumOperands() == 5 &&
    735            "Atomics min|max|umin|umax use an additional register");
    736     MCRegister Scratch2 = I->getOperand(4).getReg().asMCReg();
    737 
    738     // On Mips64 result of slt is GPR32.
    739     MCRegister Scratch2_32 =
    740         (Size == 8) ? STI->getRegisterInfo()->getSubReg(Scratch2, Mips::sub_32)
    741                     : Scratch2;
    742 
    743     unsigned SLTScratch2 = IsUnsigned ? SLTu : SLT;
    744     unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
    745     unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
    746     unsigned MOVIncr = IsMax ? MOVN : MOVZ;
    747 
    748     // unsigned: sltu Scratch2, oldVal, Incr
    749     // signed:   slt Scratch2, oldVal, Incr
    750     BuildMI(loopMBB, DL, TII->get(SLTScratch2), Scratch2_32)
    751         .addReg(OldVal)
    752         .addReg(Incr);
    753 
    754     if (STI->hasMips64r6() || STI->hasMips32r6()) {
    755       // max: seleqz Scratch, OldVal, Scratch2
    756       //      selnez Scratch2, Incr, Scratch2
    757       //      or Scratch, Scratch, Scratch2
    758       // min: selnez Scratch, OldVal, Scratch2
    759       //      seleqz Scratch2, Incr, Scratch2
    760       //      or Scratch, Scratch, Scratch2
    761       BuildMI(loopMBB, DL, TII->get(SELOldVal), Scratch)
    762           .addReg(OldVal)
    763           .addReg(Scratch2);
    764       BuildMI(loopMBB, DL, TII->get(SELIncr), Scratch2)
    765           .addReg(Incr)
    766           .addReg(Scratch2);
    767       BuildMI(loopMBB, DL, TII->get(OR), Scratch)
    768           .addReg(Scratch)
    769           .addReg(Scratch2);
    770     } else {
    771       // max: move Scratch, OldVal
    772       //      movn Scratch, Incr, Scratch2, Scratch
    773       // min: move Scratch, OldVal
    774       //      movz Scratch, Incr, Scratch2, Scratch
    775       BuildMI(loopMBB, DL, TII->get(OR), Scratch)
    776           .addReg(OldVal)
    777           .addReg(ZERO);
    778       BuildMI(loopMBB, DL, TII->get(MOVIncr), Scratch)
    779           .addReg(Incr)
    780           .addReg(Scratch2)
    781           .addReg(Scratch);
    782     }
    783 
    784   } else if (Opcode) {
    785     BuildMI(loopMBB, DL, TII->get(Opcode), Scratch).addReg(OldVal).addReg(Incr);
    786   } else if (IsNand) {
    787     assert(AND && NOR &&
    788            "Unknown nand instruction for atomic pseudo expansion");
    789     BuildMI(loopMBB, DL, TII->get(AND), Scratch).addReg(OldVal).addReg(Incr);
    790     BuildMI(loopMBB, DL, TII->get(NOR), Scratch).addReg(ZERO).addReg(Scratch);
    791   } else {
    792     assert(IsOr && OR && "Unknown instruction for atomic pseudo expansion!");
    793     (void)IsOr;
    794     BuildMI(loopMBB, DL, TII->get(OR), Scratch).addReg(Incr).addReg(ZERO);
    795   }
    796 
    797   BuildMI(loopMBB, DL, TII->get(SC), Scratch)
    798       .addReg(Scratch)
    799       .addReg(Ptr)
    800       .addImm(0);
    801   BuildMI(loopMBB, DL, TII->get(BEQ))
    802       .addReg(Scratch)
    803       .addReg(ZERO)
    804       .addMBB(loopMBB);
    805 
    806   NMBBI = BB.end();
    807   I->eraseFromParent();
    808 
    809   LivePhysRegs LiveRegs;
    810   computeAndAddLiveIns(LiveRegs, *loopMBB);
    811   computeAndAddLiveIns(LiveRegs, *exitMBB);
    812 
    813   return true;
    814 }
    815 
    816 bool MipsExpandPseudo::expandMI(MachineBasicBlock &MBB,
    817                                 MachineBasicBlock::iterator MBBI,
    818                                 MachineBasicBlock::iterator &NMBB) {
    819 
    820   bool Modified = false;
    821 
    822   switch (MBBI->getOpcode()) {
    823   case Mips::ATOMIC_CMP_SWAP_I32_POSTRA:
    824   case Mips::ATOMIC_CMP_SWAP_I64_POSTRA:
    825     return expandAtomicCmpSwap(MBB, MBBI, NMBB);
    826   case Mips::ATOMIC_CMP_SWAP_I8_POSTRA:
    827   case Mips::ATOMIC_CMP_SWAP_I16_POSTRA:
    828     return expandAtomicCmpSwapSubword(MBB, MBBI, NMBB);
    829   case Mips::ATOMIC_SWAP_I8_POSTRA:
    830   case Mips::ATOMIC_SWAP_I16_POSTRA:
    831   case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
    832   case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
    833   case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
    834   case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
    835   case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
    836   case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
    837   case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
    838   case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
    839   case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
    840   case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
    841   case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
    842   case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
    843   case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
    844   case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
    845   case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
    846   case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
    847   case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
    848   case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
    849   case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
    850   case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
    851     return expandAtomicBinOpSubword(MBB, MBBI, NMBB);
    852   case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
    853   case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
    854   case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
    855   case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
    856   case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
    857   case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
    858   case Mips::ATOMIC_SWAP_I32_POSTRA:
    859   case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
    860   case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
    861   case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
    862   case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
    863     return expandAtomicBinOp(MBB, MBBI, NMBB, 4);
    864   case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
    865   case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
    866   case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
    867   case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
    868   case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
    869   case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
    870   case Mips::ATOMIC_SWAP_I64_POSTRA:
    871   case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
    872   case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
    873   case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
    874   case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
    875     return expandAtomicBinOp(MBB, MBBI, NMBB, 8);
    876   default:
    877     return Modified;
    878   }
    879 }
    880 
    881 bool MipsExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
    882   bool Modified = false;
    883 
    884   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
    885   while (MBBI != E) {
    886     MachineBasicBlock::iterator NMBBI = std::next(MBBI);
    887     Modified |= expandMI(MBB, MBBI, NMBBI);
    888     MBBI = NMBBI;
    889   }
    890 
    891   return Modified;
    892 }
    893 
    894 bool MipsExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
    895   STI = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
    896   TII = STI->getInstrInfo();
    897 
    898   bool Modified = false;
    899   for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
    900        ++MFI)
    901     Modified |= expandMBB(*MFI);
    902 
    903   if (Modified)
    904     MF.RenumberBlocks();
    905 
    906   return Modified;
    907 }
    908 
    909 /// createMipsExpandPseudoPass - returns an instance of the pseudo instruction
    910 /// expansion pass.
    911 FunctionPass *llvm::createMipsExpandPseudoPass() {
    912   return new MipsExpandPseudo();
    913 }
    914