LLVM  3.7.0
Mips16ISelLowering.cpp
Go to the documentation of this file.
1 //===-- Mips16ISelLowering.h - Mips16 DAG Lowering Interface ----*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Subclass of MipsTargetLowering specialized for mips16.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "Mips16ISelLowering.h"
15 #include "Mips16HardFloatInfo.h"
16 #include "MipsMachineFunction.h"
17 #include "MipsRegisterInfo.h"
18 #include "MipsTargetMachine.h"
19 #include "llvm/ADT/StringRef.h"
23 #include <string>
24 
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "mips-lower"
28 
30  "mips16-dont-expand-cond-pseudo",
31  cl::init(false),
32  cl::desc("Don't expand conditional move related "
33  "pseudos for Mips 16"),
34  cl::Hidden);
35 
36 namespace {
37 struct Mips16Libcall {
39  const char *Name;
40 
41  bool operator<(const Mips16Libcall &RHS) const {
42  return std::strcmp(Name, RHS.Name) < 0;
43  }
44 };
45 
46 struct Mips16IntrinsicHelperType{
47  const char* Name;
48  const char* Helper;
49 
50  bool operator<(const Mips16IntrinsicHelperType &RHS) const {
51  return std::strcmp(Name, RHS.Name) < 0;
52  }
53  bool operator==(const Mips16IntrinsicHelperType &RHS) const {
54  return std::strcmp(Name, RHS.Name) == 0;
55  }
56 };
57 }
58 
59 // Libcalls for which no helper is generated. Sorted by name for binary search.
60 static const Mips16Libcall HardFloatLibCalls[] = {
61  { RTLIB::ADD_F64, "__mips16_adddf3" },
62  { RTLIB::ADD_F32, "__mips16_addsf3" },
63  { RTLIB::DIV_F64, "__mips16_divdf3" },
64  { RTLIB::DIV_F32, "__mips16_divsf3" },
65  { RTLIB::OEQ_F64, "__mips16_eqdf2" },
66  { RTLIB::OEQ_F32, "__mips16_eqsf2" },
67  { RTLIB::FPEXT_F32_F64, "__mips16_extendsfdf2" },
68  { RTLIB::FPTOSINT_F64_I32, "__mips16_fix_truncdfsi" },
69  { RTLIB::FPTOSINT_F32_I32, "__mips16_fix_truncsfsi" },
70  { RTLIB::SINTTOFP_I32_F64, "__mips16_floatsidf" },
71  { RTLIB::SINTTOFP_I32_F32, "__mips16_floatsisf" },
72  { RTLIB::UINTTOFP_I32_F64, "__mips16_floatunsidf" },
73  { RTLIB::UINTTOFP_I32_F32, "__mips16_floatunsisf" },
74  { RTLIB::OGE_F64, "__mips16_gedf2" },
75  { RTLIB::OGE_F32, "__mips16_gesf2" },
76  { RTLIB::OGT_F64, "__mips16_gtdf2" },
77  { RTLIB::OGT_F32, "__mips16_gtsf2" },
78  { RTLIB::OLE_F64, "__mips16_ledf2" },
79  { RTLIB::OLE_F32, "__mips16_lesf2" },
80  { RTLIB::OLT_F64, "__mips16_ltdf2" },
81  { RTLIB::OLT_F32, "__mips16_ltsf2" },
82  { RTLIB::MUL_F64, "__mips16_muldf3" },
83  { RTLIB::MUL_F32, "__mips16_mulsf3" },
84  { RTLIB::UNE_F64, "__mips16_nedf2" },
85  { RTLIB::UNE_F32, "__mips16_nesf2" },
86  { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_dc" }, // No associated libcall.
87  { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_df" }, // No associated libcall.
88  { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sc" }, // No associated libcall.
89  { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sf" }, // No associated libcall.
90  { RTLIB::SUB_F64, "__mips16_subdf3" },
91  { RTLIB::SUB_F32, "__mips16_subsf3" },
92  { RTLIB::FPROUND_F64_F32, "__mips16_truncdfsf2" },
93  { RTLIB::UO_F64, "__mips16_unorddf2" },
94  { RTLIB::UO_F32, "__mips16_unordsf2" }
95 };
96 
97 static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = {
98  {"__fixunsdfsi", "__mips16_call_stub_2" },
99  {"ceil", "__mips16_call_stub_df_2"},
100  {"ceilf", "__mips16_call_stub_sf_1"},
101  {"copysign", "__mips16_call_stub_df_10"},
102  {"copysignf", "__mips16_call_stub_sf_5"},
103  {"cos", "__mips16_call_stub_df_2"},
104  {"cosf", "__mips16_call_stub_sf_1"},
105  {"exp2", "__mips16_call_stub_df_2"},
106  {"exp2f", "__mips16_call_stub_sf_1"},
107  {"floor", "__mips16_call_stub_df_2"},
108  {"floorf", "__mips16_call_stub_sf_1"},
109  {"log2", "__mips16_call_stub_df_2"},
110  {"log2f", "__mips16_call_stub_sf_1"},
111  {"nearbyint", "__mips16_call_stub_df_2"},
112  {"nearbyintf", "__mips16_call_stub_sf_1"},
113  {"rint", "__mips16_call_stub_df_2"},
114  {"rintf", "__mips16_call_stub_sf_1"},
115  {"sin", "__mips16_call_stub_df_2"},
116  {"sinf", "__mips16_call_stub_sf_1"},
117  {"sqrt", "__mips16_call_stub_df_2"},
118  {"sqrtf", "__mips16_call_stub_sf_1"},
119  {"trunc", "__mips16_call_stub_df_2"},
120  {"truncf", "__mips16_call_stub_sf_1"},
121 };
122 
124  const MipsSubtarget &STI)
125  : MipsTargetLowering(TM, STI) {
126 
127  // Set up the register classes
128  addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);
129 
130  if (!Subtarget.useSoftFloat())
131  setMips16HardFloatLibCalls();
132 
146 
151 
153 }
154 
155 const MipsTargetLowering *
157  const MipsSubtarget &STI) {
158  return new Mips16TargetLowering(TM, STI);
159 }
160 
161 bool
163  unsigned,
164  unsigned,
165  bool *Fast) const {
166  return false;
167 }
168 
171  MachineBasicBlock *BB) const {
172  switch (MI->getOpcode()) {
173  default:
175  case Mips::SelBeqZ:
176  return emitSel16(Mips::BeqzRxImm16, MI, BB);
177  case Mips::SelBneZ:
178  return emitSel16(Mips::BnezRxImm16, MI, BB);
179  case Mips::SelTBteqZCmpi:
180  return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB);
181  case Mips::SelTBteqZSlti:
182  return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB);
183  case Mips::SelTBteqZSltiu:
184  return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB);
185  case Mips::SelTBtneZCmpi:
186  return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB);
187  case Mips::SelTBtneZSlti:
188  return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB);
189  case Mips::SelTBtneZSltiu:
190  return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB);
191  case Mips::SelTBteqZCmp:
192  return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
193  case Mips::SelTBteqZSlt:
194  return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
195  case Mips::SelTBteqZSltu:
196  return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
197  case Mips::SelTBtneZCmp:
198  return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
199  case Mips::SelTBtneZSlt:
200  return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
201  case Mips::SelTBtneZSltu:
202  return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
203  case Mips::BteqzT8CmpX16:
204  return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
205  case Mips::BteqzT8SltX16:
206  return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
207  case Mips::BteqzT8SltuX16:
208  // TBD: figure out a way to get this or remove the instruction
209  // altogether.
210  return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
211  case Mips::BtnezT8CmpX16:
212  return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
213  case Mips::BtnezT8SltX16:
214  return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
215  case Mips::BtnezT8SltuX16:
216  // TBD: figure out a way to get this or remove the instruction
217  // altogether.
218  return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
219  case Mips::BteqzT8CmpiX16: return emitFEXT_T8I8I16_ins(
220  Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);
221  case Mips::BteqzT8SltiX16: return emitFEXT_T8I8I16_ins(
222  Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);
223  case Mips::BteqzT8SltiuX16: return emitFEXT_T8I8I16_ins(
224  Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);
225  case Mips::BtnezT8CmpiX16: return emitFEXT_T8I8I16_ins(
226  Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);
227  case Mips::BtnezT8SltiX16: return emitFEXT_T8I8I16_ins(
228  Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);
229  case Mips::BtnezT8SltiuX16: return emitFEXT_T8I8I16_ins(
230  Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);
231  break;
232  case Mips::SltCCRxRy16:
233  return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);
234  break;
235  case Mips::SltiCCRxImmX16:
236  return emitFEXT_CCRXI16_ins
237  (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB);
238  case Mips::SltiuCCRxImmX16:
239  return emitFEXT_CCRXI16_ins
240  (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB);
241  case Mips::SltuCCRxRy16:
242  return emitFEXT_CCRX16_ins
243  (Mips::SltuRxRy16, MI, BB);
244  }
245 }
246 
247 bool Mips16TargetLowering::isEligibleForTailCallOptimization(
248  const CCState &CCInfo, unsigned NextStackOffset,
249  const MipsFunctionInfo &FI) const {
250  // No tail call optimization for mips16.
251  return false;
252 }
253 
254 void Mips16TargetLowering::setMips16HardFloatLibCalls() {
255  for (unsigned I = 0; I != array_lengthof(HardFloatLibCalls); ++I) {
256  assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) &&
257  "Array not sorted!");
260  }
261 
262  setLibcallName(RTLIB::O_F64, "__mips16_unorddf2");
263  setLibcallName(RTLIB::O_F32, "__mips16_unordsf2");
264 }
265 
266 //
267 // The Mips16 hard float is a crazy quilt inherited from gcc. I have a much
268 // cleaner way to do all of this but it will have to wait until the traditional
269 // gcc mechanism is completed.
270 //
271 // For Pic, in order for Mips16 code to call Mips32 code which according the abi
272 // have either arguments or returned values placed in floating point registers,
273 // we use a set of helper functions. (This includes functions which return type
274 // complex which on Mips are returned in a pair of floating point registers).
275 //
276 // This is an encoding that we inherited from gcc.
277 // In Mips traditional O32, N32 ABI, floating point numbers are passed in
278 // floating point argument registers 1,2 only when the first and optionally
279 // the second arguments are float (sf) or double (df).
280 // For Mips16 we are only concerned with the situations where floating point
281 // arguments are being passed in floating point registers by the ABI, because
282 // Mips16 mode code cannot execute floating point instructions to load those
283 // values and hence helper functions are needed.
284 // The possibilities are (), (sf), (sf, sf), (sf, df), (df), (df, sf), (df, df)
285 // the helper function suffixs for these are:
286 // 0, 1, 5, 9, 2, 6, 10
287 // this suffix can then be calculated as follows:
288 // for a given argument Arg:
289 // Arg1x, Arg2x = 1 : Arg is sf
290 // 2 : Arg is df
291 // 0: Arg is neither sf or df
292 // So this stub is the string for number Arg1x + Arg2x*4.
293 // However not all numbers between 0 and 10 are possible, we check anyway and
294 // assert if the impossible exists.
295 //
296 
297 unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
298  (ArgListTy &Args) const {
299  unsigned int resultNum = 0;
300  if (Args.size() >= 1) {
301  Type *t = Args[0].Ty;
302  if (t->isFloatTy()) {
303  resultNum = 1;
304  }
305  else if (t->isDoubleTy()) {
306  resultNum = 2;
307  }
308  }
309  if (resultNum) {
310  if (Args.size() >=2) {
311  Type *t = Args[1].Ty;
312  if (t->isFloatTy()) {
313  resultNum += 4;
314  }
315  else if (t->isDoubleTy()) {
316  resultNum += 8;
317  }
318  }
319  }
320  return resultNum;
321 }
322 
323 //
324 // Prefixes are attached to stub numbers depending on the return type.
325 // return type: float sf_
326 // double df_
327 // single complex sc_
328 // double complext dc_
329 // others NO PREFIX
330 //
331 //
332 // The full name of a helper function is__mips16_call_stub +
333 // return type dependent prefix + stub number
334 //
335 // FIXME: This is something that probably should be in a different source file
336 // and perhaps done differently but my main purpose is to not waste runtime
337 // on something that we can enumerate in the source. Another possibility is
338 // to have a python script to generate these mapping tables. This will do
339 // for now. There are a whole series of helper function mapping arrays, one
340 // for each return type class as outlined above. There there are 11 possible
341 // entries. Ones with 0 are ones which should never be selected.
342 //
343 // All the arrays are similar except for ones which return neither
344 // sf, df, sc, dc, in which we only care about ones which have sf or df as a
345 // first parameter.
346 //
347 #define P_ "__mips16_call_stub_"
348 #define MAX_STUB_NUMBER 10
349 #define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
350 #define T P "0" , T1
351 #define P P_
352 static char const * vMips16Helper[MAX_STUB_NUMBER+1] =
353  {nullptr, T1 };
354 #undef P
355 #define P P_ "sf_"
356 static char const * sfMips16Helper[MAX_STUB_NUMBER+1] =
357  { T };
358 #undef P
359 #define P P_ "df_"
360 static char const * dfMips16Helper[MAX_STUB_NUMBER+1] =
361  { T };
362 #undef P
363 #define P P_ "sc_"
364 static char const * scMips16Helper[MAX_STUB_NUMBER+1] =
365  { T };
366 #undef P
367 #define P P_ "dc_"
368 static char const * dcMips16Helper[MAX_STUB_NUMBER+1] =
369  { T };
370 #undef P
371 #undef P_
372 
373 
374 const char* Mips16TargetLowering::
375  getMips16HelperFunction
376  (Type* RetTy, ArgListTy &Args, bool &needHelper) const {
377  const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
378 #ifndef NDEBUG
379  const unsigned int maxStubNum = 10;
380  assert(stubNum <= maxStubNum);
381  const bool validStubNum[maxStubNum+1] =
382  {true, true, true, false, false, true, true, false, false, true, true};
383  assert(validStubNum[stubNum]);
384 #endif
385  const char *result;
386  if (RetTy->isFloatTy()) {
387  result = sfMips16Helper[stubNum];
388  }
389  else if (RetTy ->isDoubleTy()) {
390  result = dfMips16Helper[stubNum];
391  }
392  else if (RetTy->isStructTy()) {
393  // check if it's complex
394  if (RetTy->getNumContainedTypes() == 2) {
395  if ((RetTy->getContainedType(0)->isFloatTy()) &&
396  (RetTy->getContainedType(1)->isFloatTy())) {
397  result = scMips16Helper[stubNum];
398  }
399  else if ((RetTy->getContainedType(0)->isDoubleTy()) &&
400  (RetTy->getContainedType(1)->isDoubleTy())) {
401  result = dcMips16Helper[stubNum];
402  }
403  else {
404  llvm_unreachable("Uncovered condition");
405  }
406  }
407  else {
408  llvm_unreachable("Uncovered condition");
409  }
410  }
411  else {
412  if (stubNum == 0) {
413  needHelper = false;
414  return "";
415  }
416  result = vMips16Helper[stubNum];
417  }
418  needHelper = true;
419  return result;
420 }
421 
422 void Mips16TargetLowering::
423 getOpndList(SmallVectorImpl<SDValue> &Ops,
424  std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
425  bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
426  bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
427  SDValue Chain) const {
428  SelectionDAG &DAG = CLI.DAG;
430  MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
431  const char* Mips16HelperFunction = nullptr;
432  bool NeedMips16Helper = false;
433 
435  //
436  // currently we don't have symbols tagged with the mips16 or mips32
437  // qualifier so we will assume that we don't know what kind it is.
438  // and generate the helper
439  //
440  bool LookupHelper = true;
441  if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {
442  Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() };
443 
444  if (std::binary_search(std::begin(HardFloatLibCalls),
445  std::end(HardFloatLibCalls), Find))
446  LookupHelper = false;
447  else {
448  const char *Symbol = S->getSymbol();
449  Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" };
450  const Mips16HardFloatInfo::FuncSignature *Signature =
452  if (!IsPICCall && (Signature && (FuncInfo->StubsNeeded.find(Symbol) ==
453  FuncInfo->StubsNeeded.end()))) {
454  FuncInfo->StubsNeeded[Symbol] = Signature;
455  //
456  // S2 is normally saved if the stub is for a function which
457  // returns a float or double value and is not otherwise. This is
458  // because more work is required after the function the stub
459  // is calling completes, and so the stub cannot directly return
460  // and the stub has no stack space to store the return address so
461  // S2 is used for that purpose.
462  // In order to take advantage of not saving S2, we need to also
463  // optimize the call in the stub and this requires some further
464  // functionality in MipsAsmPrinter which we don't have yet.
465  // So for now we always save S2. The optimization will be done
466  // in a follow-on patch.
467  //
468  if (1 || (Signature->RetSig != Mips16HardFloatInfo::NoFPRet))
469  FuncInfo->setSaveS2();
470  }
471  // one more look at list of intrinsics
472  const Mips16IntrinsicHelperType *Helper =
473  std::lower_bound(std::begin(Mips16IntrinsicHelper),
474  std::end(Mips16IntrinsicHelper), IntrinsicFind);
475  if (Helper != std::end(Mips16IntrinsicHelper) &&
476  *Helper == IntrinsicFind) {
477  Mips16HelperFunction = Helper->Helper;
478  NeedMips16Helper = true;
479  LookupHelper = false;
480  }
481 
482  }
483  } else if (GlobalAddressSDNode *G =
484  dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
485  Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL,
486  G->getGlobal()->getName().data() };
487 
488  if (std::binary_search(std::begin(HardFloatLibCalls),
489  std::end(HardFloatLibCalls), Find))
490  LookupHelper = false;
491  }
492  if (LookupHelper)
493  Mips16HelperFunction =
494  getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
495  }
496 
497  SDValue JumpTarget = Callee;
498 
499  // T9 should contain the address of the callee function if
500  // -relocation-model=pic or it is an indirect call.
501  if (IsPICCall || !GlobalOrExternal) {
502  unsigned V0Reg = Mips::V0;
503  if (NeedMips16Helper) {
504  RegsToPass.push_front(std::make_pair(V0Reg, Callee));
505  JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction,
506  getPointerTy(DAG.getDataLayout()));
507  ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget);
508  JumpTarget = getAddrGlobal(S, CLI.DL, JumpTarget.getValueType(), DAG,
509  MipsII::MO_GOT, Chain,
510  FuncInfo->callPtrInfo(S->getSymbol()));
511  } else
512  RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));
513  }
514 
515  Ops.push_back(JumpTarget);
516 
517  MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
518  InternalLinkage, IsCallReloc, CLI, Callee,
519  Chain);
520 }
521 
522 MachineBasicBlock *Mips16TargetLowering::
523 emitSel16(unsigned Opc, MachineInstr *MI, MachineBasicBlock *BB) const {
525  return BB;
527  DebugLoc DL = MI->getDebugLoc();
528  // To "insert" a SELECT_CC instruction, we actually have to insert the
529  // diamond control-flow pattern. The incoming instruction knows the
530  // destination vreg to set, the condition code register to branch on, the
531  // true/false values to select between, and a branch opcode to use.
532  const BasicBlock *LLVM_BB = BB->getBasicBlock();
534  ++It;
535 
536  // thisMBB:
537  // ...
538  // TrueVal = ...
539  // setcc r1, r2, r3
540  // bNE r1, r0, copy1MBB
541  // fallthrough --> copy0MBB
542  MachineBasicBlock *thisMBB = BB;
543  MachineFunction *F = BB->getParent();
544  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
545  MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
546  F->insert(It, copy0MBB);
547  F->insert(It, sinkMBB);
548 
549  // Transfer the remainder of BB and its successor edges to sinkMBB.
550  sinkMBB->splice(sinkMBB->begin(), BB,
551  std::next(MachineBasicBlock::iterator(MI)), BB->end());
552  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
553 
554  // Next, add the true and fallthrough blocks as its successors.
555  BB->addSuccessor(copy0MBB);
556  BB->addSuccessor(sinkMBB);
557 
558  BuildMI(BB, DL, TII->get(Opc)).addReg(MI->getOperand(3).getReg())
559  .addMBB(sinkMBB);
560 
561  // copy0MBB:
562  // %FalseValue = ...
563  // # fallthrough to sinkMBB
564  BB = copy0MBB;
565 
566  // Update machine-CFG edges
567  BB->addSuccessor(sinkMBB);
568 
569  // sinkMBB:
570  // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
571  // ...
572  BB = sinkMBB;
573 
574  BuildMI(*BB, BB->begin(), DL,
575  TII->get(Mips::PHI), MI->getOperand(0).getReg())
576  .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB)
577  .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB);
578 
579  MI->eraseFromParent(); // The pseudo instruction is gone now.
580  return BB;
581 }
582 
584 Mips16TargetLowering::emitSelT16(unsigned Opc1, unsigned Opc2, MachineInstr *MI,
585  MachineBasicBlock *BB) const {
587  return BB;
588  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
589  DebugLoc DL = MI->getDebugLoc();
590  // To "insert" a SELECT_CC instruction, we actually have to insert the
591  // diamond control-flow pattern. The incoming instruction knows the
592  // destination vreg to set, the condition code register to branch on, the
593  // true/false values to select between, and a branch opcode to use.
594  const BasicBlock *LLVM_BB = BB->getBasicBlock();
596  ++It;
597 
598  // thisMBB:
599  // ...
600  // TrueVal = ...
601  // setcc r1, r2, r3
602  // bNE r1, r0, copy1MBB
603  // fallthrough --> copy0MBB
604  MachineBasicBlock *thisMBB = BB;
605  MachineFunction *F = BB->getParent();
606  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
607  MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
608  F->insert(It, copy0MBB);
609  F->insert(It, sinkMBB);
610 
611  // Transfer the remainder of BB and its successor edges to sinkMBB.
612  sinkMBB->splice(sinkMBB->begin(), BB,
613  std::next(MachineBasicBlock::iterator(MI)), BB->end());
614  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
615 
616  // Next, add the true and fallthrough blocks as its successors.
617  BB->addSuccessor(copy0MBB);
618  BB->addSuccessor(sinkMBB);
619 
620  BuildMI(BB, DL, TII->get(Opc2)).addReg(MI->getOperand(3).getReg())
621  .addReg(MI->getOperand(4).getReg());
622  BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
623 
624  // copy0MBB:
625  // %FalseValue = ...
626  // # fallthrough to sinkMBB
627  BB = copy0MBB;
628 
629  // Update machine-CFG edges
630  BB->addSuccessor(sinkMBB);
631 
632  // sinkMBB:
633  // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
634  // ...
635  BB = sinkMBB;
636 
637  BuildMI(*BB, BB->begin(), DL,
638  TII->get(Mips::PHI), MI->getOperand(0).getReg())
639  .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB)
640  .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB);
641 
642  MI->eraseFromParent(); // The pseudo instruction is gone now.
643  return BB;
644 
645 }
646 
648 Mips16TargetLowering::emitSeliT16(unsigned Opc1, unsigned Opc2,
649  MachineInstr *MI,
650  MachineBasicBlock *BB) const {
652  return BB;
653  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
654  DebugLoc DL = MI->getDebugLoc();
655  // To "insert" a SELECT_CC instruction, we actually have to insert the
656  // diamond control-flow pattern. The incoming instruction knows the
657  // destination vreg to set, the condition code register to branch on, the
658  // true/false values to select between, and a branch opcode to use.
659  const BasicBlock *LLVM_BB = BB->getBasicBlock();
661  ++It;
662 
663  // thisMBB:
664  // ...
665  // TrueVal = ...
666  // setcc r1, r2, r3
667  // bNE r1, r0, copy1MBB
668  // fallthrough --> copy0MBB
669  MachineBasicBlock *thisMBB = BB;
670  MachineFunction *F = BB->getParent();
671  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
672  MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
673  F->insert(It, copy0MBB);
674  F->insert(It, sinkMBB);
675 
676  // Transfer the remainder of BB and its successor edges to sinkMBB.
677  sinkMBB->splice(sinkMBB->begin(), BB,
678  std::next(MachineBasicBlock::iterator(MI)), BB->end());
679  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
680 
681  // Next, add the true and fallthrough blocks as its successors.
682  BB->addSuccessor(copy0MBB);
683  BB->addSuccessor(sinkMBB);
684 
685  BuildMI(BB, DL, TII->get(Opc2)).addReg(MI->getOperand(3).getReg())
686  .addImm(MI->getOperand(4).getImm());
687  BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
688 
689  // copy0MBB:
690  // %FalseValue = ...
691  // # fallthrough to sinkMBB
692  BB = copy0MBB;
693 
694  // Update machine-CFG edges
695  BB->addSuccessor(sinkMBB);
696 
697  // sinkMBB:
698  // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
699  // ...
700  BB = sinkMBB;
701 
702  BuildMI(*BB, BB->begin(), DL,
703  TII->get(Mips::PHI), MI->getOperand(0).getReg())
704  .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB)
705  .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB);
706 
707  MI->eraseFromParent(); // The pseudo instruction is gone now.
708  return BB;
709 
710 }
711 
713 Mips16TargetLowering::emitFEXT_T8I816_ins(unsigned BtOpc, unsigned CmpOpc,
714  MachineInstr *MI,
715  MachineBasicBlock *BB) const {
717  return BB;
718  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
719  unsigned regX = MI->getOperand(0).getReg();
720  unsigned regY = MI->getOperand(1).getReg();
721  MachineBasicBlock *target = MI->getOperand(2).getMBB();
722  BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(CmpOpc)).addReg(regX)
723  .addReg(regY);
724  BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(BtOpc)).addMBB(target);
725  MI->eraseFromParent(); // The pseudo instruction is gone now.
726  return BB;
727 }
728 
729 MachineBasicBlock *Mips16TargetLowering::emitFEXT_T8I8I16_ins(
730  unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, bool ImmSigned,
731  MachineInstr *MI, MachineBasicBlock *BB) const {
733  return BB;
734  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
735  unsigned regX = MI->getOperand(0).getReg();
736  int64_t imm = MI->getOperand(1).getImm();
737  MachineBasicBlock *target = MI->getOperand(2).getMBB();
738  unsigned CmpOpc;
739  if (isUInt<8>(imm))
740  CmpOpc = CmpiOpc;
741  else if ((!ImmSigned && isUInt<16>(imm)) ||
742  (ImmSigned && isInt<16>(imm)))
743  CmpOpc = CmpiXOpc;
744  else
745  llvm_unreachable("immediate field not usable");
746  BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(CmpOpc)).addReg(regX)
747  .addImm(imm);
748  BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(BtOpc)).addMBB(target);
749  MI->eraseFromParent(); // The pseudo instruction is gone now.
750  return BB;
751 }
752 
753 static unsigned Mips16WhichOp8uOr16simm
754  (unsigned shortOp, unsigned longOp, int64_t Imm) {
755  if (isUInt<8>(Imm))
756  return shortOp;
757  else if (isInt<16>(Imm))
758  return longOp;
759  else
760  llvm_unreachable("immediate field not usable");
761 }
762 
764 Mips16TargetLowering::emitFEXT_CCRX16_ins(unsigned SltOpc, MachineInstr *MI,
765  MachineBasicBlock *BB) const {
767  return BB;
768  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
769  unsigned CC = MI->getOperand(0).getReg();
770  unsigned regX = MI->getOperand(1).getReg();
771  unsigned regY = MI->getOperand(2).getReg();
772  BuildMI(*BB, MI, MI->getDebugLoc(), TII->get(SltOpc)).addReg(regX).addReg(
773  regY);
774  BuildMI(*BB, MI, MI->getDebugLoc(),
775  TII->get(Mips::MoveR3216), CC).addReg(Mips::T8);
776  MI->eraseFromParent(); // The pseudo instruction is gone now.
777  return BB;
778 }
779 
781 Mips16TargetLowering::emitFEXT_CCRXI16_ins(unsigned SltiOpc, unsigned SltiXOpc,
782  MachineInstr *MI,
783  MachineBasicBlock *BB) const {
785  return BB;
786  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
787  unsigned CC = MI->getOperand(0).getReg();
788  unsigned regX = MI->getOperand(1).getReg();
789  int64_t Imm = MI->getOperand(2).getImm();
790  unsigned SltOpc = Mips16WhichOp8uOr16simm(SltiOpc, SltiXOpc, Imm);
791  BuildMI(*BB, MI, MI->getDebugLoc(),
792  TII->get(SltOpc)).addReg(regX).addImm(Imm);
793  BuildMI(*BB, MI, MI->getDebugLoc(),
794  TII->get(Mips::MoveR3216), CC).addReg(Mips::T8);
795  MI->eraseFromParent(); // The pseudo instruction is gone now.
796  return BB;
797 
798 }
bool isUInt< 8 >(uint64_t x)
Definition: MathExtras.h:294
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:240
const char * getSymbol() const
static char const * vMips16Helper[MAX_STUB_NUMBER+1]
const MipsSubtarget & Subtarget
MachineBasicBlock * getMBB() const
const MipsTargetLowering * createMips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Create MipsTargetLowering objects.
Mips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
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
bool isDoubleTy() const
isDoubleTy - Return true if this is 'double', a 64-bit IEEE fp type.
Definition: Type.h:146
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:232
A debug info location.
Definition: DebugLoc.h:34
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB)
transferSuccessorsAndUpdatePHIs - Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor blocks which refer to fromMBB to refer to this.
F(f)
static unsigned Mips16WhichOp8uOr16simm(unsigned shortOp, unsigned longOp, int64_t Imm)
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
Definition: ISDOpcodes.h:658
SDValue getExternalSymbol(const char *Sym, EVT VT)
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:283
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APInt.h:33
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.
Definition: ISDOpcodes.h:687
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...
static char const * dfMips16Helper[MAX_STUB_NUMBER+1]
bool inMips16HardFloat() const
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
#define G(x, y, z)
Definition: MD5.cpp:52
static char const * dcMips16Helper[MAX_STUB_NUMBER+1]
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose...
int64_t getImm() const
SDValue getAddrGlobal(NodeTy *N, SDLoc DL, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:284
const BasicBlock * getBasicBlock() const
getBasicBlock - Return the LLVM basic block that this instance corresponded to originally.
static const Mips16Libcall HardFloatLibCalls[]
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:267
TargetInstrInfo - Interface to description of machine instruction set.
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:247
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:325
FuncSignature const * findFuncSignature(const char *name)
LLVM Basic Block Representation.
Definition: BasicBlock.h:65
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type...
Type * getContainedType(unsigned i) const
getContainedType - This method is used to implement the type iterator (defined at the end of the file...
Definition: Type.h:332
static const SubtargetFeatureKV * Find(StringRef S, ArrayRef< SubtargetFeatureKV > A)
Find KV in array using binary search.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
bool isFloatTy() const
isFloatTy - Return true if this is 'float', a 32-bit IEEE fp type.
Definition: Type.h:143
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
bool useSoftFloat() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
unsigned getNumContainedTypes() const
getNumContainedTypes - Return the number of types in the derived type.
Definition: Type.h:339
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo...
Definition: ISDOpcodes.h:673
EVT - Extended Value Type.
Definition: ValueTypes.h:31
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[]
CCState - This class holds information needed while lowering arguments and return values...
const MipsRegisterInfo * getRegisterInfo() const override
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:179
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:335
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:238
bool isStructTy() const
isStructTy - True if this is an instance of StructType.
Definition: Type.h:209
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)
Representation of each machine instruction.
Definition: MachineInstr.h:51
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 '...
MachinePointerInfo callPtrInfo(StringRef Name)
Create a MachinePointerInfo that has a MipsCallEntr object representing a GOT entry for an external f...
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
std::map< const char *, const llvm::Mips16HardFloatInfo::FuncSignature * > StubsNeeded
#define I(x, y, z)
Definition: MD5.cpp:54
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:42
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.
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...
bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:272
unsigned getReg() const
getReg - Returns the register number.
void insert(iterator MBBI, MachineBasicBlock *MBB)
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:332
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...
bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:298
BasicBlockListType::iterator iterator
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
#define MAX_STUB_NUMBER
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:1734
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, unsigned Align, bool *Fast) const override
Determine if the target supports unaligned memory accesses.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
addSuccessor - Add succ as a successor of this MachineBasicBlock.
#define T1