LLVM 22.0.0git
Mips16ISelLowering.cpp
Go to the documentation of this file.
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"
14#include "Mips16HardFloatInfo.h"
15#include "MipsMachineFunction.h"
16#include "MipsRegisterInfo.h"
17#include "MipsTargetMachine.h"
21
22using namespace llvm;
23
24#define DEBUG_TYPE "mips-lower"
25
27 "mips16-dont-expand-cond-pseudo",
28 cl::init(false),
29 cl::desc("Don't expand conditional move related "
30 "pseudos for Mips 16"),
32
33namespace {
34struct Mips16IntrinsicHelperType{
35 const char* Name;
36 const char* Helper;
37
38 bool operator<(const Mips16IntrinsicHelperType &RHS) const {
39 return std::strcmp(Name, RHS.Name) < 0;
40 }
41 bool operator==(const Mips16IntrinsicHelperType &RHS) const {
42 return std::strcmp(Name, RHS.Name) == 0;
43 }
44};
45} // namespace
46
47// Libcalls for which no helper is generated. Sorted by name for binary search.
48static const RTLIB::LibcallImpl HardFloatLibCalls[] = {
49 RTLIB::impl___mips16_adddf3, RTLIB::impl___mips16_addsf3,
50 RTLIB::impl___mips16_divdf3, RTLIB::impl___mips16_divsf3,
51 RTLIB::impl___mips16_eqdf2, RTLIB::impl___mips16_eqsf2,
52 RTLIB::impl___mips16_extendsfdf2, RTLIB::impl___mips16_fix_truncdfsi,
53 RTLIB::impl___mips16_fix_truncsfsi, RTLIB::impl___mips16_floatsidf,
54 RTLIB::impl___mips16_floatsisf, RTLIB::impl___mips16_floatunsidf,
55 RTLIB::impl___mips16_floatunsisf, RTLIB::impl___mips16_gedf2,
56 RTLIB::impl___mips16_gesf2, RTLIB::impl___mips16_gtdf2,
57 RTLIB::impl___mips16_gtsf2, RTLIB::impl___mips16_ledf2,
58 RTLIB::impl___mips16_lesf2, RTLIB::impl___mips16_ltdf2,
59 RTLIB::impl___mips16_ltsf2, RTLIB::impl___mips16_muldf3,
60 RTLIB::impl___mips16_mulsf3, RTLIB::impl___mips16_nedf2,
61 RTLIB::impl___mips16_nesf2, RTLIB::impl___mips16_ret_dc,
62 RTLIB::impl___mips16_ret_df, RTLIB::impl___mips16_ret_sc,
63 RTLIB::impl___mips16_ret_sf, RTLIB::impl___mips16_subdf3,
64 RTLIB::impl___mips16_subsf3, RTLIB::impl___mips16_truncdfsf2,
65 RTLIB::impl___mips16_unorddf2, RTLIB::impl___mips16_unordsf2};
66
67static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = {
68 {"__fixunsdfsi", "__mips16_call_stub_2" },
69 {"ceil", "__mips16_call_stub_df_2"},
70 {"ceilf", "__mips16_call_stub_sf_1"},
71 {"copysign", "__mips16_call_stub_df_10"},
72 {"copysignf", "__mips16_call_stub_sf_5"},
73 {"cos", "__mips16_call_stub_df_2"},
74 {"cosf", "__mips16_call_stub_sf_1"},
75 {"exp2", "__mips16_call_stub_df_2"},
76 {"exp2f", "__mips16_call_stub_sf_1"},
77 {"floor", "__mips16_call_stub_df_2"},
78 {"floorf", "__mips16_call_stub_sf_1"},
79 {"log2", "__mips16_call_stub_df_2"},
80 {"log2f", "__mips16_call_stub_sf_1"},
81 {"nearbyint", "__mips16_call_stub_df_2"},
82 {"nearbyintf", "__mips16_call_stub_sf_1"},
83 {"rint", "__mips16_call_stub_df_2"},
84 {"rintf", "__mips16_call_stub_sf_1"},
85 {"sin", "__mips16_call_stub_df_2"},
86 {"sinf", "__mips16_call_stub_sf_1"},
87 {"sqrt", "__mips16_call_stub_df_2"},
88 {"sqrtf", "__mips16_call_stub_sf_1"},
89 {"trunc", "__mips16_call_stub_df_2"},
90 {"truncf", "__mips16_call_stub_sf_1"},
91};
92
94 const MipsSubtarget &STI)
95 : MipsTargetLowering(TM, STI) {
96
97 // Set up the register classes
98 addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);
99
100 if (!Subtarget.useSoftFloat())
101 setMips16HardFloatLibCalls();
102
103 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, LibCall);
104 setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, LibCall);
105 setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, LibCall);
106 setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i32, LibCall);
107 setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i32, LibCall);
108 setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i32, LibCall);
109 setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i32, LibCall);
110 setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i32, LibCall);
111 setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i32, LibCall);
112 setOperationAction(ISD::ATOMIC_LOAD_MIN, MVT::i32, LibCall);
113 setOperationAction(ISD::ATOMIC_LOAD_MAX, MVT::i32, LibCall);
114 setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i32, LibCall);
115 setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i32, LibCall);
116
121
123}
124
125const MipsTargetLowering *
127 const MipsSubtarget &STI) {
128 return new Mips16TargetLowering(TM, STI);
129}
130
132 EVT VT, unsigned, Align, MachineMemOperand::Flags, unsigned *Fast) const {
133 return false;
134}
135
138 MachineBasicBlock *BB) const {
139 switch (MI.getOpcode()) {
140 default:
142 case Mips::SelBeqZ:
143 return emitSel16(Mips::BeqzRxImm16, MI, BB);
144 case Mips::SelBneZ:
145 return emitSel16(Mips::BnezRxImm16, MI, BB);
146 case Mips::SelTBteqZCmpi:
147 return emitSeliT16(Mips::Bteqz16, Mips::CmpiRxImmX16, MI, BB);
148 case Mips::SelTBteqZSlti:
149 return emitSeliT16(Mips::Bteqz16, Mips::SltiRxImmX16, MI, BB);
150 case Mips::SelTBteqZSltiu:
151 return emitSeliT16(Mips::Bteqz16, Mips::SltiuRxImmX16, MI, BB);
152 case Mips::SelTBtneZCmpi:
153 return emitSeliT16(Mips::Btnez16, Mips::CmpiRxImmX16, MI, BB);
154 case Mips::SelTBtneZSlti:
155 return emitSeliT16(Mips::Btnez16, Mips::SltiRxImmX16, MI, BB);
156 case Mips::SelTBtneZSltiu:
157 return emitSeliT16(Mips::Btnez16, Mips::SltiuRxImmX16, MI, BB);
158 case Mips::SelTBteqZCmp:
159 return emitSelT16(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
160 case Mips::SelTBteqZSlt:
161 return emitSelT16(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
162 case Mips::SelTBteqZSltu:
163 return emitSelT16(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
164 case Mips::SelTBtneZCmp:
165 return emitSelT16(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
166 case Mips::SelTBtneZSlt:
167 return emitSelT16(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
168 case Mips::SelTBtneZSltu:
169 return emitSelT16(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
170 case Mips::BteqzT8CmpX16:
171 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::CmpRxRy16, MI, BB);
172 case Mips::BteqzT8SltX16:
173 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltRxRy16, MI, BB);
174 case Mips::BteqzT8SltuX16:
175 // TBD: figure out a way to get this or remove the instruction
176 // altogether.
177 return emitFEXT_T8I816_ins(Mips::Bteqz16, Mips::SltuRxRy16, MI, BB);
178 case Mips::BtnezT8CmpX16:
179 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::CmpRxRy16, MI, BB);
180 case Mips::BtnezT8SltX16:
181 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltRxRy16, MI, BB);
182 case Mips::BtnezT8SltuX16:
183 // TBD: figure out a way to get this or remove the instruction
184 // altogether.
185 return emitFEXT_T8I816_ins(Mips::Btnez16, Mips::SltuRxRy16, MI, BB);
186 case Mips::BteqzT8CmpiX16: return emitFEXT_T8I8I16_ins(
187 Mips::Bteqz16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);
188 case Mips::BteqzT8SltiX16: return emitFEXT_T8I8I16_ins(
189 Mips::Bteqz16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);
190 case Mips::BteqzT8SltiuX16: return emitFEXT_T8I8I16_ins(
191 Mips::Bteqz16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);
192 case Mips::BtnezT8CmpiX16: return emitFEXT_T8I8I16_ins(
193 Mips::Btnez16, Mips::CmpiRxImm16, Mips::CmpiRxImmX16, false, MI, BB);
194 case Mips::BtnezT8SltiX16: return emitFEXT_T8I8I16_ins(
195 Mips::Btnez16, Mips::SltiRxImm16, Mips::SltiRxImmX16, true, MI, BB);
196 case Mips::BtnezT8SltiuX16: return emitFEXT_T8I8I16_ins(
197 Mips::Btnez16, Mips::SltiuRxImm16, Mips::SltiuRxImmX16, false, MI, BB);
198 break;
199 case Mips::SltCCRxRy16:
200 return emitFEXT_CCRX16_ins(Mips::SltRxRy16, MI, BB);
201 break;
202 case Mips::SltiCCRxImmX16:
203 return emitFEXT_CCRXI16_ins
204 (Mips::SltiRxImm16, Mips::SltiRxImmX16, MI, BB);
205 case Mips::SltiuCCRxImmX16:
206 return emitFEXT_CCRXI16_ins
207 (Mips::SltiuRxImm16, Mips::SltiuRxImmX16, MI, BB);
208 case Mips::SltuCCRxRy16:
209 return emitFEXT_CCRX16_ins
210 (Mips::SltuRxRy16, MI, BB);
211 }
212}
213
214bool Mips16TargetLowering::isEligibleForTailCallOptimization(
215 const CCState &CCInfo, unsigned NextStackOffset,
216 const MipsFunctionInfo &FI) const {
217 // No tail call optimization for mips16.
218 return false;
219}
220
221void Mips16TargetLowering::setMips16HardFloatLibCalls() {
222 for (unsigned I = 0; I != std::size(HardFloatLibCalls); ++I) {
223 assert((I == 0 || HardFloatLibCalls[I - 1] < HardFloatLibCalls[I]) &&
224 "Array not sorted!");
225 RTLIB::Libcall LC =
228 }
229}
230
231//
232// The Mips16 hard float is a crazy quilt inherited from gcc. I have a much
233// cleaner way to do all of this but it will have to wait until the traditional
234// gcc mechanism is completed.
235//
236// For Pic, in order for Mips16 code to call Mips32 code which according the abi
237// have either arguments or returned values placed in floating point registers,
238// we use a set of helper functions. (This includes functions which return type
239// complex which on Mips are returned in a pair of floating point registers).
240//
241// This is an encoding that we inherited from gcc.
242// In Mips traditional O32, N32 ABI, floating point numbers are passed in
243// floating point argument registers 1,2 only when the first and optionally
244// the second arguments are float (sf) or double (df).
245// For Mips16 we are only concerned with the situations where floating point
246// arguments are being passed in floating point registers by the ABI, because
247// Mips16 mode code cannot execute floating point instructions to load those
248// values and hence helper functions are needed.
249// The possibilities are (), (sf), (sf, sf), (sf, df), (df), (df, sf), (df, df)
250// the helper function suffixs for these are:
251// 0, 1, 5, 9, 2, 6, 10
252// this suffix can then be calculated as follows:
253// for a given argument Arg:
254// Arg1x, Arg2x = 1 : Arg is sf
255// 2 : Arg is df
256// 0: Arg is neither sf or df
257// So this stub is the string for number Arg1x + Arg2x*4.
258// However not all numbers between 0 and 10 are possible, we check anyway and
259// assert if the impossible exists.
260//
261
262unsigned int Mips16TargetLowering::getMips16HelperFunctionStubNumber
263 (ArgListTy &Args) const {
264 unsigned int resultNum = 0;
265 if (Args.size() >= 1) {
266 Type *t = Args[0].Ty;
267 if (t->isFloatTy()) {
268 resultNum = 1;
269 }
270 else if (t->isDoubleTy()) {
271 resultNum = 2;
272 }
273 }
274 if (resultNum) {
275 if (Args.size() >=2) {
276 Type *t = Args[1].Ty;
277 if (t->isFloatTy()) {
278 resultNum += 4;
279 }
280 else if (t->isDoubleTy()) {
281 resultNum += 8;
282 }
283 }
284 }
285 return resultNum;
286}
287
288//
289// Prefixes are attached to stub numbers depending on the return type.
290// return type: float sf_
291// double df_
292// single complex sc_
293// double complext dc_
294// others NO PREFIX
295//
296//
297// The full name of a helper function is__mips16_call_stub +
298// return type dependent prefix + stub number
299//
300// FIXME: This is something that probably should be in a different source file
301// and perhaps done differently but my main purpose is to not waste runtime
302// on something that we can enumerate in the source. Another possibility is
303// to have a python script to generate these mapping tables. This will do
304// for now. There are a whole series of helper function mapping arrays, one
305// for each return type class as outlined above. There there are 11 possible
306// entries. Ones with 0 are ones which should never be selected.
307//
308// All the arrays are similar except for ones which return neither
309// sf, df, sc, dc, in which we only care about ones which have sf or df as a
310// first parameter.
311//
312#define P_ "__mips16_call_stub_"
313#define MAX_STUB_NUMBER 10
314#define T1 P "1", P "2", 0, 0, P "5", P "6", 0, 0, P "9", P "10"
315#define T P "0" , T1
316#define P P_
317static char const * vMips16Helper[MAX_STUB_NUMBER+1] =
318 {nullptr, T1 };
319#undef P
320#define P P_ "sf_"
321static char const * sfMips16Helper[MAX_STUB_NUMBER+1] =
322 { T };
323#undef P
324#define P P_ "df_"
325static char const * dfMips16Helper[MAX_STUB_NUMBER+1] =
326 { T };
327#undef P
328#define P P_ "sc_"
329static char const * scMips16Helper[MAX_STUB_NUMBER+1] =
330 { T };
331#undef P
332#define P P_ "dc_"
333static char const * dcMips16Helper[MAX_STUB_NUMBER+1] =
334 { T };
335#undef P
336#undef P_
337
338
339const char* Mips16TargetLowering::
340 getMips16HelperFunction
341 (Type* RetTy, ArgListTy &Args, bool &needHelper) const {
342 const unsigned int stubNum = getMips16HelperFunctionStubNumber(Args);
343#ifndef NDEBUG
344 const unsigned int maxStubNum = 10;
345 assert(stubNum <= maxStubNum);
346 const bool validStubNum[maxStubNum+1] =
347 {true, true, true, false, false, true, true, false, false, true, true};
348 assert(validStubNum[stubNum]);
349#endif
350 const char *result;
351 if (RetTy->isFloatTy()) {
352 result = sfMips16Helper[stubNum];
353 }
354 else if (RetTy ->isDoubleTy()) {
355 result = dfMips16Helper[stubNum];
356 } else if (StructType *SRetTy = dyn_cast<StructType>(RetTy)) {
357 // check if it's complex
358 if (SRetTy->getNumElements() == 2) {
359 if ((SRetTy->getElementType(0)->isFloatTy()) &&
360 (SRetTy->getElementType(1)->isFloatTy())) {
361 result = scMips16Helper[stubNum];
362 } else if ((SRetTy->getElementType(0)->isDoubleTy()) &&
363 (SRetTy->getElementType(1)->isDoubleTy())) {
364 result = dcMips16Helper[stubNum];
365 } else {
366 llvm_unreachable("Uncovered condition");
367 }
368 } else {
369 llvm_unreachable("Uncovered condition");
370 }
371 } else {
372 if (stubNum == 0) {
373 needHelper = false;
374 return "";
375 }
376 result = vMips16Helper[stubNum];
377 }
378 needHelper = true;
379 return result;
380}
381
383 // FIXME: Use getSupportedLibcallImpl instead of blindly parsing the name.
384 iota_range<RTLIB::LibcallImpl> ParsedLibcalls =
386 return !ParsedLibcalls.empty() &&
387 binary_search(HardFloatLibCalls, *ParsedLibcalls.begin());
388}
389
390void Mips16TargetLowering::
391getOpndList(SmallVectorImpl<SDValue> &Ops,
392 std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
393 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
394 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,
395 SDValue Chain) const {
396 SelectionDAG &DAG = CLI.DAG;
397 MachineFunction &MF = DAG.getMachineFunction();
398 MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
399 const char* Mips16HelperFunction = nullptr;
400 bool NeedMips16Helper = false;
401
402 if (Subtarget.inMips16HardFloat()) {
403 //
404 // currently we don't have symbols tagged with the mips16 or mips32
405 // qualifier so we will assume that we don't know what kind it is.
406 // and generate the helper
407 //
408 bool LookupHelper = true;
409 if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {
410 if (isMips16HardFloatLibcall(S->getSymbol()))
411 LookupHelper = false;
412 else {
413 const char *Symbol = S->getSymbol();
414 Mips16IntrinsicHelperType IntrinsicFind = { Symbol, "" };
415 const Mips16HardFloatInfo::FuncSignature *Signature =
417 if (!IsPICCall && Signature &&
418 FuncInfo->StubsNeeded.try_emplace(Symbol, Signature).second) {
419 //
420 // S2 is normally saved if the stub is for a function which
421 // returns a float or double value and is not otherwise. This is
422 // because more work is required after the function the stub
423 // is calling completes, and so the stub cannot directly return
424 // and the stub has no stack space to store the return address so
425 // S2 is used for that purpose.
426 // In order to take advantage of not saving S2, we need to also
427 // optimize the call in the stub and this requires some further
428 // functionality in MipsAsmPrinter which we don't have yet.
429 // So for now we always save S2. The optimization will be done
430 // in a follow-on patch.
431 //
432 if (true || (Signature->RetSig != Mips16HardFloatInfo::NoFPRet))
433 FuncInfo->setSaveS2();
434 }
435 // one more look at list of intrinsics
436 const Mips16IntrinsicHelperType *Helper =
438 if (Helper != std::end(Mips16IntrinsicHelper) &&
439 *Helper == IntrinsicFind) {
440 Mips16HelperFunction = Helper->Helper;
441 NeedMips16Helper = true;
442 LookupHelper = false;
443 }
444
445 }
446 } else if (GlobalAddressSDNode *G =
447 dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
448
449 if (isMips16HardFloatLibcall(G->getGlobal()->getName()))
450 LookupHelper = false;
451 }
452 if (LookupHelper)
453 Mips16HelperFunction =
454 getMips16HelperFunction(CLI.RetTy, CLI.getArgs(), NeedMips16Helper);
455 }
456
457 SDValue JumpTarget = Callee;
458
459 // T9 should contain the address of the callee function if
460 // -relocation-model=pic or it is an indirect call.
461 if (IsPICCall || !GlobalOrExternal) {
462 unsigned V0Reg = Mips::V0;
463 if (NeedMips16Helper) {
464 RegsToPass.push_front(std::make_pair(V0Reg, Callee));
465 JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction,
467 ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget);
468 JumpTarget = getAddrGlobal(S, CLI.DL, JumpTarget.getValueType(), DAG,
469 MipsII::MO_GOT, Chain,
470 FuncInfo->callPtrInfo(MF, S->getSymbol()));
471 } else
472 RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));
473 }
474
475 Ops.push_back(JumpTarget);
476
477 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
478 InternalLinkage, IsCallReloc, CLI, Callee,
479 Chain);
480}
481
483Mips16TargetLowering::emitSel16(unsigned Opc, MachineInstr &MI,
484 MachineBasicBlock *BB) const {
486 return BB;
487 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
488 DebugLoc DL = MI.getDebugLoc();
489 // To "insert" a SELECT_CC instruction, we actually have to insert the
490 // diamond control-flow pattern. The incoming instruction knows the
491 // destination vreg to set, the condition code register to branch on, the
492 // true/false values to select between, and a branch opcode to use.
493 const BasicBlock *LLVM_BB = BB->getBasicBlock();
495
496 // thisMBB:
497 // ...
498 // TrueVal = ...
499 // setcc r1, r2, r3
500 // bNE r1, r0, copy1MBB
501 // fallthrough --> copy0MBB
502 MachineBasicBlock *thisMBB = BB;
503 MachineFunction *F = BB->getParent();
504 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
505 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
506 F->insert(It, copy0MBB);
507 F->insert(It, sinkMBB);
508
509 // Transfer the remainder of BB and its successor edges to sinkMBB.
510 sinkMBB->splice(sinkMBB->begin(), BB,
511 std::next(MachineBasicBlock::iterator(MI)), BB->end());
513
514 // Next, add the true and fallthrough blocks as its successors.
515 BB->addSuccessor(copy0MBB);
516 BB->addSuccessor(sinkMBB);
517
518 BuildMI(BB, DL, TII->get(Opc))
519 .addReg(MI.getOperand(3).getReg())
520 .addMBB(sinkMBB);
521
522 // copy0MBB:
523 // %FalseValue = ...
524 // # fallthrough to sinkMBB
525 BB = copy0MBB;
526
527 // Update machine-CFG edges
528 BB->addSuccessor(sinkMBB);
529
530 // sinkMBB:
531 // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
532 // ...
533 BB = sinkMBB;
534
535 BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
536 .addReg(MI.getOperand(1).getReg())
537 .addMBB(thisMBB)
538 .addReg(MI.getOperand(2).getReg())
539 .addMBB(copy0MBB);
540
541 MI.eraseFromParent(); // The pseudo instruction is gone now.
542 return BB;
543}
544
546Mips16TargetLowering::emitSelT16(unsigned Opc1, unsigned Opc2, MachineInstr &MI,
547 MachineBasicBlock *BB) const {
549 return BB;
550 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
551 DebugLoc DL = MI.getDebugLoc();
552 // To "insert" a SELECT_CC instruction, we actually have to insert the
553 // diamond control-flow pattern. The incoming instruction knows the
554 // destination vreg to set, the condition code register to branch on, the
555 // true/false values to select between, and a branch opcode to use.
556 const BasicBlock *LLVM_BB = BB->getBasicBlock();
558
559 // thisMBB:
560 // ...
561 // TrueVal = ...
562 // setcc r1, r2, r3
563 // bNE r1, r0, copy1MBB
564 // fallthrough --> copy0MBB
565 MachineBasicBlock *thisMBB = BB;
566 MachineFunction *F = BB->getParent();
567 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
568 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
569 F->insert(It, copy0MBB);
570 F->insert(It, sinkMBB);
571
572 // Transfer the remainder of BB and its successor edges to sinkMBB.
573 sinkMBB->splice(sinkMBB->begin(), BB,
574 std::next(MachineBasicBlock::iterator(MI)), BB->end());
576
577 // Next, add the true and fallthrough blocks as its successors.
578 BB->addSuccessor(copy0MBB);
579 BB->addSuccessor(sinkMBB);
580
581 BuildMI(BB, DL, TII->get(Opc2))
582 .addReg(MI.getOperand(3).getReg())
583 .addReg(MI.getOperand(4).getReg());
584 BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
585
586 // copy0MBB:
587 // %FalseValue = ...
588 // # fallthrough to sinkMBB
589 BB = copy0MBB;
590
591 // Update machine-CFG edges
592 BB->addSuccessor(sinkMBB);
593
594 // sinkMBB:
595 // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
596 // ...
597 BB = sinkMBB;
598
599 BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
600 .addReg(MI.getOperand(1).getReg())
601 .addMBB(thisMBB)
602 .addReg(MI.getOperand(2).getReg())
603 .addMBB(copy0MBB);
604
605 MI.eraseFromParent(); // The pseudo instruction is gone now.
606 return BB;
607
608}
609
611Mips16TargetLowering::emitSeliT16(unsigned Opc1, unsigned Opc2,
613 MachineBasicBlock *BB) const {
615 return BB;
616 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
617 DebugLoc DL = MI.getDebugLoc();
618 // To "insert" a SELECT_CC instruction, we actually have to insert the
619 // diamond control-flow pattern. The incoming instruction knows the
620 // destination vreg to set, the condition code register to branch on, the
621 // true/false values to select between, and a branch opcode to use.
622 const BasicBlock *LLVM_BB = BB->getBasicBlock();
624
625 // thisMBB:
626 // ...
627 // TrueVal = ...
628 // setcc r1, r2, r3
629 // bNE r1, r0, copy1MBB
630 // fallthrough --> copy0MBB
631 MachineBasicBlock *thisMBB = BB;
632 MachineFunction *F = BB->getParent();
633 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
634 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
635 F->insert(It, copy0MBB);
636 F->insert(It, sinkMBB);
637
638 // Transfer the remainder of BB and its successor edges to sinkMBB.
639 sinkMBB->splice(sinkMBB->begin(), BB,
640 std::next(MachineBasicBlock::iterator(MI)), BB->end());
642
643 // Next, add the true and fallthrough blocks as its successors.
644 BB->addSuccessor(copy0MBB);
645 BB->addSuccessor(sinkMBB);
646
647 BuildMI(BB, DL, TII->get(Opc2))
648 .addReg(MI.getOperand(3).getReg())
649 .addImm(MI.getOperand(4).getImm());
650 BuildMI(BB, DL, TII->get(Opc1)).addMBB(sinkMBB);
651
652 // copy0MBB:
653 // %FalseValue = ...
654 // # fallthrough to sinkMBB
655 BB = copy0MBB;
656
657 // Update machine-CFG edges
658 BB->addSuccessor(sinkMBB);
659
660 // sinkMBB:
661 // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]
662 // ...
663 BB = sinkMBB;
664
665 BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())
666 .addReg(MI.getOperand(1).getReg())
667 .addMBB(thisMBB)
668 .addReg(MI.getOperand(2).getReg())
669 .addMBB(copy0MBB);
670
671 MI.eraseFromParent(); // The pseudo instruction is gone now.
672 return BB;
673
674}
675
677Mips16TargetLowering::emitFEXT_T8I816_ins(unsigned BtOpc, unsigned CmpOpc,
679 MachineBasicBlock *BB) const {
681 return BB;
682 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
683 Register regX = MI.getOperand(0).getReg();
684 Register regY = MI.getOperand(1).getReg();
685 MachineBasicBlock *target = MI.getOperand(2).getMBB();
686 BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(CmpOpc))
687 .addReg(regX)
688 .addReg(regY);
689 BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(BtOpc)).addMBB(target);
690 MI.eraseFromParent(); // The pseudo instruction is gone now.
691 return BB;
692}
693
694MachineBasicBlock *Mips16TargetLowering::emitFEXT_T8I8I16_ins(
695 unsigned BtOpc, unsigned CmpiOpc, unsigned CmpiXOpc, bool ImmSigned,
696 MachineInstr &MI, MachineBasicBlock *BB) const {
698 return BB;
699 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
700 Register regX = MI.getOperand(0).getReg();
701 int64_t imm = MI.getOperand(1).getImm();
702 MachineBasicBlock *target = MI.getOperand(2).getMBB();
703 unsigned CmpOpc;
704 if (isUInt<8>(imm))
705 CmpOpc = CmpiOpc;
706 else if ((!ImmSigned && isUInt<16>(imm)) ||
707 (ImmSigned && isInt<16>(imm)))
708 CmpOpc = CmpiXOpc;
709 else
710 llvm_unreachable("immediate field not usable");
711 BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(CmpOpc)).addReg(regX).addImm(imm);
712 BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(BtOpc)).addMBB(target);
713 MI.eraseFromParent(); // The pseudo instruction is gone now.
714 return BB;
715}
716
718 (unsigned shortOp, unsigned longOp, int64_t Imm) {
719 if (isUInt<8>(Imm))
720 return shortOp;
721 else if (isInt<16>(Imm))
722 return longOp;
723 else
724 llvm_unreachable("immediate field not usable");
725}
726
728Mips16TargetLowering::emitFEXT_CCRX16_ins(unsigned SltOpc, MachineInstr &MI,
729 MachineBasicBlock *BB) const {
731 return BB;
732 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
733 Register CC = MI.getOperand(0).getReg();
734 Register regX = MI.getOperand(1).getReg();
735 Register regY = MI.getOperand(2).getReg();
736 BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SltOpc))
737 .addReg(regX)
738 .addReg(regY);
739 BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(Mips::MoveR3216), CC)
740 .addReg(Mips::T8);
741 MI.eraseFromParent(); // The pseudo instruction is gone now.
742 return BB;
743}
744
746Mips16TargetLowering::emitFEXT_CCRXI16_ins(unsigned SltiOpc, unsigned SltiXOpc,
748 MachineBasicBlock *BB) const {
750 return BB;
751 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
752 Register CC = MI.getOperand(0).getReg();
753 Register regX = MI.getOperand(1).getReg();
754 int64_t Imm = MI.getOperand(2).getImm();
755 unsigned SltOpc = Mips16WhichOp8uOr16simm(SltiOpc, SltiXOpc, Imm);
756 BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(SltOpc)).addReg(regX).addImm(Imm);
757 BuildMI(*BB, MI, MI.getDebugLoc(), TII->get(Mips::MoveR3216), CC)
758 .addReg(Mips::T8);
759 MI.eraseFromParent(); // The pseudo instruction is gone now.
760 return BB;
761
762}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Promote Memory to Register
Definition Mem2Reg.cpp:110
static char const * vMips16Helper[MAX_STUB_NUMBER+1]
#define T
static char const * dcMips16Helper[MAX_STUB_NUMBER+1]
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)
static char const * dfMips16Helper[MAX_STUB_NUMBER+1]
static const RTLIB::LibcallImpl HardFloatLibCalls[]
static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[]
#define MAX_STUB_NUMBER
static char const * sfMips16Helper[MAX_STUB_NUMBER+1]
#define T1
static unsigned Mips16WhichOp8uOr16simm(unsigned shortOp, unsigned longOp, int64_t Imm)
static char const * scMips16Helper[MAX_STUB_NUMBER+1]
static bool isMips16HardFloatLibcall(StringRef Name)
Value * RHS
CCState - This class holds information needed while lowering arguments and return values.
const char * getSymbol() const
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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 '...
MachineInstrBundleIterator< MachineInstr > iterator
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
Flags
Flags values. These may be or'd together.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
Mips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...
MachinePointerInfo callPtrInfo(MachineFunction &MF, const char *ES)
Create a MachinePointerInfo that has an ExternalSymbolPseudoSourceValue object representing a GOT ent...
std::map< const char *, const Mips16HardFloatInfo::FuncSignature * > StubsNeeded
const MipsRegisterInfo * getRegisterInfo() const override
SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const
MipsTargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
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...
const MipsSubtarget & Subtarget
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
EVT getValueType() const
Return the ValueType of the referenced return value.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
MachineFunction & getMachineFunction() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual 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...
void setLibcallImpl(RTLIB::Libcall Call, RTLIB::LibcallImpl Impl)
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
Definition Type.h:153
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
Definition Type.h:156
self_iterator getIterator()
Definition ilist_node.h:123
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:771
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
FuncSignature const * findFuncSignature(const char *name)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:362
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto binary_search(R &&Range, T &&Value)
Provide wrappers to std::binary_search which take ranges instead of having to pass begin/end explicit...
Definition STLExtras.h:1981
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:189
const MipsTargetLowering * createMips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)
Create MipsTargetLowering objects.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:1994
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
static LLVM_ABI iota_range< RTLIB::LibcallImpl > lookupLibcallImplName(StringRef Name)
Check if a function name is a recognized runtime call of any kind.
static RTLIB::Libcall getLibcallFromImpl(RTLIB::LibcallImpl Impl)
Return the libcall provided by Impl.
auto begin() const
Definition Sequence.h:283
bool empty() const
Definition Sequence.h:281