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;
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:
427 Register Dest =
I->getOperand(0).getReg();
429 Register Incr =
I->getOperand(2).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();
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;
483 const unsigned OpMask = SEOp == Mips::SEH ? 0xffff : 0xff;
487 }
else if (STI->hasMips32r2()) {
490 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
491 const unsigned SROp = IsUnsigned ? Mips::SRL : Mips::SRA;
513 if (STI->hasMips64r6() || STI->hasMips32r6()) {
548 }
else if (!IsSwap) {
589 if (STI->hasMips32r2()) {
592 const unsigned ShiftImm = SEOp == Mips::SEH ? 16 : 24;
608 I->eraseFromParent();
619 const bool ArePtrs64bit = STI->getABI().ArePtrs64bit();
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();
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:
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();
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;
786 BuildMI(loopMBB,
DL,
TII->get(SLTScratch2), Scratch2_32)
790 if (STI->hasMips64r6() || STI->hasMips32r6()) {
824 "Unknown nand instruction for atomic pseudo expansion");
828 assert(IsOr && OR &&
"Unknown instruction for atomic pseudo expansion!");
843 I->eraseFromParent();
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);
932 TII = STI->getInstrInfo();
947 return new MipsExpandPseudo();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
@ ZERO
Special weight used for cases with exact zero probability.
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.