23#define DEBUG_TYPE "mips-lower"
26struct Mips16IntrinsicHelperType{
30 bool operator<(
const Mips16IntrinsicHelperType &
RHS)
const {
31 return std::strcmp(Name,
RHS.Name) < 0;
34 return std::strcmp(Name,
RHS.Name) == 0;
40 {
"__fixunsdfsi",
"__mips16_call_stub_2" },
41 {
"ceil",
"__mips16_call_stub_df_2"},
42 {
"ceilf",
"__mips16_call_stub_sf_1"},
43 {
"copysign",
"__mips16_call_stub_df_10"},
44 {
"copysignf",
"__mips16_call_stub_sf_5"},
45 {
"cos",
"__mips16_call_stub_df_2"},
46 {
"cosf",
"__mips16_call_stub_sf_1"},
47 {
"exp2",
"__mips16_call_stub_df_2"},
48 {
"exp2f",
"__mips16_call_stub_sf_1"},
49 {
"floor",
"__mips16_call_stub_df_2"},
50 {
"floorf",
"__mips16_call_stub_sf_1"},
51 {
"log2",
"__mips16_call_stub_df_2"},
52 {
"log2f",
"__mips16_call_stub_sf_1"},
53 {
"nearbyint",
"__mips16_call_stub_df_2"},
54 {
"nearbyintf",
"__mips16_call_stub_sf_1"},
55 {
"rint",
"__mips16_call_stub_df_2"},
56 {
"rintf",
"__mips16_call_stub_sf_1"},
57 {
"sin",
"__mips16_call_stub_df_2"},
58 {
"sinf",
"__mips16_call_stub_sf_1"},
59 {
"sqrt",
"__mips16_call_stub_df_2"},
60 {
"sqrtf",
"__mips16_call_stub_sf_1"},
61 {
"trunc",
"__mips16_call_stub_df_2"},
62 {
"truncf",
"__mips16_call_stub_sf_1"},
108 switch (
MI.getOpcode()) {
112 return emitSel16(Mips::BeqzRxImm16,
MI, BB);
114 return emitSel16(Mips::BnezRxImm16,
MI, BB);
115 case Mips::SelTBteqZCmpi:
116 return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16,
MI, BB);
117 case Mips::SelTBteqZSlti:
118 return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16,
MI, BB);
119 case Mips::SelTBteqZSltiu:
120 return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16,
MI, BB);
121 case Mips::SelTBtneZCmpi:
122 return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16,
MI, BB);
123 case Mips::SelTBtneZSlti:
124 return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16,
MI, BB);
125 case Mips::SelTBtneZSltiu:
126 return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16,
MI, BB);
127 case Mips::SelTBteqZCmp:
128 return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16,
MI, BB);
129 case Mips::SelTBteqZSlt:
130 return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16,
MI, BB);
131 case Mips::SelTBteqZSltu:
132 return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16,
MI, BB);
133 case Mips::SelTBtneZCmp:
134 return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16,
MI, BB);
135 case Mips::SelTBtneZSlt:
136 return emitSelT16(Mips::Btnez16, Mips::SltRxRy16,
MI, BB);
137 case Mips::SelTBtneZSltu:
138 return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16,
MI, BB);
139 case Mips::BteqzT8CmpX16:
140 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16,
MI, BB);
141 case Mips::BteqzT8SltX16:
142 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16,
MI, BB);
143 case Mips::BteqzT8SltuX16:
146 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16,
MI, BB);
147 case Mips::BtnezT8CmpX16:
148 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16,
MI, BB);
149 case Mips::BtnezT8SltX16:
150 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16,
MI, BB);
151 case Mips::BtnezT8SltuX16:
154 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16,
MI, BB);
155 case Mips::BteqzT8CmpiX16:
return emitFEXT_T8I8I16_ins(
156 Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false,
MI, BB);
157 case Mips::BteqzT8SltiX16:
return emitFEXT_T8I8I16_ins(
158 Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true,
MI, BB);
159 case Mips::BteqzT8SltiuX16:
return emitFEXT_T8I8I16_ins(
160 Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false,
MI, BB);
161 case Mips::BtnezT8CmpiX16:
return emitFEXT_T8I8I16_ins(
162 Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false,
MI, BB);
163 case Mips::BtnezT8SltiX16:
return emitFEXT_T8I8I16_ins(
164 Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true,
MI, BB);
165 case Mips::BtnezT8SltiuX16:
return emitFEXT_T8I8I16_ins(
166 Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false,
MI, BB);
168 case Mips::SltCCRxRy16:
169 return emitFEXT_CCRX16_ins(Mips::SltRxRy16,
MI, BB);
171 case Mips::SltiCCRxImmX16:
172 return emitFEXT_CCRXI16_ins
173 (Mips::SltiRxImm16, Mips::SltiRxImmX16,
MI, BB);
174 case Mips::SltiuCCRxImmX16:
175 return emitFEXT_CCRXI16_ins
176 (Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
MI, BB);
177 case Mips::SltuCCRxRy16:
178 return emitFEXT_CCRX16_ins
179 (Mips::SltuRxRy16,
MI, BB);
183bool Mips16TargetLowering::isEligibleForTailCallOptimization(
184 const CCState &CCInfo,
unsigned NextStackOffset,
221unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
222 (ArgListTy &Args)
const {
223 unsigned int resultNum = 0;
224 if (Args.size() >= 1) {
225 Type *t = Args[0].Ty;
234 if (
Args.size() >=2) {
271#define P_ "__mips16_call_stub_"
272#define MAX_STUB_NUMBER 10
273#define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
298const char* Mips16TargetLowering::
299 getMips16HelperFunction
300 (
Type* RetTy, ArgListTy &Args,
bool &needHelper)
const {
301 const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
303 const unsigned int maxStubNum = 10;
304 assert(stubNum <= maxStubNum);
305 const bool validStubNum[maxStubNum+1] =
306 {
true,
true,
true,
false,
false,
true,
true,
false,
false,
true,
true};
307 assert(validStubNum[stubNum]);
313 else if (RetTy ->isDoubleTy()) {
317 if (SRetTy->getNumElements() == 2) {
318 if ((SRetTy->getElementType(0)->isFloatTy()) &&
319 (SRetTy->getElementType(1)->isFloatTy())) {
321 }
else if ((SRetTy->getElementType(0)->isDoubleTy()) &&
322 (SRetTy->getElementType(1)->isDoubleTy())) {
345 return !ParsedLibcalls.
empty() &&
347 *ParsedLibcalls.
begin());
350void Mips16TargetLowering::getOpndList(
352 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,
bool IsPICCall,
353 bool GlobalOrExternal,
bool LocalLinkage,
bool IsCallReloc,
355 SelectionDAG &DAG = CLI.DAG;
357 MipsFunctionInfo *FuncInfo = MF.
getInfo<MipsFunctionInfo>();
358 const char* Mips16HelperFunction =
nullptr;
359 bool NeedMips16Helper =
false;
367 bool LookupHelper =
true;
370 LookupHelper =
false;
372 const char *
Symbol = S->getSymbol();
373 Mips16IntrinsicHelperType IntrinsicFind = {
Symbol,
"" };
374 const Mips16HardFloatInfo::FuncSignature *Signature =
376 if (!IsPICCall && Signature &&
377 FuncInfo->
StubsNeeded.try_emplace(Symbol, Signature).second) {
395 const Mips16IntrinsicHelperType *Helper =
398 *Helper == IntrinsicFind) {
399 Mips16HelperFunction = Helper->Helper;
400 NeedMips16Helper =
true;
401 LookupHelper =
false;
405 }
else if (GlobalAddressSDNode *
G =
409 LookupHelper =
false;
412 Mips16HelperFunction =
413 getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
416 SDValue JumpTarget =
Callee;
420 if (IsPICCall || !GlobalOrExternal) {
421 unsigned V0Reg = Mips::V0;
422 if (NeedMips16Helper) {
423 RegsToPass.push_front(std::make_pair(V0Reg, Callee));
431 RegsToPass.push_front(std::make_pair((
unsigned)Mips::T9, Callee));
434 Ops.push_back(JumpTarget);
437 LocalLinkage, IsCallReloc, CLI, Callee,
444 if (
Subtarget.getCLOpts().mips16_dont_expand_cond_pseudo)
461 MachineBasicBlock *thisMBB = BB;
464 MachineBasicBlock *sinkMBB =
F->CreateMachineBasicBlock(LLVM_BB);
466 F->insert(It, sinkMBB);
500 MI.eraseFromParent();
505Mips16TargetLowering::emitSelT16(
unsigned Opc1,
unsigned Opc2,
MachineInstr &
MI,
507 if (
Subtarget.getCLOpts().mips16_dont_expand_cond_pseudo)
524 MachineBasicBlock *thisMBB = BB;
526 MachineBasicBlock *copy0MBB =
F->CreateMachineBasicBlock(LLVM_BB);
527 MachineBasicBlock *sinkMBB =
F->CreateMachineBasicBlock(LLVM_BB);
529 F->insert(It, sinkMBB);
564 MI.eraseFromParent();
570Mips16TargetLowering::emitSeliT16(
unsigned Opc1,
unsigned Opc2,
573 if (
Subtarget.getCLOpts().mips16_dont_expand_cond_pseudo)
590 MachineBasicBlock *thisMBB = BB;
592 MachineBasicBlock *copy0MBB =
F->CreateMachineBasicBlock(LLVM_BB);
593 MachineBasicBlock *sinkMBB =
F->CreateMachineBasicBlock(LLVM_BB);
595 F->insert(It, sinkMBB);
630 MI.eraseFromParent();
636Mips16TargetLowering::emitFEXT_T8I816_ins(
unsigned BtOpc,
unsigned CmpOpc,
639 if (
Subtarget.getCLOpts().mips16_dont_expand_cond_pseudo)
644 MachineBasicBlock *target =
MI.getOperand(2).getMBB();
649 MI.eraseFromParent();
654 unsigned BtOpc,
unsigned CmpiOpc,
unsigned CmpiXOpc,
bool ImmSigned,
656 if (
Subtarget.getCLOpts().mips16_dont_expand_cond_pseudo)
660 int64_t imm =
MI.getOperand(1).getImm();
661 MachineBasicBlock *target =
MI.getOperand(2).getMBB();
672 MI.eraseFromParent();
677 (
unsigned shortOp,
unsigned longOp, int64_t
Imm) {
687Mips16TargetLowering::emitFEXT_CCRX16_ins(
unsigned SltOpc,
MachineInstr &
MI,
689 if (
Subtarget.getCLOpts().mips16_dont_expand_cond_pseudo)
700 MI.eraseFromParent();
705Mips16TargetLowering::emitFEXT_CCRXI16_ins(
unsigned SltiOpc,
unsigned SltiXOpc,
708 if (
Subtarget.getCLOpts().mips16_dont_expand_cond_pseudo)
713 int64_t
Imm =
MI.getOperand(2).getImm();
718 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 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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate 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 LocalLinkage, 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...
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.
@ BSWAP
Byte Swap and Counting operators.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ BasicBlock
Various leaf nodes.
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
FuncSignature const * findFuncSignature(const char *name)
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...
@ Fast
Assign the register banks as fast as possible (default).
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 iota_range< RTLIB::LibcallImpl > lookupLibcallImplName(StringRef Name)
Check if a function name is a recognized runtime call of any kind.
constexpr auto begin() const
constexpr bool empty() const