30#define DEBUG_TYPE "mips-pseudo"
45 MachineFunctionProperties::Property::NoVRegs);
49 return "Mips pseudo instruction expansion pass";
71 char MipsExpandPseudo::ID = 0;
74bool MipsExpandPseudo::expandAtomicCmpSwapSubword(
80 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
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();
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();
178 if (STI->hasMips32r2()) {
181 const unsigned ShiftImm =
182 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I16_POSTRA ? 16 : 24;
198 I->eraseFromParent();
206 const unsigned Size =
207 I->getOpcode() == Mips::ATOMIC_CMP_SWAP_I32_POSTRA ? 4 : 8;
210 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
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();
245 Register OldVal =
I->getOperand(2).getReg();
246 Register NewVal =
I->getOperand(3).getReg();
247 Register Scratch =
I->getOperand(4).getReg();
298 I->eraseFromParent();
302bool MipsExpandPseudo::expandAtomicBinOpSubword(
308 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
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;
347 switch (
I->getOpcode()) {
348 case Mips::ATOMIC_LOAD_NAND_I8_POSTRA:
351 case Mips::ATOMIC_LOAD_NAND_I16_POSTRA:
354 case Mips::ATOMIC_SWAP_I8_POSTRA:
357 case Mips::ATOMIC_SWAP_I16_POSTRA:
360 case Mips::ATOMIC_LOAD_ADD_I8_POSTRA:
363 case Mips::ATOMIC_LOAD_ADD_I16_POSTRA:
366 case Mips::ATOMIC_LOAD_SUB_I8_POSTRA:
369 case Mips::ATOMIC_LOAD_SUB_I16_POSTRA:
372 case Mips::ATOMIC_LOAD_AND_I8_POSTRA:
375 case Mips::ATOMIC_LOAD_AND_I16_POSTRA:
378 case Mips::ATOMIC_LOAD_OR_I8_POSTRA:
381 case Mips::ATOMIC_LOAD_OR_I16_POSTRA:
384 case Mips::ATOMIC_LOAD_XOR_I8_POSTRA:
387 case Mips::ATOMIC_LOAD_XOR_I16_POSTRA:
390 case Mips::ATOMIC_LOAD_UMIN_I8_POSTRA:
391 case Mips::ATOMIC_LOAD_UMIN_I16_POSTRA:
394 case Mips::ATOMIC_LOAD_MIN_I8_POSTRA:
395 case Mips::ATOMIC_LOAD_MIN_I16_POSTRA:
398 case Mips::ATOMIC_LOAD_UMAX_I8_POSTRA:
399 case Mips::ATOMIC_LOAD_UMAX_I16_POSTRA:
402 case Mips::ATOMIC_LOAD_MAX_I8_POSTRA:
403 case Mips::ATOMIC_LOAD_MAX_I16_POSTRA:
410 Register Dest =
I->getOperand(0).getReg();
412 Register Incr =
I->getOperand(2).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();
451 }
else if (IsMin || IsMax) {
453 assert(
I->getNumOperands() == 10 &&
454 "Atomics min|max|umin|umax use an additional register");
455 Register Scratch4 =
I->getOperand(9).getReg();
457 unsigned SLTScratch4 = IsUnsigned ? SLTu : SLT;
458 unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
459 unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
460 unsigned MOVIncr = IsMax ? MOVN : MOVZ;
463 if (STI->isLittle()) {
478 if (STI->hasMips64r6() || STI->hasMips32r6()) {
513 }
else if (!IsSwap) {
554 if (STI->hasMips32r2()) {
557 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
572 I->eraseFromParent();
583 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
586 unsigned LL,
SC,
ZERO, BEQ, SLT, SLTu,
OR, MOVN, MOVZ, SELNEZ, SELEQZ;
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;
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;
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);
611 MOVN = Mips::MOVN_I_I;
612 MOVZ = Mips::MOVZ_I_I;
613 SELNEZ = Mips::SELNEZ;
614 SELEQZ = Mips::SELEQZ;
619 LL = STI->hasMips64r6() ? Mips::LLD_R6 : Mips::LLD;
620 SC = STI->hasMips64r6() ? Mips::SCD_R6 : Mips::SCD;
621 ZERO = Mips::ZERO_64;
626 MOVN = Mips::MOVN_I64_I64;
627 MOVZ = Mips::MOVZ_I64_I64;
628 SELNEZ = Mips::SELNEZ64;
629 SELEQZ = Mips::SELEQZ64;
632 Register OldVal =
I->getOperand(0).getReg();
634 Register Incr =
I->getOperand(2).getReg();
635 Register Scratch =
I->getOperand(3).getReg();
645 bool IsUnsigned =
false;
647 switch (
I->getOpcode()) {
648 case Mips::ATOMIC_LOAD_ADD_I32_POSTRA:
651 case Mips::ATOMIC_LOAD_SUB_I32_POSTRA:
654 case Mips::ATOMIC_LOAD_AND_I32_POSTRA:
657 case Mips::ATOMIC_LOAD_OR_I32_POSTRA:
660 case Mips::ATOMIC_LOAD_XOR_I32_POSTRA:
663 case Mips::ATOMIC_LOAD_NAND_I32_POSTRA:
668 case Mips::ATOMIC_SWAP_I32_POSTRA:
671 case Mips::ATOMIC_LOAD_ADD_I64_POSTRA:
674 case Mips::ATOMIC_LOAD_SUB_I64_POSTRA:
677 case Mips::ATOMIC_LOAD_AND_I64_POSTRA:
680 case Mips::ATOMIC_LOAD_OR_I64_POSTRA:
683 case Mips::ATOMIC_LOAD_XOR_I64_POSTRA:
686 case Mips::ATOMIC_LOAD_NAND_I64_POSTRA:
691 case Mips::ATOMIC_SWAP_I64_POSTRA:
694 case Mips::ATOMIC_LOAD_UMIN_I32_POSTRA:
695 case Mips::ATOMIC_LOAD_UMIN_I64_POSTRA:
698 case Mips::ATOMIC_LOAD_MIN_I32_POSTRA:
699 case Mips::ATOMIC_LOAD_MIN_I64_POSTRA:
702 case Mips::ATOMIC_LOAD_UMAX_I32_POSTRA:
703 case Mips::ATOMIC_LOAD_UMAX_I64_POSTRA:
706 case Mips::ATOMIC_LOAD_MAX_I32_POSTRA:
707 case Mips::ATOMIC_LOAD_MAX_I64_POSTRA:
730 assert((OldVal !=
Ptr) &&
"Clobbered the wrong ptr reg!");
731 assert((OldVal != Incr) &&
"Clobbered the wrong reg!");
732 if (IsMin || IsMax) {
734 assert(
I->getNumOperands() == 5 &&
735 "Atomics min|max|umin|umax use an additional register");
736 MCRegister Scratch2 =
I->getOperand(4).getReg().asMCReg();
740 (
Size == 8) ? STI->getRegisterInfo()->getSubReg(Scratch2, Mips::sub_32)
743 unsigned SLTScratch2 = IsUnsigned ? SLTu : SLT;
744 unsigned SELIncr = IsMax ? SELNEZ : SELEQZ;
745 unsigned SELOldVal = IsMax ? SELEQZ : SELNEZ;
746 unsigned MOVIncr = IsMax ? MOVN : MOVZ;
750 BuildMI(loopMBB,
DL,
TII->get(SLTScratch2), Scratch2_32)
754 if (STI->hasMips64r6() || STI->hasMips32r6()) {
788 "Unknown nand instruction for atomic pseudo expansion");
792 assert(IsOr && OR &&
"Unknown instruction for atomic pseudo expansion!");
807 I->eraseFromParent();
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);
896 TII = STI->getInstrInfo();
911 return new MipsExpandPseudo();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
@ ZERO
Special weight used for cases with exact zero probability.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static constexpr uint32_t Opcode
LLVM Basic Block Representation.
static BranchProbability getOne()
FunctionPass class - This class is used to implement most global optimizations.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
Wrapper class representing physical registers. Should be passed by value.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
StringRef - Represent a constant reference to a string, i.e.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
FunctionPass * createMipsExpandPseudoPass()
createMipsExpandPseudoPass - returns an instance of the pseudo instruction expansion pass.