xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/Mips16ISelLowering.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- Mips16ISelLowering.h - Mips16 DAG Lowering Interface ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Subclass of MipsTargetLowering specialized for mips16.
10 //
11 //===----------------------------------------------------------------------===//
12 #include "Mips16ISelLowering.h"
13 #include "MCTargetDesc/MipsBaseInfo.h"
14 #include "Mips16HardFloatInfo.h"
15 #include "MipsMachineFunction.h"
16 #include "MipsRegisterInfo.h"
17 #include "MipsTargetMachine.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/TargetInstrInfo.h"
20 #include "llvm/Support/CommandLine.h"
21 
22 using namespace llvm;
23 
24 #define DEBUG_TYPE "mips-lower"
25 
26 static cl::opt<bool> DontExpandCondPseudos16(
27   "mips16-dont-expand-cond-pseudo",
28   cl::init(false),
29   cl::desc("Don't expand conditional move related "
30            "pseudos for Mips 16"),
31   cl::Hidden);
32 
33 namespace {
34 struct Mips16Libcall {
35   RTLIB::Libcall Libcall;
36   RTLIB::LibcallImpl Impl;
37   const char *Name; // FIXME: Remove this
38 
operator <__anon9886fd620111::Mips16Libcall39   bool operator<(const Mips16Libcall &RHS) const {
40     return std::strcmp(Name, RHS.Name) < 0;
41   }
42 };
43 
44 struct Mips16IntrinsicHelperType{
45   const char* Name;
46   const char* Helper;
47 
operator <__anon9886fd620111::Mips16IntrinsicHelperType48   bool operator<(const Mips16IntrinsicHelperType &RHS) const {
49     return std::strcmp(Name, RHS.Name) < 0;
50   }
operator ==__anon9886fd620111::Mips16IntrinsicHelperType51   bool operator==(const Mips16IntrinsicHelperType &RHS) const {
52     return std::strcmp(Name, RHS.Name) == 0;
53   }
54 };
55 }
56 
57 // Libcalls for which no helper is generated. Sorted by name for binary search.
58 static const Mips16Libcall HardFloatLibCalls[] = {
59     {RTLIB::ADD_F64, RTLIB::__mips16_adddf3, "__mips16_adddf3"},
60     {RTLIB::ADD_F32, RTLIB::__mips16_addsf3, "__mips16_addsf3"},
61     {RTLIB::DIV_F64, RTLIB::__mips16_divdf3, "__mips16_divdf3"},
62     {RTLIB::DIV_F32, RTLIB::__mips16_divsf3, "__mips16_divsf3"},
63     {RTLIB::OEQ_F64, RTLIB::__mips16_eqdf2, "__mips16_eqdf2"},
64     {RTLIB::OEQ_F32, RTLIB::__mips16_eqsf2, "__mips16_eqsf2"},
65     {RTLIB::FPEXT_F32_F64, RTLIB::__mips16_extendsfdf2, "__mips16_extendsfdf2"},
66     {RTLIB::FPTOSINT_F64_I32, RTLIB::__mips16_fix_truncdfsi,
67      "__mips16_fix_truncdfsi"},
68     {RTLIB::FPTOSINT_F32_I32, RTLIB::__mips16_fix_truncsfsi,
69      "__mips16_fix_truncsfsi"},
70     {RTLIB::SINTTOFP_I32_F64, RTLIB::__mips16_floatsidf, "__mips16_floatsidf"},
71     {RTLIB::SINTTOFP_I32_F32, RTLIB::__mips16_floatsisf, "__mips16_floatsisf"},
72     {RTLIB::UINTTOFP_I32_F64, RTLIB::__mips16_floatunsidf,
73      "__mips16_floatunsidf"},
74     {RTLIB::UINTTOFP_I32_F32, RTLIB::__mips16_floatunsisf,
75      "__mips16_floatunsisf"},
76     {RTLIB::OGE_F64, RTLIB::__mips16_gedf2, "__mips16_gedf2"},
77     {RTLIB::OGE_F32, RTLIB::__mips16_gesf2, "__mips16_gesf2"},
78     {RTLIB::OGT_F64, RTLIB::__mips16_gtdf2, "__mips16_gtdf2"},
79     {RTLIB::OGT_F32, RTLIB::__mips16_gtsf2, "__mips16_gtsf2"},
80     {RTLIB::OLE_F64, RTLIB::__mips16_ledf2, "__mips16_ledf2"},
81     {RTLIB::OLE_F32, RTLIB::__mips16_lesf2, "__mips16_lesf2"},
82     {RTLIB::OLT_F64, RTLIB::__mips16_ltdf2, "__mips16_ltdf2"},
83     {RTLIB::OLT_F32, RTLIB::__mips16_ltsf2, "__mips16_ltsf2"},
84     {RTLIB::MUL_F64, RTLIB::__mips16_muldf3, "__mips16_muldf3"},
85     {RTLIB::MUL_F32, RTLIB::__mips16_mulsf3, "__mips16_mulsf3"},
86     {RTLIB::UNE_F64, RTLIB::__mips16_nedf2, "__mips16_nedf2"},
87     {RTLIB::UNE_F32, RTLIB::__mips16_nesf2, "__mips16_nesf2"},
88     {RTLIB::UNKNOWN_LIBCALL, RTLIB::__mips16_ret_dc,
89      "__mips16_ret_dc"}, // No associated libcall.
90     {RTLIB::UNKNOWN_LIBCALL, RTLIB::__mips16_ret_df,
91      "__mips16_ret_df"}, // No associated libcall.
92     {RTLIB::UNKNOWN_LIBCALL, RTLIB::__mips16_ret_sc,
93      "__mips16_ret_sc"}, // No associated libcall.
94     {RTLIB::UNKNOWN_LIBCALL, RTLIB::__mips16_ret_sf,
95      "__mips16_ret_sf"}, // No associated libcall.
96     {RTLIB::SUB_F64, RTLIB::__mips16_subdf3, "__mips16_subdf3"},
97     {RTLIB::SUB_F32, RTLIB::__mips16_subsf3, "__mips16_subsf3"},
98     {RTLIB::FPROUND_F64_F32, RTLIB::__mips16_truncdfsf2, "__mips16_truncdfsf2"},
99     {RTLIB::UO_F64, RTLIB::__mips16_unorddf2, "__mips16_unorddf2"},
100     {RTLIB::UO_F32, RTLIB::__mips16_unordsf2, "__mips16_unordsf2"}};
101 
102 static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = {
103   {"__fixunsdfsi", "__mips16_call_stub_2" },
104   {"ceil",  "__mips16_call_stub_df_2"},
105   {"ceilf", "__mips16_call_stub_sf_1"},
106   {"copysign",  "__mips16_call_stub_df_10"},
107   {"copysignf", "__mips16_call_stub_sf_5"},
108   {"cos",  "__mips16_call_stub_df_2"},
109   {"cosf", "__mips16_call_stub_sf_1"},
110   {"exp2",  "__mips16_call_stub_df_2"},
111   {"exp2f", "__mips16_call_stub_sf_1"},
112   {"floor",  "__mips16_call_stub_df_2"},
113   {"floorf", "__mips16_call_stub_sf_1"},
114   {"log2",  "__mips16_call_stub_df_2"},
115   {"log2f", "__mips16_call_stub_sf_1"},
116   {"nearbyint",  "__mips16_call_stub_df_2"},
117   {"nearbyintf", "__mips16_call_stub_sf_1"},
118   {"rint",  "__mips16_call_stub_df_2"},
119   {"rintf", "__mips16_call_stub_sf_1"},
120   {"sin",  "__mips16_call_stub_df_2"},
121   {"sinf", "__mips16_call_stub_sf_1"},
122   {"sqrt",  "__mips16_call_stub_df_2"},
123   {"sqrtf", "__mips16_call_stub_sf_1"},
124   {"trunc",  "__mips16_call_stub_df_2"},
125   {"truncf", "__mips16_call_stub_sf_1"},
126 };
127 
Mips16TargetLowering(const MipsTargetMachine & TM,const MipsSubtarget & STI)128 Mips16TargetLowering::Mips16TargetLowering(const MipsTargetMachine &TM,
129                                            const MipsSubtarget &STI)
130     : MipsTargetLowering(TM, STI) {
131 
132   // Set up the register classes
133   addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);
134 
135   if (!Subtarget.useSoftFloat())
136     setMips16HardFloatLibCalls();
137 
138   setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, LibCall);
139   setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, LibCall);
140   setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, LibCall);
141   setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i32, LibCall);
142   setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i32, LibCall);
143   setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i32, LibCall);
144   setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i32, LibCall);
145   setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i32, LibCall);
146   setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i32, LibCall);
147   setOperationAction(ISD::ATOMIC_LOAD_MIN, MVT::i32, LibCall);
148   setOperationAction(ISD::ATOMIC_LOAD_MAX, MVT::i32, LibCall);
149   setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i32, LibCall);
150   setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i32, LibCall);
151 
152   setOperationAction(ISD::ROTR, MVT::i32,  Expand);
153   setOperationAction(ISD::ROTR, MVT::i64,  Expand);
154   setOperationAction(ISD::BSWAP, MVT::i32, Expand);
155   setOperationAction(ISD::BSWAP, MVT::i64, Expand);
156 
157   computeRegisterProperties(STI.getRegisterInfo());
158 }
159 
160 const MipsTargetLowering *
createMips16TargetLowering(const MipsTargetMachine & TM,const MipsSubtarget & STI)161 llvm::createMips16TargetLowering(const MipsTargetMachine &TM,
162                                  const MipsSubtarget &STI) {
163   return new Mips16TargetLowering(TM, STI);
164 }
165 
allowsMisalignedMemoryAccesses(EVT VT,unsigned,Align,MachineMemOperand::Flags,unsigned * Fast) const166 bool Mips16TargetLowering::allowsMisalignedMemoryAccesses(
167     EVT VT, unsigned, Align, MachineMemOperand::Flags, unsigned *Fast) const {
168   return false;
169 }
170 
171 MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr & MI,MachineBasicBlock * BB) const172 Mips16TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
173                                                   MachineBasicBlock *BB) const {
174   switch (MI.getOpcode()) {
175   default:
176     return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
177   case Mips::SelBeqZ:
178     return emitSel16(Mips::BeqzRxImm16, MI, BB);
179   case Mips::SelBneZ:
180     return emitSel16(Mips::BnezRxImm16, MI, BB);
181   case Mips::SelTBteqZCmpi:
182     return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB);
183   case Mips::SelTBteqZSlti:
184     return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB);
185   case Mips::SelTBteqZSltiu:
186     return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB);
187   case Mips::SelTBtneZCmpi:
188     return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB);
189   case Mips::SelTBtneZSlti:
190     return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB);
191   case Mips::SelTBtneZSltiu:
192     return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB);
193   case Mips::SelTBteqZCmp:
194     return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
195   case Mips::SelTBteqZSlt:
196     return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
197   case Mips::SelTBteqZSltu:
198     return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
199   case Mips::SelTBtneZCmp:
200     return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
201   case Mips::SelTBtneZSlt:
202     return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
203   case Mips::SelTBtneZSltu:
204     return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
205   case Mips::BteqzT8CmpX16:
206     return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
207   case Mips::BteqzT8SltX16:
208     return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
209   case Mips::BteqzT8SltuX16:
210     // TBD: figure out a way to get this or remove the instruction
211     // altogether.
212     return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
213   case Mips::BtnezT8CmpX16:
214     return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
215   case Mips::BtnezT8SltX16:
216     return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
217   case Mips::BtnezT8SltuX16:
218     // TBD: figure out a way to get this or remove the instruction
219     // altogether.
220     return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
221   case Mips::BteqzT8CmpiX16: return emitFEXT_T8I8I16_ins(
222     Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);
223   case Mips::BteqzT8SltiX16: return emitFEXT_T8I8I16_ins(
224     Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);
225   case Mips::BteqzT8SltiuX16: return emitFEXT_T8I8I16_ins(
226     Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);
227   case Mips::BtnezT8CmpiX16: return emitFEXT_T8I8I16_ins(
228     Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);
229   case Mips::BtnezT8SltiX16: return emitFEXT_T8I8I16_ins(
230     Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);
231   case Mips::BtnezT8SltiuX16: return emitFEXT_T8I8I16_ins(
232     Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);
233     break;
234   case Mips::SltCCRxRy16:
235     return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);
236     break;
237   case Mips::SltiCCRxImmX16:
238     return emitFEXT_CCRXI16_ins
239       (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB);
240   case Mips::SltiuCCRxImmX16:
241     return emitFEXT_CCRXI16_ins
242       (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB);
243   case Mips::SltuCCRxRy16:
244     return emitFEXT_CCRX16_ins
245       (Mips::SltuRxRy16, MI, BB);
246   }
247 }
248 
isEligibleForTailCallOptimization(const CCState & CCInfo,unsigned NextStackOffset,const MipsFunctionInfo & FI) const249 bool Mips16TargetLowering::isEligibleForTailCallOptimization(
250     const CCState &CCInfo, unsigned NextStackOffset,
251     const MipsFunctionInfo &FI) const {
252   // No tail call optimization for mips16.
253   return false;
254 }
255 
setMips16HardFloatLibCalls()256 void Mips16TargetLowering::setMips16HardFloatLibCalls() {
257   for (unsigned I = 0; I != std::size(HardFloatLibCalls); ++I) {
258     assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) &&
259            "Array not sorted!");
260     if (HardFloatLibCalls[I].Libcall != RTLIB::UNKNOWN_LIBCALL)
261       setLibcallImpl(HardFloatLibCalls[I].Libcall, HardFloatLibCalls[I].Impl);
262   }
263 }
264 
265 //
266 // The Mips16 hard float is a crazy quilt inherited from gcc. I have a much
267 // cleaner way to do all of this but it will have to wait until the traditional
268 // gcc mechanism is completed.
269 //
270 // For Pic, in order for Mips16 code to call Mips32 code which according the abi
271 // have either arguments or returned values placed in floating point registers,
272 // we use a set of helper functions. (This includes functions which return type
273 //  complex which on Mips are returned in a pair of floating point registers).
274 //
275 // This is an encoding that we inherited from gcc.
276 // In Mips traditional O32, N32 ABI, floating point numbers are passed in
277 // floating point argument registers 1,2 only when the first and optionally
278 // the second arguments are float (sf) or double (df).
279 // For Mips16 we are only concerned with the situations where floating point
280 // arguments are being passed in floating point registers by the ABI, because
281 // Mips16 mode code cannot execute floating point instructions to load those
282 // values and hence helper functions are needed.
283 // The possibilities are (), (sf), (sf, sf), (sf, df), (df), (df, sf), (df, df)
284 // the helper function suffixs for these are:
285 //                        0,  1,    5,        9,         2,   6,        10
286 // this suffix can then be calculated as follows:
287 // for a given argument Arg:
288 //     Arg1x, Arg2x = 1 :  Arg is sf
289 //                    2 :  Arg is df
290 //                    0:   Arg is neither sf or df
291 // So this stub is the string for number Arg1x + Arg2x*4.
292 // However not all numbers between 0 and 10 are possible, we check anyway and
293 // assert if the impossible exists.
294 //
295 
getMips16HelperFunctionStubNumber(ArgListTy & Args) const296 unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
297   (ArgListTy &Args) const {
298   unsigned int resultNum = 0;
299   if (Args.size() >= 1) {
300     Type *t = Args[0].Ty;
301     if (t->isFloatTy()) {
302       resultNum = 1;
303     }
304     else if (t->isDoubleTy()) {
305       resultNum = 2;
306     }
307   }
308   if (resultNum) {
309     if (Args.size() >=2) {
310       Type *t = Args[1].Ty;
311       if (t->isFloatTy()) {
312         resultNum += 4;
313       }
314       else if (t->isDoubleTy()) {
315         resultNum += 8;
316       }
317     }
318   }
319   return resultNum;
320 }
321 
322 //
323 // Prefixes are attached to stub numbers depending on the return type.
324 // return type: float  sf_
325 //              double df_
326 //              single complex sc_
327 //              double complext dc_
328 //              others  NO PREFIX
329 //
330 //
331 // The full name of a helper function is__mips16_call_stub +
332 //    return type dependent prefix + stub number
333 //
334 // FIXME: This is something that probably should be in a different source file
335 // and perhaps done differently but my main purpose is to not waste runtime
336 // on something that we can enumerate in the source. Another possibility is
337 // to have a python script to generate these mapping tables. This will do
338 // for now. There are a whole series of helper function mapping arrays, one
339 // for each return type class as outlined above. There there are 11 possible
340 // entries. Ones with 0 are ones which should never be selected.
341 //
342 // All the arrays are similar except for ones which return neither
343 // sf, df, sc, dc, in which we only care about ones which have sf or df as a
344 // first parameter.
345 //
346 #define P_ "__mips16_call_stub_"
347 #define MAX_STUB_NUMBER 10
348 #define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
349 #define T P "0" , T1
350 #define P P_
351 static char const * vMips16Helper[MAX_STUB_NUMBER+1] =
352   {nullptr, T1 };
353 #undef P
354 #define P P_ "sf_"
355 static char const * sfMips16Helper[MAX_STUB_NUMBER+1] =
356   { T };
357 #undef P
358 #define P P_ "df_"
359 static char const * dfMips16Helper[MAX_STUB_NUMBER+1] =
360   { T };
361 #undef P
362 #define P P_ "sc_"
363 static char const * scMips16Helper[MAX_STUB_NUMBER+1] =
364   { T };
365 #undef P
366 #define P P_ "dc_"
367 static char const * dcMips16Helper[MAX_STUB_NUMBER+1] =
368   { T };
369 #undef P
370 #undef P_
371 
372 
373 const char* Mips16TargetLowering::
getMips16HelperFunction(Type * RetTy,ArgListTy & Args,bool & needHelper) const374   getMips16HelperFunction
375     (Type* RetTy, ArgListTy &Args, bool &needHelper) const {
376   const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
377 #ifndef NDEBUG
378   const unsigned int maxStubNum = 10;
379   assert(stubNum <= maxStubNum);
380   const bool validStubNum[maxStubNum+1] =
381     {true, true, true, false, false, true, true, false, false, true, true};
382   assert(validStubNum[stubNum]);
383 #endif
384   const char *result;
385   if (RetTy->isFloatTy()) {
386     result = sfMips16Helper[stubNum];
387   }
388   else if (RetTy ->isDoubleTy()) {
389     result = dfMips16Helper[stubNum];
390   } else if (StructType *SRetTy = dyn_cast<StructType>(RetTy)) {
391     // check if it's complex
392     if (SRetTy->getNumElements() == 2) {
393       if ((SRetTy->getElementType(0)->isFloatTy()) &&
394           (SRetTy->getElementType(1)->isFloatTy())) {
395         result = scMips16Helper[stubNum];
396       } else if ((SRetTy->getElementType(0)->isDoubleTy()) &&
397                  (SRetTy->getElementType(1)->isDoubleTy())) {
398         result = dcMips16Helper[stubNum];
399       } else {
400         llvm_unreachable("Uncovered condition");
401       }
402     } else {
403       llvm_unreachable("Uncovered condition");
404     }
405   } else {
406     if (stubNum == 0) {
407       needHelper = false;
408       return "";
409     }
410     result = vMips16Helper[stubNum];
411   }
412   needHelper = true;
413   return result;
414 }
415 
416 void Mips16TargetLowering::
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) const417 getOpndList(SmallVectorImpl<SDValue> &Ops,
418             std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
419             bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
420             bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
421             SDValue Chain) const {
422   SelectionDAG &DAG = CLI.DAG;
423   MachineFunction &MF = DAG.getMachineFunction();
424   MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
425   const char* Mips16HelperFunction = nullptr;
426   bool NeedMips16Helper = false;
427 
428   if (Subtarget.inMips16HardFloat()) {
429     //
430     // currently we don't have symbols tagged with the mips16 or mips32
431     // qualifier so we will assume that we don't know what kind it is.
432     // and generate the helper
433     //
434     bool LookupHelper = true;
435     if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {
436       Mips16Libcall Find = {RTLIB::UNKNOWN_LIBCALL, RTLIB::Unsupported,
437                             S->getSymbol()};
438 
439       if (llvm::binary_search(HardFloatLibCalls, Find))
440         LookupHelper = false;
441       else {
442         const char *Symbol = S->getSymbol();
443         Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" };
444         const Mips16HardFloatInfo::FuncSignature *Signature =
445             Mips16HardFloatInfo::findFuncSignature(Symbol);
446         if (!IsPICCall && Signature &&
447             FuncInfo->StubsNeeded.try_emplace(Symbol, Signature).second) {
448           //
449           // S2 is normally saved if the stub is for a function which
450           // returns a float or double value and is not otherwise. This is
451           // because more work is required after the function the stub
452           // is calling completes, and so the stub cannot directly return
453           // and the stub has no stack space to store the return address so
454           // S2 is used for that purpose.
455           // In order to take advantage of not saving S2, we need to also
456           // optimize the call in the stub and this requires some further
457           // functionality in MipsAsmPrinter which we don't have yet.
458           // So for now we always save S2. The optimization will be done
459           // in a follow-on patch.
460           //
461           if (true || (Signature->RetSig != Mips16HardFloatInfo::NoFPRet))
462             FuncInfo->setSaveS2();
463         }
464         // one more look at list of intrinsics
465         const Mips16IntrinsicHelperType *Helper =
466             llvm::lower_bound(Mips16IntrinsicHelper, IntrinsicFind);
467         if (Helper != std::end(Mips16IntrinsicHelper) &&
468             *Helper == IntrinsicFind) {
469           Mips16HelperFunction = Helper->Helper;
470           NeedMips16Helper = true;
471           LookupHelper = false;
472         }
473 
474       }
475     } else if (GlobalAddressSDNode *G =
476                    dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
477       Mips16Libcall Find = {RTLIB::UNKNOWN_LIBCALL, RTLIB::Unsupported,
478                             G->getGlobal()->getName().data()};
479 
480       if (llvm::binary_search(HardFloatLibCalls, Find))
481         LookupHelper = false;
482     }
483     if (LookupHelper)
484       Mips16HelperFunction =
485         getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
486   }
487 
488   SDValue JumpTarget = Callee;
489 
490   // T9 should contain the address of the callee function if
491   // -relocation-model=pic or it is an indirect call.
492   if (IsPICCall || !GlobalOrExternal) {
493     unsigned V0Reg = Mips::V0;
494     if (NeedMips16Helper) {
495       RegsToPass.push_front(std::make_pair(V0Reg, Callee));
496       JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction,
497                                          getPointerTy(DAG.getDataLayout()));
498       ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget);
499       JumpTarget = getAddrGlobal(S, CLI.DL, JumpTarget.getValueType(), DAG,
500                                  MipsII::MO_GOT, Chain,
501                                  FuncInfo->callPtrInfo(MF, S->getSymbol()));
502     } else
503       RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));
504   }
505 
506   Ops.push_back(JumpTarget);
507 
508   MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
509                                   InternalLinkage, IsCallReloc, CLI, Callee,
510                                   Chain);
511 }
512 
513 MachineBasicBlock *
emitSel16(unsigned Opc,MachineInstr & MI,MachineBasicBlock * BB) const514 Mips16TargetLowering::emitSel16(unsigned Opc, MachineInstr &MI,
515                                 MachineBasicBlock *BB) const {
516   if (DontExpandCondPseudos16)
517     return BB;
518   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
519   DebugLoc DL = MI.getDebugLoc();
520   // To "insert" a SELECT_CC instruction, we actually have to insert the
521   // diamond control-flow pattern.  The incoming instruction knows the
522   // destination vreg to set, the condition code register to branch on, the
523   // true/false values to select between, and a branch opcode to use.
524   const BasicBlock *LLVM_BB = BB->getBasicBlock();
525   MachineFunction::iterator It = ++BB->getIterator();
526 
527   //  thisMBB:
528   //  ...
529   //   TrueVal = ...
530   //   setcc r1, r2, r3
531   //   bNE   r1, r0, copy1MBB
532   //   fallthrough --> copy0MBB
533   MachineBasicBlock *thisMBB  = BB;
534   MachineFunction *F = BB->getParent();
535   MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
536   MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB);
537   F->insert(It, copy0MBB);
538   F->insert(It, sinkMBB);
539 
540   // Transfer the remainder of BB and its successor edges to sinkMBB.
541   sinkMBB->splice(sinkMBB->begin(), BB,
542                   std::next(MachineBasicBlock::iterator(MI)), BB->end());
543   sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
544 
545   // Next, add the true and fallthrough blocks as its successors.
546   BB->addSuccessor(copy0MBB);
547   BB->addSuccessor(sinkMBB);
548 
549   BuildMI(BB, DL, TII->get(Opc))
550       .addReg(MI.getOperand(3).getReg())
551       .addMBB(sinkMBB);
552 
553   //  copy0MBB:
554   //   %FalseValue = ...
555   //   # fallthrough to sinkMBB
556   BB = copy0MBB;
557 
558   // Update machine-CFG edges
559   BB->addSuccessor(sinkMBB);
560 
561   //  sinkMBB:
562   //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
563   //  ...
564   BB = sinkMBB;
565 
566   BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
567       .addReg(MI.getOperand(1).getReg())
568       .addMBB(thisMBB)
569       .addReg(MI.getOperand(2).getReg())
570       .addMBB(copy0MBB);
571 
572   MI.eraseFromParent(); // The pseudo instruction is gone now.
573   return BB;
574 }
575 
576 MachineBasicBlock *
emitSelT16(unsigned Opc1,unsigned Opc2,MachineInstr & MI,MachineBasicBlock * BB) const577 Mips16TargetLowering::emitSelT16(unsigned Opc1, unsigned Opc2, MachineInstr &MI,
578                                  MachineBasicBlock *BB) const {
579   if (DontExpandCondPseudos16)
580     return BB;
581   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
582   DebugLoc DL = MI.getDebugLoc();
583   // To "insert" a SELECT_CC instruction, we actually have to insert the
584   // diamond control-flow pattern.  The incoming instruction knows the
585   // destination vreg to set, the condition code register to branch on, the
586   // true/false values to select between, and a branch opcode to use.
587   const BasicBlock *LLVM_BB = BB->getBasicBlock();
588   MachineFunction::iterator It = ++BB->getIterator();
589 
590   //  thisMBB:
591   //  ...
592   //   TrueVal = ...
593   //   setcc r1, r2, r3
594   //   bNE   r1, r0, copy1MBB
595   //   fallthrough --> copy0MBB
596   MachineBasicBlock *thisMBB  = BB;
597   MachineFunction *F = BB->getParent();
598   MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
599   MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB);
600   F->insert(It, copy0MBB);
601   F->insert(It, sinkMBB);
602 
603   // Transfer the remainder of BB and its successor edges to sinkMBB.
604   sinkMBB->splice(sinkMBB->begin(), BB,
605                   std::next(MachineBasicBlock::iterator(MI)), BB->end());
606   sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
607 
608   // Next, add the true and fallthrough blocks as its successors.
609   BB->addSuccessor(copy0MBB);
610   BB->addSuccessor(sinkMBB);
611 
612   BuildMI(BB, DL, TII->get(Opc2))
613       .addReg(MI.getOperand(3).getReg())
614       .addReg(MI.getOperand(4).getReg());
615   BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
616 
617   //  copy0MBB:
618   //   %FalseValue = ...
619   //   # fallthrough to sinkMBB
620   BB = copy0MBB;
621 
622   // Update machine-CFG edges
623   BB->addSuccessor(sinkMBB);
624 
625   //  sinkMBB:
626   //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
627   //  ...
628   BB = sinkMBB;
629 
630   BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
631       .addReg(MI.getOperand(1).getReg())
632       .addMBB(thisMBB)
633       .addReg(MI.getOperand(2).getReg())
634       .addMBB(copy0MBB);
635 
636   MI.eraseFromParent(); // The pseudo instruction is gone now.
637   return BB;
638 
639 }
640 
641 MachineBasicBlock *
emitSeliT16(unsigned Opc1,unsigned Opc2,MachineInstr & MI,MachineBasicBlock * BB) const642 Mips16TargetLowering::emitSeliT16(unsigned Opc1, unsigned Opc2,
643                                   MachineInstr &MI,
644                                   MachineBasicBlock *BB) const {
645   if (DontExpandCondPseudos16)
646     return BB;
647   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
648   DebugLoc DL = MI.getDebugLoc();
649   // To "insert" a SELECT_CC instruction, we actually have to insert the
650   // diamond control-flow pattern.  The incoming instruction knows the
651   // destination vreg to set, the condition code register to branch on, the
652   // true/false values to select between, and a branch opcode to use.
653   const BasicBlock *LLVM_BB = BB->getBasicBlock();
654   MachineFunction::iterator It = ++BB->getIterator();
655 
656   //  thisMBB:
657   //  ...
658   //   TrueVal = ...
659   //   setcc r1, r2, r3
660   //   bNE   r1, r0, copy1MBB
661   //   fallthrough --> copy0MBB
662   MachineBasicBlock *thisMBB  = BB;
663   MachineFunction *F = BB->getParent();
664   MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
665   MachineBasicBlock *sinkMBB  = F->CreateMachineBasicBlock(LLVM_BB);
666   F->insert(It, copy0MBB);
667   F->insert(It, sinkMBB);
668 
669   // Transfer the remainder of BB and its successor edges to sinkMBB.
670   sinkMBB->splice(sinkMBB->begin(), BB,
671                   std::next(MachineBasicBlock::iterator(MI)), BB->end());
672   sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
673 
674   // Next, add the true and fallthrough blocks as its successors.
675   BB->addSuccessor(copy0MBB);
676   BB->addSuccessor(sinkMBB);
677 
678   BuildMI(BB, DL, TII->get(Opc2))
679       .addReg(MI.getOperand(3).getReg())
680       .addImm(MI.getOperand(4).getImm());
681   BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
682 
683   //  copy0MBB:
684   //   %FalseValue = ...
685   //   # fallthrough to sinkMBB
686   BB = copy0MBB;
687 
688   // Update machine-CFG edges
689   BB->addSuccessor(sinkMBB);
690 
691   //  sinkMBB:
692   //   %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
693   //  ...
694   BB = sinkMBB;
695 
696   BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
697       .addReg(MI.getOperand(1).getReg())
698       .addMBB(thisMBB)
699       .addReg(MI.getOperand(2).getReg())
700       .addMBB(copy0MBB);
701 
702   MI.eraseFromParent(); // The pseudo instruction is gone now.
703   return BB;
704 
705 }
706 
707 MachineBasicBlock *
emitFEXT_T8I816_ins(unsigned BtOpc,unsigned CmpOpc,MachineInstr & MI,MachineBasicBlock * BB) const708 Mips16TargetLowering::emitFEXT_T8I816_ins(unsigned BtOpc, unsigned CmpOpc,
709                                           MachineInstr &MI,
710                                           MachineBasicBlock *BB) const {
711   if (DontExpandCondPseudos16)
712     return BB;
713   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
714   Register regX = MI.getOperand(0).getReg();
715   Register regY = MI.getOperand(1).getReg();
716   MachineBasicBlock *target = MI.getOperand(2).getMBB();
717   BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(CmpOpc))
718       .addReg(regX)
719       .addReg(regY);
720   BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(BtOpc)).addMBB(target);
721   MI.eraseFromParent(); // The pseudo instruction is gone now.
722   return BB;
723 }
724 
emitFEXT_T8I8I16_ins(unsigned BtOpc,unsigned CmpiOpc,unsigned CmpiXOpc,bool ImmSigned,MachineInstr & MI,MachineBasicBlock * BB) const725 MachineBasicBlock *Mips16TargetLowering::emitFEXT_T8I8I16_ins(
726     unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, bool ImmSigned,
727     MachineInstr &MI, MachineBasicBlock *BB) const {
728   if (DontExpandCondPseudos16)
729     return BB;
730   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
731   Register regX = MI.getOperand(0).getReg();
732   int64_t imm = MI.getOperand(1).getImm();
733   MachineBasicBlock *target = MI.getOperand(2).getMBB();
734   unsigned CmpOpc;
735   if (isUInt<8>(imm))
736     CmpOpc = CmpiOpc;
737   else if ((!ImmSigned && isUInt<16>(imm)) ||
738            (ImmSigned && isInt<16>(imm)))
739     CmpOpc = CmpiXOpc;
740   else
741     llvm_unreachable("immediate field not usable");
742   BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(CmpOpc)).addReg(regX).addImm(imm);
743   BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(BtOpc)).addMBB(target);
744   MI.eraseFromParent(); // The pseudo instruction is gone now.
745   return BB;
746 }
747 
Mips16WhichOp8uOr16simm(unsigned shortOp,unsigned longOp,int64_t Imm)748 static unsigned Mips16WhichOp8uOr16simm
749   (unsigned shortOp, unsigned longOp, int64_t Imm) {
750   if (isUInt<8>(Imm))
751     return shortOp;
752   else if (isInt<16>(Imm))
753     return longOp;
754   else
755     llvm_unreachable("immediate field not usable");
756 }
757 
758 MachineBasicBlock *
emitFEXT_CCRX16_ins(unsigned SltOpc,MachineInstr & MI,MachineBasicBlock * BB) const759 Mips16TargetLowering::emitFEXT_CCRX16_ins(unsigned SltOpc, MachineInstr &MI,
760                                           MachineBasicBlock *BB) const {
761   if (DontExpandCondPseudos16)
762     return BB;
763   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
764   Register CC = MI.getOperand(0).getReg();
765   Register regX = MI.getOperand(1).getReg();
766   Register regY = MI.getOperand(2).getReg();
767   BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SltOpc))
768       .addReg(regX)
769       .addReg(regY);
770   BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(Mips::MoveR3216), CC)
771       .addReg(Mips::T8);
772   MI.eraseFromParent(); // The pseudo instruction is gone now.
773   return BB;
774 }
775 
776 MachineBasicBlock *
emitFEXT_CCRXI16_ins(unsigned SltiOpc,unsigned SltiXOpc,MachineInstr & MI,MachineBasicBlock * BB) const777 Mips16TargetLowering::emitFEXT_CCRXI16_ins(unsigned SltiOpc, unsigned SltiXOpc,
778                                            MachineInstr &MI,
779                                            MachineBasicBlock *BB) const {
780   if (DontExpandCondPseudos16)
781     return BB;
782   const TargetInstrInfo *TII = Subtarget.getInstrInfo();
783   Register CC = MI.getOperand(0).getReg();
784   Register regX = MI.getOperand(1).getReg();
785   int64_t Imm = MI.getOperand(2).getImm();
786   unsigned SltOpc = Mips16WhichOp8uOr16simm(SltiOpc, SltiXOpc, Imm);
787   BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SltOpc)).addReg(regX).addImm(Imm);
788   BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(Mips::MoveR3216), CC)
789       .addReg(Mips::T8);
790   MI.eraseFromParent(); // The pseudo instruction is gone now.
791   return BB;
792 
793 }
794