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;
48 {
"__fixunsdfsi",
"__mips16_call_stub_2" },
49 {
"ceil",
"__mips16_call_stub_df_2"},
50 {
"ceilf",
"__mips16_call_stub_sf_1"},
51 {
"copysign",
"__mips16_call_stub_df_10"},
52 {
"copysignf",
"__mips16_call_stub_sf_5"},
53 {
"cos",
"__mips16_call_stub_df_2"},
54 {
"cosf",
"__mips16_call_stub_sf_1"},
55 {
"exp2",
"__mips16_call_stub_df_2"},
56 {
"exp2f",
"__mips16_call_stub_sf_1"},
57 {
"floor",
"__mips16_call_stub_df_2"},
58 {
"floorf",
"__mips16_call_stub_sf_1"},
59 {
"log2",
"__mips16_call_stub_df_2"},
60 {
"log2f",
"__mips16_call_stub_sf_1"},
61 {
"nearbyint",
"__mips16_call_stub_df_2"},
62 {
"nearbyintf",
"__mips16_call_stub_sf_1"},
63 {
"rint",
"__mips16_call_stub_df_2"},
64 {
"rintf",
"__mips16_call_stub_sf_1"},
65 {
"sin",
"__mips16_call_stub_df_2"},
66 {
"sinf",
"__mips16_call_stub_sf_1"},
67 {
"sqrt",
"__mips16_call_stub_df_2"},
68 {
"sqrtf",
"__mips16_call_stub_sf_1"},
69 {
"trunc",
"__mips16_call_stub_df_2"},
70 {
"truncf",
"__mips16_call_stub_sf_1"},
116 switch (
MI.getOpcode()) {
120 return emitSel16(Mips::BeqzRxImm16,
MI, BB);
122 return emitSel16(Mips::BnezRxImm16,
MI, BB);
123 case Mips::SelTBteqZCmpi:
124 return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16,
MI, BB);
125 case Mips::SelTBteqZSlti:
126 return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16,
MI, BB);
127 case Mips::SelTBteqZSltiu:
128 return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16,
MI, BB);
129 case Mips::SelTBtneZCmpi:
130 return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16,
MI, BB);
131 case Mips::SelTBtneZSlti:
132 return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16,
MI, BB);
133 case Mips::SelTBtneZSltiu:
134 return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16,
MI, BB);
135 case Mips::SelTBteqZCmp:
136 return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16,
MI, BB);
137 case Mips::SelTBteqZSlt:
138 return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16,
MI, BB);
139 case Mips::SelTBteqZSltu:
140 return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16,
MI, BB);
141 case Mips::SelTBtneZCmp:
142 return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16,
MI, BB);
143 case Mips::SelTBtneZSlt:
144 return emitSelT16(Mips::Btnez16, Mips::SltRxRy16,
MI, BB);
145 case Mips::SelTBtneZSltu:
146 return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16,
MI, BB);
147 case Mips::BteqzT8CmpX16:
148 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16,
MI, BB);
149 case Mips::BteqzT8SltX16:
150 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16,
MI, BB);
151 case Mips::BteqzT8SltuX16:
154 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16,
MI, BB);
155 case Mips::BtnezT8CmpX16:
156 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16,
MI, BB);
157 case Mips::BtnezT8SltX16:
158 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16,
MI, BB);
159 case Mips::BtnezT8SltuX16:
162 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16,
MI, BB);
163 case Mips::BteqzT8CmpiX16:
return emitFEXT_T8I8I16_ins(
164 Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false,
MI, BB);
165 case Mips::BteqzT8SltiX16:
return emitFEXT_T8I8I16_ins(
166 Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true,
MI, BB);
167 case Mips::BteqzT8SltiuX16:
return emitFEXT_T8I8I16_ins(
168 Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false,
MI, BB);
169 case Mips::BtnezT8CmpiX16:
return emitFEXT_T8I8I16_ins(
170 Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false,
MI, BB);
171 case Mips::BtnezT8SltiX16:
return emitFEXT_T8I8I16_ins(
172 Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true,
MI, BB);
173 case Mips::BtnezT8SltiuX16:
return emitFEXT_T8I8I16_ins(
174 Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false,
MI, BB);
176 case Mips::SltCCRxRy16:
177 return emitFEXT_CCRX16_ins(Mips::SltRxRy16,
MI, BB);
179 case Mips::SltiCCRxImmX16:
180 return emitFEXT_CCRXI16_ins
181 (Mips::SltiRxImm16, Mips::SltiRxImmX16,
MI, BB);
182 case Mips::SltiuCCRxImmX16:
183 return emitFEXT_CCRXI16_ins
184 (Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
MI, BB);
185 case Mips::SltuCCRxRy16:
186 return emitFEXT_CCRX16_ins
187 (Mips::SltuRxRy16,
MI, BB);
191bool Mips16TargetLowering::isEligibleForTailCallOptimization(
192 const CCState &CCInfo,
unsigned NextStackOffset,
229unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
230 (ArgListTy &Args)
const {
231 unsigned int resultNum = 0;
232 if (Args.size() >= 1) {
233 Type *t = Args[0].Ty;
242 if (
Args.size() >=2) {
279#define P_ "__mips16_call_stub_"
280#define MAX_STUB_NUMBER 10
281#define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
306const char* Mips16TargetLowering::
307 getMips16HelperFunction
308 (
Type* RetTy, ArgListTy &Args,
bool &needHelper)
const {
309 const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
311 const unsigned int maxStubNum = 10;
312 assert(stubNum <= maxStubNum);
313 const bool validStubNum[maxStubNum+1] =
314 {
true,
true,
true,
false,
false,
true,
true,
false,
false,
true,
true};
315 assert(validStubNum[stubNum]);
321 else if (RetTy ->isDoubleTy()) {
325 if (SRetTy->getNumElements() == 2) {
326 if ((SRetTy->getElementType(0)->isFloatTy()) &&
327 (SRetTy->getElementType(1)->isFloatTy())) {
329 }
else if ((SRetTy->getElementType(0)->isDoubleTy()) &&
330 (SRetTy->getElementType(1)->isDoubleTy())) {
353 return !ParsedLibcalls.
empty() &&
355 *ParsedLibcalls.
begin());
358void Mips16TargetLowering::
360 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
361 bool IsPICCall,
bool GlobalOrExternal,
bool InternalLinkage,
362 bool IsCallReloc, CallLoweringInfo &CLI,
SDValue Callee,
364 SelectionDAG &DAG = CLI.DAG;
366 MipsFunctionInfo *FuncInfo = MF.
getInfo<MipsFunctionInfo>();
367 const char* Mips16HelperFunction =
nullptr;
368 bool NeedMips16Helper =
false;
376 bool LookupHelper =
true;
379 LookupHelper =
false;
381 const char *
Symbol = S->getSymbol();
382 Mips16IntrinsicHelperType IntrinsicFind = {
Symbol,
"" };
383 const Mips16HardFloatInfo::FuncSignature *Signature =
385 if (!IsPICCall && Signature &&
386 FuncInfo->
StubsNeeded.try_emplace(Symbol, Signature).second) {
404 const Mips16IntrinsicHelperType *Helper =
407 *Helper == IntrinsicFind) {
408 Mips16HelperFunction = Helper->Helper;
409 NeedMips16Helper =
true;
410 LookupHelper =
false;
414 }
else if (GlobalAddressSDNode *
G =
418 LookupHelper =
false;
421 Mips16HelperFunction =
422 getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
429 if (IsPICCall || !GlobalOrExternal) {
430 unsigned V0Reg = Mips::V0;
431 if (NeedMips16Helper) {
432 RegsToPass.push_front(std::make_pair(V0Reg, Callee));
440 RegsToPass.push_front(std::make_pair((
unsigned)Mips::T9, Callee));
443 Ops.push_back(JumpTarget);
446 InternalLinkage, IsCallReloc, CLI, Callee,
470 MachineBasicBlock *thisMBB = BB;
473 MachineBasicBlock *sinkMBB =
F->CreateMachineBasicBlock(LLVM_BB);
475 F->insert(It, sinkMBB);
509 MI.eraseFromParent();
514Mips16TargetLowering::emitSelT16(
unsigned Opc1,
unsigned Opc2,
MachineInstr &
MI,
533 MachineBasicBlock *thisMBB = BB;
535 MachineBasicBlock *copy0MBB =
F->CreateMachineBasicBlock(LLVM_BB);
536 MachineBasicBlock *sinkMBB =
F->CreateMachineBasicBlock(LLVM_BB);
538 F->insert(It, sinkMBB);
573 MI.eraseFromParent();
579Mips16TargetLowering::emitSeliT16(
unsigned Opc1,
unsigned Opc2,
599 MachineBasicBlock *thisMBB = BB;
601 MachineBasicBlock *copy0MBB =
F->CreateMachineBasicBlock(LLVM_BB);
602 MachineBasicBlock *sinkMBB =
F->CreateMachineBasicBlock(LLVM_BB);
604 F->insert(It, sinkMBB);
639 MI.eraseFromParent();
645Mips16TargetLowering::emitFEXT_T8I816_ins(
unsigned BtOpc,
unsigned CmpOpc,
653 MachineBasicBlock *target =
MI.getOperand(2).getMBB();
658 MI.eraseFromParent();
663 unsigned BtOpc,
unsigned CmpiOpc,
unsigned CmpiXOpc,
bool ImmSigned,
669 int64_t imm =
MI.getOperand(1).getImm();
670 MachineBasicBlock *target =
MI.getOperand(2).getMBB();
681 MI.eraseFromParent();
686 (
unsigned shortOp,
unsigned longOp, int64_t Imm) {
696Mips16TargetLowering::emitFEXT_CCRX16_ins(
unsigned SltOpc,
MachineInstr &
MI,
709 MI.eraseFromParent();
714Mips16TargetLowering::emitFEXT_CCRXI16_ins(
unsigned SltiOpc,
unsigned SltiXOpc,
722 int64_t
Imm =
MI.getOperand(2).getImm();
727 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 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
static const RTLIB::LibcallImpl HardFloatLibCalls[34]
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...
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.