Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.cpp
35266 views
1
//===-- CSKYISelLowering.cpp - CSKY DAG Lowering Implementation ----------===//
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
// This file defines the interfaces that CSKY uses to lower LLVM code into a
10
// selection DAG.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "CSKYISelLowering.h"
15
#include "CSKYCallingConv.h"
16
#include "CSKYConstantPoolValue.h"
17
#include "CSKYMachineFunctionInfo.h"
18
#include "CSKYRegisterInfo.h"
19
#include "CSKYSubtarget.h"
20
#include "llvm/ADT/Statistic.h"
21
#include "llvm/CodeGen/CallingConvLower.h"
22
#include "llvm/CodeGen/MachineFrameInfo.h"
23
#include "llvm/CodeGen/MachineJumpTableInfo.h"
24
#include "llvm/Support/Debug.h"
25
26
using namespace llvm;
27
28
#define DEBUG_TYPE "csky-isel-lowering"
29
30
STATISTIC(NumTailCalls, "Number of tail calls");
31
32
#include "CSKYGenCallingConv.inc"
33
34
static const MCPhysReg GPRArgRegs[] = {CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3};
35
36
CSKYTargetLowering::CSKYTargetLowering(const TargetMachine &TM,
37
const CSKYSubtarget &STI)
38
: TargetLowering(TM), Subtarget(STI) {
39
// Register Class
40
addRegisterClass(MVT::i32, &CSKY::GPRRegClass);
41
42
if (STI.useHardFloat()) {
43
if (STI.hasFPUv2SingleFloat())
44
addRegisterClass(MVT::f32, &CSKY::sFPR32RegClass);
45
else if (STI.hasFPUv3SingleFloat())
46
addRegisterClass(MVT::f32, &CSKY::FPR32RegClass);
47
48
if (STI.hasFPUv2DoubleFloat())
49
addRegisterClass(MVT::f64, &CSKY::sFPR64RegClass);
50
else if (STI.hasFPUv3DoubleFloat())
51
addRegisterClass(MVT::f64, &CSKY::FPR64RegClass);
52
}
53
54
setOperationAction(ISD::UADDO_CARRY, MVT::i32, Legal);
55
setOperationAction(ISD::USUBO_CARRY, MVT::i32, Legal);
56
setOperationAction(ISD::BITREVERSE, MVT::i32, Legal);
57
58
setOperationAction(ISD::SREM, MVT::i32, Expand);
59
setOperationAction(ISD::UREM, MVT::i32, Expand);
60
setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
61
setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
62
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
63
setOperationAction(ISD::ROTR, MVT::i32, Expand);
64
setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
65
setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
66
setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
67
setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
68
setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
69
setOperationAction(ISD::SELECT_CC, MVT::i32, Expand);
70
setOperationAction(ISD::BR_CC, MVT::i32, Expand);
71
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
72
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
73
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
74
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
75
setOperationAction(ISD::MULHS, MVT::i32, Expand);
76
setOperationAction(ISD::MULHU, MVT::i32, Expand);
77
setOperationAction(ISD::VAARG, MVT::Other, Expand);
78
setOperationAction(ISD::VACOPY, MVT::Other, Expand);
79
setOperationAction(ISD::VAEND, MVT::Other, Expand);
80
81
setLoadExtAction(ISD::EXTLOAD, MVT::i32, MVT::i1, Promote);
82
setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i1, Promote);
83
setLoadExtAction(ISD::ZEXTLOAD, MVT::i32, MVT::i1, Promote);
84
85
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
86
setOperationAction(ISD::ExternalSymbol, MVT::i32, Custom);
87
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
88
setOperationAction(ISD::BlockAddress, MVT::i32, Custom);
89
if (!Subtarget.hasE2()) {
90
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
91
}
92
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
93
setOperationAction(ISD::VASTART, MVT::Other, Custom);
94
95
if (!Subtarget.hasE2()) {
96
setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i8, Expand);
97
setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i16, Expand);
98
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
99
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
100
}
101
102
if (!Subtarget.has2E3()) {
103
setOperationAction(ISD::ABS, MVT::i32, Expand);
104
setOperationAction(ISD::BITREVERSE, MVT::i32, Expand);
105
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
106
setOperationAction(ISD::SDIV, MVT::i32, Expand);
107
setOperationAction(ISD::UDIV, MVT::i32, Expand);
108
}
109
110
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand);
111
112
// Float
113
114
ISD::CondCode FPCCToExtend[] = {
115
ISD::SETONE, ISD::SETUEQ, ISD::SETUGT,
116
ISD::SETUGE, ISD::SETULT, ISD::SETULE,
117
};
118
119
ISD::NodeType FPOpToExpand[] = {
120
ISD::FSIN, ISD::FCOS, ISD::FSINCOS, ISD::FPOW,
121
ISD::FREM, ISD::FCOPYSIGN, ISD::FP16_TO_FP, ISD::FP_TO_FP16};
122
123
if (STI.useHardFloat()) {
124
125
MVT AllVTy[] = {MVT::f32, MVT::f64};
126
127
for (auto VT : AllVTy) {
128
setOperationAction(ISD::FREM, VT, Expand);
129
setOperationAction(ISD::SELECT_CC, VT, Expand);
130
setOperationAction(ISD::BR_CC, VT, Expand);
131
132
for (auto CC : FPCCToExtend)
133
setCondCodeAction(CC, VT, Expand);
134
for (auto Op : FPOpToExpand)
135
setOperationAction(Op, VT, Expand);
136
}
137
138
if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat()) {
139
setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
140
setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
141
setTruncStoreAction(MVT::f32, MVT::f16, Expand);
142
}
143
if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat()) {
144
setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
145
setTruncStoreAction(MVT::f64, MVT::f32, Expand);
146
setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
147
setTruncStoreAction(MVT::f64, MVT::f16, Expand);
148
}
149
}
150
151
// Compute derived properties from the register classes.
152
computeRegisterProperties(STI.getRegisterInfo());
153
154
setBooleanContents(UndefinedBooleanContent);
155
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
156
157
// TODO: Add atomic support fully.
158
setMaxAtomicSizeInBitsSupported(0);
159
160
setStackPointerRegisterToSaveRestore(CSKY::R14);
161
setMinFunctionAlignment(Align(2));
162
setSchedulingPreference(Sched::Source);
163
}
164
165
SDValue CSKYTargetLowering::LowerOperation(SDValue Op,
166
SelectionDAG &DAG) const {
167
switch (Op.getOpcode()) {
168
default:
169
llvm_unreachable("unimplemented op");
170
case ISD::GlobalAddress:
171
return LowerGlobalAddress(Op, DAG);
172
case ISD::ExternalSymbol:
173
return LowerExternalSymbol(Op, DAG);
174
case ISD::GlobalTLSAddress:
175
return LowerGlobalTLSAddress(Op, DAG);
176
case ISD::JumpTable:
177
return LowerJumpTable(Op, DAG);
178
case ISD::BlockAddress:
179
return LowerBlockAddress(Op, DAG);
180
case ISD::ConstantPool:
181
return LowerConstantPool(Op, DAG);
182
case ISD::VASTART:
183
return LowerVASTART(Op, DAG);
184
case ISD::FRAMEADDR:
185
return LowerFRAMEADDR(Op, DAG);
186
case ISD::RETURNADDR:
187
return LowerRETURNADDR(Op, DAG);
188
}
189
}
190
191
EVT CSKYTargetLowering::getSetCCResultType(const DataLayout &DL,
192
LLVMContext &Context, EVT VT) const {
193
if (!VT.isVector())
194
return MVT::i32;
195
196
return VT.changeVectorElementTypeToInteger();
197
}
198
199
static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val,
200
const CCValAssign &VA, const SDLoc &DL) {
201
EVT LocVT = VA.getLocVT();
202
203
switch (VA.getLocInfo()) {
204
default:
205
llvm_unreachable("Unexpected CCValAssign::LocInfo");
206
case CCValAssign::Full:
207
break;
208
case CCValAssign::BCvt:
209
Val = DAG.getNode(ISD::BITCAST, DL, LocVT, Val);
210
break;
211
}
212
return Val;
213
}
214
215
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,
216
const CCValAssign &VA, const SDLoc &DL) {
217
switch (VA.getLocInfo()) {
218
default:
219
llvm_unreachable("Unexpected CCValAssign::LocInfo");
220
case CCValAssign::Full:
221
break;
222
case CCValAssign::BCvt:
223
Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val);
224
break;
225
}
226
return Val;
227
}
228
229
static SDValue unpackFromRegLoc(const CSKYSubtarget &Subtarget,
230
SelectionDAG &DAG, SDValue Chain,
231
const CCValAssign &VA, const SDLoc &DL) {
232
MachineFunction &MF = DAG.getMachineFunction();
233
MachineRegisterInfo &RegInfo = MF.getRegInfo();
234
EVT LocVT = VA.getLocVT();
235
SDValue Val;
236
const TargetRegisterClass *RC;
237
238
switch (LocVT.getSimpleVT().SimpleTy) {
239
default:
240
llvm_unreachable("Unexpected register type");
241
case MVT::i32:
242
RC = &CSKY::GPRRegClass;
243
break;
244
case MVT::f32:
245
RC = Subtarget.hasFPUv2SingleFloat() ? &CSKY::sFPR32RegClass
246
: &CSKY::FPR32RegClass;
247
break;
248
case MVT::f64:
249
RC = Subtarget.hasFPUv2DoubleFloat() ? &CSKY::sFPR64RegClass
250
: &CSKY::FPR64RegClass;
251
break;
252
}
253
254
Register VReg = RegInfo.createVirtualRegister(RC);
255
RegInfo.addLiveIn(VA.getLocReg(), VReg);
256
Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
257
258
return convertLocVTToValVT(DAG, Val, VA, DL);
259
}
260
261
static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain,
262
const CCValAssign &VA, const SDLoc &DL) {
263
MachineFunction &MF = DAG.getMachineFunction();
264
MachineFrameInfo &MFI = MF.getFrameInfo();
265
EVT LocVT = VA.getLocVT();
266
EVT ValVT = VA.getValVT();
267
EVT PtrVT = MVT::getIntegerVT(DAG.getDataLayout().getPointerSizeInBits(0));
268
int FI = MFI.CreateFixedObject(ValVT.getSizeInBits() / 8,
269
VA.getLocMemOffset(), /*Immutable=*/true);
270
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
271
SDValue Val;
272
273
ISD::LoadExtType ExtType;
274
switch (VA.getLocInfo()) {
275
default:
276
llvm_unreachable("Unexpected CCValAssign::LocInfo");
277
case CCValAssign::Full:
278
case CCValAssign::BCvt:
279
ExtType = ISD::NON_EXTLOAD;
280
break;
281
}
282
Val = DAG.getExtLoad(
283
ExtType, DL, LocVT, Chain, FIN,
284
MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), ValVT);
285
return Val;
286
}
287
288
static SDValue unpack64(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA,
289
const SDLoc &DL) {
290
assert(VA.getLocVT() == MVT::i32 &&
291
(VA.getValVT() == MVT::f64 || VA.getValVT() == MVT::i64) &&
292
"Unexpected VA");
293
MachineFunction &MF = DAG.getMachineFunction();
294
MachineFrameInfo &MFI = MF.getFrameInfo();
295
MachineRegisterInfo &RegInfo = MF.getRegInfo();
296
297
if (VA.isMemLoc()) {
298
// f64/i64 is passed on the stack.
299
int FI = MFI.CreateFixedObject(8, VA.getLocMemOffset(), /*Immutable=*/true);
300
SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
301
return DAG.getLoad(VA.getValVT(), DL, Chain, FIN,
302
MachinePointerInfo::getFixedStack(MF, FI));
303
}
304
305
assert(VA.isRegLoc() && "Expected register VA assignment");
306
307
Register LoVReg = RegInfo.createVirtualRegister(&CSKY::GPRRegClass);
308
RegInfo.addLiveIn(VA.getLocReg(), LoVReg);
309
SDValue Lo = DAG.getCopyFromReg(Chain, DL, LoVReg, MVT::i32);
310
SDValue Hi;
311
if (VA.getLocReg() == CSKY::R3) {
312
// Second half of f64/i64 is passed on the stack.
313
int FI = MFI.CreateFixedObject(4, 0, /*Immutable=*/true);
314
SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
315
Hi = DAG.getLoad(MVT::i32, DL, Chain, FIN,
316
MachinePointerInfo::getFixedStack(MF, FI));
317
} else {
318
// Second half of f64/i64 is passed in another GPR.
319
Register HiVReg = RegInfo.createVirtualRegister(&CSKY::GPRRegClass);
320
RegInfo.addLiveIn(VA.getLocReg() + 1, HiVReg);
321
Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i32);
322
}
323
return DAG.getNode(CSKYISD::BITCAST_FROM_LOHI, DL, VA.getValVT(), Lo, Hi);
324
}
325
326
// Transform physical registers into virtual registers.
327
SDValue CSKYTargetLowering::LowerFormalArguments(
328
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
329
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
330
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
331
332
switch (CallConv) {
333
default:
334
report_fatal_error("Unsupported calling convention");
335
case CallingConv::C:
336
case CallingConv::Fast:
337
break;
338
}
339
340
MachineFunction &MF = DAG.getMachineFunction();
341
342
// Used with vargs to acumulate store chains.
343
std::vector<SDValue> OutChains;
344
345
// Assign locations to all of the incoming arguments.
346
SmallVector<CCValAssign, 16> ArgLocs;
347
CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
348
349
CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));
350
351
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
352
CCValAssign &VA = ArgLocs[i];
353
SDValue ArgValue;
354
355
bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
356
357
if (IsF64OnCSKY)
358
ArgValue = unpack64(DAG, Chain, VA, DL);
359
else if (VA.isRegLoc())
360
ArgValue = unpackFromRegLoc(Subtarget, DAG, Chain, VA, DL);
361
else
362
ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
363
364
InVals.push_back(ArgValue);
365
}
366
367
if (IsVarArg) {
368
const unsigned XLenInBytes = 4;
369
const MVT XLenVT = MVT::i32;
370
371
ArrayRef<MCPhysReg> ArgRegs = ArrayRef(GPRArgRegs);
372
unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
373
const TargetRegisterClass *RC = &CSKY::GPRRegClass;
374
MachineFrameInfo &MFI = MF.getFrameInfo();
375
MachineRegisterInfo &RegInfo = MF.getRegInfo();
376
CSKYMachineFunctionInfo *CSKYFI = MF.getInfo<CSKYMachineFunctionInfo>();
377
378
// Offset of the first variable argument from stack pointer, and size of
379
// the vararg save area. For now, the varargs save area is either zero or
380
// large enough to hold a0-a4.
381
int VaArgOffset, VarArgsSaveSize;
382
383
// If all registers are allocated, then all varargs must be passed on the
384
// stack and we don't need to save any argregs.
385
if (ArgRegs.size() == Idx) {
386
VaArgOffset = CCInfo.getStackSize();
387
VarArgsSaveSize = 0;
388
} else {
389
VarArgsSaveSize = XLenInBytes * (ArgRegs.size() - Idx);
390
VaArgOffset = -VarArgsSaveSize;
391
}
392
393
// Record the frame index of the first variable argument
394
// which is a value necessary to VASTART.
395
int FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
396
CSKYFI->setVarArgsFrameIndex(FI);
397
398
// Copy the integer registers that may have been used for passing varargs
399
// to the vararg save area.
400
for (unsigned I = Idx; I < ArgRegs.size();
401
++I, VaArgOffset += XLenInBytes) {
402
const Register Reg = RegInfo.createVirtualRegister(RC);
403
RegInfo.addLiveIn(ArgRegs[I], Reg);
404
SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, XLenVT);
405
FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
406
SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
407
SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,
408
MachinePointerInfo::getFixedStack(MF, FI));
409
cast<StoreSDNode>(Store.getNode())
410
->getMemOperand()
411
->setValue((Value *)nullptr);
412
OutChains.push_back(Store);
413
}
414
CSKYFI->setVarArgsSaveSize(VarArgsSaveSize);
415
}
416
417
// All stores are grouped in one node to allow the matching between
418
// the size of Ins and InVals. This only happens for vararg functions.
419
if (!OutChains.empty()) {
420
OutChains.push_back(Chain);
421
Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
422
}
423
424
return Chain;
425
}
426
427
bool CSKYTargetLowering::CanLowerReturn(
428
CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
429
const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
430
SmallVector<CCValAssign, 16> CSKYLocs;
431
CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context);
432
return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
433
}
434
435
SDValue
436
CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
437
bool IsVarArg,
438
const SmallVectorImpl<ISD::OutputArg> &Outs,
439
const SmallVectorImpl<SDValue> &OutVals,
440
const SDLoc &DL, SelectionDAG &DAG) const {
441
// Stores the assignment of the return value to a location.
442
SmallVector<CCValAssign, 16> CSKYLocs;
443
444
// Info about the registers and stack slot.
445
CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), CSKYLocs,
446
*DAG.getContext());
447
CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
448
449
SDValue Glue;
450
SmallVector<SDValue, 4> RetOps(1, Chain);
451
452
// Copy the result values into the output registers.
453
for (unsigned i = 0, e = CSKYLocs.size(); i < e; ++i) {
454
SDValue Val = OutVals[i];
455
CCValAssign &VA = CSKYLocs[i];
456
assert(VA.isRegLoc() && "Can only return in registers!");
457
458
bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
459
460
if (IsF64OnCSKY) {
461
462
assert(VA.isRegLoc() && "Expected return via registers");
463
SDValue Split64 = DAG.getNode(CSKYISD::BITCAST_TO_LOHI, DL,
464
DAG.getVTList(MVT::i32, MVT::i32), Val);
465
SDValue Lo = Split64.getValue(0);
466
SDValue Hi = Split64.getValue(1);
467
468
Register RegLo = VA.getLocReg();
469
assert(RegLo < CSKY::R31 && "Invalid register pair");
470
Register RegHi = RegLo + 1;
471
472
Chain = DAG.getCopyToReg(Chain, DL, RegLo, Lo, Glue);
473
Glue = Chain.getValue(1);
474
RetOps.push_back(DAG.getRegister(RegLo, MVT::i32));
475
Chain = DAG.getCopyToReg(Chain, DL, RegHi, Hi, Glue);
476
Glue = Chain.getValue(1);
477
RetOps.push_back(DAG.getRegister(RegHi, MVT::i32));
478
} else {
479
// Handle a 'normal' return.
480
Val = convertValVTToLocVT(DAG, Val, VA, DL);
481
Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue);
482
483
// Guarantee that all emitted copies are stuck together.
484
Glue = Chain.getValue(1);
485
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
486
}
487
}
488
489
RetOps[0] = Chain; // Update chain.
490
491
// Add the glue node if we have it.
492
if (Glue.getNode()) {
493
RetOps.push_back(Glue);
494
}
495
496
// Interrupt service routines use different return instructions.
497
if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt"))
498
return DAG.getNode(CSKYISD::NIR, DL, MVT::Other, RetOps);
499
500
return DAG.getNode(CSKYISD::RET, DL, MVT::Other, RetOps);
501
}
502
503
// Lower a call to a callseq_start + CALL + callseq_end chain, and add input
504
// and output parameter nodes.
505
SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,
506
SmallVectorImpl<SDValue> &InVals) const {
507
SelectionDAG &DAG = CLI.DAG;
508
SDLoc &DL = CLI.DL;
509
SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
510
SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
511
SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
512
SDValue Chain = CLI.Chain;
513
SDValue Callee = CLI.Callee;
514
bool &IsTailCall = CLI.IsTailCall;
515
CallingConv::ID CallConv = CLI.CallConv;
516
bool IsVarArg = CLI.IsVarArg;
517
EVT PtrVT = getPointerTy(DAG.getDataLayout());
518
MVT XLenVT = MVT::i32;
519
520
MachineFunction &MF = DAG.getMachineFunction();
521
522
// Analyze the operands of the call, assigning locations to each operand.
523
SmallVector<CCValAssign, 16> ArgLocs;
524
CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
525
526
ArgCCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, IsVarArg));
527
528
// Check if it's really possible to do a tail call.
529
if (IsTailCall)
530
IsTailCall = false; // TODO: TailCallOptimization;
531
532
if (IsTailCall)
533
++NumTailCalls;
534
else if (CLI.CB && CLI.CB->isMustTailCall())
535
report_fatal_error("failed to perform tail call elimination on a call "
536
"site marked musttail");
537
538
// Get a count of how many bytes are to be pushed on the stack.
539
unsigned NumBytes = ArgCCInfo.getStackSize();
540
541
// Create local copies for byval args
542
SmallVector<SDValue, 8> ByValArgs;
543
for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
544
ISD::ArgFlagsTy Flags = Outs[i].Flags;
545
if (!Flags.isByVal())
546
continue;
547
548
SDValue Arg = OutVals[i];
549
unsigned Size = Flags.getByValSize();
550
Align Alignment = Flags.getNonZeroByValAlign();
551
552
int FI =
553
MF.getFrameInfo().CreateStackObject(Size, Alignment, /*isSS=*/false);
554
SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
555
SDValue SizeNode = DAG.getConstant(Size, DL, XLenVT);
556
557
Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment,
558
/*IsVolatile=*/false,
559
/*AlwaysInline=*/false, /*CI=*/nullptr, IsTailCall,
560
MachinePointerInfo(), MachinePointerInfo());
561
ByValArgs.push_back(FIPtr);
562
}
563
564
if (!IsTailCall)
565
Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
566
567
// Copy argument values to their designated locations.
568
SmallVector<std::pair<Register, SDValue>, 8> RegsToPass;
569
SmallVector<SDValue, 8> MemOpChains;
570
SDValue StackPtr;
571
for (unsigned i = 0, j = 0, e = ArgLocs.size(); i != e; ++i) {
572
CCValAssign &VA = ArgLocs[i];
573
SDValue ArgValue = OutVals[i];
574
ISD::ArgFlagsTy Flags = Outs[i].Flags;
575
576
bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
577
578
if (IsF64OnCSKY && VA.isRegLoc()) {
579
SDValue Split64 =
580
DAG.getNode(CSKYISD::BITCAST_TO_LOHI, DL,
581
DAG.getVTList(MVT::i32, MVT::i32), ArgValue);
582
SDValue Lo = Split64.getValue(0);
583
SDValue Hi = Split64.getValue(1);
584
585
Register RegLo = VA.getLocReg();
586
RegsToPass.push_back(std::make_pair(RegLo, Lo));
587
588
if (RegLo == CSKY::R3) {
589
// Second half of f64/i64 is passed on the stack.
590
// Work out the address of the stack slot.
591
if (!StackPtr.getNode())
592
StackPtr = DAG.getCopyFromReg(Chain, DL, CSKY::R14, PtrVT);
593
// Emit the store.
594
MemOpChains.push_back(
595
DAG.getStore(Chain, DL, Hi, StackPtr, MachinePointerInfo()));
596
} else {
597
// Second half of f64/i64 is passed in another GPR.
598
assert(RegLo < CSKY::R31 && "Invalid register pair");
599
Register RegHigh = RegLo + 1;
600
RegsToPass.push_back(std::make_pair(RegHigh, Hi));
601
}
602
continue;
603
}
604
605
ArgValue = convertValVTToLocVT(DAG, ArgValue, VA, DL);
606
607
// Use local copy if it is a byval arg.
608
if (Flags.isByVal())
609
ArgValue = ByValArgs[j++];
610
611
if (VA.isRegLoc()) {
612
// Queue up the argument copies and emit them at the end.
613
RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
614
} else {
615
assert(VA.isMemLoc() && "Argument not register or memory");
616
assert(!IsTailCall && "Tail call not allowed if stack is used "
617
"for passing parameters");
618
619
// Work out the address of the stack slot.
620
if (!StackPtr.getNode())
621
StackPtr = DAG.getCopyFromReg(Chain, DL, CSKY::R14, PtrVT);
622
SDValue Address =
623
DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
624
DAG.getIntPtrConstant(VA.getLocMemOffset(), DL));
625
626
// Emit the store.
627
MemOpChains.push_back(
628
DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
629
}
630
}
631
632
// Join the stores, which are independent of one another.
633
if (!MemOpChains.empty())
634
Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
635
636
SDValue Glue;
637
638
// Build a sequence of copy-to-reg nodes, chained and glued together.
639
for (auto &Reg : RegsToPass) {
640
Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, Glue);
641
Glue = Chain.getValue(1);
642
}
643
644
SmallVector<SDValue, 8> Ops;
645
EVT Ty = getPointerTy(DAG.getDataLayout());
646
bool IsRegCall = false;
647
648
Ops.push_back(Chain);
649
650
if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
651
const GlobalValue *GV = S->getGlobal();
652
bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(GV);
653
654
if (isPositionIndependent() || !Subtarget.has2E3()) {
655
IsRegCall = true;
656
Ops.push_back(getAddr<GlobalAddressSDNode, true>(S, DAG, IsLocal));
657
} else {
658
Ops.push_back(getTargetNode(cast<GlobalAddressSDNode>(Callee), DL, Ty,
659
DAG, CSKYII::MO_None));
660
Ops.push_back(getTargetConstantPoolValue(
661
cast<GlobalAddressSDNode>(Callee), Ty, DAG, CSKYII::MO_None));
662
}
663
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
664
bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(nullptr);
665
666
if (isPositionIndependent() || !Subtarget.has2E3()) {
667
IsRegCall = true;
668
Ops.push_back(getAddr<ExternalSymbolSDNode, true>(S, DAG, IsLocal));
669
} else {
670
Ops.push_back(getTargetNode(cast<ExternalSymbolSDNode>(Callee), DL, Ty,
671
DAG, CSKYII::MO_None));
672
Ops.push_back(getTargetConstantPoolValue(
673
cast<ExternalSymbolSDNode>(Callee), Ty, DAG, CSKYII::MO_None));
674
}
675
} else {
676
IsRegCall = true;
677
Ops.push_back(Callee);
678
}
679
680
// Add argument registers to the end of the list so that they are
681
// known live into the call.
682
for (auto &Reg : RegsToPass)
683
Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
684
685
if (!IsTailCall) {
686
// Add a register mask operand representing the call-preserved registers.
687
const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
688
const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
689
assert(Mask && "Missing call preserved mask for calling convention");
690
Ops.push_back(DAG.getRegisterMask(Mask));
691
}
692
693
// Glue the call to the argument copies, if any.
694
if (Glue.getNode())
695
Ops.push_back(Glue);
696
697
// Emit the call.
698
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
699
700
if (IsTailCall) {
701
MF.getFrameInfo().setHasTailCall();
702
return DAG.getNode(IsRegCall ? CSKYISD::TAILReg : CSKYISD::TAIL, DL,
703
NodeTys, Ops);
704
}
705
706
Chain = DAG.getNode(IsRegCall ? CSKYISD::CALLReg : CSKYISD::CALL, DL, NodeTys,
707
Ops);
708
DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
709
Glue = Chain.getValue(1);
710
711
// Mark the end of the call, which is glued to the call itself.
712
Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, DL);
713
Glue = Chain.getValue(1);
714
715
// Assign locations to each value returned by this call.
716
SmallVector<CCValAssign, 16> CSKYLocs;
717
CCState RetCCInfo(CallConv, IsVarArg, MF, CSKYLocs, *DAG.getContext());
718
RetCCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv, IsVarArg));
719
720
// Copy all of the result registers out of their specified physreg.
721
for (auto &VA : CSKYLocs) {
722
// Copy the value out
723
SDValue RetValue =
724
DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue);
725
// Glue the RetValue to the end of the call sequence
726
Chain = RetValue.getValue(1);
727
Glue = RetValue.getValue(2);
728
729
bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
730
731
if (IsF64OnCSKY) {
732
assert(VA.getLocReg() == GPRArgRegs[0] && "Unexpected reg assignment");
733
SDValue RetValue2 =
734
DAG.getCopyFromReg(Chain, DL, GPRArgRegs[1], MVT::i32, Glue);
735
Chain = RetValue2.getValue(1);
736
Glue = RetValue2.getValue(2);
737
RetValue = DAG.getNode(CSKYISD::BITCAST_FROM_LOHI, DL, VA.getValVT(),
738
RetValue, RetValue2);
739
}
740
741
RetValue = convertLocVTToValVT(DAG, RetValue, VA, DL);
742
743
InVals.push_back(RetValue);
744
}
745
746
return Chain;
747
}
748
749
CCAssignFn *CSKYTargetLowering::CCAssignFnForReturn(CallingConv::ID CC,
750
bool IsVarArg) const {
751
if (IsVarArg || !Subtarget.useHardFloatABI())
752
return RetCC_CSKY_ABIV2_SOFT;
753
else
754
return RetCC_CSKY_ABIV2_FP;
755
}
756
757
CCAssignFn *CSKYTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
758
bool IsVarArg) const {
759
if (IsVarArg || !Subtarget.useHardFloatABI())
760
return CC_CSKY_ABIV2_SOFT;
761
else
762
return CC_CSKY_ABIV2_FP;
763
}
764
765
static CSKYCP::CSKYCPModifier getModifier(unsigned Flags) {
766
767
if (Flags == CSKYII::MO_ADDR32)
768
return CSKYCP::ADDR;
769
else if (Flags == CSKYII::MO_GOT32)
770
return CSKYCP::GOT;
771
else if (Flags == CSKYII::MO_GOTOFF)
772
return CSKYCP::GOTOFF;
773
else if (Flags == CSKYII::MO_PLT32)
774
return CSKYCP::PLT;
775
else if (Flags == CSKYII::MO_None)
776
return CSKYCP::NO_MOD;
777
else
778
assert(0 && "unknown CSKYII Modifier");
779
return CSKYCP::NO_MOD;
780
}
781
782
SDValue CSKYTargetLowering::getTargetConstantPoolValue(GlobalAddressSDNode *N,
783
EVT Ty,
784
SelectionDAG &DAG,
785
unsigned Flags) const {
786
CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(
787
N->getGlobal(), CSKYCP::CPValue, 0, getModifier(Flags), false);
788
789
return DAG.getTargetConstantPool(CPV, Ty);
790
}
791
792
CSKYTargetLowering::ConstraintType
793
CSKYTargetLowering::getConstraintType(StringRef Constraint) const {
794
if (Constraint.size() == 1) {
795
switch (Constraint[0]) {
796
default:
797
break;
798
case 'a':
799
case 'b':
800
case 'v':
801
case 'w':
802
case 'y':
803
return C_RegisterClass;
804
case 'c':
805
case 'l':
806
case 'h':
807
case 'z':
808
return C_Register;
809
}
810
}
811
return TargetLowering::getConstraintType(Constraint);
812
}
813
814
std::pair<unsigned, const TargetRegisterClass *>
815
CSKYTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
816
StringRef Constraint,
817
MVT VT) const {
818
if (Constraint.size() == 1) {
819
switch (Constraint[0]) {
820
case 'r':
821
return std::make_pair(0U, &CSKY::GPRRegClass);
822
case 'a':
823
return std::make_pair(0U, &CSKY::mGPRRegClass);
824
case 'b':
825
return std::make_pair(0U, &CSKY::sGPRRegClass);
826
case 'z':
827
return std::make_pair(CSKY::R14, &CSKY::GPRRegClass);
828
case 'c':
829
return std::make_pair(CSKY::C, &CSKY::CARRYRegClass);
830
case 'w':
831
if ((Subtarget.hasFPUv2SingleFloat() ||
832
Subtarget.hasFPUv3SingleFloat()) &&
833
VT == MVT::f32)
834
return std::make_pair(0U, &CSKY::sFPR32RegClass);
835
if ((Subtarget.hasFPUv2DoubleFloat() ||
836
Subtarget.hasFPUv3DoubleFloat()) &&
837
VT == MVT::f64)
838
return std::make_pair(0U, &CSKY::sFPR64RegClass);
839
break;
840
case 'v':
841
if (Subtarget.hasFPUv2SingleFloat() && VT == MVT::f32)
842
return std::make_pair(0U, &CSKY::sFPR32RegClass);
843
if (Subtarget.hasFPUv3SingleFloat() && VT == MVT::f32)
844
return std::make_pair(0U, &CSKY::FPR32RegClass);
845
if (Subtarget.hasFPUv2DoubleFloat() && VT == MVT::f64)
846
return std::make_pair(0U, &CSKY::sFPR64RegClass);
847
if (Subtarget.hasFPUv3DoubleFloat() && VT == MVT::f64)
848
return std::make_pair(0U, &CSKY::FPR64RegClass);
849
break;
850
default:
851
break;
852
}
853
}
854
855
if (Constraint == "{c}")
856
return std::make_pair(CSKY::C, &CSKY::CARRYRegClass);
857
858
// Clang will correctly decode the usage of register name aliases into their
859
// official names. However, other frontends like `rustc` do not. This allows
860
// users of these frontends to use the ABI names for registers in LLVM-style
861
// register constraints.
862
unsigned XRegFromAlias = StringSwitch<unsigned>(Constraint.lower())
863
.Case("{a0}", CSKY::R0)
864
.Case("{a1}", CSKY::R1)
865
.Case("{a2}", CSKY::R2)
866
.Case("{a3}", CSKY::R3)
867
.Case("{l0}", CSKY::R4)
868
.Case("{l1}", CSKY::R5)
869
.Case("{l2}", CSKY::R6)
870
.Case("{l3}", CSKY::R7)
871
.Case("{l4}", CSKY::R8)
872
.Case("{l5}", CSKY::R9)
873
.Case("{l6}", CSKY::R10)
874
.Case("{l7}", CSKY::R11)
875
.Case("{t0}", CSKY::R12)
876
.Case("{t1}", CSKY::R13)
877
.Case("{sp}", CSKY::R14)
878
.Case("{lr}", CSKY::R15)
879
.Case("{l8}", CSKY::R16)
880
.Case("{l9}", CSKY::R17)
881
.Case("{t2}", CSKY::R18)
882
.Case("{t3}", CSKY::R19)
883
.Case("{t4}", CSKY::R20)
884
.Case("{t5}", CSKY::R21)
885
.Case("{t6}", CSKY::R22)
886
.Cases("{t7}", "{fp}", CSKY::R23)
887
.Cases("{t8}", "{top}", CSKY::R24)
888
.Cases("{t9}", "{bsp}", CSKY::R25)
889
.Case("{r26}", CSKY::R26)
890
.Case("{r27}", CSKY::R27)
891
.Cases("{gb}", "{rgb}", "{rdb}", CSKY::R28)
892
.Cases("{tb}", "{rtb}", CSKY::R29)
893
.Case("{svbr}", CSKY::R30)
894
.Case("{tls}", CSKY::R31)
895
.Default(CSKY::NoRegister);
896
897
if (XRegFromAlias != CSKY::NoRegister)
898
return std::make_pair(XRegFromAlias, &CSKY::GPRRegClass);
899
900
// Since TargetLowering::getRegForInlineAsmConstraint uses the name of the
901
// TableGen record rather than the AsmName to choose registers for InlineAsm
902
// constraints, plus we want to match those names to the widest floating point
903
// register type available, manually select floating point registers here.
904
//
905
// The second case is the ABI name of the register, so that frontends can also
906
// use the ABI names in register constraint lists.
907
if (Subtarget.useHardFloat()) {
908
unsigned FReg = StringSwitch<unsigned>(Constraint.lower())
909
.Cases("{fr0}", "{vr0}", CSKY::F0_32)
910
.Cases("{fr1}", "{vr1}", CSKY::F1_32)
911
.Cases("{fr2}", "{vr2}", CSKY::F2_32)
912
.Cases("{fr3}", "{vr3}", CSKY::F3_32)
913
.Cases("{fr4}", "{vr4}", CSKY::F4_32)
914
.Cases("{fr5}", "{vr5}", CSKY::F5_32)
915
.Cases("{fr6}", "{vr6}", CSKY::F6_32)
916
.Cases("{fr7}", "{vr7}", CSKY::F7_32)
917
.Cases("{fr8}", "{vr8}", CSKY::F8_32)
918
.Cases("{fr9}", "{vr9}", CSKY::F9_32)
919
.Cases("{fr10}", "{vr10}", CSKY::F10_32)
920
.Cases("{fr11}", "{vr11}", CSKY::F11_32)
921
.Cases("{fr12}", "{vr12}", CSKY::F12_32)
922
.Cases("{fr13}", "{vr13}", CSKY::F13_32)
923
.Cases("{fr14}", "{vr14}", CSKY::F14_32)
924
.Cases("{fr15}", "{vr15}", CSKY::F15_32)
925
.Cases("{fr16}", "{vr16}", CSKY::F16_32)
926
.Cases("{fr17}", "{vr17}", CSKY::F17_32)
927
.Cases("{fr18}", "{vr18}", CSKY::F18_32)
928
.Cases("{fr19}", "{vr19}", CSKY::F19_32)
929
.Cases("{fr20}", "{vr20}", CSKY::F20_32)
930
.Cases("{fr21}", "{vr21}", CSKY::F21_32)
931
.Cases("{fr22}", "{vr22}", CSKY::F22_32)
932
.Cases("{fr23}", "{vr23}", CSKY::F23_32)
933
.Cases("{fr24}", "{vr24}", CSKY::F24_32)
934
.Cases("{fr25}", "{vr25}", CSKY::F25_32)
935
.Cases("{fr26}", "{vr26}", CSKY::F26_32)
936
.Cases("{fr27}", "{vr27}", CSKY::F27_32)
937
.Cases("{fr28}", "{vr28}", CSKY::F28_32)
938
.Cases("{fr29}", "{vr29}", CSKY::F29_32)
939
.Cases("{fr30}", "{vr30}", CSKY::F30_32)
940
.Cases("{fr31}", "{vr31}", CSKY::F31_32)
941
.Default(CSKY::NoRegister);
942
if (FReg != CSKY::NoRegister) {
943
assert(CSKY::F0_32 <= FReg && FReg <= CSKY::F31_32 && "Unknown fp-reg");
944
unsigned RegNo = FReg - CSKY::F0_32;
945
unsigned DReg = CSKY::F0_64 + RegNo;
946
947
if (Subtarget.hasFPUv2DoubleFloat())
948
return std::make_pair(DReg, &CSKY::sFPR64RegClass);
949
else if (Subtarget.hasFPUv3DoubleFloat())
950
return std::make_pair(DReg, &CSKY::FPR64RegClass);
951
else if (Subtarget.hasFPUv2SingleFloat())
952
return std::make_pair(FReg, &CSKY::sFPR32RegClass);
953
else if (Subtarget.hasFPUv3SingleFloat())
954
return std::make_pair(FReg, &CSKY::FPR32RegClass);
955
}
956
}
957
958
return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
959
}
960
961
static MachineBasicBlock *
962
emitSelectPseudo(MachineInstr &MI, MachineBasicBlock *BB, unsigned Opcode) {
963
964
const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
965
DebugLoc DL = MI.getDebugLoc();
966
967
// To "insert" a SELECT instruction, we actually have to insert the
968
// diamond control-flow pattern. The incoming instruction knows the
969
// destination vreg to set, the condition code register to branch on, the
970
// true/false values to select between, and a branch opcode to use.
971
const BasicBlock *LLVM_BB = BB->getBasicBlock();
972
MachineFunction::iterator It = ++BB->getIterator();
973
974
// thisMBB:
975
// ...
976
// TrueVal = ...
977
// bt32 c, sinkMBB
978
// fallthrough --> copyMBB
979
MachineBasicBlock *thisMBB = BB;
980
MachineFunction *F = BB->getParent();
981
MachineBasicBlock *copyMBB = F->CreateMachineBasicBlock(LLVM_BB);
982
MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
983
F->insert(It, copyMBB);
984
F->insert(It, sinkMBB);
985
986
// Transfer the remainder of BB and its successor edges to sinkMBB.
987
sinkMBB->splice(sinkMBB->begin(), BB,
988
std::next(MachineBasicBlock::iterator(MI)), BB->end());
989
sinkMBB->transferSuccessorsAndUpdatePHIs(BB);
990
991
// Next, add the true and fallthrough blocks as its successors.
992
BB->addSuccessor(copyMBB);
993
BB->addSuccessor(sinkMBB);
994
995
// bt32 condition, sinkMBB
996
BuildMI(BB, DL, TII.get(Opcode))
997
.addReg(MI.getOperand(1).getReg())
998
.addMBB(sinkMBB);
999
1000
// copyMBB:
1001
// %FalseValue = ...
1002
// # fallthrough to sinkMBB
1003
BB = copyMBB;
1004
1005
// Update machine-CFG edges
1006
BB->addSuccessor(sinkMBB);
1007
1008
// sinkMBB:
1009
// %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copyMBB ]
1010
// ...
1011
BB = sinkMBB;
1012
1013
BuildMI(*BB, BB->begin(), DL, TII.get(CSKY::PHI), MI.getOperand(0).getReg())
1014
.addReg(MI.getOperand(2).getReg())
1015
.addMBB(thisMBB)
1016
.addReg(MI.getOperand(3).getReg())
1017
.addMBB(copyMBB);
1018
1019
MI.eraseFromParent(); // The pseudo instruction is gone now.
1020
1021
return BB;
1022
}
1023
1024
MachineBasicBlock *
1025
CSKYTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1026
MachineBasicBlock *BB) const {
1027
switch (MI.getOpcode()) {
1028
default:
1029
llvm_unreachable("Unexpected instr type to insert");
1030
case CSKY::FSELS:
1031
case CSKY::FSELD:
1032
if (Subtarget.hasE2())
1033
return emitSelectPseudo(MI, BB, CSKY::BT32);
1034
else
1035
return emitSelectPseudo(MI, BB, CSKY::BT16);
1036
case CSKY::ISEL32:
1037
return emitSelectPseudo(MI, BB, CSKY::BT32);
1038
case CSKY::ISEL16:
1039
return emitSelectPseudo(MI, BB, CSKY::BT16);
1040
}
1041
}
1042
1043
SDValue CSKYTargetLowering::getTargetConstantPoolValue(ExternalSymbolSDNode *N,
1044
EVT Ty,
1045
SelectionDAG &DAG,
1046
unsigned Flags) const {
1047
CSKYConstantPoolValue *CPV =
1048
CSKYConstantPoolSymbol::Create(Type::getInt32Ty(*DAG.getContext()),
1049
N->getSymbol(), 0, getModifier(Flags));
1050
1051
return DAG.getTargetConstantPool(CPV, Ty);
1052
}
1053
1054
SDValue CSKYTargetLowering::getTargetConstantPoolValue(JumpTableSDNode *N,
1055
EVT Ty,
1056
SelectionDAG &DAG,
1057
unsigned Flags) const {
1058
CSKYConstantPoolValue *CPV =
1059
CSKYConstantPoolJT::Create(Type::getInt32Ty(*DAG.getContext()),
1060
N->getIndex(), 0, getModifier(Flags));
1061
return DAG.getTargetConstantPool(CPV, Ty);
1062
}
1063
1064
SDValue CSKYTargetLowering::getTargetConstantPoolValue(BlockAddressSDNode *N,
1065
EVT Ty,
1066
SelectionDAG &DAG,
1067
unsigned Flags) const {
1068
assert(N->getOffset() == 0);
1069
CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(
1070
N->getBlockAddress(), CSKYCP::CPBlockAddress, 0, getModifier(Flags),
1071
false);
1072
return DAG.getTargetConstantPool(CPV, Ty);
1073
}
1074
1075
SDValue CSKYTargetLowering::getTargetConstantPoolValue(ConstantPoolSDNode *N,
1076
EVT Ty,
1077
SelectionDAG &DAG,
1078
unsigned Flags) const {
1079
assert(N->getOffset() == 0);
1080
CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(
1081
N->getConstVal(), Type::getInt32Ty(*DAG.getContext()),
1082
CSKYCP::CPConstPool, 0, getModifier(Flags), false);
1083
return DAG.getTargetConstantPool(CPV, Ty);
1084
}
1085
1086
SDValue CSKYTargetLowering::getTargetNode(GlobalAddressSDNode *N, SDLoc DL,
1087
EVT Ty, SelectionDAG &DAG,
1088
unsigned Flags) const {
1089
return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags);
1090
}
1091
1092
SDValue CSKYTargetLowering::getTargetNode(ExternalSymbolSDNode *N, SDLoc DL,
1093
EVT Ty, SelectionDAG &DAG,
1094
unsigned Flags) const {
1095
return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flags);
1096
}
1097
1098
SDValue CSKYTargetLowering::getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty,
1099
SelectionDAG &DAG,
1100
unsigned Flags) const {
1101
return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
1102
}
1103
1104
SDValue CSKYTargetLowering::getTargetNode(BlockAddressSDNode *N, SDLoc DL,
1105
EVT Ty, SelectionDAG &DAG,
1106
unsigned Flags) const {
1107
return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, N->getOffset(),
1108
Flags);
1109
}
1110
1111
SDValue CSKYTargetLowering::getTargetNode(ConstantPoolSDNode *N, SDLoc DL,
1112
EVT Ty, SelectionDAG &DAG,
1113
unsigned Flags) const {
1114
1115
return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),
1116
N->getOffset(), Flags);
1117
}
1118
1119
const char *CSKYTargetLowering::getTargetNodeName(unsigned Opcode) const {
1120
switch (Opcode) {
1121
default:
1122
llvm_unreachable("unknown CSKYISD node");
1123
case CSKYISD::NIE:
1124
return "CSKYISD::NIE";
1125
case CSKYISD::NIR:
1126
return "CSKYISD::NIR";
1127
case CSKYISD::RET:
1128
return "CSKYISD::RET";
1129
case CSKYISD::CALL:
1130
return "CSKYISD::CALL";
1131
case CSKYISD::CALLReg:
1132
return "CSKYISD::CALLReg";
1133
case CSKYISD::TAIL:
1134
return "CSKYISD::TAIL";
1135
case CSKYISD::TAILReg:
1136
return "CSKYISD::TAILReg";
1137
case CSKYISD::LOAD_ADDR:
1138
return "CSKYISD::LOAD_ADDR";
1139
case CSKYISD::BITCAST_TO_LOHI:
1140
return "CSKYISD::BITCAST_TO_LOHI";
1141
case CSKYISD::BITCAST_FROM_LOHI:
1142
return "CSKYISD::BITCAST_FROM_LOHI";
1143
}
1144
}
1145
1146
SDValue CSKYTargetLowering::LowerGlobalAddress(SDValue Op,
1147
SelectionDAG &DAG) const {
1148
SDLoc DL(Op);
1149
EVT Ty = Op.getValueType();
1150
GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
1151
int64_t Offset = N->getOffset();
1152
1153
const GlobalValue *GV = N->getGlobal();
1154
bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(GV);
1155
SDValue Addr = getAddr<GlobalAddressSDNode, false>(N, DAG, IsLocal);
1156
1157
// In order to maximise the opportunity for common subexpression elimination,
1158
// emit a separate ADD node for the global address offset instead of folding
1159
// it in the global address node. Later peephole optimisations may choose to
1160
// fold it back in when profitable.
1161
if (Offset != 0)
1162
return DAG.getNode(ISD::ADD, DL, Ty, Addr,
1163
DAG.getConstant(Offset, DL, MVT::i32));
1164
return Addr;
1165
}
1166
1167
SDValue CSKYTargetLowering::LowerExternalSymbol(SDValue Op,
1168
SelectionDAG &DAG) const {
1169
ExternalSymbolSDNode *N = cast<ExternalSymbolSDNode>(Op);
1170
1171
return getAddr(N, DAG, false);
1172
}
1173
1174
SDValue CSKYTargetLowering::LowerJumpTable(SDValue Op,
1175
SelectionDAG &DAG) const {
1176
JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
1177
1178
return getAddr<JumpTableSDNode, false>(N, DAG);
1179
}
1180
1181
SDValue CSKYTargetLowering::LowerBlockAddress(SDValue Op,
1182
SelectionDAG &DAG) const {
1183
BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
1184
1185
return getAddr(N, DAG);
1186
}
1187
1188
SDValue CSKYTargetLowering::LowerConstantPool(SDValue Op,
1189
SelectionDAG &DAG) const {
1190
assert(!Subtarget.hasE2());
1191
ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
1192
1193
return getAddr(N, DAG);
1194
}
1195
1196
SDValue CSKYTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
1197
MachineFunction &MF = DAG.getMachineFunction();
1198
CSKYMachineFunctionInfo *FuncInfo = MF.getInfo<CSKYMachineFunctionInfo>();
1199
1200
SDLoc DL(Op);
1201
SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
1202
getPointerTy(MF.getDataLayout()));
1203
1204
// vastart just stores the address of the VarArgsFrameIndex slot into the
1205
// memory location argument.
1206
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1207
return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
1208
MachinePointerInfo(SV));
1209
}
1210
1211
SDValue CSKYTargetLowering::LowerFRAMEADDR(SDValue Op,
1212
SelectionDAG &DAG) const {
1213
const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();
1214
MachineFunction &MF = DAG.getMachineFunction();
1215
MachineFrameInfo &MFI = MF.getFrameInfo();
1216
MFI.setFrameAddressIsTaken(true);
1217
1218
EVT VT = Op.getValueType();
1219
SDLoc dl(Op);
1220
unsigned Depth = Op.getConstantOperandVal(0);
1221
Register FrameReg = RI.getFrameRegister(MF);
1222
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
1223
while (Depth--)
1224
FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1225
MachinePointerInfo());
1226
return FrameAddr;
1227
}
1228
1229
SDValue CSKYTargetLowering::LowerRETURNADDR(SDValue Op,
1230
SelectionDAG &DAG) const {
1231
const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();
1232
MachineFunction &MF = DAG.getMachineFunction();
1233
MachineFrameInfo &MFI = MF.getFrameInfo();
1234
MFI.setReturnAddressIsTaken(true);
1235
1236
if (verifyReturnAddressArgumentIsConstant(Op, DAG))
1237
return SDValue();
1238
1239
EVT VT = Op.getValueType();
1240
SDLoc dl(Op);
1241
unsigned Depth = Op.getConstantOperandVal(0);
1242
if (Depth) {
1243
SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1244
SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
1245
return DAG.getLoad(VT, dl, DAG.getEntryNode(),
1246
DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
1247
MachinePointerInfo());
1248
}
1249
// Return the value of the return address register, marking it an implicit
1250
// live-in.
1251
unsigned Reg = MF.addLiveIn(RI.getRARegister(), getRegClassFor(MVT::i32));
1252
return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
1253
}
1254
1255
Register CSKYTargetLowering::getExceptionPointerRegister(
1256
const Constant *PersonalityFn) const {
1257
return CSKY::R0;
1258
}
1259
1260
Register CSKYTargetLowering::getExceptionSelectorRegister(
1261
const Constant *PersonalityFn) const {
1262
return CSKY::R1;
1263
}
1264
1265
SDValue CSKYTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1266
SelectionDAG &DAG) const {
1267
SDLoc DL(Op);
1268
EVT Ty = Op.getValueType();
1269
GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
1270
int64_t Offset = N->getOffset();
1271
MVT XLenVT = MVT::i32;
1272
1273
TLSModel::Model Model = getTargetMachine().getTLSModel(N->getGlobal());
1274
SDValue Addr;
1275
switch (Model) {
1276
case TLSModel::LocalExec:
1277
Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/false);
1278
break;
1279
case TLSModel::InitialExec:
1280
Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/true);
1281
break;
1282
case TLSModel::LocalDynamic:
1283
case TLSModel::GeneralDynamic:
1284
Addr = getDynamicTLSAddr(N, DAG);
1285
break;
1286
}
1287
1288
// In order to maximise the opportunity for common subexpression elimination,
1289
// emit a separate ADD node for the global address offset instead of folding
1290
// it in the global address node. Later peephole optimisations may choose to
1291
// fold it back in when profitable.
1292
if (Offset != 0)
1293
return DAG.getNode(ISD::ADD, DL, Ty, Addr,
1294
DAG.getConstant(Offset, DL, XLenVT));
1295
return Addr;
1296
}
1297
1298
SDValue CSKYTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
1299
SelectionDAG &DAG,
1300
bool UseGOT) const {
1301
MachineFunction &MF = DAG.getMachineFunction();
1302
CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
1303
1304
unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();
1305
1306
SDLoc DL(N);
1307
EVT Ty = getPointerTy(DAG.getDataLayout());
1308
1309
CSKYCP::CSKYCPModifier Flag = UseGOT ? CSKYCP::TLSIE : CSKYCP::TLSLE;
1310
bool AddCurrentAddr = UseGOT ? true : false;
1311
unsigned char PCAjust = UseGOT ? 4 : 0;
1312
1313
CSKYConstantPoolValue *CPV =
1314
CSKYConstantPoolConstant::Create(N->getGlobal(), CSKYCP::CPValue, PCAjust,
1315
Flag, AddCurrentAddr, CSKYPCLabelIndex);
1316
SDValue CAddr = DAG.getTargetConstantPool(CPV, Ty);
1317
1318
SDValue Load;
1319
if (UseGOT) {
1320
SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);
1321
auto *LRWGRS = DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty},
1322
{CAddr, PICLabel});
1323
auto LRWADDGRS =
1324
DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));
1325
Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), LRWADDGRS,
1326
MachinePointerInfo(N->getGlobal()));
1327
} else {
1328
Load = SDValue(DAG.getMachineNode(CSKY::LRW32, DL, Ty, CAddr), 0);
1329
}
1330
1331
// Add the thread pointer.
1332
SDValue TPReg = DAG.getRegister(CSKY::R31, MVT::i32);
1333
return DAG.getNode(ISD::ADD, DL, Ty, Load, TPReg);
1334
}
1335
1336
SDValue CSKYTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N,
1337
SelectionDAG &DAG) const {
1338
MachineFunction &MF = DAG.getMachineFunction();
1339
CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
1340
1341
unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();
1342
1343
SDLoc DL(N);
1344
EVT Ty = getPointerTy(DAG.getDataLayout());
1345
IntegerType *CallTy = Type::getIntNTy(*DAG.getContext(), Ty.getSizeInBits());
1346
1347
CSKYConstantPoolValue *CPV =
1348
CSKYConstantPoolConstant::Create(N->getGlobal(), CSKYCP::CPValue, 4,
1349
CSKYCP::TLSGD, true, CSKYPCLabelIndex);
1350
SDValue Addr = DAG.getTargetConstantPool(CPV, Ty);
1351
SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);
1352
1353
auto *LRWGRS =
1354
DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty}, {Addr, PICLabel});
1355
1356
auto Load =
1357
DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));
1358
1359
// Prepare argument list to generate call.
1360
ArgListTy Args;
1361
ArgListEntry Entry;
1362
Entry.Node = Load;
1363
Entry.Ty = CallTy;
1364
Args.push_back(Entry);
1365
1366
// Setup call to __tls_get_addr.
1367
TargetLowering::CallLoweringInfo CLI(DAG);
1368
CLI.setDebugLoc(DL)
1369
.setChain(DAG.getEntryNode())
1370
.setLibCallee(CallingConv::C, CallTy,
1371
DAG.getExternalSymbol("__tls_get_addr", Ty),
1372
std::move(Args));
1373
SDValue V = LowerCallTo(CLI).first;
1374
1375
return V;
1376
}
1377
1378
bool CSKYTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
1379
SDValue C) const {
1380
if (!VT.isScalarInteger())
1381
return false;
1382
1383
// Omit if data size exceeds.
1384
if (VT.getSizeInBits() > Subtarget.XLen)
1385
return false;
1386
1387
if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode())) {
1388
const APInt &Imm = ConstNode->getAPIntValue();
1389
// Break MULT to LSLI + ADDU/SUBU.
1390
if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2() ||
1391
(1 - Imm).isPowerOf2())
1392
return true;
1393
// Only break MULT for sub targets without MULT32, since an extra
1394
// instruction will be generated against the above 3 cases. We leave it
1395
// unchanged on sub targets with MULT32, since not sure it is better.
1396
if (!Subtarget.hasE2() && (-1 - Imm).isPowerOf2())
1397
return true;
1398
// Break (MULT x, imm) to ([IXH32|IXW32|IXD32] (LSLI32 x, i0), x) when
1399
// imm=(1<<i0)+[2|4|8] and imm has to be composed via a MOVIH32/ORI32 pair.
1400
if (Imm.ugt(0xffff) && ((Imm - 2).isPowerOf2() || (Imm - 4).isPowerOf2()) &&
1401
Subtarget.hasE2())
1402
return true;
1403
if (Imm.ugt(0xffff) && (Imm - 8).isPowerOf2() && Subtarget.has2E3())
1404
return true;
1405
}
1406
1407
return false;
1408
}
1409
1410
bool CSKYTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
1411
return Subtarget.has2E3();
1412
}
1413
1414
bool CSKYTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {
1415
return Subtarget.hasE2();
1416
}
1417
1418