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