xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MipsExpandPseudo.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
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;
MipsExpandPseudo()36     MipsExpandPseudo() : MachineFunctionPass(ID) {}
37 
38     const MipsInstrInfo *TII;
39     const MipsSubtarget *STI;
40 
41     bool runOnMachineFunction(MachineFunction &Fn) override;
42 
getRequiredProperties() const43     MachineFunctionProperties getRequiredProperties() const override {
44       return MachineFunctionProperties().setNoVRegs();
45     }
46 
getPassName() const47     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 
expandAtomicCmpSwapSubword(MachineBasicBlock & BB,MachineBasicBlock::iterator I,MachineBasicBlock::iterator & NMBBI)73 bool 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 block
112   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 --> loop1MBB
131   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, Mask
143   //   bne Mask', ShiftCmpVal, exitMBB
144   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, mask2
153   //   or dest, dest, ShiftNewVal
154   //   sc dest, dest, 0(ptr)
155   //   beq dest, $0, loop1MBB
156   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', shiftamt
173   //    sign_extend dest,srlres
174   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 
expandAtomicCmpSwap(MachineBasicBlock & BB,MachineBasicBlock::iterator I,MachineBasicBlock::iterator & NMBBI)201 bool 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 block
249   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 --> loop1MBB
266   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, exitMBB
277   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, NewVal
283   //   sc Scratch, Scratch, 0(ptr)
284   //   beq Scratch, $0, loop1MBB
285   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 
expandAtomicBinOpSubword(MachineBasicBlock & BB,MachineBasicBlock::iterator I,MachineBasicBlock::iterator & NMBBI)301 bool 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, incr2
477     //  nor binopres, $0, andres
478     //  and newval, binopres, mask
479     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, Incr
528     // signed:   slt Scratch4, StoreVal, Incr
529     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, Scratch4
535       //      selnez Scratch4, Incr, Scratch4
536       //      or BinOpRes, BinOpRes, Scratch4
537       // min: selnqz BinOpRes, OldVal, Scratch4
538       //      seleqz Scratch4, Incr, Scratch4
539       //      or BinOpRes, BinOpRes, Scratch4
540       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, StoreVal
551       //      movn BinOpRes, Incr, Scratch4, BinOpRes
552       // min: move BinOpRes, StoreVal
553       //      movz BinOpRes, Incr, Scratch4, BinOpRes
554       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, StoreVal
564       //           beq Scratch4, 0, loop1MBB
565       //           j loop2MBB
566       // loop1MBB: move BinOpRes, Incr
567       // loop2MBB: and BinOpRes, BinOpRes, Mask
568       //           and StoreVal, OlddVal, Mask2
569       //           or StoreVal, StoreVal, BinOpRes
570       //           StoreVal<tied1> = sc StoreVal, 0(Ptr)
571       //           beq StoreVal, zero, loopMBB
572       //
573       // if max:
574       // loopMBB:  move BinOpRes, Incr
575       //           beq Scratch4, 0, loop1MBB
576       //           j loop2MBB
577       // loop1MBB: move BinOpRes, StoreVal
578       // loop2MBB: and BinOpRes, BinOpRes, Mask
579       //           and StoreVal, OlddVal, Mask2
580       //           or StoreVal, StoreVal, BinOpRes
581       //           StoreVal<tied1> = sc StoreVal, 0(Ptr)
582       //           beq StoreVal, zero, loopMBB
583       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, Mask
606     if (NoMovnInstr)
607       BuildMI(loop2MBB, DL, TII->get(Mips::AND), BinOpRes)
608           .addReg(BinOpRes)
609           .addReg(Mask);
610     else
611       BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
612           .addReg(BinOpRes)
613           .addReg(Mask);
614 
615   } else if (!IsSwap) {
616     //  <binop> binopres, oldval, incr2
617     //  and newval, binopres, mask
618     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.swap
625     //  and newval, incr2, mask
626     BuildMI(loopMBB, DL, TII->get(Mips::AND), BinOpRes)
627         .addReg(Incr)
628         .addReg(Mask);
629   }
630 
631   // and StoreVal, OlddVal, Mask2
632   // or StoreVal, StoreVal, BinOpRes
633   // StoreVal<tied1> = sc StoreVal, 0(Ptr)
634   // beq StoreVal, zero, loopMBB
635   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,mask
669   //    srl     srlres,maskedoldval1,shiftamt
670   //    sign_extend dest,srlres
671 
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 
expandAtomicBinOp(MachineBasicBlock & BB,MachineBasicBlock::iterator I,MachineBasicBlock::iterator & NMBBI,unsigned Size)708 bool 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, Incr
901     // signed:   slt Scratch2, oldVal, Incr
902     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, Scratch2
908       //      selnez Scratch2, Incr, Scratch2
909       //      or Scratch, Scratch, Scratch2
910       // min: selnez Scratch, OldVal, Scratch2
911       //      seleqz Scratch2, Incr, Scratch2
912       //      or Scratch, Scratch, Scratch2
913       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, OldVal
924       //      movn Scratch, Incr, Scratch2, Scratch
925       // min: move Scratch, OldVal
926       //      movz Scratch, Incr, Scratch2, Scratch
927       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, OldVal
937       //           beq Scratch2_32, 0, loop1MBB
938       //           j loop2MBB
939       // loop1MBB: move Scratch, Incr
940       // loop2MBB: sc $2, 0($4)
941       //           beqz	$2, $BB0_1
942       //           nop
943       //
944       // if max:
945       // loopMBB:  move Scratch, Incr
946       //           beq Scratch2_32, 0, loop1MBB
947       //           j loop2MBB
948       // loop1MBB: move Scratch, OldVal
949       // loop2MBB: sc $2, 0($4)
950       //           beqz	$2, $BB0_1
951       //           nop
952       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 
expandMI(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,MachineBasicBlock::iterator & NMBB)1016 bool 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 
expandMBB(MachineBasicBlock & MBB)1081 bool 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 
runOnMachineFunction(MachineFunction & MF)1094 bool 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 instruction
1109 /// expansion pass.
createMipsExpandPseudoPass()1110 FunctionPass *llvm::createMipsExpandPseudoPass() {
1111   return new MipsExpandPseudo();
1112 }
1113