25 #define DEBUG_TYPE "mips-lower" 28 "mips16-dont-expand-cond-pseudo",
30 cl::desc(
"Don't expand conditional move related " 31 "pseudos for Mips 16"),
35 struct Mips16Libcall {
39 bool operator<(
const Mips16Libcall &RHS)
const {
40 return std::strcmp(Name, RHS.Name) < 0;
44 struct Mips16IntrinsicHelperType{
48 bool operator<(
const Mips16IntrinsicHelperType &RHS)
const {
49 return std::strcmp(Name, RHS.Name) < 0;
51 bool operator==(
const Mips16IntrinsicHelperType &RHS)
const {
52 return std::strcmp(Name, RHS.Name) == 0;
59 { RTLIB::ADD_F64,
"__mips16_adddf3" },
60 { RTLIB::ADD_F32,
"__mips16_addsf3" },
61 { RTLIB::DIV_F64,
"__mips16_divdf3" },
62 { RTLIB::DIV_F32,
"__mips16_divsf3" },
63 { RTLIB::OEQ_F64,
"__mips16_eqdf2" },
64 { RTLIB::OEQ_F32,
"__mips16_eqsf2" },
65 { RTLIB::FPEXT_F32_F64,
"__mips16_extendsfdf2" },
66 { RTLIB::FPTOSINT_F64_I32,
"__mips16_fix_truncdfsi" },
67 { RTLIB::FPTOSINT_F32_I32,
"__mips16_fix_truncsfsi" },
68 { RTLIB::SINTTOFP_I32_F64,
"__mips16_floatsidf" },
69 { RTLIB::SINTTOFP_I32_F32,
"__mips16_floatsisf" },
70 { RTLIB::UINTTOFP_I32_F64,
"__mips16_floatunsidf" },
71 { RTLIB::UINTTOFP_I32_F32,
"__mips16_floatunsisf" },
72 { RTLIB::OGE_F64,
"__mips16_gedf2" },
73 { RTLIB::OGE_F32,
"__mips16_gesf2" },
74 { RTLIB::OGT_F64,
"__mips16_gtdf2" },
75 { RTLIB::OGT_F32,
"__mips16_gtsf2" },
76 { RTLIB::OLE_F64,
"__mips16_ledf2" },
77 { RTLIB::OLE_F32,
"__mips16_lesf2" },
78 { RTLIB::OLT_F64,
"__mips16_ltdf2" },
79 { RTLIB::OLT_F32,
"__mips16_ltsf2" },
80 { RTLIB::MUL_F64,
"__mips16_muldf3" },
81 { RTLIB::MUL_F32,
"__mips16_mulsf3" },
82 { RTLIB::UNE_F64,
"__mips16_nedf2" },
83 { RTLIB::UNE_F32,
"__mips16_nesf2" },
84 { RTLIB::UNKNOWN_LIBCALL,
"__mips16_ret_dc" },
85 { RTLIB::UNKNOWN_LIBCALL,
"__mips16_ret_df" },
86 { RTLIB::UNKNOWN_LIBCALL,
"__mips16_ret_sc" },
87 { RTLIB::UNKNOWN_LIBCALL,
"__mips16_ret_sf" },
88 { RTLIB::SUB_F64,
"__mips16_subdf3" },
89 { RTLIB::SUB_F32,
"__mips16_subsf3" },
90 { RTLIB::FPROUND_F64_F32,
"__mips16_truncdfsf2" },
91 { RTLIB::UO_F64,
"__mips16_unorddf2" },
92 { RTLIB::UO_F32,
"__mips16_unordsf2" }
96 {
"__fixunsdfsi",
"__mips16_call_stub_2" },
97 {
"ceil",
"__mips16_call_stub_df_2"},
98 {
"ceilf",
"__mips16_call_stub_sf_1"},
99 {
"copysign",
"__mips16_call_stub_df_10"},
100 {
"copysignf",
"__mips16_call_stub_sf_5"},
101 {
"cos",
"__mips16_call_stub_df_2"},
102 {
"cosf",
"__mips16_call_stub_sf_1"},
103 {
"exp2",
"__mips16_call_stub_df_2"},
104 {
"exp2f",
"__mips16_call_stub_sf_1"},
105 {
"floor",
"__mips16_call_stub_df_2"},
106 {
"floorf",
"__mips16_call_stub_sf_1"},
107 {
"log2",
"__mips16_call_stub_df_2"},
108 {
"log2f",
"__mips16_call_stub_sf_1"},
109 {
"nearbyint",
"__mips16_call_stub_df_2"},
110 {
"nearbyintf",
"__mips16_call_stub_sf_1"},
111 {
"rint",
"__mips16_call_stub_df_2"},
112 {
"rintf",
"__mips16_call_stub_sf_1"},
113 {
"sin",
"__mips16_call_stub_df_2"},
114 {
"sinf",
"__mips16_call_stub_sf_1"},
115 {
"sqrt",
"__mips16_call_stub_df_2"},
116 {
"sqrtf",
"__mips16_call_stub_sf_1"},
117 {
"trunc",
"__mips16_call_stub_df_2"},
118 {
"truncf",
"__mips16_call_stub_sf_1"},
129 setMips16HardFloatLibCalls();
174 return emitSel16(Mips::BeqzRxImm16, MI, BB);
176 return emitSel16(Mips::BnezRxImm16, MI, BB);
177 case Mips::SelTBteqZCmpi:
178 return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB);
179 case Mips::SelTBteqZSlti:
180 return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB);
181 case Mips::SelTBteqZSltiu:
182 return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB);
183 case Mips::SelTBtneZCmpi:
184 return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB);
185 case Mips::SelTBtneZSlti:
186 return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB);
187 case Mips::SelTBtneZSltiu:
188 return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB);
189 case Mips::SelTBteqZCmp:
190 return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
191 case Mips::SelTBteqZSlt:
192 return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
193 case Mips::SelTBteqZSltu:
194 return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
195 case Mips::SelTBtneZCmp:
196 return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
197 case Mips::SelTBtneZSlt:
198 return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
199 case Mips::SelTBtneZSltu:
200 return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
201 case Mips::BteqzT8CmpX16:
202 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
203 case Mips::BteqzT8SltX16:
204 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
205 case Mips::BteqzT8SltuX16:
208 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
209 case Mips::BtnezT8CmpX16:
210 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
211 case Mips::BtnezT8SltX16:
212 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
213 case Mips::BtnezT8SltuX16:
216 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
217 case Mips::BteqzT8CmpiX16:
return emitFEXT_T8I8I16_ins(
218 Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false, MI, BB);
219 case Mips::BteqzT8SltiX16:
return emitFEXT_T8I8I16_ins(
220 Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true, MI, BB);
221 case Mips::BteqzT8SltiuX16:
return emitFEXT_T8I8I16_ins(
222 Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false, MI, BB);
223 case Mips::BtnezT8CmpiX16:
return emitFEXT_T8I8I16_ins(
224 Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false, MI, BB);
225 case Mips::BtnezT8SltiX16:
return emitFEXT_T8I8I16_ins(
226 Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true, MI, BB);
227 case Mips::BtnezT8SltiuX16:
return emitFEXT_T8I8I16_ins(
228 Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false, MI, BB);
230 case Mips::SltCCRxRy16:
231 return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);
233 case Mips::SltiCCRxImmX16:
234 return emitFEXT_CCRXI16_ins
235 (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB);
236 case Mips::SltiuCCRxImmX16:
237 return emitFEXT_CCRXI16_ins
238 (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB);
239 case Mips::SltuCCRxRy16:
240 return emitFEXT_CCRX16_ins
241 (Mips::SltuRxRy16, MI, BB);
245 bool Mips16TargetLowering::isEligibleForTailCallOptimization(
246 const CCState &CCInfo,
unsigned NextStackOffset,
252 void Mips16TargetLowering::setMips16HardFloatLibCalls() {
254 assert((
I == 0 || HardFloatLibCalls[
I - 1] < HardFloatLibCalls[
I]) &&
255 "Array not sorted!");
256 if (HardFloatLibCalls[I].
Libcall != RTLIB::UNKNOWN_LIBCALL)
295 unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
297 unsigned int resultNum = 0;
298 if (Args.size() >= 1) {
299 Type *t = Args[0].Ty;
308 if (Args.size() >=2) {
309 Type *t = Args[1].Ty;
345 #define P_ "__mips16_call_stub_" 346 #define MAX_STUB_NUMBER 10 347 #define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10" 372 const char* Mips16TargetLowering::
373 getMips16HelperFunction
375 const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
377 const unsigned int maxStubNum = 10;
378 assert(stubNum <= maxStubNum);
379 const bool validStubNum[maxStubNum+1] =
380 {
true,
true,
true,
false,
false,
true,
true,
false,
false,
true,
true};
381 assert(validStubNum[stubNum]);
385 result = sfMips16Helper[stubNum];
387 else if (RetTy ->isDoubleTy()) {
388 result = dfMips16Helper[stubNum];
389 }
else if (
StructType *SRetTy = dyn_cast<StructType>(RetTy)) {
391 if (SRetTy->getNumElements() == 2) {
392 if ((SRetTy->getElementType(0)->isFloatTy()) &&
393 (SRetTy->getElementType(1)->isFloatTy())) {
394 result = scMips16Helper[stubNum];
395 }
else if ((SRetTy->getElementType(0)->isDoubleTy()) &&
396 (SRetTy->getElementType(1)->isDoubleTy())) {
397 result = dcMips16Helper[stubNum];
409 result = vMips16Helper[stubNum];
415 void Mips16TargetLowering::
417 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
418 bool IsPICCall,
bool GlobalOrExternal,
bool InternalLinkage,
424 const char* Mips16HelperFunction =
nullptr;
425 bool NeedMips16Helper =
false;
433 bool LookupHelper =
true;
435 Mips16Libcall
Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() };
437 if (std::binary_search(
std::begin(HardFloatLibCalls),
439 LookupHelper =
false;
441 const char *
Symbol = S->getSymbol();
442 Mips16IntrinsicHelperType IntrinsicFind = {
Symbol,
"" };
445 if (!IsPICCall && (Signature && (FuncInfo->
StubsNeeded.find(Symbol) ==
465 const Mips16IntrinsicHelperType *Helper =
467 std::end(Mips16IntrinsicHelper), IntrinsicFind);
468 if (Helper !=
std::end(Mips16IntrinsicHelper) &&
469 *Helper == IntrinsicFind) {
470 Mips16HelperFunction = Helper->Helper;
471 NeedMips16Helper =
true;
472 LookupHelper =
false;
477 dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
478 Mips16Libcall
Find = { RTLIB::UNKNOWN_LIBCALL,
479 G->getGlobal()->getName().data() };
481 if (std::binary_search(
std::begin(HardFloatLibCalls),
483 LookupHelper =
false;
486 Mips16HelperFunction =
487 getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
494 if (IsPICCall || !GlobalOrExternal) {
495 unsigned V0Reg = Mips::V0;
496 if (NeedMips16Helper) {
497 RegsToPass.push_front(std::make_pair(V0Reg, Callee));
505 RegsToPass.push_front(std::make_pair((
unsigned)Mips::T9, Callee));
511 InternalLinkage, IsCallReloc, CLI, Callee,
579 Mips16TargetLowering::emitSelT16(
unsigned Opc1,
unsigned Opc2,
MachineInstr &MI,
617 BuildMI(BB, DL, TII->
get(Opc1)).addMBB(sinkMBB);
644 Mips16TargetLowering::emitSeliT16(
unsigned Opc1,
unsigned Opc2,
683 BuildMI(BB, DL, TII->
get(Opc1)).addMBB(sinkMBB);
710 Mips16TargetLowering::emitFEXT_T8I816_ins(
unsigned BtOpc,
unsigned CmpOpc,
728 unsigned BtOpc,
unsigned CmpiOpc,
unsigned CmpiXOpc,
bool ImmSigned,
751 (
unsigned shortOp,
unsigned longOp, int64_t Imm) {
761 Mips16TargetLowering::emitFEXT_CCRX16_ins(
unsigned SltOpc,
MachineInstr &MI,
779 Mips16TargetLowering::emitFEXT_CCRXI16_ins(
unsigned SltiOpc,
unsigned SltiXOpc,
bool inMips16HardFloat() const
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
MachineBasicBlock * getMBB() const
static char const * vMips16Helper[MAX_STUB_NUMBER+1]
const MipsSubtarget & Subtarget
This class represents lattice values for constants.
const MipsTargetLowering * createMips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Create MipsTargetLowering objects.
Mips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
void push_back(const T &Elt)
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getReg() const
getReg - Returns the register number.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
static char const * scMips16Helper[MAX_STUB_NUMBER+1]
const MipsInstrInfo * getInstrInfo() const override
std::map< const char *, const Mips16HardFloatInfo::FuncSignature * > StubsNeeded
constexpr bool isInt< 16 >(int64_t x)
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
static unsigned Mips16WhichOp8uOr16simm(unsigned shortOp, unsigned longOp, int64_t Imm)
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
SDValue getExternalSymbol(const char *Sym, EVT VT)
MachinePointerInfo callPtrInfo(const char *ES)
Create a MachinePointerInfo that has an ExternalSymbolPseudoSourceValue object representing a GOT ent...
amdgpu Simplify well known AMD library false Value Value const Twine & Name
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
const HexagonInstrInfo * TII
Class to represent struct types.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt) For double-word atomic operations: ValLo, ValHi, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amtLo, amtHi) ValLo, ValHi, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amtLo, amtHi) These correspond to the atomicrmw instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
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...
const DataLayout & getDataLayout() const
static char const * dfMips16Helper[MAX_STUB_NUMBER+1]
static char const * dcMips16Helper[MAX_STUB_NUMBER+1]
Fast - This calling convention attempts to make calls as fast as possible (e.g.
MachineFunction & getMachineFunction() const
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose...
auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
amdgpu Simplify well known AMD library false Value * Callee
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const char * getSymbol() const
static const Mips16Libcall HardFloatLibCalls[]
TargetInstrInfo - Interface to description of machine instruction set.
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)
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
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...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
constexpr bool isUInt< 8 >(uint64_t x)
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...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type...
static const SubtargetFeatureKV * Find(StringRef S, ArrayRef< SubtargetFeatureKV > A)
Find KV in array using binary search.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
self_iterator getIterator()
SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo...
std::vector< ArgListEntry > ArgListTy
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
FuncSignature const * findFuncSignature(const char *name)
static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[]
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
Iterator for intrusive lists based on ilist_node.
CCState - This class holds information needed while lowering arguments and return values...
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MipsRegisterInfo * getRegisterInfo() const override
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Byte Swap and Counting operators.
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static char const * sfMips16Helper[MAX_STUB_NUMBER+1]
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 '...
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
constexpr bool isUInt< 16 >(uint64_t x)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
bool operator<(int64_t V1, const APSInt &V2)
bool useSoftFloat() const
bool operator==(uint64_t V1, const APInt &V2)
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, unsigned Align, bool *Fast) const override
Determine if the target supports unaligned memory accesses.
const MachineOperand & getOperand(unsigned i) const
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.