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"),
34 struct Mips16Libcall {
39 return std::strcmp(Name,
RHS.Name) < 0;
43 struct Mips16IntrinsicHelperType{
47 bool operator<(
const Mips16IntrinsicHelperType &
RHS)
const {
48 return std::strcmp(Name,
RHS.Name) < 0;
51 return std::strcmp(Name,
RHS.Name) == 0;
58 { RTLIB::ADD_F64,
"__mips16_adddf3" },
59 { RTLIB::ADD_F32,
"__mips16_addsf3" },
60 { RTLIB::DIV_F64,
"__mips16_divdf3" },
61 { RTLIB::DIV_F32,
"__mips16_divsf3" },
62 { RTLIB::OEQ_F64,
"__mips16_eqdf2" },
63 { RTLIB::OEQ_F32,
"__mips16_eqsf2" },
64 { RTLIB::FPEXT_F32_F64,
"__mips16_extendsfdf2" },
65 { RTLIB::FPTOSINT_F64_I32,
"__mips16_fix_truncdfsi" },
66 { RTLIB::FPTOSINT_F32_I32,
"__mips16_fix_truncsfsi" },
67 { RTLIB::SINTTOFP_I32_F64,
"__mips16_floatsidf" },
68 { RTLIB::SINTTOFP_I32_F32,
"__mips16_floatsisf" },
69 { RTLIB::UINTTOFP_I32_F64,
"__mips16_floatunsidf" },
70 { RTLIB::UINTTOFP_I32_F32,
"__mips16_floatunsisf" },
71 { RTLIB::OGE_F64,
"__mips16_gedf2" },
72 { RTLIB::OGE_F32,
"__mips16_gesf2" },
73 { RTLIB::OGT_F64,
"__mips16_gtdf2" },
74 { RTLIB::OGT_F32,
"__mips16_gtsf2" },
75 { RTLIB::OLE_F64,
"__mips16_ledf2" },
76 { RTLIB::OLE_F32,
"__mips16_lesf2" },
77 { RTLIB::OLT_F64,
"__mips16_ltdf2" },
78 { RTLIB::OLT_F32,
"__mips16_ltsf2" },
79 { RTLIB::MUL_F64,
"__mips16_muldf3" },
80 { RTLIB::MUL_F32,
"__mips16_mulsf3" },
81 { RTLIB::UNE_F64,
"__mips16_nedf2" },
82 { RTLIB::UNE_F32,
"__mips16_nesf2" },
83 { RTLIB::UNKNOWN_LIBCALL,
"__mips16_ret_dc" },
84 { RTLIB::UNKNOWN_LIBCALL,
"__mips16_ret_df" },
85 { RTLIB::UNKNOWN_LIBCALL,
"__mips16_ret_sc" },
86 { RTLIB::UNKNOWN_LIBCALL,
"__mips16_ret_sf" },
87 { RTLIB::SUB_F64,
"__mips16_subdf3" },
88 { RTLIB::SUB_F32,
"__mips16_subsf3" },
89 { RTLIB::FPROUND_F64_F32,
"__mips16_truncdfsf2" },
90 { RTLIB::UO_F64,
"__mips16_unorddf2" },
91 { RTLIB::UO_F32,
"__mips16_unordsf2" }
95 {
"__fixunsdfsi",
"__mips16_call_stub_2" },
96 {
"ceil",
"__mips16_call_stub_df_2"},
97 {
"ceilf",
"__mips16_call_stub_sf_1"},
98 {
"copysign",
"__mips16_call_stub_df_10"},
99 {
"copysignf",
"__mips16_call_stub_sf_5"},
100 {
"cos",
"__mips16_call_stub_df_2"},
101 {
"cosf",
"__mips16_call_stub_sf_1"},
102 {
"exp2",
"__mips16_call_stub_df_2"},
103 {
"exp2f",
"__mips16_call_stub_sf_1"},
104 {
"floor",
"__mips16_call_stub_df_2"},
105 {
"floorf",
"__mips16_call_stub_sf_1"},
106 {
"log2",
"__mips16_call_stub_df_2"},
107 {
"log2f",
"__mips16_call_stub_sf_1"},
108 {
"nearbyint",
"__mips16_call_stub_df_2"},
109 {
"nearbyintf",
"__mips16_call_stub_sf_1"},
110 {
"rint",
"__mips16_call_stub_df_2"},
111 {
"rintf",
"__mips16_call_stub_sf_1"},
112 {
"sin",
"__mips16_call_stub_df_2"},
113 {
"sinf",
"__mips16_call_stub_sf_1"},
114 {
"sqrt",
"__mips16_call_stub_df_2"},
115 {
"sqrtf",
"__mips16_call_stub_sf_1"},
116 {
"trunc",
"__mips16_call_stub_df_2"},
117 {
"truncf",
"__mips16_call_stub_sf_1"},
128 setMips16HardFloatLibCalls();
166 switch (
MI.getOpcode()) {
170 return emitSel16(Mips::BeqzRxImm16,
MI,
BB);
172 return emitSel16(Mips::BnezRxImm16,
MI,
BB);
173 case Mips::SelTBteqZCmpi:
174 return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16,
MI,
BB);
175 case Mips::SelTBteqZSlti:
176 return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16,
MI,
BB);
177 case Mips::SelTBteqZSltiu:
178 return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16,
MI,
BB);
179 case Mips::SelTBtneZCmpi:
180 return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16,
MI,
BB);
181 case Mips::SelTBtneZSlti:
182 return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16,
MI,
BB);
183 case Mips::SelTBtneZSltiu:
184 return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16,
MI,
BB);
185 case Mips::SelTBteqZCmp:
186 return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16,
MI,
BB);
187 case Mips::SelTBteqZSlt:
188 return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16,
MI,
BB);
189 case Mips::SelTBteqZSltu:
190 return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16,
MI,
BB);
191 case Mips::SelTBtneZCmp:
192 return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16,
MI,
BB);
193 case Mips::SelTBtneZSlt:
194 return emitSelT16(Mips::Btnez16, Mips::SltRxRy16,
MI,
BB);
195 case Mips::SelTBtneZSltu:
196 return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16,
MI,
BB);
197 case Mips::BteqzT8CmpX16:
198 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16,
MI,
BB);
199 case Mips::BteqzT8SltX16:
200 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16,
MI,
BB);
201 case Mips::BteqzT8SltuX16:
204 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16,
MI,
BB);
205 case Mips::BtnezT8CmpX16:
206 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16,
MI,
BB);
207 case Mips::BtnezT8SltX16:
208 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16,
MI,
BB);
209 case Mips::BtnezT8SltuX16:
212 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16,
MI,
BB);
213 case Mips::BteqzT8CmpiX16:
return emitFEXT_T8I8I16_ins(
214 Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false,
MI,
BB);
215 case Mips::BteqzT8SltiX16:
return emitFEXT_T8I8I16_ins(
216 Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true,
MI,
BB);
217 case Mips::BteqzT8SltiuX16:
return emitFEXT_T8I8I16_ins(
218 Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false,
MI,
BB);
219 case Mips::BtnezT8CmpiX16:
return emitFEXT_T8I8I16_ins(
220 Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16,
false,
MI,
BB);
221 case Mips::BtnezT8SltiX16:
return emitFEXT_T8I8I16_ins(
222 Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16,
true,
MI,
BB);
223 case Mips::BtnezT8SltiuX16:
return emitFEXT_T8I8I16_ins(
224 Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
false,
MI,
BB);
226 case Mips::SltCCRxRy16:
227 return emitFEXT_CCRX16_ins(Mips::SltRxRy16,
MI,
BB);
229 case Mips::SltiCCRxImmX16:
230 return emitFEXT_CCRXI16_ins
231 (Mips::SltiRxImm16, Mips::SltiRxImmX16,
MI,
BB);
232 case Mips::SltiuCCRxImmX16:
233 return emitFEXT_CCRXI16_ins
234 (Mips::SltiuRxImm16, Mips::SltiuRxImmX16,
MI,
BB);
235 case Mips::SltuCCRxRy16:
236 return emitFEXT_CCRX16_ins
237 (Mips::SltuRxRy16,
MI,
BB);
241 bool Mips16TargetLowering::isEligibleForTailCallOptimization(
242 const CCState &CCInfo,
unsigned NextStackOffset,
248 void Mips16TargetLowering::setMips16HardFloatLibCalls() {
251 "Array not sorted!");
288 unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
289 (ArgListTy &
Args)
const {
290 unsigned int resultNum = 0;
291 if (
Args.size() >= 1) {
293 if (
t->isFloatTy()) {
296 else if (
t->isDoubleTy()) {
301 if (
Args.size() >=2) {
303 if (
t->isFloatTy()) {
306 else if (
t->isDoubleTy()) {
338 #define P_ "__mips16_call_stub_"
339 #define MAX_STUB_NUMBER 10
340 #define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
365 const char* Mips16TargetLowering::
366 getMips16HelperFunction
367 (
Type* RetTy, ArgListTy &
Args,
bool &needHelper)
const {
368 const unsigned int stubNum = getMips16HelperFunctionStubNumber(
Args);
370 const unsigned int maxStubNum = 10;
371 assert(stubNum <= maxStubNum);
372 const bool validStubNum[maxStubNum+1] =
373 {
true,
true,
true,
false,
false,
true,
true,
false,
false,
true,
true};
374 assert(validStubNum[stubNum]);
380 else if (RetTy ->isDoubleTy()) {
382 }
else if (
StructType *SRetTy = dyn_cast<StructType>(RetTy)) {
384 if (SRetTy->getNumElements() == 2) {
385 if ((SRetTy->getElementType(0)->isFloatTy()) &&
386 (SRetTy->getElementType(1)->isFloatTy())) {
388 }
else if ((SRetTy->getElementType(0)->isDoubleTy()) &&
389 (SRetTy->getElementType(1)->isDoubleTy())) {
408 void Mips16TargetLowering::
410 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
411 bool IsPICCall,
bool GlobalOrExternal,
bool InternalLinkage,
412 bool IsCallReloc, CallLoweringInfo &CLI,
SDValue Callee,
417 const char* Mips16HelperFunction =
nullptr;
418 bool NeedMips16Helper =
false;
426 bool LookupHelper =
true;
428 Mips16Libcall
Find = { RTLIB::UNKNOWN_LIBCALL,
S->getSymbol() };
432 LookupHelper =
false;
434 const char *
Symbol =
S->getSymbol();
435 Mips16IntrinsicHelperType IntrinsicFind = {
Symbol,
"" };
438 if (!IsPICCall && (Signature && (FuncInfo->
StubsNeeded.find(Symbol) ==
458 const Mips16IntrinsicHelperType *Helper =
461 *Helper == IntrinsicFind) {
462 Mips16HelperFunction = Helper->Helper;
463 NeedMips16Helper =
true;
464 LookupHelper =
false;
469 dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
470 Mips16Libcall
Find = { RTLIB::UNKNOWN_LIBCALL,
471 G->getGlobal()->getName().data() };
475 LookupHelper =
false;
478 Mips16HelperFunction =
479 getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
486 if (IsPICCall || !GlobalOrExternal) {
487 unsigned V0Reg = Mips::V0;
488 if (NeedMips16Helper) {
489 RegsToPass.push_front(std::make_pair(V0Reg, Callee));
497 RegsToPass.push_front(std::make_pair((
unsigned)Mips::T9, Callee));
500 Ops.push_back(JumpTarget);
503 InternalLinkage, IsCallReloc, CLI, Callee,
531 F->insert(It, copy0MBB);
532 F->insert(It, sinkMBB);
540 BB->addSuccessor(copy0MBB);
541 BB->addSuccessor(sinkMBB);
553 BB->addSuccessor(sinkMBB);
566 MI.eraseFromParent();
571 Mips16TargetLowering::emitSelT16(
unsigned Opc1,
unsigned Opc2,
MachineInstr &
MI,
594 F->insert(It, copy0MBB);
595 F->insert(It, sinkMBB);
603 BB->addSuccessor(copy0MBB);
604 BB->addSuccessor(sinkMBB);
617 BB->addSuccessor(sinkMBB);
630 MI.eraseFromParent();
636 Mips16TargetLowering::emitSeliT16(
unsigned Opc1,
unsigned Opc2,
660 F->insert(It, copy0MBB);
661 F->insert(It, sinkMBB);
669 BB->addSuccessor(copy0MBB);
670 BB->addSuccessor(sinkMBB);
683 BB->addSuccessor(sinkMBB);
696 MI.eraseFromParent();
702 Mips16TargetLowering::emitFEXT_T8I816_ins(
unsigned BtOpc,
unsigned CmpOpc,
715 MI.eraseFromParent();
720 unsigned BtOpc,
unsigned CmpiOpc,
unsigned CmpiXOpc,
bool ImmSigned,
726 int64_t imm =
MI.getOperand(1).getImm();
731 else if ((!ImmSigned && isUInt<16>(imm)) ||
732 (ImmSigned && isInt<16>(imm)))
738 MI.eraseFromParent();
743 (
unsigned shortOp,
unsigned longOp, int64_t
Imm) {
746 else if (isInt<16>(
Imm))
753 Mips16TargetLowering::emitFEXT_CCRX16_ins(
unsigned SltOpc,
MachineInstr &
MI,
766 MI.eraseFromParent();
771 Mips16TargetLowering::emitFEXT_CCRXI16_ins(
unsigned SltiOpc,
unsigned SltiXOpc,
779 int64_t
Imm =
MI.getOperand(2).getImm();
784 MI.eraseFromParent();