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