MipsExpandPseudo.cpp revision 360784
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
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().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
74bool 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
202bool 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
302bool 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
577bool 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    Register Scratch2 = I->getOperand(4).getReg();
737
738    // On Mips64 result of slt is GPR32.
739    Register 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
816bool 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
881bool 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
894bool 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.
911FunctionPass *llvm::createMipsExpandPseudoPass() {
912  return new MipsExpandPseudo();
913}
914