24#define DEBUG_TYPE "mips-lower"
27 "mips16-dont-expand-cond-pseudo",
29 cl::desc(
"Don't expand conditional move related "
30 "pseudos for Mips 16"),
34struct Mips16IntrinsicHelperType{
38 bool operator<(
const Mips16IntrinsicHelperType &
RHS)
const {
39 return std::strcmp(Name,
RHS.Name) < 0;
42 return std::strcmp(Name,
RHS.Name) == 0;
49 RTLIB::impl___mips16_adddf3, RTLIB::impl___mips16_addsf3,
50 RTLIB::impl___mips16_divdf3, RTLIB::impl___mips16_divsf3,
51 RTLIB::impl___mips16_eqdf2, RTLIB::impl___mips16_eqsf2,
52 RTLIB::impl___mips16_extendsfdf2, RTLIB::impl___mips16_fix_truncdfsi,
53 RTLIB::impl___mips16_fix_truncsfsi, RTLIB::impl___mips16_floatsidf,
54 RTLIB::impl___mips16_floatsisf, RTLIB::impl___mips16_floatunsidf,
55 RTLIB::impl___mips16_floatunsisf, RTLIB::impl___mips16_gedf2,
56 RTLIB::impl___mips16_gesf2, RTLIB::impl___mips16_gtdf2,
57 RTLIB::impl___mips16_gtsf2, RTLIB::impl___mips16_ledf2,
58 RTLIB::impl___mips16_lesf2, RTLIB::impl___mips16_ltdf2,
59 RTLIB::impl___mips16_ltsf2, RTLIB::impl___mips16_muldf3,
60 RTLIB::impl___mips16_mulsf3, RTLIB::impl___mips16_nedf2,
61 RTLIB::impl___mips16_nesf2, RTLIB::impl___mips16_ret_dc,
62 RTLIB::impl___mips16_ret_df, RTLIB::impl___mips16_ret_sc,
63 RTLIB::impl___mips16_ret_sf, RTLIB::impl___mips16_subdf3,
64 RTLIB::impl___mips16_subsf3, RTLIB::impl___mips16_truncdfsf2,
65 RTLIB::impl___mips16_unorddf2, RTLIB::impl___mips16_unordsf2};
68 {
"__fixunsdfsi",
"__mips16_call_stub_2" },
69 {
"ceil",
"__mips16_call_stub_df_2"},
70 {
"ceilf",
"__mips16_call_stub_sf_1"},
71 {
"copysign",
"__mips16_call_stub_df_10"},
72 {
"copysignf",
"__mips16_call_stub_sf_5"},
73 {
"cos",
"__mips16_call_stub_df_2"},
74 {
"cosf",
"__mips16_call_stub_sf_1"},
75 {
"exp2",
"__mips16_call_stub_df_2"},
76 {
"exp2f",
"__mips16_call_stub_sf_1"},
77 {
"floor",
"__mips16_call_stub_df_2"},
78 {
"floorf",
"__mips16_call_stub_sf_1"},
79 {
"log2",
"__mips16_call_stub_df_2"},
80 {
"log2f",
"__mips16_call_stub_sf_1"},
81 {
"nearbyint",
"__mips16_call_stub_df_2"},
82 {
"nearbyintf",
"__mips16_call_stub_sf_1"},
83 {
"rint",
"__mips16_call_stub_df_2"},
84 {
"rintf",
"__mips16_call_stub_sf_1"},
85 {
"sin",
"__mips16_call_stub_df_2"},
86 {
"sinf",
"__mips16_call_stub_sf_1"},
87 {
"sqrt",
"__mips16_call_stub_df_2"},
88 {
"sqrtf",
"__mips16_call_stub_sf_1"},
89 {
"trunc",
"__mips16_call_stub_df_2"},
90 {
"truncf",
"__mips16_call_stub_sf_1"},
101 setMips16HardFloatLibCalls();
139 switch (
MI.getOpcode()) {
143 return emitSel16(Mips::BeqzRxImm16,
MI, BB);
145 return emitSel16(Mips::BnezRxImm16,
MI, BB);
146 case Mips::SelTBteqZCmpi:
147 return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16,
MI, BB);
148 case Mips::SelTBteqZSlti:
149 return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16,
MI, BB);
150 case Mips::SelTBteqZSltiu:
151 return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16,
MI, BB);
152 case Mips::SelTBtneZCmpi:
153 return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16,
MI, BB);
154 case Mips::SelTBtneZSlti:
155 return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16,
MI, BB);
156 case Mips::SelTBtneZSltiu:
157 return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16,
MI, BB);
158 case Mips::SelTBteqZCmp:
159 return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16,
MI, BB);
160 case Mips::SelTBteqZSlt:
161 return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16,
MI, BB);
162 case Mips::SelTBteqZSltu:
163 return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16,
MI, BB);
164 case Mips::SelTBtneZCmp:
165 return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16,
MI, BB);
166 case Mips::SelTBtneZSlt:
167 return emitSelT16(Mips::Btnez16, Mips::SltRxRy16,
MI, BB);
168 case Mips::SelTBtneZSltu:
169 return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16,
MI, BB);
170 case Mips::BteqzT8CmpX16:
171 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16,
MI, BB);
172 case Mips::BteqzT8SltX16:
173 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16,
MI, BB);
174 case Mips::BteqzT8SltuX16:
177 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16,
MI, BB);
178 case Mips::BtnezT8CmpX16:
179 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16,
MI, BB);
180 case Mips::BtnezT8SltX16:
181 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16,
MI, BB);
182 case Mips::BtnezT8SltuX16:
185 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16,
MI, BB);
186 case Mips::BteqzT8CmpiX16:
return emitFEXT_T8I8I16_ins(
187 Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false,
MI, BB);
188 case Mips::BteqzT8SltiX16:
return emitFEXT_T8I8I16_ins(
189 Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true,
MI, BB);
190 case Mips::BteqzT8SltiuX16:
return emitFEXT_T8I8I16_ins(
191 Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false,
MI, BB);
192 case Mips::BtnezT8CmpiX16:
return emitFEXT_T8I8I16_ins(
193 Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false,
MI, BB);
194 case Mips::BtnezT8SltiX16:
return emitFEXT_T8I8I16_ins(
195 Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true,
MI, BB);
196 case Mips::BtnezT8SltiuX16:
return emitFEXT_T8I8I16_ins(
197 Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false,
MI, BB);
199 case Mips::SltCCRxRy16:
200 return emitFEXT_CCRX16_ins(Mips::SltRxRy16,
MI, BB);
202 case Mips::SltiCCRxImmX16:
203 return emitFEXT_CCRXI16_ins
204 (Mips::SltiRxImm16, Mips::SltiRxImmX16,
MI, BB);
205 case Mips::SltiuCCRxImmX16:
206 return emitFEXT_CCRXI16_ins
207 (Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
MI, BB);
208 case Mips::SltuCCRxRy16:
209 return emitFEXT_CCRX16_ins
210 (Mips::SltuRxRy16,
MI, BB);
214bool Mips16TargetLowering::isEligibleForTailCallOptimization(
215 const CCState &CCInfo,
unsigned NextStackOffset,
221void Mips16TargetLowering::setMips16HardFloatLibCalls() {
224 "Array not sorted!");
262unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
263 (ArgListTy &Args)
const {
264 unsigned int resultNum = 0;
265 if (
Args.size() >= 1) {
275 if (
Args.size() >=2) {
312#define P_ "__mips16_call_stub_"
313#define MAX_STUB_NUMBER 10
314#define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
339const char* Mips16TargetLowering::
340 getMips16HelperFunction
341 (
Type* RetTy, ArgListTy &Args,
bool &needHelper)
const {
342 const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
344 const unsigned int maxStubNum = 10;
345 assert(stubNum <= maxStubNum);
346 const bool validStubNum[maxStubNum+1] =
347 {
true,
true,
true,
false,
false,
true,
true,
false,
false,
true,
true};
348 assert(validStubNum[stubNum]);
354 else if (RetTy ->isDoubleTy()) {
358 if (SRetTy->getNumElements() == 2) {
359 if ((SRetTy->getElementType(0)->isFloatTy()) &&
360 (SRetTy->getElementType(1)->isFloatTy())) {
362 }
else if ((SRetTy->getElementType(0)->isDoubleTy()) &&
363 (SRetTy->getElementType(1)->isDoubleTy())) {
386 return !ParsedLibcalls.
empty() &&
390void Mips16TargetLowering::
392 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
393 bool IsPICCall,
bool GlobalOrExternal,
bool InternalLinkage,
394 bool IsCallReloc, CallLoweringInfo &CLI,
SDValue Callee,
396 SelectionDAG &DAG = CLI.DAG;
398 MipsFunctionInfo *FuncInfo = MF.
getInfo<MipsFunctionInfo>();
399 const char* Mips16HelperFunction =
nullptr;
400 bool NeedMips16Helper =
false;
408 bool LookupHelper =
true;
411 LookupHelper =
false;
413 const char *
Symbol = S->getSymbol();
414 Mips16IntrinsicHelperType IntrinsicFind = {
Symbol,
"" };
415 const Mips16HardFloatInfo::FuncSignature *Signature =
417 if (!IsPICCall && Signature &&
418 FuncInfo->
StubsNeeded.try_emplace(Symbol, Signature).second) {
436 const Mips16IntrinsicHelperType *Helper =
439 *Helper == IntrinsicFind) {
440 Mips16HelperFunction = Helper->Helper;
441 NeedMips16Helper =
true;
442 LookupHelper =
false;
446 }
else if (GlobalAddressSDNode *
G =
450 LookupHelper =
false;
453 Mips16HelperFunction =
454 getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
461 if (IsPICCall || !GlobalOrExternal) {
462 unsigned V0Reg = Mips::V0;
463 if (NeedMips16Helper) {
464 RegsToPass.push_front(std::make_pair(V0Reg, Callee));
472 RegsToPass.push_front(std::make_pair((
unsigned)Mips::T9, Callee));
475 Ops.push_back(JumpTarget);
478 InternalLinkage, IsCallReloc, CLI, Callee,
502 MachineBasicBlock *thisMBB = BB;
505 MachineBasicBlock *sinkMBB =
F->CreateMachineBasicBlock(LLVM_BB);
507 F->insert(It, sinkMBB);
541 MI.eraseFromParent();
546Mips16TargetLowering::emitSelT16(
unsigned Opc1,
unsigned Opc2,
MachineInstr &
MI,
565 MachineBasicBlock *thisMBB = BB;
567 MachineBasicBlock *copy0MBB =
F->CreateMachineBasicBlock(LLVM_BB);
568 MachineBasicBlock *sinkMBB =
F->CreateMachineBasicBlock(LLVM_BB);
570 F->insert(It, sinkMBB);
605 MI.eraseFromParent();
611Mips16TargetLowering::emitSeliT16(
unsigned Opc1,
unsigned Opc2,
631 MachineBasicBlock *thisMBB = BB;
633 MachineBasicBlock *copy0MBB =
F->CreateMachineBasicBlock(LLVM_BB);
634 MachineBasicBlock *sinkMBB =
F->CreateMachineBasicBlock(LLVM_BB);
636 F->insert(It, sinkMBB);
671 MI.eraseFromParent();
677Mips16TargetLowering::emitFEXT_T8I816_ins(
unsigned BtOpc,
unsigned CmpOpc,
685 MachineBasicBlock *target =
MI.getOperand(2).getMBB();
690 MI.eraseFromParent();
695 unsigned BtOpc,
unsigned CmpiOpc,
unsigned CmpiXOpc,
bool ImmSigned,
701 int64_t imm =
MI.getOperand(1).getImm();
702 MachineBasicBlock *target =
MI.getOperand(2).getMBB();
713 MI.eraseFromParent();
718 (
unsigned shortOp,
unsigned longOp, int64_t Imm) {
728Mips16TargetLowering::emitFEXT_CCRX16_ins(
unsigned SltOpc,
MachineInstr &
MI,
741 MI.eraseFromParent();
746Mips16TargetLowering::emitFEXT_CCRXI16_ins(
unsigned SltiOpc,
unsigned SltiXOpc,
754 int64_t
Imm =
MI.getOperand(2).getImm();
759 MI.eraseFromParent();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const HexagonInstrInfo * TII
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Promote Memory to Register
static char const * vMips16Helper[MAX_STUB_NUMBER+1]
static char const * dcMips16Helper[MAX_STUB_NUMBER+1]
static cl::opt< bool > DontExpandCondPseudos16("mips16-dont-expand-cond-pseudo", cl::init(false), cl::desc("Don't expand conditional move related " "pseudos for Mips 16"), cl::Hidden)
static char const * dfMips16Helper[MAX_STUB_NUMBER+1]
static const RTLIB::LibcallImpl HardFloatLibCalls[]
static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[]
static char const * sfMips16Helper[MAX_STUB_NUMBER+1]
static unsigned Mips16WhichOp8uOr16simm(unsigned shortOp, unsigned longOp, int64_t Imm)
static char const * scMips16Helper[MAX_STUB_NUMBER+1]
static bool isMips16HardFloatLibcall(StringRef Name)
CCState - This class holds information needed while lowering arguments and return values.
const char * getSymbol() const
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI 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 '...
MachineInstrBundleIterator< MachineInstr > iterator
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
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
Representation of each machine instruction.
Flags
Flags values. These may be or'd together.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
Mips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
MachinePointerInfo callPtrInfo(MachineFunction &MF, const char *ES)
Create a MachinePointerInfo that has an ExternalSymbolPseudoSourceValue object representing a GOT ent...
std::map< const char *, const Mips16HardFloatInfo::FuncSignature * > StubsNeeded
const MipsRegisterInfo * getRegisterInfo() const override
SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
MipsTargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
virtual void getOpndList(SmallVectorImpl< SDValue > &Ops, std::deque< std::pair< unsigned, SDValue > > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const
This function fills Ops, which is the list of operands that will later be used when a function call n...
const MipsSubtarget & Subtarget
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
EVT getValueType() const
Return the ValueType of the referenced return value.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
MachineFunction & getMachineFunction() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ BSWAP
Byte Swap and Counting operators.
@ BasicBlock
Various leaf nodes.
FuncSignature const * findFuncSignature(const char *name)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto binary_search(R &&Range, T &&Value)
Provide wrappers to std::binary_search which take ranges instead of having to pass begin/end explicit...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
const MipsTargetLowering * createMips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Create MipsTargetLowering objects.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static LLVM_ABI iota_range< RTLIB::LibcallImpl > lookupLibcallImplName(StringRef Name)
Check if a function name is a recognized runtime call of any kind.
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl)
Return the libcall provided by Impl.