xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.cpp (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
1*349cc55cSDimitry Andric //===-- CSKYISelLowering.cpp - CSKY DAG Lowering Implementation  ----------===//
2*349cc55cSDimitry Andric //
3*349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*349cc55cSDimitry Andric //
7*349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8*349cc55cSDimitry Andric //
9*349cc55cSDimitry Andric // This file defines the interfaces that CSKY uses to lower LLVM code into a
10*349cc55cSDimitry Andric // selection DAG.
11*349cc55cSDimitry Andric //
12*349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
13*349cc55cSDimitry Andric 
14*349cc55cSDimitry Andric #include "CSKYISelLowering.h"
15*349cc55cSDimitry Andric #include "CSKYCallingConv.h"
16*349cc55cSDimitry Andric #include "CSKYMachineFunctionInfo.h"
17*349cc55cSDimitry Andric #include "CSKYRegisterInfo.h"
18*349cc55cSDimitry Andric #include "CSKYSubtarget.h"
19*349cc55cSDimitry Andric #include "llvm/ADT/Statistic.h"
20*349cc55cSDimitry Andric #include "llvm/CodeGen/CallingConvLower.h"
21*349cc55cSDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h"
22*349cc55cSDimitry Andric #include "llvm/Support/Debug.h"
23*349cc55cSDimitry Andric 
24*349cc55cSDimitry Andric using namespace llvm;
25*349cc55cSDimitry Andric 
26*349cc55cSDimitry Andric #define DEBUG_TYPE "csky-isel-lowering"
27*349cc55cSDimitry Andric 
28*349cc55cSDimitry Andric STATISTIC(NumTailCalls, "Number of tail calls");
29*349cc55cSDimitry Andric 
30*349cc55cSDimitry Andric #include "CSKYGenCallingConv.inc"
31*349cc55cSDimitry Andric 
32*349cc55cSDimitry Andric static const MCPhysReg GPRArgRegs[] = {CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3};
33*349cc55cSDimitry Andric 
34*349cc55cSDimitry Andric CSKYTargetLowering::CSKYTargetLowering(const TargetMachine &TM,
35*349cc55cSDimitry Andric                                        const CSKYSubtarget &STI)
36*349cc55cSDimitry Andric     : TargetLowering(TM), Subtarget(STI) {
37*349cc55cSDimitry Andric   // Register Class
38*349cc55cSDimitry Andric   addRegisterClass(MVT::i32, &CSKY::GPRRegClass);
39*349cc55cSDimitry Andric 
40*349cc55cSDimitry Andric   // Compute derived properties from the register classes.
41*349cc55cSDimitry Andric   computeRegisterProperties(STI.getRegisterInfo());
42*349cc55cSDimitry Andric 
43*349cc55cSDimitry Andric   setBooleanContents(UndefinedBooleanContent);
44*349cc55cSDimitry Andric   setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
45*349cc55cSDimitry Andric 
46*349cc55cSDimitry Andric   // TODO: Add atomic support fully.
47*349cc55cSDimitry Andric   setMaxAtomicSizeInBitsSupported(0);
48*349cc55cSDimitry Andric 
49*349cc55cSDimitry Andric   setStackPointerRegisterToSaveRestore(CSKY::R14);
50*349cc55cSDimitry Andric   const Align FunctionAlignment(2);
51*349cc55cSDimitry Andric   setMinFunctionAlignment(FunctionAlignment);
52*349cc55cSDimitry Andric   setSchedulingPreference(Sched::Source);
53*349cc55cSDimitry Andric }
54*349cc55cSDimitry Andric 
55*349cc55cSDimitry Andric EVT CSKYTargetLowering::getSetCCResultType(const DataLayout &DL,
56*349cc55cSDimitry Andric                                            LLVMContext &Context, EVT VT) const {
57*349cc55cSDimitry Andric   if (!VT.isVector())
58*349cc55cSDimitry Andric     return MVT::i32;
59*349cc55cSDimitry Andric 
60*349cc55cSDimitry Andric   return VT.changeVectorElementTypeToInteger();
61*349cc55cSDimitry Andric }
62*349cc55cSDimitry Andric 
63*349cc55cSDimitry Andric static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val,
64*349cc55cSDimitry Andric                                    const CCValAssign &VA, const SDLoc &DL) {
65*349cc55cSDimitry Andric   EVT LocVT = VA.getLocVT();
66*349cc55cSDimitry Andric 
67*349cc55cSDimitry Andric   switch (VA.getLocInfo()) {
68*349cc55cSDimitry Andric   default:
69*349cc55cSDimitry Andric     llvm_unreachable("Unexpected CCValAssign::LocInfo");
70*349cc55cSDimitry Andric   case CCValAssign::Full:
71*349cc55cSDimitry Andric     break;
72*349cc55cSDimitry Andric   case CCValAssign::BCvt:
73*349cc55cSDimitry Andric     Val = DAG.getNode(ISD::BITCAST, DL, LocVT, Val);
74*349cc55cSDimitry Andric     break;
75*349cc55cSDimitry Andric   }
76*349cc55cSDimitry Andric   return Val;
77*349cc55cSDimitry Andric }
78*349cc55cSDimitry Andric 
79*349cc55cSDimitry Andric static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val,
80*349cc55cSDimitry Andric                                    const CCValAssign &VA, const SDLoc &DL) {
81*349cc55cSDimitry Andric   switch (VA.getLocInfo()) {
82*349cc55cSDimitry Andric   default:
83*349cc55cSDimitry Andric     llvm_unreachable("Unexpected CCValAssign::LocInfo");
84*349cc55cSDimitry Andric   case CCValAssign::Full:
85*349cc55cSDimitry Andric     break;
86*349cc55cSDimitry Andric   case CCValAssign::BCvt:
87*349cc55cSDimitry Andric     Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val);
88*349cc55cSDimitry Andric     break;
89*349cc55cSDimitry Andric   }
90*349cc55cSDimitry Andric   return Val;
91*349cc55cSDimitry Andric }
92*349cc55cSDimitry Andric 
93*349cc55cSDimitry Andric static SDValue unpackFromRegLoc(const CSKYSubtarget &Subtarget,
94*349cc55cSDimitry Andric                                 SelectionDAG &DAG, SDValue Chain,
95*349cc55cSDimitry Andric                                 const CCValAssign &VA, const SDLoc &DL) {
96*349cc55cSDimitry Andric   MachineFunction &MF = DAG.getMachineFunction();
97*349cc55cSDimitry Andric   MachineRegisterInfo &RegInfo = MF.getRegInfo();
98*349cc55cSDimitry Andric   EVT LocVT = VA.getLocVT();
99*349cc55cSDimitry Andric   SDValue Val;
100*349cc55cSDimitry Andric   const TargetRegisterClass *RC;
101*349cc55cSDimitry Andric 
102*349cc55cSDimitry Andric   switch (LocVT.getSimpleVT().SimpleTy) {
103*349cc55cSDimitry Andric   default:
104*349cc55cSDimitry Andric     llvm_unreachable("Unexpected register type");
105*349cc55cSDimitry Andric   case MVT::i32:
106*349cc55cSDimitry Andric     RC = &CSKY::GPRRegClass;
107*349cc55cSDimitry Andric     break;
108*349cc55cSDimitry Andric   }
109*349cc55cSDimitry Andric 
110*349cc55cSDimitry Andric   Register VReg = RegInfo.createVirtualRegister(RC);
111*349cc55cSDimitry Andric   RegInfo.addLiveIn(VA.getLocReg(), VReg);
112*349cc55cSDimitry Andric   Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
113*349cc55cSDimitry Andric 
114*349cc55cSDimitry Andric   return convertLocVTToValVT(DAG, Val, VA, DL);
115*349cc55cSDimitry Andric }
116*349cc55cSDimitry Andric 
117*349cc55cSDimitry Andric static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain,
118*349cc55cSDimitry Andric                                 const CCValAssign &VA, const SDLoc &DL) {
119*349cc55cSDimitry Andric   MachineFunction &MF = DAG.getMachineFunction();
120*349cc55cSDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
121*349cc55cSDimitry Andric   EVT LocVT = VA.getLocVT();
122*349cc55cSDimitry Andric   EVT ValVT = VA.getValVT();
123*349cc55cSDimitry Andric   EVT PtrVT = MVT::getIntegerVT(DAG.getDataLayout().getPointerSizeInBits(0));
124*349cc55cSDimitry Andric   int FI = MFI.CreateFixedObject(ValVT.getSizeInBits() / 8,
125*349cc55cSDimitry Andric                                  VA.getLocMemOffset(), /*Immutable=*/true);
126*349cc55cSDimitry Andric   SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
127*349cc55cSDimitry Andric   SDValue Val;
128*349cc55cSDimitry Andric 
129*349cc55cSDimitry Andric   ISD::LoadExtType ExtType;
130*349cc55cSDimitry Andric   switch (VA.getLocInfo()) {
131*349cc55cSDimitry Andric   default:
132*349cc55cSDimitry Andric     llvm_unreachable("Unexpected CCValAssign::LocInfo");
133*349cc55cSDimitry Andric   case CCValAssign::Full:
134*349cc55cSDimitry Andric   case CCValAssign::BCvt:
135*349cc55cSDimitry Andric     ExtType = ISD::NON_EXTLOAD;
136*349cc55cSDimitry Andric     break;
137*349cc55cSDimitry Andric   }
138*349cc55cSDimitry Andric   Val = DAG.getExtLoad(
139*349cc55cSDimitry Andric       ExtType, DL, LocVT, Chain, FIN,
140*349cc55cSDimitry Andric       MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), ValVT);
141*349cc55cSDimitry Andric   return Val;
142*349cc55cSDimitry Andric }
143*349cc55cSDimitry Andric 
144*349cc55cSDimitry Andric // Transform physical registers into virtual registers.
145*349cc55cSDimitry Andric SDValue CSKYTargetLowering::LowerFormalArguments(
146*349cc55cSDimitry Andric     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
147*349cc55cSDimitry Andric     const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
148*349cc55cSDimitry Andric     SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
149*349cc55cSDimitry Andric 
150*349cc55cSDimitry Andric   switch (CallConv) {
151*349cc55cSDimitry Andric   default:
152*349cc55cSDimitry Andric     report_fatal_error("Unsupported calling convention");
153*349cc55cSDimitry Andric   case CallingConv::C:
154*349cc55cSDimitry Andric   case CallingConv::Fast:
155*349cc55cSDimitry Andric     break;
156*349cc55cSDimitry Andric   }
157*349cc55cSDimitry Andric 
158*349cc55cSDimitry Andric   MachineFunction &MF = DAG.getMachineFunction();
159*349cc55cSDimitry Andric 
160*349cc55cSDimitry Andric   // Used with vargs to acumulate store chains.
161*349cc55cSDimitry Andric   std::vector<SDValue> OutChains;
162*349cc55cSDimitry Andric 
163*349cc55cSDimitry Andric   // Assign locations to all of the incoming arguments.
164*349cc55cSDimitry Andric   SmallVector<CCValAssign, 16> ArgLocs;
165*349cc55cSDimitry Andric   CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
166*349cc55cSDimitry Andric 
167*349cc55cSDimitry Andric   CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));
168*349cc55cSDimitry Andric 
169*349cc55cSDimitry Andric   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
170*349cc55cSDimitry Andric     CCValAssign &VA = ArgLocs[i];
171*349cc55cSDimitry Andric     SDValue ArgValue;
172*349cc55cSDimitry Andric 
173*349cc55cSDimitry Andric     if (VA.isRegLoc())
174*349cc55cSDimitry Andric       ArgValue = unpackFromRegLoc(Subtarget, DAG, Chain, VA, DL);
175*349cc55cSDimitry Andric     else
176*349cc55cSDimitry Andric       ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
177*349cc55cSDimitry Andric 
178*349cc55cSDimitry Andric     InVals.push_back(ArgValue);
179*349cc55cSDimitry Andric   }
180*349cc55cSDimitry Andric 
181*349cc55cSDimitry Andric   if (IsVarArg) {
182*349cc55cSDimitry Andric     const unsigned XLenInBytes = 4;
183*349cc55cSDimitry Andric     const MVT XLenVT = MVT::i32;
184*349cc55cSDimitry Andric 
185*349cc55cSDimitry Andric     ArrayRef<MCPhysReg> ArgRegs = makeArrayRef(GPRArgRegs);
186*349cc55cSDimitry Andric     unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
187*349cc55cSDimitry Andric     const TargetRegisterClass *RC = &CSKY::GPRRegClass;
188*349cc55cSDimitry Andric     MachineFrameInfo &MFI = MF.getFrameInfo();
189*349cc55cSDimitry Andric     MachineRegisterInfo &RegInfo = MF.getRegInfo();
190*349cc55cSDimitry Andric     CSKYMachineFunctionInfo *CSKYFI = MF.getInfo<CSKYMachineFunctionInfo>();
191*349cc55cSDimitry Andric 
192*349cc55cSDimitry Andric     // Offset of the first variable argument from stack pointer, and size of
193*349cc55cSDimitry Andric     // the vararg save area. For now, the varargs save area is either zero or
194*349cc55cSDimitry Andric     // large enough to hold a0-a4.
195*349cc55cSDimitry Andric     int VaArgOffset, VarArgsSaveSize;
196*349cc55cSDimitry Andric 
197*349cc55cSDimitry Andric     // If all registers are allocated, then all varargs must be passed on the
198*349cc55cSDimitry Andric     // stack and we don't need to save any argregs.
199*349cc55cSDimitry Andric     if (ArgRegs.size() == Idx) {
200*349cc55cSDimitry Andric       VaArgOffset = CCInfo.getNextStackOffset();
201*349cc55cSDimitry Andric       VarArgsSaveSize = 0;
202*349cc55cSDimitry Andric     } else {
203*349cc55cSDimitry Andric       VarArgsSaveSize = XLenInBytes * (ArgRegs.size() - Idx);
204*349cc55cSDimitry Andric       VaArgOffset = -VarArgsSaveSize;
205*349cc55cSDimitry Andric     }
206*349cc55cSDimitry Andric 
207*349cc55cSDimitry Andric     // Record the frame index of the first variable argument
208*349cc55cSDimitry Andric     // which is a value necessary to VASTART.
209*349cc55cSDimitry Andric     int FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
210*349cc55cSDimitry Andric     CSKYFI->setVarArgsFrameIndex(FI);
211*349cc55cSDimitry Andric 
212*349cc55cSDimitry Andric     // Copy the integer registers that may have been used for passing varargs
213*349cc55cSDimitry Andric     // to the vararg save area.
214*349cc55cSDimitry Andric     for (unsigned I = Idx; I < ArgRegs.size();
215*349cc55cSDimitry Andric          ++I, VaArgOffset += XLenInBytes) {
216*349cc55cSDimitry Andric       const Register Reg = RegInfo.createVirtualRegister(RC);
217*349cc55cSDimitry Andric       RegInfo.addLiveIn(ArgRegs[I], Reg);
218*349cc55cSDimitry Andric       SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, XLenVT);
219*349cc55cSDimitry Andric       FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
220*349cc55cSDimitry Andric       SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
221*349cc55cSDimitry Andric       SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,
222*349cc55cSDimitry Andric                                    MachinePointerInfo::getFixedStack(MF, FI));
223*349cc55cSDimitry Andric       cast<StoreSDNode>(Store.getNode())
224*349cc55cSDimitry Andric           ->getMemOperand()
225*349cc55cSDimitry Andric           ->setValue((Value *)nullptr);
226*349cc55cSDimitry Andric       OutChains.push_back(Store);
227*349cc55cSDimitry Andric     }
228*349cc55cSDimitry Andric     CSKYFI->setVarArgsSaveSize(VarArgsSaveSize);
229*349cc55cSDimitry Andric   }
230*349cc55cSDimitry Andric 
231*349cc55cSDimitry Andric   // All stores are grouped in one node to allow the matching between
232*349cc55cSDimitry Andric   // the size of Ins and InVals. This only happens for vararg functions.
233*349cc55cSDimitry Andric   if (!OutChains.empty()) {
234*349cc55cSDimitry Andric     OutChains.push_back(Chain);
235*349cc55cSDimitry Andric     Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
236*349cc55cSDimitry Andric   }
237*349cc55cSDimitry Andric 
238*349cc55cSDimitry Andric   return Chain;
239*349cc55cSDimitry Andric }
240*349cc55cSDimitry Andric 
241*349cc55cSDimitry Andric bool CSKYTargetLowering::CanLowerReturn(
242*349cc55cSDimitry Andric     CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
243*349cc55cSDimitry Andric     const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
244*349cc55cSDimitry Andric   SmallVector<CCValAssign, 16> CSKYLocs;
245*349cc55cSDimitry Andric   CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context);
246*349cc55cSDimitry Andric   return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
247*349cc55cSDimitry Andric }
248*349cc55cSDimitry Andric 
249*349cc55cSDimitry Andric SDValue
250*349cc55cSDimitry Andric CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
251*349cc55cSDimitry Andric                                 bool IsVarArg,
252*349cc55cSDimitry Andric                                 const SmallVectorImpl<ISD::OutputArg> &Outs,
253*349cc55cSDimitry Andric                                 const SmallVectorImpl<SDValue> &OutVals,
254*349cc55cSDimitry Andric                                 const SDLoc &DL, SelectionDAG &DAG) const {
255*349cc55cSDimitry Andric   // Stores the assignment of the return value to a location.
256*349cc55cSDimitry Andric   SmallVector<CCValAssign, 16> CSKYLocs;
257*349cc55cSDimitry Andric 
258*349cc55cSDimitry Andric   // Info about the registers and stack slot.
259*349cc55cSDimitry Andric   CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), CSKYLocs,
260*349cc55cSDimitry Andric                  *DAG.getContext());
261*349cc55cSDimitry Andric   CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
262*349cc55cSDimitry Andric 
263*349cc55cSDimitry Andric   SDValue Glue;
264*349cc55cSDimitry Andric   SmallVector<SDValue, 4> RetOps(1, Chain);
265*349cc55cSDimitry Andric 
266*349cc55cSDimitry Andric   // Copy the result values into the output registers.
267*349cc55cSDimitry Andric   for (unsigned i = 0, e = CSKYLocs.size(); i < e; ++i) {
268*349cc55cSDimitry Andric     SDValue Val = OutVals[i];
269*349cc55cSDimitry Andric     CCValAssign &VA = CSKYLocs[i];
270*349cc55cSDimitry Andric     assert(VA.isRegLoc() && "Can only return in registers!");
271*349cc55cSDimitry Andric 
272*349cc55cSDimitry Andric     bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
273*349cc55cSDimitry Andric 
274*349cc55cSDimitry Andric     if (IsF64OnCSKY) {
275*349cc55cSDimitry Andric 
276*349cc55cSDimitry Andric       assert(VA.isRegLoc() && "Expected return via registers");
277*349cc55cSDimitry Andric       SDValue Split64 = DAG.getNode(CSKYISD::BITCAST_TO_LOHI, DL,
278*349cc55cSDimitry Andric                                     DAG.getVTList(MVT::i32, MVT::i32), Val);
279*349cc55cSDimitry Andric       SDValue Lo = Split64.getValue(0);
280*349cc55cSDimitry Andric       SDValue Hi = Split64.getValue(1);
281*349cc55cSDimitry Andric 
282*349cc55cSDimitry Andric       Register RegLo = VA.getLocReg();
283*349cc55cSDimitry Andric       assert(RegLo < CSKY::R31 && "Invalid register pair");
284*349cc55cSDimitry Andric       Register RegHi = RegLo + 1;
285*349cc55cSDimitry Andric 
286*349cc55cSDimitry Andric       Chain = DAG.getCopyToReg(Chain, DL, RegLo, Lo, Glue);
287*349cc55cSDimitry Andric       Glue = Chain.getValue(1);
288*349cc55cSDimitry Andric       RetOps.push_back(DAG.getRegister(RegLo, MVT::i32));
289*349cc55cSDimitry Andric       Chain = DAG.getCopyToReg(Chain, DL, RegHi, Hi, Glue);
290*349cc55cSDimitry Andric       Glue = Chain.getValue(1);
291*349cc55cSDimitry Andric       RetOps.push_back(DAG.getRegister(RegHi, MVT::i32));
292*349cc55cSDimitry Andric     } else {
293*349cc55cSDimitry Andric       // Handle a 'normal' return.
294*349cc55cSDimitry Andric       Val = convertValVTToLocVT(DAG, Val, VA, DL);
295*349cc55cSDimitry Andric       Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue);
296*349cc55cSDimitry Andric 
297*349cc55cSDimitry Andric       // Guarantee that all emitted copies are stuck together.
298*349cc55cSDimitry Andric       Glue = Chain.getValue(1);
299*349cc55cSDimitry Andric       RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
300*349cc55cSDimitry Andric     }
301*349cc55cSDimitry Andric   }
302*349cc55cSDimitry Andric 
303*349cc55cSDimitry Andric   RetOps[0] = Chain; // Update chain.
304*349cc55cSDimitry Andric 
305*349cc55cSDimitry Andric   // Add the glue node if we have it.
306*349cc55cSDimitry Andric   if (Glue.getNode()) {
307*349cc55cSDimitry Andric     RetOps.push_back(Glue);
308*349cc55cSDimitry Andric   }
309*349cc55cSDimitry Andric 
310*349cc55cSDimitry Andric   // Interrupt service routines use different return instructions.
311*349cc55cSDimitry Andric   if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt"))
312*349cc55cSDimitry Andric     return DAG.getNode(CSKYISD::NIR, DL, MVT::Other, RetOps);
313*349cc55cSDimitry Andric 
314*349cc55cSDimitry Andric   return DAG.getNode(CSKYISD::RET, DL, MVT::Other, RetOps);
315*349cc55cSDimitry Andric }
316*349cc55cSDimitry Andric 
317*349cc55cSDimitry Andric CCAssignFn *CSKYTargetLowering::CCAssignFnForReturn(CallingConv::ID CC,
318*349cc55cSDimitry Andric                                                     bool IsVarArg) const {
319*349cc55cSDimitry Andric   if (IsVarArg || !Subtarget.useHardFloatABI())
320*349cc55cSDimitry Andric     return RetCC_CSKY_ABIV2_SOFT;
321*349cc55cSDimitry Andric   else
322*349cc55cSDimitry Andric     return RetCC_CSKY_ABIV2_FP;
323*349cc55cSDimitry Andric }
324*349cc55cSDimitry Andric 
325*349cc55cSDimitry Andric CCAssignFn *CSKYTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
326*349cc55cSDimitry Andric                                                   bool IsVarArg) const {
327*349cc55cSDimitry Andric   if (IsVarArg || !Subtarget.useHardFloatABI())
328*349cc55cSDimitry Andric     return CC_CSKY_ABIV2_SOFT;
329*349cc55cSDimitry Andric   else
330*349cc55cSDimitry Andric     return CC_CSKY_ABIV2_FP;
331*349cc55cSDimitry Andric }
332*349cc55cSDimitry Andric 
333*349cc55cSDimitry Andric const char *CSKYTargetLowering::getTargetNodeName(unsigned Opcode) const {
334*349cc55cSDimitry Andric   switch (Opcode) {
335*349cc55cSDimitry Andric   default:
336*349cc55cSDimitry Andric     llvm_unreachable("unknown CSKYISD node");
337*349cc55cSDimitry Andric   case CSKYISD::NIE:
338*349cc55cSDimitry Andric     return "CSKYISD::NIE";
339*349cc55cSDimitry Andric   case CSKYISD::NIR:
340*349cc55cSDimitry Andric     return "CSKYISD::NIR";
341*349cc55cSDimitry Andric   case CSKYISD::RET:
342*349cc55cSDimitry Andric     return "CSKYISD::RET";
343*349cc55cSDimitry Andric   case CSKYISD::BITCAST_TO_LOHI:
344*349cc55cSDimitry Andric     return "CSKYISD::BITCAST_TO_LOHI";
345*349cc55cSDimitry Andric   }
346*349cc55cSDimitry Andric }
347