LLVM  4.0.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"
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "mips-lower"
26 
28  "mips16-dont-expand-cond-pseudo",
29  cl::init(false),
30  cl::desc("Don't expand conditional move related "
31  "pseudos for Mips 16"),
32  cl::Hidden);
33 
34 namespace {
35 struct Mips16Libcall {
37  const char *Name;
38 
39  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 
48  bool operator<(const Mips16IntrinsicHelperType &RHS) const {
49  return std::strcmp(Name, RHS.Name) < 0;
50  }
51  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, "__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" }, // No associated libcall.
85  { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_df" }, // No associated libcall.
86  { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sc" }, // No associated libcall.
87  { RTLIB::UNKNOWN_LIBCALL, "__mips16_ret_sf" }, // No associated libcall.
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" }
93 };
94 
95 static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = {
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"},
119 };
120 
122  const MipsSubtarget &STI)
123  : MipsTargetLowering(TM, STI) {
124 
125  // Set up the register classes
126  addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);
127 
128  if (!Subtarget.useSoftFloat())
129  setMips16HardFloatLibCalls();
130 
144 
149 
151 }
152 
153 const MipsTargetLowering *
155  const MipsSubtarget &STI) {
156  return new Mips16TargetLowering(TM, STI);
157 }
158 
159 bool
161  unsigned,
162  unsigned,
163  bool *Fast) const {
164  return false;
165 }
166 
169  MachineBasicBlock *BB) const {
170  switch (MI.getOpcode()) {
171  default:
173  case Mips::SelBeqZ:
174  return emitSel16(Mips::BeqzRxImm16, MI, BB);
175  case Mips::SelBneZ:
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:
206  // TBD: figure out a way to get this or remove the instruction
207  // altogether.
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:
214  // TBD: figure out a way to get this or remove the instruction
215  // altogether.
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);
229  break;
230  case Mips::SltCCRxRy16:
231  return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);
232  break;
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);
242  }
243 }
244 
245 bool Mips16TargetLowering::isEligibleForTailCallOptimization(
246  const CCState &CCInfo, unsigned NextStackOffset,
247  const MipsFunctionInfo &FI) const {
248  // No tail call optimization for mips16.
249  return false;
250 }
251 
252 void Mips16TargetLowering::setMips16HardFloatLibCalls() {
253  for (unsigned I = 0; I != array_lengthof(HardFloatLibCalls); ++I) {
254  assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) &&
255  "Array not sorted!");
258  }
259 
260  setLibcallName(RTLIB::O_F64, "__mips16_unorddf2");
261  setLibcallName(RTLIB::O_F32, "__mips16_unordsf2");
262 }
263 
264 //
265 // The Mips16 hard float is a crazy quilt inherited from gcc. I have a much
266 // cleaner way to do all of this but it will have to wait until the traditional
267 // gcc mechanism is completed.
268 //
269 // For Pic, in order for Mips16 code to call Mips32 code which according the abi
270 // have either arguments or returned values placed in floating point registers,
271 // we use a set of helper functions. (This includes functions which return type
272 // complex which on Mips are returned in a pair of floating point registers).
273 //
274 // This is an encoding that we inherited from gcc.
275 // In Mips traditional O32, N32 ABI, floating point numbers are passed in
276 // floating point argument registers 1,2 only when the first and optionally
277 // the second arguments are float (sf) or double (df).
278 // For Mips16 we are only concerned with the situations where floating point
279 // arguments are being passed in floating point registers by the ABI, because
280 // Mips16 mode code cannot execute floating point instructions to load those
281 // values and hence helper functions are needed.
282 // The possibilities are (), (sf), (sf, sf), (sf, df), (df), (df, sf), (df, df)
283 // the helper function suffixs for these are:
284 // 0, 1, 5, 9, 2, 6, 10
285 // this suffix can then be calculated as follows:
286 // for a given argument Arg:
287 // Arg1x, Arg2x = 1 : Arg is sf
288 // 2 : Arg is df
289 // 0: Arg is neither sf or df
290 // So this stub is the string for number Arg1x + Arg2x*4.
291 // However not all numbers between 0 and 10 are possible, we check anyway and
292 // assert if the impossible exists.
293 //
294 
295 unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
296  (ArgListTy &Args) const {
297  unsigned int resultNum = 0;
298  if (Args.size() >= 1) {
299  Type *t = Args[0].Ty;
300  if (t->isFloatTy()) {
301  resultNum = 1;
302  }
303  else if (t->isDoubleTy()) {
304  resultNum = 2;
305  }
306  }
307  if (resultNum) {
308  if (Args.size() >=2) {
309  Type *t = Args[1].Ty;
310  if (t->isFloatTy()) {
311  resultNum += 4;
312  }
313  else if (t->isDoubleTy()) {
314  resultNum += 8;
315  }
316  }
317  }
318  return resultNum;
319 }
320 
321 //
322 // Prefixes are attached to stub numbers depending on the return type.
323 // return type: float sf_
324 // double df_
325 // single complex sc_
326 // double complext dc_
327 // others NO PREFIX
328 //
329 //
330 // The full name of a helper function is__mips16_call_stub +
331 // return type dependent prefix + stub number
332 //
333 // FIXME: This is something that probably should be in a different source file
334 // and perhaps done differently but my main purpose is to not waste runtime
335 // on something that we can enumerate in the source. Another possibility is
336 // to have a python script to generate these mapping tables. This will do
337 // for now. There are a whole series of helper function mapping arrays, one
338 // for each return type class as outlined above. There there are 11 possible
339 // entries. Ones with 0 are ones which should never be selected.
340 //
341 // All the arrays are similar except for ones which return neither
342 // sf, df, sc, dc, in which we only care about ones which have sf or df as a
343 // first parameter.
344 //
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"
348 #define T P "0" , T1
349 #define P P_
350 static char const * vMips16Helper[MAX_STUB_NUMBER+1] =
351  {nullptr, T1 };
352 #undef P
353 #define P P_ "sf_"
354 static char const * sfMips16Helper[MAX_STUB_NUMBER+1] =
355  { T };
356 #undef P
357 #define P P_ "df_"
358 static char const * dfMips16Helper[MAX_STUB_NUMBER+1] =
359  { T };
360 #undef P
361 #define P P_ "sc_"
362 static char const * scMips16Helper[MAX_STUB_NUMBER+1] =
363  { T };
364 #undef P
365 #define P P_ "dc_"
366 static char const * dcMips16Helper[MAX_STUB_NUMBER+1] =
367  { T };
368 #undef P
369 #undef P_
370 
371 
372 const char* Mips16TargetLowering::
373  getMips16HelperFunction
374  (Type* RetTy, ArgListTy &Args, bool &needHelper) const {
375  const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
376 #ifndef NDEBUG
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]);
382 #endif
383  const char *result;
384  if (RetTy->isFloatTy()) {
385  result = sfMips16Helper[stubNum];
386  }
387  else if (RetTy ->isDoubleTy()) {
388  result = dfMips16Helper[stubNum];
389  }
390  else if (RetTy->isStructTy()) {
391  // check if it's complex
392  if (RetTy->getNumContainedTypes() == 2) {
393  if ((RetTy->getContainedType(0)->isFloatTy()) &&
394  (RetTy->getContainedType(1)->isFloatTy())) {
395  result = scMips16Helper[stubNum];
396  }
397  else if ((RetTy->getContainedType(0)->isDoubleTy()) &&
398  (RetTy->getContainedType(1)->isDoubleTy())) {
399  result = dcMips16Helper[stubNum];
400  }
401  else {
402  llvm_unreachable("Uncovered condition");
403  }
404  }
405  else {
406  llvm_unreachable("Uncovered condition");
407  }
408  }
409  else {
410  if (stubNum == 0) {
411  needHelper = false;
412  return "";
413  }
414  result = vMips16Helper[stubNum];
415  }
416  needHelper = true;
417  return result;
418 }
419 
420 void Mips16TargetLowering::
421 getOpndList(SmallVectorImpl<SDValue> &Ops,
422  std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
423  bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
424  bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
425  SDValue Chain) const {
426  SelectionDAG &DAG = CLI.DAG;
428  MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
429  const char* Mips16HelperFunction = nullptr;
430  bool NeedMips16Helper = false;
431 
433  //
434  // currently we don't have symbols tagged with the mips16 or mips32
435  // qualifier so we will assume that we don't know what kind it is.
436  // and generate the helper
437  //
438  bool LookupHelper = true;
439  if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {
440  Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() };
441 
442  if (std::binary_search(std::begin(HardFloatLibCalls),
443  std::end(HardFloatLibCalls), Find))
444  LookupHelper = false;
445  else {
446  const char *Symbol = S->getSymbol();
447  Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" };
448  const Mips16HardFloatInfo::FuncSignature *Signature =
450  if (!IsPICCall && (Signature && (FuncInfo->StubsNeeded.find(Symbol) ==
451  FuncInfo->StubsNeeded.end()))) {
452  FuncInfo->StubsNeeded[Symbol] = Signature;
453  //
454  // S2 is normally saved if the stub is for a function which
455  // returns a float or double value and is not otherwise. This is
456  // because more work is required after the function the stub
457  // is calling completes, and so the stub cannot directly return
458  // and the stub has no stack space to store the return address so
459  // S2 is used for that purpose.
460  // In order to take advantage of not saving S2, we need to also
461  // optimize the call in the stub and this requires some further
462  // functionality in MipsAsmPrinter which we don't have yet.
463  // So for now we always save S2. The optimization will be done
464  // in a follow-on patch.
465  //
466  if (1 || (Signature->RetSig != Mips16HardFloatInfo::NoFPRet))
467  FuncInfo->setSaveS2();
468  }
469  // one more look at list of intrinsics
470  const Mips16IntrinsicHelperType *Helper =
471  std::lower_bound(std::begin(Mips16IntrinsicHelper),
472  std::end(Mips16IntrinsicHelper), IntrinsicFind);
473  if (Helper != std::end(Mips16IntrinsicHelper) &&
474  *Helper == IntrinsicFind) {
475  Mips16HelperFunction = Helper->Helper;
476  NeedMips16Helper = true;
477  LookupHelper = false;
478  }
479 
480  }
481  } else if (GlobalAddressSDNode *G =
482  dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
483  Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL,
484  G->getGlobal()->getName().data() };
485 
486  if (std::binary_search(std::begin(HardFloatLibCalls),
487  std::end(HardFloatLibCalls), Find))
488  LookupHelper = false;
489  }
490  if (LookupHelper)
491  Mips16HelperFunction =
492  getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
493  }
494 
495  SDValue JumpTarget = Callee;
496 
497  // T9 should contain the address of the callee function if
498  // -relocation-model=pic or it is an indirect call.
499  if (IsPICCall || !GlobalOrExternal) {
500  unsigned V0Reg = Mips::V0;
501  if (NeedMips16Helper) {
502  RegsToPass.push_front(std::make_pair(V0Reg, Callee));
503  JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction,
504  getPointerTy(DAG.getDataLayout()));
505  ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget);
506  JumpTarget = getAddrGlobal(S, CLI.DL, JumpTarget.getValueType(), DAG,
507  MipsII::MO_GOT, Chain,
508  FuncInfo->callPtrInfo(S->getSymbol()));
509  } else
510  RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));
511  }
512 
513  Ops.push_back(JumpTarget);
514 
515  MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
516  InternalLinkage, IsCallReloc, CLI, Callee,
517  Chain);
518 }
519 
521 Mips16TargetLowering::emitSel16(unsigned Opc, MachineInstr &MI,
522  MachineBasicBlock *BB) const {
524  return BB;
526  DebugLoc DL = MI.getDebugLoc();
527  // To "insert" a SELECT_CC instruction, we actually have to insert the
528  // diamond control-flow pattern. The incoming instruction knows the
529  // destination vreg to set, the condition code register to branch on, the
530  // true/false values to select between, and a branch opcode to use.
531  const BasicBlock *LLVM_BB = BB->getBasicBlock();
533 
534  // thisMBB:
535  // ...
536  // TrueVal = ...
537  // setcc r1, r2, r3
538  // bNE r1, r0, copy1MBB
539  // fallthrough --> copy0MBB
540  MachineBasicBlock *thisMBB = BB;
541  MachineFunction *F = BB->getParent();
542  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
543  MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
544  F->insert(It, copy0MBB);
545  F->insert(It, sinkMBB);
546 
547  // Transfer the remainder of BB and its successor edges to sinkMBB.
548  sinkMBB->splice(sinkMBB->begin(), BB,
549  std::next(MachineBasicBlock::iterator(MI)), BB->end());
550  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
551 
552  // Next, add the true and fallthrough blocks as its successors.
553  BB->addSuccessor(copy0MBB);
554  BB->addSuccessor(sinkMBB);
555 
556  BuildMI(BB, DL, TII->get(Opc))
557  .addReg(MI.getOperand(3).getReg())
558  .addMBB(sinkMBB);
559 
560  // copy0MBB:
561  // %FalseValue = ...
562  // # fallthrough to sinkMBB
563  BB = copy0MBB;
564 
565  // Update machine-CFG edges
566  BB->addSuccessor(sinkMBB);
567 
568  // sinkMBB:
569  // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
570  // ...
571  BB = sinkMBB;
572 
573  BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
574  .addReg(MI.getOperand(1).getReg())
575  .addMBB(thisMBB)
576  .addReg(MI.getOperand(2).getReg())
577  .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 
597  // thisMBB:
598  // ...
599  // TrueVal = ...
600  // setcc r1, r2, r3
601  // bNE r1, r0, copy1MBB
602  // fallthrough --> copy0MBB
603  MachineBasicBlock *thisMBB = BB;
604  MachineFunction *F = BB->getParent();
605  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
606  MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
607  F->insert(It, copy0MBB);
608  F->insert(It, sinkMBB);
609 
610  // Transfer the remainder of BB and its successor edges to sinkMBB.
611  sinkMBB->splice(sinkMBB->begin(), BB,
612  std::next(MachineBasicBlock::iterator(MI)), BB->end());
613  sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
614 
615  // Next, add the true and fallthrough blocks as its successors.
616  BB->addSuccessor(copy0MBB);
617  BB->addSuccessor(sinkMBB);
618 
619  BuildMI(BB, DL, TII->get(Opc2))
620  .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, TII->get(Mips::PHI), MI.getOperand(0).getReg())
638  .addReg(MI.getOperand(1).getReg())
639  .addMBB(thisMBB)
640  .addReg(MI.getOperand(2).getReg())
641  .addMBB(copy0MBB);
642 
643  MI.eraseFromParent(); // The pseudo instruction is gone now.
644  return BB;
645 
646 }
647 
649 Mips16TargetLowering::emitSeliT16(unsigned Opc1, unsigned Opc2,
650  MachineInstr &MI,
651  MachineBasicBlock *BB) const {
653  return BB;
654  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
655  DebugLoc DL = MI.getDebugLoc();
656  // To "insert" a SELECT_CC instruction, we actually have to insert the
657  // diamond control-flow pattern. The incoming instruction knows the
658  // destination vreg to set, the condition code register to branch on, the
659  // true/false values to select between, and a branch opcode to use.
660  const BasicBlock *LLVM_BB = BB->getBasicBlock();
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))
686  .addReg(MI.getOperand(3).getReg())
687  .addImm(MI.getOperand(4).getImm());
688  BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
689 
690  // copy0MBB:
691  // %FalseValue = ...
692  // # fallthrough to sinkMBB
693  BB = copy0MBB;
694 
695  // Update machine-CFG edges
696  BB->addSuccessor(sinkMBB);
697 
698  // sinkMBB:
699  // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
700  // ...
701  BB = sinkMBB;
702 
703  BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
704  .addReg(MI.getOperand(1).getReg())
705  .addMBB(thisMBB)
706  .addReg(MI.getOperand(2).getReg())
707  .addMBB(copy0MBB);
708 
709  MI.eraseFromParent(); // The pseudo instruction is gone now.
710  return BB;
711 
712 }
713 
715 Mips16TargetLowering::emitFEXT_T8I816_ins(unsigned BtOpc, unsigned CmpOpc,
716  MachineInstr &MI,
717  MachineBasicBlock *BB) const {
719  return BB;
720  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
721  unsigned regX = MI.getOperand(0).getReg();
722  unsigned regY = MI.getOperand(1).getReg();
723  MachineBasicBlock *target = MI.getOperand(2).getMBB();
724  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(CmpOpc))
725  .addReg(regX)
726  .addReg(regY);
727  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(BtOpc)).addMBB(target);
728  MI.eraseFromParent(); // The pseudo instruction is gone now.
729  return BB;
730 }
731 
732 MachineBasicBlock *Mips16TargetLowering::emitFEXT_T8I8I16_ins(
733  unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, bool ImmSigned,
734  MachineInstr &MI, MachineBasicBlock *BB) const {
736  return BB;
737  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
738  unsigned regX = MI.getOperand(0).getReg();
739  int64_t imm = MI.getOperand(1).getImm();
740  MachineBasicBlock *target = MI.getOperand(2).getMBB();
741  unsigned CmpOpc;
742  if (isUInt<8>(imm))
743  CmpOpc = CmpiOpc;
744  else if ((!ImmSigned && isUInt<16>(imm)) ||
745  (ImmSigned && isInt<16>(imm)))
746  CmpOpc = CmpiXOpc;
747  else
748  llvm_unreachable("immediate field not usable");
749  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(CmpOpc)).addReg(regX).addImm(imm);
750  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(BtOpc)).addMBB(target);
751  MI.eraseFromParent(); // The pseudo instruction is gone now.
752  return BB;
753 }
754 
755 static unsigned Mips16WhichOp8uOr16simm
756  (unsigned shortOp, unsigned longOp, int64_t Imm) {
757  if (isUInt<8>(Imm))
758  return shortOp;
759  else if (isInt<16>(Imm))
760  return longOp;
761  else
762  llvm_unreachable("immediate field not usable");
763 }
764 
766 Mips16TargetLowering::emitFEXT_CCRX16_ins(unsigned SltOpc, MachineInstr &MI,
767  MachineBasicBlock *BB) const {
769  return BB;
770  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
771  unsigned CC = MI.getOperand(0).getReg();
772  unsigned regX = MI.getOperand(1).getReg();
773  unsigned regY = MI.getOperand(2).getReg();
774  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SltOpc))
775  .addReg(regX)
776  .addReg(regY);
777  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(Mips::MoveR3216), CC)
778  .addReg(Mips::T8);
779  MI.eraseFromParent(); // The pseudo instruction is gone now.
780  return BB;
781 }
782 
784 Mips16TargetLowering::emitFEXT_CCRXI16_ins(unsigned SltiOpc, unsigned SltiXOpc,
785  MachineInstr &MI,
786  MachineBasicBlock *BB) const {
788  return BB;
789  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
790  unsigned CC = MI.getOperand(0).getReg();
791  unsigned regX = MI.getOperand(1).getReg();
792  int64_t Imm = MI.getOperand(2).getImm();
793  unsigned SltOpc = Mips16WhichOp8uOr16simm(SltiOpc, SltiXOpc, Imm);
794  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SltOpc)).addReg(regX).addImm(Imm);
795  BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(Mips::MoveR3216), CC)
796  .addReg(Mips::T8);
797  MI.eraseFromParent(); // The pseudo instruction is gone now.
798  return BB;
799 
800 }
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:241
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)
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
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition: Type.h:148
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:233
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:271
A debug info location.
Definition: DebugLoc.h:34
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with strcmp
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:690
SDValue getExternalSymbol(const char *Sym, EVT VT)
MachinePointerInfo callPtrInfo(const char *ES)
Create a MachinePointerInfo that has an ExternalSymbolPseudoSourceValue object representing a GOT ent...
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
static F t[256]
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:327
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:32
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:719
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
Add a new immediate operand.
static char const * dcMips16Helper[MAX_STUB_NUMBER+1]
#define F(x, y, z)
Definition: MD5.cpp:51
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
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:328
const BasicBlock * getBasicBlock() const
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:273
TargetInstrInfo - Interface to description of machine instruction set.
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)
Definition: CommandLine.h:395
FuncSignature const * findFuncSignature(const char *name)
constexpr bool isUInt< 8 >(uint64_t x)
Definition: MathExtras.h:309
LLVM Basic Block Representation.
Definition: BasicBlock.h:51
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
This method is used to implement the type iterator (defined at the end of the file).
Definition: Type.h:316
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:279
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition: Type.h:145
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
self_iterator getIterator()
Definition: ilist_node.h:81
bool useSoftFloat() const
unsigned getNumContainedTypes() const
Return the number of types in the derived type.
Definition: Type.h:322
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo...
Definition: ISDOpcodes.h:705
EVT - Extended Value Type.
Definition: ValueTypes.h:31
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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[]
MO_GOT - Represents the offset into the global offset table at which the address the relocation entry...
Definition: MipsBaseInfo.h:38
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...
Definition: SelectionDAG.h:166
SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:649
const DataFlowGraph & G
Definition: RDFGraph.cpp:206
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:347
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:250
bool isStructTy() const
True if this is an instance of StructType.
Definition: Type.h:207
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:52
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 '...
std::map< const char *, const llvm::Mips16HardFloatInfo::FuncSignature * > StubsNeeded
#define I(x, y, z)
Definition: MD5.cpp:54
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...
constexpr bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:312
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:326
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...
IRTranslator LLVM IR MI
#define MAX_STUB_NUMBER
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:1722
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
Add a new virtual register operand.
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:42
#define T1