1385 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the interfaces that CSKY uses to lower LLVM code into a10// 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 26using namespace llvm;27 28#define DEBUG_TYPE "csky-isel-lowering"29 30STATISTIC(NumTailCalls, "Number of tail calls");31 32#include "CSKYGenCallingConv.inc"33 34static const MCPhysReg GPRArgRegs[] = {CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3};35 36CSKYTargetLowering::CSKYTargetLowering(const TargetMachine &TM,37 const CSKYSubtarget &STI)38 : TargetLowering(TM, STI), Subtarget(STI) {39 // Register Class40 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 // Float113 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 165SDValue 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 191EVT 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 199static 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 215static 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 229static 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::sFPR32RegClass246 : &CSKY::FPR32RegClass;247 break;248 case MVT::f64:249 RC = Subtarget.hasFPUv2DoubleFloat() ? &CSKY::sFPR64RegClass250 : &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 261static 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 288static 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.327SDValue 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 else362 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 of379 // the vararg save area. For now, the varargs save area is either zero or380 // large enough to hold a0-a4.381 int VaArgOffset, VarArgsSaveSize;382 383 // If all registers are allocated, then all varargs must be passed on the384 // 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 argument394 // 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 varargs399 // 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 between418 // 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 427bool CSKYTargetLowering::CanLowerReturn(428 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,429 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,430 const Type *RetTy) const {431 SmallVector<CCValAssign, 16> CSKYLocs;432 CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context);433 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));434}435 436SDValue437CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,438 bool IsVarArg,439 const SmallVectorImpl<ISD::OutputArg> &Outs,440 const SmallVectorImpl<SDValue> &OutVals,441 const SDLoc &DL, SelectionDAG &DAG) const {442 // Stores the assignment of the return value to a location.443 SmallVector<CCValAssign, 16> CSKYLocs;444 445 // Info about the registers and stack slot.446 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), CSKYLocs,447 *DAG.getContext());448 CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));449 450 SDValue Glue;451 SmallVector<SDValue, 4> RetOps(1, Chain);452 453 // Copy the result values into the output registers.454 for (unsigned i = 0, e = CSKYLocs.size(); i < e; ++i) {455 SDValue Val = OutVals[i];456 CCValAssign &VA = CSKYLocs[i];457 assert(VA.isRegLoc() && "Can only return in registers!");458 459 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;460 461 if (IsF64OnCSKY) {462 463 assert(VA.isRegLoc() && "Expected return via registers");464 SDValue Split64 = DAG.getNode(CSKYISD::BITCAST_TO_LOHI, DL,465 DAG.getVTList(MVT::i32, MVT::i32), Val);466 SDValue Lo = Split64.getValue(0);467 SDValue Hi = Split64.getValue(1);468 469 Register RegLo = VA.getLocReg();470 assert(RegLo < CSKY::R31 && "Invalid register pair");471 Register RegHi = RegLo + 1;472 473 Chain = DAG.getCopyToReg(Chain, DL, RegLo, Lo, Glue);474 Glue = Chain.getValue(1);475 RetOps.push_back(DAG.getRegister(RegLo, MVT::i32));476 Chain = DAG.getCopyToReg(Chain, DL, RegHi, Hi, Glue);477 Glue = Chain.getValue(1);478 RetOps.push_back(DAG.getRegister(RegHi, MVT::i32));479 } else {480 // Handle a 'normal' return.481 Val = convertValVTToLocVT(DAG, Val, VA, DL);482 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue);483 484 // Guarantee that all emitted copies are stuck together.485 Glue = Chain.getValue(1);486 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));487 }488 }489 490 RetOps[0] = Chain; // Update chain.491 492 // Add the glue node if we have it.493 if (Glue.getNode()) {494 RetOps.push_back(Glue);495 }496 497 // Interrupt service routines use different return instructions.498 if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt"))499 return DAG.getNode(CSKYISD::NIR, DL, MVT::Other, RetOps);500 501 return DAG.getNode(CSKYISD::RET, DL, MVT::Other, RetOps);502}503 504// Lower a call to a callseq_start + CALL + callseq_end chain, and add input505// and output parameter nodes.506SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,507 SmallVectorImpl<SDValue> &InVals) const {508 SelectionDAG &DAG = CLI.DAG;509 SDLoc &DL = CLI.DL;510 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;511 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;512 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;513 SDValue Chain = CLI.Chain;514 SDValue Callee = CLI.Callee;515 bool &IsTailCall = CLI.IsTailCall;516 CallingConv::ID CallConv = CLI.CallConv;517 bool IsVarArg = CLI.IsVarArg;518 EVT PtrVT = getPointerTy(DAG.getDataLayout());519 MVT XLenVT = MVT::i32;520 521 MachineFunction &MF = DAG.getMachineFunction();522 523 // Analyze the operands of the call, assigning locations to each operand.524 SmallVector<CCValAssign, 16> ArgLocs;525 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());526 527 ArgCCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, IsVarArg));528 529 // Check if it's really possible to do a tail call.530 if (IsTailCall)531 IsTailCall = false; // TODO: TailCallOptimization;532 533 if (IsTailCall)534 ++NumTailCalls;535 else if (CLI.CB && CLI.CB->isMustTailCall())536 report_fatal_error("failed to perform tail call elimination on a call "537 "site marked musttail");538 539 // Get a count of how many bytes are to be pushed on the stack.540 unsigned NumBytes = ArgCCInfo.getStackSize();541 542 // Create local copies for byval args543 SmallVector<SDValue, 8> ByValArgs;544 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {545 ISD::ArgFlagsTy Flags = Outs[i].Flags;546 if (!Flags.isByVal())547 continue;548 549 SDValue Arg = OutVals[i];550 unsigned Size = Flags.getByValSize();551 Align Alignment = Flags.getNonZeroByValAlign();552 553 int FI =554 MF.getFrameInfo().CreateStackObject(Size, Alignment, /*isSS=*/false);555 SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));556 SDValue SizeNode = DAG.getConstant(Size, DL, XLenVT);557 558 Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment,559 /*IsVolatile=*/false,560 /*AlwaysInline=*/false, /*CI=*/nullptr, IsTailCall,561 MachinePointerInfo(), MachinePointerInfo());562 ByValArgs.push_back(FIPtr);563 }564 565 if (!IsTailCall)566 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);567 568 // Copy argument values to their designated locations.569 SmallVector<std::pair<Register, SDValue>, 8> RegsToPass;570 SmallVector<SDValue, 8> MemOpChains;571 SDValue StackPtr;572 for (unsigned i = 0, j = 0, e = ArgLocs.size(); i != e; ++i) {573 CCValAssign &VA = ArgLocs[i];574 SDValue ArgValue = OutVals[i];575 ISD::ArgFlagsTy Flags = Outs[i].Flags;576 577 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;578 579 if (IsF64OnCSKY && VA.isRegLoc()) {580 SDValue Split64 =581 DAG.getNode(CSKYISD::BITCAST_TO_LOHI, DL,582 DAG.getVTList(MVT::i32, MVT::i32), ArgValue);583 SDValue Lo = Split64.getValue(0);584 SDValue Hi = Split64.getValue(1);585 586 Register RegLo = VA.getLocReg();587 RegsToPass.push_back(std::make_pair(RegLo, Lo));588 589 if (RegLo == CSKY::R3) {590 // Second half of f64/i64 is passed on the stack.591 // Work out the address of the stack slot.592 if (!StackPtr.getNode())593 StackPtr = DAG.getCopyFromReg(Chain, DL, CSKY::R14, PtrVT);594 // Emit the store.595 MemOpChains.push_back(596 DAG.getStore(Chain, DL, Hi, StackPtr, MachinePointerInfo()));597 } else {598 // Second half of f64/i64 is passed in another GPR.599 assert(RegLo < CSKY::R31 && "Invalid register pair");600 Register RegHigh = RegLo + 1;601 RegsToPass.push_back(std::make_pair(RegHigh, Hi));602 }603 continue;604 }605 606 ArgValue = convertValVTToLocVT(DAG, ArgValue, VA, DL);607 608 // Use local copy if it is a byval arg.609 if (Flags.isByVal())610 ArgValue = ByValArgs[j++];611 612 if (VA.isRegLoc()) {613 // Queue up the argument copies and emit them at the end.614 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));615 } else {616 assert(VA.isMemLoc() && "Argument not register or memory");617 assert(!IsTailCall && "Tail call not allowed if stack is used "618 "for passing parameters");619 620 // Work out the address of the stack slot.621 if (!StackPtr.getNode())622 StackPtr = DAG.getCopyFromReg(Chain, DL, CSKY::R14, PtrVT);623 SDValue Address =624 DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,625 DAG.getIntPtrConstant(VA.getLocMemOffset(), DL));626 627 // Emit the store.628 MemOpChains.push_back(629 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));630 }631 }632 633 // Join the stores, which are independent of one another.634 if (!MemOpChains.empty())635 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);636 637 SDValue Glue;638 639 // Build a sequence of copy-to-reg nodes, chained and glued together.640 for (auto &Reg : RegsToPass) {641 Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, Glue);642 Glue = Chain.getValue(1);643 }644 645 SmallVector<SDValue, 8> Ops;646 EVT Ty = getPointerTy(DAG.getDataLayout());647 bool IsRegCall = false;648 649 Ops.push_back(Chain);650 651 if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {652 const GlobalValue *GV = S->getGlobal();653 bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(GV);654 655 if (isPositionIndependent() || !Subtarget.has2E3()) {656 IsRegCall = true;657 Ops.push_back(getAddr<GlobalAddressSDNode, true>(S, DAG, IsLocal));658 } else {659 Ops.push_back(getTargetNode(cast<GlobalAddressSDNode>(Callee), DL, Ty,660 DAG, CSKYII::MO_None));661 Ops.push_back(getTargetConstantPoolValue(662 cast<GlobalAddressSDNode>(Callee), Ty, DAG, CSKYII::MO_None));663 }664 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {665 bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(nullptr);666 667 if (isPositionIndependent() || !Subtarget.has2E3()) {668 IsRegCall = true;669 Ops.push_back(getAddr<ExternalSymbolSDNode, true>(S, DAG, IsLocal));670 } else {671 Ops.push_back(getTargetNode(cast<ExternalSymbolSDNode>(Callee), DL, Ty,672 DAG, CSKYII::MO_None));673 Ops.push_back(getTargetConstantPoolValue(674 cast<ExternalSymbolSDNode>(Callee), Ty, DAG, CSKYII::MO_None));675 }676 } else {677 IsRegCall = true;678 Ops.push_back(Callee);679 }680 681 // Add argument registers to the end of the list so that they are682 // known live into the call.683 for (auto &Reg : RegsToPass)684 Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));685 686 if (!IsTailCall) {687 // Add a register mask operand representing the call-preserved registers.688 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();689 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);690 assert(Mask && "Missing call preserved mask for calling convention");691 Ops.push_back(DAG.getRegisterMask(Mask));692 }693 694 // Glue the call to the argument copies, if any.695 if (Glue.getNode())696 Ops.push_back(Glue);697 698 // Emit the call.699 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);700 701 if (IsTailCall) {702 MF.getFrameInfo().setHasTailCall();703 return DAG.getNode(IsRegCall ? CSKYISD::TAILReg : CSKYISD::TAIL, DL,704 NodeTys, Ops);705 }706 707 Chain = DAG.getNode(IsRegCall ? CSKYISD::CALLReg : CSKYISD::CALL, DL, NodeTys,708 Ops);709 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);710 Glue = Chain.getValue(1);711 712 // Mark the end of the call, which is glued to the call itself.713 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, DL);714 Glue = Chain.getValue(1);715 716 // Assign locations to each value returned by this call.717 SmallVector<CCValAssign, 16> CSKYLocs;718 CCState RetCCInfo(CallConv, IsVarArg, MF, CSKYLocs, *DAG.getContext());719 RetCCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv, IsVarArg));720 721 // Copy all of the result registers out of their specified physreg.722 for (auto &VA : CSKYLocs) {723 // Copy the value out724 SDValue RetValue =725 DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue);726 // Glue the RetValue to the end of the call sequence727 Chain = RetValue.getValue(1);728 Glue = RetValue.getValue(2);729 730 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;731 732 if (IsF64OnCSKY) {733 assert(VA.getLocReg() == GPRArgRegs[0] && "Unexpected reg assignment");734 SDValue RetValue2 =735 DAG.getCopyFromReg(Chain, DL, GPRArgRegs[1], MVT::i32, Glue);736 Chain = RetValue2.getValue(1);737 Glue = RetValue2.getValue(2);738 RetValue = DAG.getNode(CSKYISD::BITCAST_FROM_LOHI, DL, VA.getValVT(),739 RetValue, RetValue2);740 }741 742 RetValue = convertLocVTToValVT(DAG, RetValue, VA, DL);743 744 InVals.push_back(RetValue);745 }746 747 return Chain;748}749 750CCAssignFn *CSKYTargetLowering::CCAssignFnForReturn(CallingConv::ID CC,751 bool IsVarArg) const {752 if (IsVarArg || !Subtarget.useHardFloatABI())753 return RetCC_CSKY_ABIV2_SOFT;754 else755 return RetCC_CSKY_ABIV2_FP;756}757 758CCAssignFn *CSKYTargetLowering::CCAssignFnForCall(CallingConv::ID CC,759 bool IsVarArg) const {760 if (IsVarArg || !Subtarget.useHardFloatABI())761 return CC_CSKY_ABIV2_SOFT;762 else763 return CC_CSKY_ABIV2_FP;764}765 766static CSKYCP::CSKYCPModifier getModifier(unsigned Flags) {767 768 if (Flags == CSKYII::MO_ADDR32)769 return CSKYCP::ADDR;770 else if (Flags == CSKYII::MO_GOT32)771 return CSKYCP::GOT;772 else if (Flags == CSKYII::MO_GOTOFF)773 return CSKYCP::GOTOFF;774 else if (Flags == CSKYII::MO_PLT32)775 return CSKYCP::PLT;776 else if (Flags == CSKYII::MO_None)777 return CSKYCP::NO_MOD;778 else779 assert(0 && "unknown CSKYII Modifier");780 return CSKYCP::NO_MOD;781}782 783SDValue CSKYTargetLowering::getTargetConstantPoolValue(GlobalAddressSDNode *N,784 EVT Ty,785 SelectionDAG &DAG,786 unsigned Flags) const {787 CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(788 N->getGlobal(), CSKYCP::CPValue, 0, getModifier(Flags), false);789 790 return DAG.getTargetConstantPool(CPV, Ty);791}792 793CSKYTargetLowering::ConstraintType794CSKYTargetLowering::getConstraintType(StringRef Constraint) const {795 if (Constraint.size() == 1) {796 switch (Constraint[0]) {797 default:798 break;799 case 'a':800 case 'b':801 case 'v':802 case 'w':803 case 'y':804 return C_RegisterClass;805 case 'c':806 case 'l':807 case 'h':808 case 'z':809 return C_Register;810 }811 }812 return TargetLowering::getConstraintType(Constraint);813}814 815std::pair<unsigned, const TargetRegisterClass *>816CSKYTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,817 StringRef Constraint,818 MVT VT) const {819 if (Constraint.size() == 1) {820 switch (Constraint[0]) {821 case 'r':822 return std::make_pair(0U, &CSKY::GPRRegClass);823 case 'a':824 return std::make_pair(0U, &CSKY::mGPRRegClass);825 case 'b':826 return std::make_pair(0U, &CSKY::sGPRRegClass);827 case 'z':828 return std::make_pair(CSKY::R14, &CSKY::GPRRegClass);829 case 'c':830 return std::make_pair(CSKY::C, &CSKY::CARRYRegClass);831 case 'w':832 if ((Subtarget.hasFPUv2SingleFloat() ||833 Subtarget.hasFPUv3SingleFloat()) &&834 VT == MVT::f32)835 return std::make_pair(0U, &CSKY::sFPR32RegClass);836 if ((Subtarget.hasFPUv2DoubleFloat() ||837 Subtarget.hasFPUv3DoubleFloat()) &&838 VT == MVT::f64)839 return std::make_pair(0U, &CSKY::sFPR64RegClass);840 break;841 case 'v':842 if (Subtarget.hasFPUv2SingleFloat() && VT == MVT::f32)843 return std::make_pair(0U, &CSKY::sFPR32RegClass);844 if (Subtarget.hasFPUv3SingleFloat() && VT == MVT::f32)845 return std::make_pair(0U, &CSKY::FPR32RegClass);846 if (Subtarget.hasFPUv2DoubleFloat() && VT == MVT::f64)847 return std::make_pair(0U, &CSKY::sFPR64RegClass);848 if (Subtarget.hasFPUv3DoubleFloat() && VT == MVT::f64)849 return std::make_pair(0U, &CSKY::FPR64RegClass);850 break;851 default:852 break;853 }854 }855 856 if (Constraint == "{c}")857 return std::make_pair(CSKY::C, &CSKY::CARRYRegClass);858 859 // Clang will correctly decode the usage of register name aliases into their860 // official names. However, other frontends like `rustc` do not. This allows861 // users of these frontends to use the ABI names for registers in LLVM-style862 // register constraints.863 unsigned XRegFromAlias = StringSwitch<unsigned>(Constraint.lower())864 .Case("{a0}", CSKY::R0)865 .Case("{a1}", CSKY::R1)866 .Case("{a2}", CSKY::R2)867 .Case("{a3}", CSKY::R3)868 .Case("{l0}", CSKY::R4)869 .Case("{l1}", CSKY::R5)870 .Case("{l2}", CSKY::R6)871 .Case("{l3}", CSKY::R7)872 .Case("{l4}", CSKY::R8)873 .Case("{l5}", CSKY::R9)874 .Case("{l6}", CSKY::R10)875 .Case("{l7}", CSKY::R11)876 .Case("{t0}", CSKY::R12)877 .Case("{t1}", CSKY::R13)878 .Case("{sp}", CSKY::R14)879 .Case("{lr}", CSKY::R15)880 .Case("{l8}", CSKY::R16)881 .Case("{l9}", CSKY::R17)882 .Case("{t2}", CSKY::R18)883 .Case("{t3}", CSKY::R19)884 .Case("{t4}", CSKY::R20)885 .Case("{t5}", CSKY::R21)886 .Case("{t6}", CSKY::R22)887 .Cases({"{t7}", "{fp}"}, CSKY::R23)888 .Cases({"{t8}", "{top}"}, CSKY::R24)889 .Cases({"{t9}", "{bsp}"}, CSKY::R25)890 .Case("{r26}", CSKY::R26)891 .Case("{r27}", CSKY::R27)892 .Cases({"{gb}", "{rgb}", "{rdb}"}, CSKY::R28)893 .Cases({"{tb}", "{rtb}"}, CSKY::R29)894 .Case("{svbr}", CSKY::R30)895 .Case("{tls}", CSKY::R31)896 .Default(CSKY::NoRegister);897 898 if (XRegFromAlias != CSKY::NoRegister)899 return std::make_pair(XRegFromAlias, &CSKY::GPRRegClass);900 901 // Since TargetLowering::getRegForInlineAsmConstraint uses the name of the902 // TableGen record rather than the AsmName to choose registers for InlineAsm903 // constraints, plus we want to match those names to the widest floating point904 // register type available, manually select floating point registers here.905 //906 // The second case is the ABI name of the register, so that frontends can also907 // use the ABI names in register constraint lists.908 if (Subtarget.useHardFloat()) {909 unsigned FReg = StringSwitch<unsigned>(Constraint.lower())910 .Cases({"{fr0}", "{vr0}"}, CSKY::F0_32)911 .Cases({"{fr1}", "{vr1}"}, CSKY::F1_32)912 .Cases({"{fr2}", "{vr2}"}, CSKY::F2_32)913 .Cases({"{fr3}", "{vr3}"}, CSKY::F3_32)914 .Cases({"{fr4}", "{vr4}"}, CSKY::F4_32)915 .Cases({"{fr5}", "{vr5}"}, CSKY::F5_32)916 .Cases({"{fr6}", "{vr6}"}, CSKY::F6_32)917 .Cases({"{fr7}", "{vr7}"}, CSKY::F7_32)918 .Cases({"{fr8}", "{vr8}"}, CSKY::F8_32)919 .Cases({"{fr9}", "{vr9}"}, CSKY::F9_32)920 .Cases({"{fr10}", "{vr10}"}, CSKY::F10_32)921 .Cases({"{fr11}", "{vr11}"}, CSKY::F11_32)922 .Cases({"{fr12}", "{vr12}"}, CSKY::F12_32)923 .Cases({"{fr13}", "{vr13}"}, CSKY::F13_32)924 .Cases({"{fr14}", "{vr14}"}, CSKY::F14_32)925 .Cases({"{fr15}", "{vr15}"}, CSKY::F15_32)926 .Cases({"{fr16}", "{vr16}"}, CSKY::F16_32)927 .Cases({"{fr17}", "{vr17}"}, CSKY::F17_32)928 .Cases({"{fr18}", "{vr18}"}, CSKY::F18_32)929 .Cases({"{fr19}", "{vr19}"}, CSKY::F19_32)930 .Cases({"{fr20}", "{vr20}"}, CSKY::F20_32)931 .Cases({"{fr21}", "{vr21}"}, CSKY::F21_32)932 .Cases({"{fr22}", "{vr22}"}, CSKY::F22_32)933 .Cases({"{fr23}", "{vr23}"}, CSKY::F23_32)934 .Cases({"{fr24}", "{vr24}"}, CSKY::F24_32)935 .Cases({"{fr25}", "{vr25}"}, CSKY::F25_32)936 .Cases({"{fr26}", "{vr26}"}, CSKY::F26_32)937 .Cases({"{fr27}", "{vr27}"}, CSKY::F27_32)938 .Cases({"{fr28}", "{vr28}"}, CSKY::F28_32)939 .Cases({"{fr29}", "{vr29}"}, CSKY::F29_32)940 .Cases({"{fr30}", "{vr30}"}, CSKY::F30_32)941 .Cases({"{fr31}", "{vr31}"}, CSKY::F31_32)942 .Default(CSKY::NoRegister);943 if (FReg != CSKY::NoRegister) {944 assert(CSKY::F0_32 <= FReg && FReg <= CSKY::F31_32 && "Unknown fp-reg");945 unsigned RegNo = FReg - CSKY::F0_32;946 unsigned DReg = CSKY::F0_64 + RegNo;947 948 if (Subtarget.hasFPUv2DoubleFloat())949 return std::make_pair(DReg, &CSKY::sFPR64RegClass);950 else if (Subtarget.hasFPUv3DoubleFloat())951 return std::make_pair(DReg, &CSKY::FPR64RegClass);952 else if (Subtarget.hasFPUv2SingleFloat())953 return std::make_pair(FReg, &CSKY::sFPR32RegClass);954 else if (Subtarget.hasFPUv3SingleFloat())955 return std::make_pair(FReg, &CSKY::FPR32RegClass);956 }957 }958 959 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);960}961 962static MachineBasicBlock *963emitSelectPseudo(MachineInstr &MI, MachineBasicBlock *BB, unsigned Opcode) {964 965 const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();966 DebugLoc DL = MI.getDebugLoc();967 968 // To "insert" a SELECT instruction, we actually have to insert the969 // diamond control-flow pattern. The incoming instruction knows the970 // destination vreg to set, the condition code register to branch on, the971 // true/false values to select between, and a branch opcode to use.972 const BasicBlock *LLVM_BB = BB->getBasicBlock();973 MachineFunction::iterator It = ++BB->getIterator();974 975 // thisMBB:976 // ...977 // TrueVal = ...978 // bt32 c, sinkMBB979 // fallthrough --> copyMBB980 MachineBasicBlock *thisMBB = BB;981 MachineFunction *F = BB->getParent();982 MachineBasicBlock *copyMBB = F->CreateMachineBasicBlock(LLVM_BB);983 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);984 F->insert(It, copyMBB);985 F->insert(It, sinkMBB);986 987 // Transfer the remainder of BB and its successor edges to sinkMBB.988 sinkMBB->splice(sinkMBB->begin(), BB,989 std::next(MachineBasicBlock::iterator(MI)), BB->end());990 sinkMBB->transferSuccessorsAndUpdatePHIs(BB);991 992 // Next, add the true and fallthrough blocks as its successors.993 BB->addSuccessor(copyMBB);994 BB->addSuccessor(sinkMBB);995 996 // bt32 condition, sinkMBB997 BuildMI(BB, DL, TII.get(Opcode))998 .addReg(MI.getOperand(1).getReg())999 .addMBB(sinkMBB);1000 1001 // copyMBB:1002 // %FalseValue = ...1003 // # fallthrough to sinkMBB1004 BB = copyMBB;1005 1006 // Update machine-CFG edges1007 BB->addSuccessor(sinkMBB);1008 1009 // sinkMBB:1010 // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copyMBB ]1011 // ...1012 BB = sinkMBB;1013 1014 BuildMI(*BB, BB->begin(), DL, TII.get(CSKY::PHI), MI.getOperand(0).getReg())1015 .addReg(MI.getOperand(2).getReg())1016 .addMBB(thisMBB)1017 .addReg(MI.getOperand(3).getReg())1018 .addMBB(copyMBB);1019 1020 MI.eraseFromParent(); // The pseudo instruction is gone now.1021 1022 return BB;1023}1024 1025MachineBasicBlock *1026CSKYTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,1027 MachineBasicBlock *BB) const {1028 switch (MI.getOpcode()) {1029 default:1030 llvm_unreachable("Unexpected instr type to insert");1031 case CSKY::FSELS:1032 case CSKY::FSELD:1033 if (Subtarget.hasE2())1034 return emitSelectPseudo(MI, BB, CSKY::BT32);1035 else1036 return emitSelectPseudo(MI, BB, CSKY::BT16);1037 case CSKY::ISEL32:1038 return emitSelectPseudo(MI, BB, CSKY::BT32);1039 case CSKY::ISEL16:1040 return emitSelectPseudo(MI, BB, CSKY::BT16);1041 }1042}1043 1044SDValue CSKYTargetLowering::getTargetConstantPoolValue(ExternalSymbolSDNode *N,1045 EVT Ty,1046 SelectionDAG &DAG,1047 unsigned Flags) const {1048 CSKYConstantPoolValue *CPV =1049 CSKYConstantPoolSymbol::Create(Type::getInt32Ty(*DAG.getContext()),1050 N->getSymbol(), 0, getModifier(Flags));1051 1052 return DAG.getTargetConstantPool(CPV, Ty);1053}1054 1055SDValue CSKYTargetLowering::getTargetConstantPoolValue(JumpTableSDNode *N,1056 EVT Ty,1057 SelectionDAG &DAG,1058 unsigned Flags) const {1059 CSKYConstantPoolValue *CPV =1060 CSKYConstantPoolJT::Create(Type::getInt32Ty(*DAG.getContext()),1061 N->getIndex(), 0, getModifier(Flags));1062 return DAG.getTargetConstantPool(CPV, Ty);1063}1064 1065SDValue CSKYTargetLowering::getTargetConstantPoolValue(BlockAddressSDNode *N,1066 EVT Ty,1067 SelectionDAG &DAG,1068 unsigned Flags) const {1069 assert(N->getOffset() == 0);1070 CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(1071 N->getBlockAddress(), CSKYCP::CPBlockAddress, 0, getModifier(Flags),1072 false);1073 return DAG.getTargetConstantPool(CPV, Ty);1074}1075 1076SDValue CSKYTargetLowering::getTargetConstantPoolValue(ConstantPoolSDNode *N,1077 EVT Ty,1078 SelectionDAG &DAG,1079 unsigned Flags) const {1080 assert(N->getOffset() == 0);1081 CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(1082 N->getConstVal(), Type::getInt32Ty(*DAG.getContext()),1083 CSKYCP::CPConstPool, 0, getModifier(Flags), false);1084 return DAG.getTargetConstantPool(CPV, Ty);1085}1086 1087SDValue CSKYTargetLowering::getTargetNode(GlobalAddressSDNode *N, SDLoc DL,1088 EVT Ty, SelectionDAG &DAG,1089 unsigned Flags) const {1090 return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags);1091}1092 1093SDValue CSKYTargetLowering::getTargetNode(ExternalSymbolSDNode *N, SDLoc DL,1094 EVT Ty, SelectionDAG &DAG,1095 unsigned Flags) const {1096 return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flags);1097}1098 1099SDValue CSKYTargetLowering::getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty,1100 SelectionDAG &DAG,1101 unsigned Flags) const {1102 return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);1103}1104 1105SDValue CSKYTargetLowering::getTargetNode(BlockAddressSDNode *N, SDLoc DL,1106 EVT Ty, SelectionDAG &DAG,1107 unsigned Flags) const {1108 return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, N->getOffset(),1109 Flags);1110}1111 1112SDValue CSKYTargetLowering::getTargetNode(ConstantPoolSDNode *N, SDLoc DL,1113 EVT Ty, SelectionDAG &DAG,1114 unsigned Flags) const {1115 1116 return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),1117 N->getOffset(), Flags);1118}1119 1120SDValue CSKYTargetLowering::LowerGlobalAddress(SDValue Op,1121 SelectionDAG &DAG) const {1122 SDLoc DL(Op);1123 EVT Ty = Op.getValueType();1124 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);1125 int64_t Offset = N->getOffset();1126 1127 const GlobalValue *GV = N->getGlobal();1128 bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(GV);1129 SDValue Addr = getAddr<GlobalAddressSDNode, false>(N, DAG, IsLocal);1130 1131 // In order to maximise the opportunity for common subexpression elimination,1132 // emit a separate ADD node for the global address offset instead of folding1133 // it in the global address node. Later peephole optimisations may choose to1134 // fold it back in when profitable.1135 if (Offset != 0)1136 return DAG.getNode(ISD::ADD, DL, Ty, Addr,1137 DAG.getConstant(Offset, DL, MVT::i32));1138 return Addr;1139}1140 1141SDValue CSKYTargetLowering::LowerExternalSymbol(SDValue Op,1142 SelectionDAG &DAG) const {1143 ExternalSymbolSDNode *N = cast<ExternalSymbolSDNode>(Op);1144 1145 return getAddr(N, DAG, false);1146}1147 1148SDValue CSKYTargetLowering::LowerJumpTable(SDValue Op,1149 SelectionDAG &DAG) const {1150 JumpTableSDNode *N = cast<JumpTableSDNode>(Op);1151 1152 return getAddr<JumpTableSDNode, false>(N, DAG);1153}1154 1155SDValue CSKYTargetLowering::LowerBlockAddress(SDValue Op,1156 SelectionDAG &DAG) const {1157 BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);1158 1159 return getAddr(N, DAG);1160}1161 1162SDValue CSKYTargetLowering::LowerConstantPool(SDValue Op,1163 SelectionDAG &DAG) const {1164 assert(!Subtarget.hasE2());1165 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);1166 1167 return getAddr(N, DAG);1168}1169 1170SDValue CSKYTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {1171 MachineFunction &MF = DAG.getMachineFunction();1172 CSKYMachineFunctionInfo *FuncInfo = MF.getInfo<CSKYMachineFunctionInfo>();1173 1174 SDLoc DL(Op);1175 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),1176 getPointerTy(MF.getDataLayout()));1177 1178 // vastart just stores the address of the VarArgsFrameIndex slot into the1179 // memory location argument.1180 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();1181 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),1182 MachinePointerInfo(SV));1183}1184 1185SDValue CSKYTargetLowering::LowerFRAMEADDR(SDValue Op,1186 SelectionDAG &DAG) const {1187 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();1188 MachineFunction &MF = DAG.getMachineFunction();1189 MachineFrameInfo &MFI = MF.getFrameInfo();1190 MFI.setFrameAddressIsTaken(true);1191 1192 EVT VT = Op.getValueType();1193 SDLoc dl(Op);1194 unsigned Depth = Op.getConstantOperandVal(0);1195 Register FrameReg = RI.getFrameRegister(MF);1196 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);1197 while (Depth--)1198 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,1199 MachinePointerInfo());1200 return FrameAddr;1201}1202 1203SDValue CSKYTargetLowering::LowerRETURNADDR(SDValue Op,1204 SelectionDAG &DAG) const {1205 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();1206 MachineFunction &MF = DAG.getMachineFunction();1207 MachineFrameInfo &MFI = MF.getFrameInfo();1208 MFI.setReturnAddressIsTaken(true);1209 1210 EVT VT = Op.getValueType();1211 SDLoc dl(Op);1212 unsigned Depth = Op.getConstantOperandVal(0);1213 if (Depth) {1214 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);1215 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);1216 return DAG.getLoad(VT, dl, DAG.getEntryNode(),1217 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),1218 MachinePointerInfo());1219 }1220 // Return the value of the return address register, marking it an implicit1221 // live-in.1222 unsigned Reg = MF.addLiveIn(RI.getRARegister(), getRegClassFor(MVT::i32));1223 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);1224}1225 1226Register CSKYTargetLowering::getExceptionPointerRegister(1227 const Constant *PersonalityFn) const {1228 return CSKY::R0;1229}1230 1231Register CSKYTargetLowering::getExceptionSelectorRegister(1232 const Constant *PersonalityFn) const {1233 return CSKY::R1;1234}1235 1236SDValue CSKYTargetLowering::LowerGlobalTLSAddress(SDValue Op,1237 SelectionDAG &DAG) const {1238 SDLoc DL(Op);1239 EVT Ty = Op.getValueType();1240 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);1241 int64_t Offset = N->getOffset();1242 MVT XLenVT = MVT::i32;1243 1244 TLSModel::Model Model = getTargetMachine().getTLSModel(N->getGlobal());1245 SDValue Addr;1246 switch (Model) {1247 case TLSModel::LocalExec:1248 Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/false);1249 break;1250 case TLSModel::InitialExec:1251 Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/true);1252 break;1253 case TLSModel::LocalDynamic:1254 case TLSModel::GeneralDynamic:1255 Addr = getDynamicTLSAddr(N, DAG);1256 break;1257 }1258 1259 // In order to maximise the opportunity for common subexpression elimination,1260 // emit a separate ADD node for the global address offset instead of folding1261 // it in the global address node. Later peephole optimisations may choose to1262 // fold it back in when profitable.1263 if (Offset != 0)1264 return DAG.getNode(ISD::ADD, DL, Ty, Addr,1265 DAG.getConstant(Offset, DL, XLenVT));1266 return Addr;1267}1268 1269SDValue CSKYTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,1270 SelectionDAG &DAG,1271 bool UseGOT) const {1272 MachineFunction &MF = DAG.getMachineFunction();1273 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();1274 1275 unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();1276 1277 SDLoc DL(N);1278 EVT Ty = getPointerTy(DAG.getDataLayout());1279 1280 CSKYCP::CSKYCPModifier Flag = UseGOT ? CSKYCP::TLSIE : CSKYCP::TLSLE;1281 bool AddCurrentAddr = UseGOT ? true : false;1282 unsigned char PCAjust = UseGOT ? 4 : 0;1283 1284 CSKYConstantPoolValue *CPV =1285 CSKYConstantPoolConstant::Create(N->getGlobal(), CSKYCP::CPValue, PCAjust,1286 Flag, AddCurrentAddr, CSKYPCLabelIndex);1287 SDValue CAddr = DAG.getTargetConstantPool(CPV, Ty);1288 1289 SDValue Load;1290 if (UseGOT) {1291 SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);1292 auto *LRWGRS = DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty},1293 {CAddr, PICLabel});1294 auto LRWADDGRS =1295 DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));1296 Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), LRWADDGRS,1297 MachinePointerInfo(N->getGlobal()));1298 } else {1299 Load = SDValue(DAG.getMachineNode(CSKY::LRW32, DL, Ty, CAddr), 0);1300 }1301 1302 // Add the thread pointer.1303 SDValue TPReg = DAG.getRegister(CSKY::R31, MVT::i32);1304 return DAG.getNode(ISD::ADD, DL, Ty, Load, TPReg);1305}1306 1307SDValue CSKYTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N,1308 SelectionDAG &DAG) const {1309 MachineFunction &MF = DAG.getMachineFunction();1310 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();1311 1312 unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();1313 1314 SDLoc DL(N);1315 EVT Ty = getPointerTy(DAG.getDataLayout());1316 IntegerType *CallTy = Type::getIntNTy(*DAG.getContext(), Ty.getSizeInBits());1317 1318 CSKYConstantPoolValue *CPV =1319 CSKYConstantPoolConstant::Create(N->getGlobal(), CSKYCP::CPValue, 4,1320 CSKYCP::TLSGD, true, CSKYPCLabelIndex);1321 SDValue Addr = DAG.getTargetConstantPool(CPV, Ty);1322 SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);1323 1324 auto *LRWGRS =1325 DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty}, {Addr, PICLabel});1326 1327 auto Load =1328 DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));1329 1330 // Prepare argument list to generate call.1331 ArgListTy Args;1332 Args.emplace_back(Load, CallTy);1333 1334 // Setup call to __tls_get_addr.1335 TargetLowering::CallLoweringInfo CLI(DAG);1336 CLI.setDebugLoc(DL)1337 .setChain(DAG.getEntryNode())1338 .setLibCallee(CallingConv::C, CallTy,1339 DAG.getExternalSymbol("__tls_get_addr", Ty),1340 std::move(Args));1341 SDValue V = LowerCallTo(CLI).first;1342 1343 return V;1344}1345 1346bool CSKYTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,1347 SDValue C) const {1348 if (!VT.isScalarInteger())1349 return false;1350 1351 // Omit if data size exceeds.1352 if (VT.getSizeInBits() > Subtarget.XLen)1353 return false;1354 1355 if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode())) {1356 const APInt &Imm = ConstNode->getAPIntValue();1357 // Break MULT to LSLI + ADDU/SUBU.1358 if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2() ||1359 (1 - Imm).isPowerOf2())1360 return true;1361 // Only break MULT for sub targets without MULT32, since an extra1362 // instruction will be generated against the above 3 cases. We leave it1363 // unchanged on sub targets with MULT32, since not sure it is better.1364 if (!Subtarget.hasE2() && (-1 - Imm).isPowerOf2())1365 return true;1366 // Break (MULT x, imm) to ([IXH32|IXW32|IXD32] (LSLI32 x, i0), x) when1367 // imm=(1<<i0)+[2|4|8] and imm has to be composed via a MOVIH32/ORI32 pair.1368 if (Imm.ugt(0xffff) && ((Imm - 2).isPowerOf2() || (Imm - 4).isPowerOf2()) &&1369 Subtarget.hasE2())1370 return true;1371 if (Imm.ugt(0xffff) && (Imm - 8).isPowerOf2() && Subtarget.has2E3())1372 return true;1373 }1374 1375 return false;1376}1377 1378bool CSKYTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {1379 return Subtarget.has2E3();1380}1381 1382bool CSKYTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {1383 return Subtarget.hasE2();1384}1385