1 //===-- MipsExpandPseudoInsts.cpp - Expand pseudo instructions ------------===//
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
7 //===----------------------------------------------------------------------===//
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.
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.
19 //===----------------------------------------------------------------------===//
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"
30 #define DEBUG_TYPE "mips-pseudo"
33 class MipsExpandPseudo
: public MachineFunctionPass
{
36 MipsExpandPseudo() : MachineFunctionPass(ID
) {}
38 const MipsInstrInfo
*TII
;
39 const MipsSubtarget
*STI
;
41 bool runOnMachineFunction(MachineFunction
&Fn
) override
;
43 MachineFunctionProperties
getRequiredProperties() const override
{
44 return MachineFunctionProperties().set(
45 MachineFunctionProperties::Property::NoVRegs
);
48 StringRef
getPassName() const override
{
49 return "Mips pseudo instruction expansion pass";
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
);
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
);
67 bool expandMI(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator MBBI
,
68 MachineBasicBlock::iterator
&NMBB
);
69 bool expandMBB(MachineBasicBlock
&MBB
);
71 char MipsExpandPseudo::ID
= 0;
74 bool MipsExpandPseudo::expandAtomicCmpSwapSubword(
75 MachineBasicBlock
&BB
, MachineBasicBlock::iterator I
,
76 MachineBasicBlock::iterator
&NMBBI
) {
78 MachineFunction
*MF
= BB
.getParent();
80 const bool ArePtrs64bit
= STI
->getABI().ArePtrs64bit();
81 DebugLoc DL
= I
->getDebugLoc();
84 unsigned ZERO
= Mips::ZERO
;
85 unsigned BNE
= Mips::BNE
;
86 unsigned BEQ
= Mips::BEQ
;
88 I
->getOpcode() == Mips::ATOMIC_CMP_SWAP_I8_POSTRA
? Mips::SEB
: Mips::SEH
;
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
;
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
);
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();
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
);
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
);
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());
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
)
149 BuildMI(loop1MBB
, DL
, TII
->get(BNE
))
150 .addReg(Scratch2
).addReg(ShiftCmpVal
).addMBB(sinkMBB
);
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
)
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
)
167 BuildMI(loop2MBB
, DL
, TII
->get(BEQ
))
168 .addReg(Scratch
, RegState::Kill
)
173 // srl srlres, Mask', shiftamt
174 // sign_extend dest,srlres
175 BuildMI(sinkMBB
, DL
, TII
->get(Mips::SRLV
), Dest
)
178 if (STI
->hasMips32r2()) {
179 BuildMI(sinkMBB
, DL
, TII
->get(SEOp
), Dest
).addReg(Dest
);
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
)
186 BuildMI(sinkMBB
, DL
, TII
->get(Mips::SRA
), Dest
)
187 .addReg(Dest
, RegState::Kill
)
191 LivePhysRegs LiveRegs
;
192 computeAndAddLiveIns(LiveRegs
, *loop1MBB
);
193 computeAndAddLiveIns(LiveRegs
, *loop2MBB
);
194 computeAndAddLiveIns(LiveRegs
, *sinkMBB
);
195 computeAndAddLiveIns(LiveRegs
, *exitMBB
);
198 I
->eraseFromParent();
202 bool MipsExpandPseudo::expandAtomicCmpSwap(MachineBasicBlock
&BB
,
203 MachineBasicBlock::iterator I
,
204 MachineBasicBlock::iterator
&NMBBI
) {
206 const unsigned Size
=
207 I
->getOpcode() == Mips::ATOMIC_CMP_SWAP_I32_POSTRA
? 4 : 8;
208 MachineFunction
*MF
= BB
.getParent();
210 const bool ArePtrs64bit
= STI
->getABI().ArePtrs64bit();
211 DebugLoc DL
= I
->getDebugLoc();
213 unsigned LL
, SC
, ZERO
, BNE
, BEQ
, MOVE
;
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
;
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
);
235 LL
= STI
->hasMips64r6() ? Mips::LLD_R6
: Mips::LLD
;
236 SC
= STI
->hasMips64r6() ? Mips::SCD_R6
: Mips::SCD
;
237 ZERO
= Mips::ZERO_64
;
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();
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
);
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
);
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();
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
);
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
);
292 LivePhysRegs LiveRegs
;
293 computeAndAddLiveIns(LiveRegs
, *loop1MBB
);
294 computeAndAddLiveIns(LiveRegs
, *loop2MBB
);
295 computeAndAddLiveIns(LiveRegs
, *exitMBB
);
298 I
->eraseFromParent();
302 bool MipsExpandPseudo::expandAtomicBinOpSubword(
303 MachineBasicBlock
&BB
, MachineBasicBlock::iterator I
,
304 MachineBasicBlock::iterator
&NMBBI
) {
306 MachineFunction
*MF
= BB
.getParent();
308 const bool ArePtrs64bit
= STI
->getABI().ArePtrs64bit();
309 DebugLoc DL
= I
->getDebugLoc();
311 unsigned LL
, SC
, SLT
, SLTu
, OR
, MOVN
, MOVZ
, SELNEZ
, SELEQZ
;
312 unsigned BEQ
= Mips::BEQ
;
313 unsigned SEOp
= Mips::SEH
;
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
;
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
;
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
);
334 MOVN
= Mips::MOVN_I_I
;
335 MOVZ
= Mips::MOVZ_I_I
;
336 SELNEZ
= Mips::SELNEZ
;
337 SELEQZ
= Mips::SELEQZ
;
344 bool IsUnsigned
= false;
348 switch (I
->getOpcode()) {
349 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA
:
352 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA
:
355 case Mips::ATOMIC_SWAP_I8_POSTRA
:
358 case Mips::ATOMIC_SWAP_I16_POSTRA
:
361 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA
:
364 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA
:
367 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA
:
370 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA
:
373 case Mips::ATOMIC_LOAD_AND_I8_POSTRA
:
376 case Mips::ATOMIC_LOAD_AND_I16_POSTRA
:
379 case Mips::ATOMIC_LOAD_OR_I8_POSTRA
:
382 case Mips::ATOMIC_LOAD_OR_I16_POSTRA
:
385 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA
:
388 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA
:
391 case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA
:
396 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA
:
400 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA
:
404 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA
:
407 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA
:
412 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA
:
416 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA
:
420 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA
:
424 llvm_unreachable("Unknown subword atomic pseudo for expansion!");
427 Register Dest
= I
->getOperand(0).getReg();
428 Register Ptr
= I
->getOperand(1).getReg();
429 Register Incr
= I
->getOperand(2).getReg();
430 Register Mask
= I
->getOperand(3).getReg();
431 Register Mask2
= I
->getOperand(4).getReg();
432 Register ShiftAmnt
= I
->getOperand(5).getReg();
433 Register OldVal
= I
->getOperand(6).getReg();
434 Register BinOpRes
= I
->getOperand(7).getReg();
435 Register StoreVal
= I
->getOperand(8).getReg();
437 const BasicBlock
*LLVM_BB
= BB
.getBasicBlock();
438 MachineBasicBlock
*loopMBB
= MF
->CreateMachineBasicBlock(LLVM_BB
);
439 MachineBasicBlock
*sinkMBB
= MF
->CreateMachineBasicBlock(LLVM_BB
);
440 MachineBasicBlock
*exitMBB
= MF
->CreateMachineBasicBlock(LLVM_BB
);
441 MachineFunction::iterator It
= ++BB
.getIterator();
442 MF
->insert(It
, loopMBB
);
443 MF
->insert(It
, sinkMBB
);
444 MF
->insert(It
, exitMBB
);
446 exitMBB
->splice(exitMBB
->begin(), &BB
, std::next(I
), BB
.end());
447 exitMBB
->transferSuccessorsAndUpdatePHIs(&BB
);
449 BB
.addSuccessor(loopMBB
, BranchProbability::getOne());
450 loopMBB
->addSuccessor(sinkMBB
);
451 loopMBB
->addSuccessor(loopMBB
);
452 loopMBB
->normalizeSuccProbs();
454 BuildMI(loopMBB
, DL
, TII
->get(LL
), OldVal
).addReg(Ptr
).addImm(0);
456 // and andres, oldval, incr2
457 // nor binopres, $0, andres
458 // and newval, binopres, mask
459 BuildMI(loopMBB
, DL
, TII
->get(Mips::AND
), BinOpRes
)
462 BuildMI(loopMBB
, DL
, TII
->get(Mips::NOR
), BinOpRes
)
465 BuildMI(loopMBB
, DL
, TII
->get(Mips::AND
), BinOpRes
)
468 } else if (IsMin
|| IsMax
) {
470 assert(I
->getNumOperands() == 10 &&
471 "Atomics min|max|umin|umax use an additional register");
472 Register Scratch4
= I
->getOperand(9).getReg();
474 unsigned SLTScratch4
= IsUnsigned
? SLTu
: SLT
;
475 unsigned SELIncr
= IsMax
? SELNEZ
: SELEQZ
;
476 unsigned SELOldVal
= IsMax
? SELEQZ
: SELNEZ
;
477 unsigned MOVIncr
= IsMax
? MOVN
: MOVZ
;
479 BuildMI(loopMBB
, DL
, TII
->get(Mips::SRAV
), StoreVal
)
483 const unsigned OpMask
= SEOp
== Mips::SEH
? 0xffff : 0xff;
484 BuildMI(loopMBB
, DL
, TII
->get(Mips::ANDi
), StoreVal
)
487 } else if (STI
->hasMips32r2()) {
488 BuildMI(loopMBB
, DL
, TII
->get(SEOp
), StoreVal
).addReg(StoreVal
);
490 const unsigned ShiftImm
= SEOp
== Mips::SEH
? 16 : 24;
491 const unsigned SROp
= IsUnsigned
? Mips::SRL
: Mips::SRA
;
492 BuildMI(loopMBB
, DL
, TII
->get(Mips::SLL
), StoreVal
)
493 .addReg(StoreVal
, RegState::Kill
)
495 BuildMI(loopMBB
, DL
, TII
->get(SROp
), StoreVal
)
496 .addReg(StoreVal
, RegState::Kill
)
499 BuildMI(loopMBB
, DL
, TII
->get(Mips::OR
), Dest
)
503 BuildMI(loopMBB
, DL
, TII
->get(Mips::SLLV
), StoreVal
)
507 // unsigned: sltu Scratch4, StoreVal, Incr
508 // signed: slt Scratch4, StoreVal, Incr
509 BuildMI(loopMBB
, DL
, TII
->get(SLTScratch4
), Scratch4
)
513 if (STI
->hasMips64r6() || STI
->hasMips32r6()) {
514 // max: seleqz BinOpRes, OldVal, Scratch4
515 // selnez Scratch4, Incr, Scratch4
516 // or BinOpRes, BinOpRes, Scratch4
517 // min: selnqz BinOpRes, OldVal, Scratch4
518 // seleqz Scratch4, Incr, Scratch4
519 // or BinOpRes, BinOpRes, Scratch4
520 BuildMI(loopMBB
, DL
, TII
->get(SELOldVal
), BinOpRes
)
523 BuildMI(loopMBB
, DL
, TII
->get(SELIncr
), Scratch4
)
526 BuildMI(loopMBB
, DL
, TII
->get(OR
), BinOpRes
)
530 // max: move BinOpRes, StoreVal
531 // movn BinOpRes, Incr, Scratch4, BinOpRes
532 // min: move BinOpRes, StoreVal
533 // movz BinOpRes, Incr, Scratch4, BinOpRes
534 BuildMI(loopMBB
, DL
, TII
->get(OR
), BinOpRes
)
537 BuildMI(loopMBB
, DL
, TII
->get(MOVIncr
), BinOpRes
)
543 // and BinOpRes, BinOpRes, Mask
544 BuildMI(loopMBB
, DL
, TII
->get(Mips::AND
), BinOpRes
)
548 } else if (!IsSwap
) {
549 // <binop> binopres, oldval, incr2
550 // and newval, binopres, mask
551 BuildMI(loopMBB
, DL
, TII
->get(Opcode
), BinOpRes
)
554 BuildMI(loopMBB
, DL
, TII
->get(Mips::AND
), BinOpRes
)
557 } else { // atomic.swap
558 // and newval, incr2, mask
559 BuildMI(loopMBB
, DL
, TII
->get(Mips::AND
), BinOpRes
)
564 // and StoreVal, OlddVal, Mask2
565 // or StoreVal, StoreVal, BinOpRes
566 // StoreVal<tied1> = sc StoreVal, 0(Ptr)
567 // beq StoreVal, zero, loopMBB
568 BuildMI(loopMBB
, DL
, TII
->get(Mips::AND
), StoreVal
)
569 .addReg(OldVal
).addReg(Mask2
);
570 BuildMI(loopMBB
, DL
, TII
->get(Mips::OR
), StoreVal
)
571 .addReg(StoreVal
).addReg(BinOpRes
);
572 BuildMI(loopMBB
, DL
, TII
->get(SC
), StoreVal
)
573 .addReg(StoreVal
).addReg(Ptr
).addImm(0);
574 BuildMI(loopMBB
, DL
, TII
->get(BEQ
))
575 .addReg(StoreVal
).addReg(Mips::ZERO
).addMBB(loopMBB
);
578 // and maskedoldval1,oldval,mask
579 // srl srlres,maskedoldval1,shiftamt
580 // sign_extend dest,srlres
583 sinkMBB
->addSuccessor(exitMBB
, BranchProbability::getOne());
584 BuildMI(sinkMBB
, DL
, TII
->get(Mips::AND
), Dest
).addReg(OldVal
).addReg(Mask
);
585 BuildMI(sinkMBB
, DL
, TII
->get(Mips::SRLV
), Dest
)
589 if (STI
->hasMips32r2()) {
590 BuildMI(sinkMBB
, DL
, TII
->get(SEOp
), Dest
).addReg(Dest
);
592 const unsigned ShiftImm
= SEOp
== Mips::SEH
? 16 : 24;
593 BuildMI(sinkMBB
, DL
, TII
->get(Mips::SLL
), Dest
)
594 .addReg(Dest
, RegState::Kill
)
596 BuildMI(sinkMBB
, DL
, TII
->get(Mips::SRA
), Dest
)
597 .addReg(Dest
, RegState::Kill
)
602 LivePhysRegs LiveRegs
;
603 computeAndAddLiveIns(LiveRegs
, *loopMBB
);
604 computeAndAddLiveIns(LiveRegs
, *sinkMBB
);
605 computeAndAddLiveIns(LiveRegs
, *exitMBB
);
608 I
->eraseFromParent();
613 bool MipsExpandPseudo::expandAtomicBinOp(MachineBasicBlock
&BB
,
614 MachineBasicBlock::iterator I
,
615 MachineBasicBlock::iterator
&NMBBI
,
617 MachineFunction
*MF
= BB
.getParent();
619 const bool ArePtrs64bit
= STI
->getABI().ArePtrs64bit();
620 DebugLoc DL
= I
->getDebugLoc();
622 unsigned LL
, SC
, ZERO
, BEQ
, SLT
, SLTu
, OR
, MOVN
, MOVZ
, SELNEZ
, SELEQZ
;
625 if (STI
->inMicroMipsMode()) {
626 LL
= STI
->hasMips32r6() ? Mips::LL_MMR6
: Mips::LL_MM
;
627 SC
= STI
->hasMips32r6() ? Mips::SC_MMR6
: Mips::SC_MM
;
628 BEQ
= STI
->hasMips32r6() ? Mips::BEQC_MMR6
: Mips::BEQ_MM
;
630 SLTu
= Mips::SLTu_MM
;
631 OR
= STI
->hasMips32r6() ? Mips::OR_MMR6
: Mips::OR_MM
;
632 MOVN
= Mips::MOVN_I_MM
;
633 MOVZ
= Mips::MOVZ_I_MM
;
634 SELNEZ
= STI
->hasMips32r6() ? Mips::SELNEZ_MMR6
: Mips::SELNEZ
;
635 SELEQZ
= STI
->hasMips32r6() ? Mips::SELEQZ_MMR6
: Mips::SELEQZ
;
637 LL
= STI
->hasMips32r6()
638 ? (ArePtrs64bit
? Mips::LL64_R6
: Mips::LL_R6
)
639 : (ArePtrs64bit
? Mips::LL64
: Mips::LL
);
640 SC
= STI
->hasMips32r6()
641 ? (ArePtrs64bit
? Mips::SC64_R6
: Mips::SC_R6
)
642 : (ArePtrs64bit
? Mips::SC64
: Mips::SC
);
647 MOVN
= Mips::MOVN_I_I
;
648 MOVZ
= Mips::MOVZ_I_I
;
649 SELNEZ
= Mips::SELNEZ
;
650 SELEQZ
= Mips::SELEQZ
;
655 LL
= STI
->hasMips64r6() ? Mips::LLD_R6
: Mips::LLD
;
656 SC
= STI
->hasMips64r6() ? Mips::SCD_R6
: Mips::SCD
;
657 ZERO
= Mips::ZERO_64
;
662 MOVN
= Mips::MOVN_I64_I64
;
663 MOVZ
= Mips::MOVZ_I64_I64
;
664 SELNEZ
= Mips::SELNEZ64
;
665 SELEQZ
= Mips::SELEQZ64
;
668 Register OldVal
= I
->getOperand(0).getReg();
669 Register Ptr
= I
->getOperand(1).getReg();
670 Register Incr
= I
->getOperand(2).getReg();
671 Register Scratch
= I
->getOperand(3).getReg();
681 bool IsUnsigned
= false;
683 switch (I
->getOpcode()) {
684 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA
:
687 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA
:
690 case Mips::ATOMIC_LOAD_AND_I32_POSTRA
:
693 case Mips::ATOMIC_LOAD_OR_I32_POSTRA
:
696 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA
:
699 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA
:
704 case Mips::ATOMIC_SWAP_I32_POSTRA
:
707 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA
:
708 Opcode
= Mips::DADDu
;
710 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA
:
711 Opcode
= Mips::DSUBu
;
713 case Mips::ATOMIC_LOAD_AND_I64_POSTRA
:
714 Opcode
= Mips::AND64
;
716 case Mips::ATOMIC_LOAD_OR_I64_POSTRA
:
719 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA
:
720 Opcode
= Mips::XOR64
;
722 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA
:
727 case Mips::ATOMIC_SWAP_I64_POSTRA
:
730 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA
:
731 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA
:
734 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA
:
735 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA
:
738 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA
:
739 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA
:
742 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA
:
743 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA
:
747 llvm_unreachable("Unknown pseudo atomic!");
750 const BasicBlock
*LLVM_BB
= BB
.getBasicBlock();
751 MachineBasicBlock
*loopMBB
= MF
->CreateMachineBasicBlock(LLVM_BB
);
752 MachineBasicBlock
*exitMBB
= MF
->CreateMachineBasicBlock(LLVM_BB
);
753 MachineFunction::iterator It
= ++BB
.getIterator();
754 MF
->insert(It
, loopMBB
);
755 MF
->insert(It
, exitMBB
);
757 exitMBB
->splice(exitMBB
->begin(), &BB
, std::next(I
), BB
.end());
758 exitMBB
->transferSuccessorsAndUpdatePHIs(&BB
);
760 BB
.addSuccessor(loopMBB
, BranchProbability::getOne());
761 loopMBB
->addSuccessor(exitMBB
);
762 loopMBB
->addSuccessor(loopMBB
);
763 loopMBB
->normalizeSuccProbs();
765 BuildMI(loopMBB
, DL
, TII
->get(LL
), OldVal
).addReg(Ptr
).addImm(0);
766 assert((OldVal
!= Ptr
) && "Clobbered the wrong ptr reg!");
767 assert((OldVal
!= Incr
) && "Clobbered the wrong reg!");
768 if (IsMin
|| IsMax
) {
770 assert(I
->getNumOperands() == 5 &&
771 "Atomics min|max|umin|umax use an additional register");
772 MCRegister Scratch2
= I
->getOperand(4).getReg().asMCReg();
774 // On Mips64 result of slt is GPR32.
775 MCRegister Scratch2_32
=
776 (Size
== 8) ? STI
->getRegisterInfo()->getSubReg(Scratch2
, Mips::sub_32
)
779 unsigned SLTScratch2
= IsUnsigned
? SLTu
: SLT
;
780 unsigned SELIncr
= IsMax
? SELNEZ
: SELEQZ
;
781 unsigned SELOldVal
= IsMax
? SELEQZ
: SELNEZ
;
782 unsigned MOVIncr
= IsMax
? MOVN
: MOVZ
;
784 // unsigned: sltu Scratch2, oldVal, Incr
785 // signed: slt Scratch2, oldVal, Incr
786 BuildMI(loopMBB
, DL
, TII
->get(SLTScratch2
), Scratch2_32
)
790 if (STI
->hasMips64r6() || STI
->hasMips32r6()) {
791 // max: seleqz Scratch, OldVal, Scratch2
792 // selnez Scratch2, Incr, Scratch2
793 // or Scratch, Scratch, Scratch2
794 // min: selnez Scratch, OldVal, Scratch2
795 // seleqz Scratch2, Incr, Scratch2
796 // or Scratch, Scratch, Scratch2
797 BuildMI(loopMBB
, DL
, TII
->get(SELOldVal
), Scratch
)
800 BuildMI(loopMBB
, DL
, TII
->get(SELIncr
), Scratch2
)
803 BuildMI(loopMBB
, DL
, TII
->get(OR
), Scratch
)
807 // max: move Scratch, OldVal
808 // movn Scratch, Incr, Scratch2, Scratch
809 // min: move Scratch, OldVal
810 // movz Scratch, Incr, Scratch2, Scratch
811 BuildMI(loopMBB
, DL
, TII
->get(OR
), Scratch
)
814 BuildMI(loopMBB
, DL
, TII
->get(MOVIncr
), Scratch
)
821 BuildMI(loopMBB
, DL
, TII
->get(Opcode
), Scratch
).addReg(OldVal
).addReg(Incr
);
824 "Unknown nand instruction for atomic pseudo expansion");
825 BuildMI(loopMBB
, DL
, TII
->get(AND
), Scratch
).addReg(OldVal
).addReg(Incr
);
826 BuildMI(loopMBB
, DL
, TII
->get(NOR
), Scratch
).addReg(ZERO
).addReg(Scratch
);
828 assert(IsOr
&& OR
&& "Unknown instruction for atomic pseudo expansion!");
830 BuildMI(loopMBB
, DL
, TII
->get(OR
), Scratch
).addReg(Incr
).addReg(ZERO
);
833 BuildMI(loopMBB
, DL
, TII
->get(SC
), Scratch
)
837 BuildMI(loopMBB
, DL
, TII
->get(BEQ
))
843 I
->eraseFromParent();
845 LivePhysRegs LiveRegs
;
846 computeAndAddLiveIns(LiveRegs
, *loopMBB
);
847 computeAndAddLiveIns(LiveRegs
, *exitMBB
);
852 bool MipsExpandPseudo::expandMI(MachineBasicBlock
&MBB
,
853 MachineBasicBlock::iterator MBBI
,
854 MachineBasicBlock::iterator
&NMBB
) {
856 bool Modified
= false;
858 switch (MBBI
->getOpcode()) {
859 case Mips::ATOMIC_CMP_SWAP_I32_POSTRA
:
860 case Mips::ATOMIC_CMP_SWAP_I64_POSTRA
:
861 return expandAtomicCmpSwap(MBB
, MBBI
, NMBB
);
862 case Mips::ATOMIC_CMP_SWAP_I8_POSTRA
:
863 case Mips::ATOMIC_CMP_SWAP_I16_POSTRA
:
864 return expandAtomicCmpSwapSubword(MBB
, MBBI
, NMBB
);
865 case Mips::ATOMIC_SWAP_I8_POSTRA
:
866 case Mips::ATOMIC_SWAP_I16_POSTRA
:
867 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA
:
868 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA
:
869 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA
:
870 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA
:
871 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA
:
872 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA
:
873 case Mips::ATOMIC_LOAD_AND_I8_POSTRA
:
874 case Mips::ATOMIC_LOAD_AND_I16_POSTRA
:
875 case Mips::ATOMIC_LOAD_OR_I8_POSTRA
:
876 case Mips::ATOMIC_LOAD_OR_I16_POSTRA
:
877 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA
:
878 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA
:
879 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA
:
880 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA
:
881 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA
:
882 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA
:
883 case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA
:
884 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA
:
885 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA
:
886 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA
:
887 return expandAtomicBinOpSubword(MBB
, MBBI
, NMBB
);
888 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA
:
889 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA
:
890 case Mips::ATOMIC_LOAD_AND_I32_POSTRA
:
891 case Mips::ATOMIC_LOAD_OR_I32_POSTRA
:
892 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA
:
893 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA
:
894 case Mips::ATOMIC_SWAP_I32_POSTRA
:
895 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA
:
896 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA
:
897 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA
:
898 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA
:
899 return expandAtomicBinOp(MBB
, MBBI
, NMBB
, 4);
900 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA
:
901 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA
:
902 case Mips::ATOMIC_LOAD_AND_I64_POSTRA
:
903 case Mips::ATOMIC_LOAD_OR_I64_POSTRA
:
904 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA
:
905 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA
:
906 case Mips::ATOMIC_SWAP_I64_POSTRA
:
907 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA
:
908 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA
:
909 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA
:
910 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA
:
911 return expandAtomicBinOp(MBB
, MBBI
, NMBB
, 8);
917 bool MipsExpandPseudo::expandMBB(MachineBasicBlock
&MBB
) {
918 bool Modified
= false;
920 MachineBasicBlock::iterator MBBI
= MBB
.begin(), E
= MBB
.end();
922 MachineBasicBlock::iterator NMBBI
= std::next(MBBI
);
923 Modified
|= expandMI(MBB
, MBBI
, NMBBI
);
930 bool MipsExpandPseudo::runOnMachineFunction(MachineFunction
&MF
) {
931 STI
= &MF
.getSubtarget
<MipsSubtarget
>();
932 TII
= STI
->getInstrInfo();
934 bool Modified
= false;
935 for (MachineBasicBlock
&MBB
: MF
)
936 Modified
|= expandMBB(MBB
);
944 /// createMipsExpandPseudoPass - returns an instance of the pseudo instruction
946 FunctionPass
*llvm::createMipsExpandPseudoPass() {
947 return new MipsExpandPseudo();