LLVM 18.0.0git
CSKYISelLowering.cpp
Go to the documentation of this file.
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"
18#include "CSKYRegisterInfo.h"
19#include "CSKYSubtarget.h"
20#include "llvm/ADT/Statistic.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
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
57
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
89 if (!Subtarget.hasE2()) {
91 }
94
95 if (!Subtarget.hasE2()) {
96 setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i8, Expand);
97 setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i16, Expand);
100 }
101
102 if (!Subtarget.has2E3()) {
108 }
109
111
112 // Float
113
114 ISD::CondCode FPCCToExtend[] = {
117 };
118
119 ISD::NodeType FPOpToExpand[] = {
122
123 if (STI.useHardFloat()) {
124
125 MVT AllVTy[] = {MVT::f32, MVT::f64};
126
127 for (auto VT : AllVTy) {
131
132 for (auto CC : FPCCToExtend)
134 for (auto Op : FPOpToExpand)
136 }
137
138 if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat()) {
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.
153
156
157 // TODO: Add atomic support fully.
159
163}
164
166 SelectionDAG &DAG) const {
167 switch (Op.getOpcode()) {
168 default:
169 llvm_unreachable("unimplemented op");
171 return LowerGlobalAddress(Op, DAG);
173 return LowerExternalSymbol(Op, DAG);
175 return LowerGlobalTLSAddress(Op, DAG);
176 case ISD::JumpTable:
177 return LowerJumpTable(Op, DAG);
179 return LowerBlockAddress(Op, DAG);
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
192 LLVMContext &Context, EVT VT) const {
193 if (!VT.isVector())
194 return MVT::i32;
195
197}
198
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");
207 break;
209 Val = DAG.getNode(ISD::BITCAST, DL, LocVT, Val);
210 break;
211 }
212 return Val;
213}
214
216 const CCValAssign &VA, const SDLoc &DL) {
217 switch (VA.getLocInfo()) {
218 default:
219 llvm_unreachable("Unexpected CCValAssign::LocInfo");
221 break;
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) {
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
262 const CCValAssign &VA, const SDLoc &DL) {
264 MachineFrameInfo &MFI = MF.getFrameInfo();
265 EVT LocVT = VA.getLocVT();
266 EVT ValVT = VA.getValVT();
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");
279 ExtType = ISD::NON_EXTLOAD;
280 break;
281 }
282 Val = DAG.getExtLoad(
283 ExtType, DL, LocVT, Chain, FIN,
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");
294 MachineFrameInfo &MFI = MF.getFrameInfo();
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,
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,
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:
337 break;
338 }
339
341
342 // Used with vargs to acumulate store chains.
343 std::vector<SDValue> OutChains;
344
345 // Assign locations to all of the incoming arguments.
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
372 unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
373 const TargetRegisterClass *RC = &CSKY::GPRRegClass;
374 MachineFrameInfo &MFI = MF.getFrameInfo();
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,
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
427bool CSKYTargetLowering::CanLowerReturn(
428 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
429 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
431 CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context);
432 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
433}
434
436CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
437 bool IsVarArg,
439 const SmallVectorImpl<SDValue> &OutVals,
440 const SDLoc &DL, SelectionDAG &DAG) const {
441 // Stores the assignment of the return value to a location.
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");
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.
505SDValue 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;
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
521
522 // Analyze the operands of the call, assigning locations to each operand.
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, IsTailCall,
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.
569 SmallVector<SDValue, 8> MemOpChains;
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 =
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);
623 DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
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
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 =
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(
666 *MF.getFunction().getParent(), nullptr);
667
668 if (isPositionIndependent() || !Subtarget.has2E3()) {
669 IsRegCall = true;
670 Ops.push_back(getAddr<ExternalSymbolSDNode, true>(S, DAG, IsLocal));
671 } else {
672 Ops.push_back(getTargetNode(cast<ExternalSymbolSDNode>(Callee), DL, Ty,
673 DAG, CSKYII::MO_None));
674 Ops.push_back(getTargetConstantPoolValue(
675 cast<ExternalSymbolSDNode>(Callee), Ty, DAG, CSKYII::MO_None));
676 }
677 } else {
678 IsRegCall = true;
679 Ops.push_back(Callee);
680 }
681
682 // Add argument registers to the end of the list so that they are
683 // known live into the call.
684 for (auto &Reg : RegsToPass)
685 Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
686
687 if (!IsTailCall) {
688 // Add a register mask operand representing the call-preserved registers.
689 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
690 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
691 assert(Mask && "Missing call preserved mask for calling convention");
692 Ops.push_back(DAG.getRegisterMask(Mask));
693 }
694
695 // Glue the call to the argument copies, if any.
696 if (Glue.getNode())
697 Ops.push_back(Glue);
698
699 // Emit the call.
700 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
701
702 if (IsTailCall) {
704 return DAG.getNode(IsRegCall ? CSKYISD::TAILReg : CSKYISD::TAIL, DL,
705 NodeTys, Ops);
706 }
707
708 Chain = DAG.getNode(IsRegCall ? CSKYISD::CALLReg : CSKYISD::CALL, DL, NodeTys,
709 Ops);
710 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
711 Glue = Chain.getValue(1);
712
713 // Mark the end of the call, which is glued to the call itself.
714 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, DL);
715 Glue = Chain.getValue(1);
716
717 // Assign locations to each value returned by this call.
719 CCState RetCCInfo(CallConv, IsVarArg, MF, CSKYLocs, *DAG.getContext());
720 RetCCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv, IsVarArg));
721
722 // Copy all of the result registers out of their specified physreg.
723 for (auto &VA : CSKYLocs) {
724 // Copy the value out
725 SDValue RetValue =
726 DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue);
727 // Glue the RetValue to the end of the call sequence
728 Chain = RetValue.getValue(1);
729 Glue = RetValue.getValue(2);
730
731 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
732
733 if (IsF64OnCSKY) {
734 assert(VA.getLocReg() == GPRArgRegs[0] && "Unexpected reg assignment");
735 SDValue RetValue2 =
736 DAG.getCopyFromReg(Chain, DL, GPRArgRegs[1], MVT::i32, Glue);
737 Chain = RetValue2.getValue(1);
738 Glue = RetValue2.getValue(2);
739 RetValue = DAG.getNode(CSKYISD::BITCAST_FROM_LOHI, DL, VA.getValVT(),
740 RetValue, RetValue2);
741 }
742
743 RetValue = convertLocVTToValVT(DAG, RetValue, VA, DL);
744
745 InVals.push_back(RetValue);
746 }
747
748 return Chain;
749}
750
751CCAssignFn *CSKYTargetLowering::CCAssignFnForReturn(CallingConv::ID CC,
752 bool IsVarArg) const {
753 if (IsVarArg || !Subtarget.useHardFloatABI())
754 return RetCC_CSKY_ABIV2_SOFT;
755 else
756 return RetCC_CSKY_ABIV2_FP;
757}
758
759CCAssignFn *CSKYTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
760 bool IsVarArg) const {
761 if (IsVarArg || !Subtarget.useHardFloatABI())
762 return CC_CSKY_ABIV2_SOFT;
763 else
764 return CC_CSKY_ABIV2_FP;
765}
766
767static CSKYCP::CSKYCPModifier getModifier(unsigned Flags) {
768
769 if (Flags == CSKYII::MO_ADDR32)
770 return CSKYCP::ADDR;
771 else if (Flags == CSKYII::MO_GOT32)
772 return CSKYCP::GOT;
773 else if (Flags == CSKYII::MO_GOTOFF)
774 return CSKYCP::GOTOFF;
775 else if (Flags == CSKYII::MO_PLT32)
776 return CSKYCP::PLT;
777 else if (Flags == CSKYII::MO_None)
778 return CSKYCP::NO_MOD;
779 else
780 assert(0 && "unknown CSKYII Modifier");
781 return CSKYCP::NO_MOD;
782}
783
784SDValue CSKYTargetLowering::getTargetConstantPoolValue(GlobalAddressSDNode *N,
785 EVT Ty,
786 SelectionDAG &DAG,
787 unsigned Flags) const {
789 N->getGlobal(), CSKYCP::CPValue, 0, getModifier(Flags), false);
790
791 return DAG.getTargetConstantPool(CPV, Ty);
792}
793
795CSKYTargetLowering::getConstraintType(StringRef Constraint) const {
796 if (Constraint.size() == 1) {
797 switch (Constraint[0]) {
798 default:
799 break;
800 case 'a':
801 case 'b':
802 case 'v':
803 case 'w':
804 case 'y':
805 return C_RegisterClass;
806 case 'c':
807 case 'l':
808 case 'h':
809 case 'z':
810 return C_Register;
811 }
812 }
813 return TargetLowering::getConstraintType(Constraint);
814}
815
816std::pair<unsigned, const TargetRegisterClass *>
817CSKYTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
818 StringRef Constraint,
819 MVT VT) const {
820 if (Constraint.size() == 1) {
821 switch (Constraint[0]) {
822 case 'r':
823 return std::make_pair(0U, &CSKY::GPRRegClass);
824 case 'a':
825 return std::make_pair(0U, &CSKY::mGPRRegClass);
826 case 'b':
827 return std::make_pair(0U, &CSKY::sGPRRegClass);
828 case 'z':
829 return std::make_pair(CSKY::R14, &CSKY::GPRRegClass);
830 case 'c':
831 return std::make_pair(CSKY::C, &CSKY::CARRYRegClass);
832 case 'w':
833 if ((Subtarget.hasFPUv2SingleFloat() ||
834 Subtarget.hasFPUv3SingleFloat()) &&
835 VT == MVT::f32)
836 return std::make_pair(0U, &CSKY::sFPR32RegClass);
837 if ((Subtarget.hasFPUv2DoubleFloat() ||
838 Subtarget.hasFPUv3DoubleFloat()) &&
839 VT == MVT::f64)
840 return std::make_pair(0U, &CSKY::sFPR64RegClass);
841 break;
842 case 'v':
843 if (Subtarget.hasFPUv2SingleFloat() && VT == MVT::f32)
844 return std::make_pair(0U, &CSKY::sFPR32RegClass);
845 if (Subtarget.hasFPUv3SingleFloat() && VT == MVT::f32)
846 return std::make_pair(0U, &CSKY::FPR32RegClass);
847 if (Subtarget.hasFPUv2DoubleFloat() && VT == MVT::f64)
848 return std::make_pair(0U, &CSKY::sFPR64RegClass);
849 if (Subtarget.hasFPUv3DoubleFloat() && VT == MVT::f64)
850 return std::make_pair(0U, &CSKY::FPR64RegClass);
851 break;
852 default:
853 break;
854 }
855 }
856
857 if (Constraint == "{c}")
858 return std::make_pair(CSKY::C, &CSKY::CARRYRegClass);
859
860 // Clang will correctly decode the usage of register name aliases into their
861 // official names. However, other frontends like `rustc` do not. This allows
862 // users of these frontends to use the ABI names for registers in LLVM-style
863 // register constraints.
864 unsigned XRegFromAlias = StringSwitch<unsigned>(Constraint.lower())
865 .Case("{a0}", CSKY::R0)
866 .Case("{a1}", CSKY::R1)
867 .Case("{a2}", CSKY::R2)
868 .Case("{a3}", CSKY::R3)
869 .Case("{l0}", CSKY::R4)
870 .Case("{l1}", CSKY::R5)
871 .Case("{l2}", CSKY::R6)
872 .Case("{l3}", CSKY::R7)
873 .Case("{l4}", CSKY::R8)
874 .Case("{l5}", CSKY::R9)
875 .Case("{l6}", CSKY::R10)
876 .Case("{l7}", CSKY::R11)
877 .Case("{t0}", CSKY::R12)
878 .Case("{t1}", CSKY::R13)
879 .Case("{sp}", CSKY::R14)
880 .Case("{lr}", CSKY::R15)
881 .Case("{l8}", CSKY::R16)
882 .Case("{l9}", CSKY::R17)
883 .Case("{t2}", CSKY::R18)
884 .Case("{t3}", CSKY::R19)
885 .Case("{t4}", CSKY::R20)
886 .Case("{t5}", CSKY::R21)
887 .Case("{t6}", CSKY::R22)
888 .Cases("{t7}", "{fp}", CSKY::R23)
889 .Cases("{t8}", "{top}", CSKY::R24)
890 .Cases("{t9}", "{bsp}", CSKY::R25)
891 .Case("{r26}", CSKY::R26)
892 .Case("{r27}", CSKY::R27)
893 .Cases("{gb}", "{rgb}", "{rdb}", CSKY::R28)
894 .Cases("{tb}", "{rtb}", CSKY::R29)
895 .Case("{svbr}", CSKY::R30)
896 .Case("{tls}", CSKY::R31)
897 .Default(CSKY::NoRegister);
898
899 if (XRegFromAlias != CSKY::NoRegister)
900 return std::make_pair(XRegFromAlias, &CSKY::GPRRegClass);
901
902 // Since TargetLowering::getRegForInlineAsmConstraint uses the name of the
903 // TableGen record rather than the AsmName to choose registers for InlineAsm
904 // constraints, plus we want to match those names to the widest floating point
905 // register type available, manually select floating point registers here.
906 //
907 // The second case is the ABI name of the register, so that frontends can also
908 // use the ABI names in register constraint lists.
909 if (Subtarget.useHardFloat()) {
910 unsigned FReg = StringSwitch<unsigned>(Constraint.lower())
911 .Cases("{fr0}", "{vr0}", CSKY::F0_32)
912 .Cases("{fr1}", "{vr1}", CSKY::F1_32)
913 .Cases("{fr2}", "{vr2}", CSKY::F2_32)
914 .Cases("{fr3}", "{vr3}", CSKY::F3_32)
915 .Cases("{fr4}", "{vr4}", CSKY::F4_32)
916 .Cases("{fr5}", "{vr5}", CSKY::F5_32)
917 .Cases("{fr6}", "{vr6}", CSKY::F6_32)
918 .Cases("{fr7}", "{vr7}", CSKY::F7_32)
919 .Cases("{fr8}", "{vr8}", CSKY::F8_32)
920 .Cases("{fr9}", "{vr9}", CSKY::F9_32)
921 .Cases("{fr10}", "{vr10}", CSKY::F10_32)
922 .Cases("{fr11}", "{vr11}", CSKY::F11_32)
923 .Cases("{fr12}", "{vr12}", CSKY::F12_32)
924 .Cases("{fr13}", "{vr13}", CSKY::F13_32)
925 .Cases("{fr14}", "{vr14}", CSKY::F14_32)
926 .Cases("{fr15}", "{vr15}", CSKY::F15_32)
927 .Cases("{fr16}", "{vr16}", CSKY::F16_32)
928 .Cases("{fr17}", "{vr17}", CSKY::F17_32)
929 .Cases("{fr18}", "{vr18}", CSKY::F18_32)
930 .Cases("{fr19}", "{vr19}", CSKY::F19_32)
931 .Cases("{fr20}", "{vr20}", CSKY::F20_32)
932 .Cases("{fr21}", "{vr21}", CSKY::F21_32)
933 .Cases("{fr22}", "{vr22}", CSKY::F22_32)
934 .Cases("{fr23}", "{vr23}", CSKY::F23_32)
935 .Cases("{fr24}", "{vr24}", CSKY::F24_32)
936 .Cases("{fr25}", "{vr25}", CSKY::F25_32)
937 .Cases("{fr26}", "{vr26}", CSKY::F26_32)
938 .Cases("{fr27}", "{vr27}", CSKY::F27_32)
939 .Cases("{fr28}", "{vr28}", CSKY::F28_32)
940 .Cases("{fr29}", "{vr29}", CSKY::F29_32)
941 .Cases("{fr30}", "{vr30}", CSKY::F30_32)
942 .Cases("{fr31}", "{vr31}", CSKY::F31_32)
943 .Default(CSKY::NoRegister);
944 if (FReg != CSKY::NoRegister) {
945 assert(CSKY::F0_32 <= FReg && FReg <= CSKY::F31_32 && "Unknown fp-reg");
946 unsigned RegNo = FReg - CSKY::F0_32;
947 unsigned DReg = CSKY::F0_64 + RegNo;
948
949 if (Subtarget.hasFPUv2DoubleFloat())
950 return std::make_pair(DReg, &CSKY::sFPR64RegClass);
951 else if (Subtarget.hasFPUv3DoubleFloat())
952 return std::make_pair(DReg, &CSKY::FPR64RegClass);
953 else if (Subtarget.hasFPUv2SingleFloat())
954 return std::make_pair(FReg, &CSKY::sFPR32RegClass);
955 else if (Subtarget.hasFPUv3SingleFloat())
956 return std::make_pair(FReg, &CSKY::FPR32RegClass);
957 }
958 }
959
961}
962
963static MachineBasicBlock *
965
967 DebugLoc DL = MI.getDebugLoc();
968
969 // To "insert" a SELECT instruction, we actually have to insert the
970 // diamond control-flow pattern. The incoming instruction knows the
971 // destination vreg to set, the condition code register to branch on, the
972 // true/false values to select between, and a branch opcode to use.
973 const BasicBlock *LLVM_BB = BB->getBasicBlock();
975
976 // thisMBB:
977 // ...
978 // TrueVal = ...
979 // bt32 c, sinkMBB
980 // fallthrough --> copyMBB
981 MachineBasicBlock *thisMBB = BB;
982 MachineFunction *F = BB->getParent();
983 MachineBasicBlock *copyMBB = F->CreateMachineBasicBlock(LLVM_BB);
984 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
985 F->insert(It, copyMBB);
986 F->insert(It, sinkMBB);
987
988 // Transfer the remainder of BB and its successor edges to sinkMBB.
989 sinkMBB->splice(sinkMBB->begin(), BB,
990 std::next(MachineBasicBlock::iterator(MI)), BB->end());
992
993 // Next, add the true and fallthrough blocks as its successors.
994 BB->addSuccessor(copyMBB);
995 BB->addSuccessor(sinkMBB);
996
997 // bt32 condition, sinkMBB
998 BuildMI(BB, DL, TII.get(Opcode))
999 .addReg(MI.getOperand(1).getReg())
1000 .addMBB(sinkMBB);
1001
1002 // copyMBB:
1003 // %FalseValue = ...
1004 // # fallthrough to sinkMBB
1005 BB = copyMBB;
1006
1007 // Update machine-CFG edges
1008 BB->addSuccessor(sinkMBB);
1009
1010 // sinkMBB:
1011 // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copyMBB ]
1012 // ...
1013 BB = sinkMBB;
1014
1015 BuildMI(*BB, BB->begin(), DL, TII.get(CSKY::PHI), MI.getOperand(0).getReg())
1016 .addReg(MI.getOperand(2).getReg())
1017 .addMBB(thisMBB)
1018 .addReg(MI.getOperand(3).getReg())
1019 .addMBB(copyMBB);
1020
1021 MI.eraseFromParent(); // The pseudo instruction is gone now.
1022
1023 return BB;
1024}
1025
1027CSKYTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1028 MachineBasicBlock *BB) const {
1029 switch (MI.getOpcode()) {
1030 default:
1031 llvm_unreachable("Unexpected instr type to insert");
1032 case CSKY::FSELS:
1033 case CSKY::FSELD:
1034 if (Subtarget.hasE2())
1035 return emitSelectPseudo(MI, BB, CSKY::BT32);
1036 else
1037 return emitSelectPseudo(MI, BB, CSKY::BT16);
1038 case CSKY::ISEL32:
1039 return emitSelectPseudo(MI, BB, CSKY::BT32);
1040 case CSKY::ISEL16:
1041 return emitSelectPseudo(MI, BB, CSKY::BT16);
1042 }
1043}
1044
1045SDValue CSKYTargetLowering::getTargetConstantPoolValue(ExternalSymbolSDNode *N,
1046 EVT Ty,
1047 SelectionDAG &DAG,
1048 unsigned Flags) const {
1051 N->getSymbol(), 0, getModifier(Flags));
1052
1053 return DAG.getTargetConstantPool(CPV, Ty);
1054}
1055
1056SDValue CSKYTargetLowering::getTargetConstantPoolValue(JumpTableSDNode *N,
1057 EVT Ty,
1058 SelectionDAG &DAG,
1059 unsigned Flags) const {
1062 N->getIndex(), 0, getModifier(Flags));
1063 return DAG.getTargetConstantPool(CPV, Ty);
1064}
1065
1066SDValue CSKYTargetLowering::getTargetConstantPoolValue(BlockAddressSDNode *N,
1067 EVT Ty,
1068 SelectionDAG &DAG,
1069 unsigned Flags) const {
1070 assert(N->getOffset() == 0);
1072 N->getBlockAddress(), CSKYCP::CPBlockAddress, 0, getModifier(Flags),
1073 false);
1074 return DAG.getTargetConstantPool(CPV, Ty);
1075}
1076
1077SDValue CSKYTargetLowering::getTargetConstantPoolValue(ConstantPoolSDNode *N,
1078 EVT Ty,
1079 SelectionDAG &DAG,
1080 unsigned Flags) const {
1081 assert(N->getOffset() == 0);
1083 N->getConstVal(), Type::getInt32Ty(*DAG.getContext()),
1084 CSKYCP::CPConstPool, 0, getModifier(Flags), false);
1085 return DAG.getTargetConstantPool(CPV, Ty);
1086}
1087
1088SDValue CSKYTargetLowering::getTargetNode(GlobalAddressSDNode *N, SDLoc DL,
1089 EVT Ty, SelectionDAG &DAG,
1090 unsigned Flags) const {
1091 return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags);
1092}
1093
1094SDValue CSKYTargetLowering::getTargetNode(ExternalSymbolSDNode *N, SDLoc DL,
1095 EVT Ty, SelectionDAG &DAG,
1096 unsigned Flags) const {
1097 return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flags);
1098}
1099
1100SDValue CSKYTargetLowering::getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty,
1101 SelectionDAG &DAG,
1102 unsigned Flags) const {
1103 return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
1104}
1105
1106SDValue CSKYTargetLowering::getTargetNode(BlockAddressSDNode *N, SDLoc DL,
1107 EVT Ty, SelectionDAG &DAG,
1108 unsigned Flags) const {
1109 return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, N->getOffset(),
1110 Flags);
1111}
1112
1113SDValue CSKYTargetLowering::getTargetNode(ConstantPoolSDNode *N, SDLoc DL,
1114 EVT Ty, SelectionDAG &DAG,
1115 unsigned Flags) const {
1116
1117 return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),
1118 N->getOffset(), Flags);
1119}
1120
1121const char *CSKYTargetLowering::getTargetNodeName(unsigned Opcode) const {
1122 switch (Opcode) {
1123 default:
1124 llvm_unreachable("unknown CSKYISD node");
1125 case CSKYISD::NIE:
1126 return "CSKYISD::NIE";
1127 case CSKYISD::NIR:
1128 return "CSKYISD::NIR";
1129 case CSKYISD::RET:
1130 return "CSKYISD::RET";
1131 case CSKYISD::CALL:
1132 return "CSKYISD::CALL";
1133 case CSKYISD::CALLReg:
1134 return "CSKYISD::CALLReg";
1135 case CSKYISD::TAIL:
1136 return "CSKYISD::TAIL";
1137 case CSKYISD::TAILReg:
1138 return "CSKYISD::TAILReg";
1139 case CSKYISD::LOAD_ADDR:
1140 return "CSKYISD::LOAD_ADDR";
1142 return "CSKYISD::BITCAST_TO_LOHI";
1144 return "CSKYISD::BITCAST_FROM_LOHI";
1145 }
1146}
1147
1148SDValue CSKYTargetLowering::LowerGlobalAddress(SDValue Op,
1149 SelectionDAG &DAG) const {
1150 SDLoc DL(Op);
1151 EVT Ty = Op.getValueType();
1152 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
1153 int64_t Offset = N->getOffset();
1154
1155 const GlobalValue *GV = N->getGlobal();
1156 bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV);
1157 SDValue Addr = getAddr<GlobalAddressSDNode, false>(N, DAG, IsLocal);
1158
1159 // In order to maximise the opportunity for common subexpression elimination,
1160 // emit a separate ADD node for the global address offset instead of folding
1161 // it in the global address node. Later peephole optimisations may choose to
1162 // fold it back in when profitable.
1163 if (Offset != 0)
1164 return DAG.getNode(ISD::ADD, DL, Ty, Addr,
1165 DAG.getConstant(Offset, DL, MVT::i32));
1166 return Addr;
1167}
1168
1169SDValue CSKYTargetLowering::LowerExternalSymbol(SDValue Op,
1170 SelectionDAG &DAG) const {
1171 ExternalSymbolSDNode *N = cast<ExternalSymbolSDNode>(Op);
1172
1173 return getAddr(N, DAG, false);
1174}
1175
1176SDValue CSKYTargetLowering::LowerJumpTable(SDValue Op,
1177 SelectionDAG &DAG) const {
1178 JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
1179
1180 return getAddr<JumpTableSDNode, false>(N, DAG);
1181}
1182
1183SDValue CSKYTargetLowering::LowerBlockAddress(SDValue Op,
1184 SelectionDAG &DAG) const {
1185 BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
1186
1187 return getAddr(N, DAG);
1188}
1189
1190SDValue CSKYTargetLowering::LowerConstantPool(SDValue Op,
1191 SelectionDAG &DAG) const {
1192 assert(!Subtarget.hasE2());
1193 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
1194
1195 return getAddr(N, DAG);
1196}
1197
1198SDValue CSKYTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
1201
1202 SDLoc DL(Op);
1203 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
1205
1206 // vastart just stores the address of the VarArgsFrameIndex slot into the
1207 // memory location argument.
1208 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1209 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
1210 MachinePointerInfo(SV));
1211}
1212
1213SDValue CSKYTargetLowering::LowerFRAMEADDR(SDValue Op,
1214 SelectionDAG &DAG) const {
1215 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();
1217 MachineFrameInfo &MFI = MF.getFrameInfo();
1218 MFI.setFrameAddressIsTaken(true);
1219
1220 EVT VT = Op.getValueType();
1221 SDLoc dl(Op);
1222 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1223 Register FrameReg = RI.getFrameRegister(MF);
1224 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
1225 while (Depth--)
1226 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1228 return FrameAddr;
1229}
1230
1231SDValue CSKYTargetLowering::LowerRETURNADDR(SDValue Op,
1232 SelectionDAG &DAG) const {
1233 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();
1235 MachineFrameInfo &MFI = MF.getFrameInfo();
1236 MFI.setReturnAddressIsTaken(true);
1237
1239 return SDValue();
1240
1241 EVT VT = Op.getValueType();
1242 SDLoc dl(Op);
1243 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1244 if (Depth) {
1245 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1246 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
1247 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
1248 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
1250 }
1251 // Return the value of the return address register, marking it an implicit
1252 // live-in.
1253 unsigned Reg = MF.addLiveIn(RI.getRARegister(), getRegClassFor(MVT::i32));
1254 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
1255}
1256
1257Register CSKYTargetLowering::getExceptionPointerRegister(
1258 const Constant *PersonalityFn) const {
1259 return CSKY::R0;
1260}
1261
1262Register CSKYTargetLowering::getExceptionSelectorRegister(
1263 const Constant *PersonalityFn) const {
1264 return CSKY::R1;
1265}
1266
1267SDValue CSKYTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1268 SelectionDAG &DAG) const {
1269 SDLoc DL(Op);
1270 EVT Ty = Op.getValueType();
1271 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
1272 int64_t Offset = N->getOffset();
1273 MVT XLenVT = MVT::i32;
1274
1276 SDValue Addr;
1277 switch (Model) {
1279 Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/false);
1280 break;
1282 Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/true);
1283 break;
1286 Addr = getDynamicTLSAddr(N, DAG);
1287 break;
1288 }
1289
1290 // In order to maximise the opportunity for common subexpression elimination,
1291 // emit a separate ADD node for the global address offset instead of folding
1292 // it in the global address node. Later peephole optimisations may choose to
1293 // fold it back in when profitable.
1294 if (Offset != 0)
1295 return DAG.getNode(ISD::ADD, DL, Ty, Addr,
1296 DAG.getConstant(Offset, DL, XLenVT));
1297 return Addr;
1298}
1299
1300SDValue CSKYTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
1301 SelectionDAG &DAG,
1302 bool UseGOT) const {
1305
1306 unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();
1307
1308 SDLoc DL(N);
1309 EVT Ty = getPointerTy(DAG.getDataLayout());
1310
1312 bool AddCurrentAddr = UseGOT ? true : false;
1313 unsigned char PCAjust = UseGOT ? 4 : 0;
1314
1316 CSKYConstantPoolConstant::Create(N->getGlobal(), CSKYCP::CPValue, PCAjust,
1317 Flag, AddCurrentAddr, CSKYPCLabelIndex);
1318 SDValue CAddr = DAG.getTargetConstantPool(CPV, Ty);
1319
1320 SDValue Load;
1321 if (UseGOT) {
1322 SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);
1323 auto *LRWGRS = DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty},
1324 {CAddr, PICLabel});
1325 auto LRWADDGRS =
1326 DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));
1327 Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), LRWADDGRS,
1328 MachinePointerInfo(N->getGlobal()));
1329 } else {
1330 Load = SDValue(DAG.getMachineNode(CSKY::LRW32, DL, Ty, CAddr), 0);
1331 }
1332
1333 // Add the thread pointer.
1334 SDValue TPReg = DAG.getRegister(CSKY::R31, MVT::i32);
1335 return DAG.getNode(ISD::ADD, DL, Ty, Load, TPReg);
1336}
1337
1338SDValue CSKYTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N,
1339 SelectionDAG &DAG) const {
1342
1343 unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();
1344
1345 SDLoc DL(N);
1346 EVT Ty = getPointerTy(DAG.getDataLayout());
1347 IntegerType *CallTy = Type::getIntNTy(*DAG.getContext(), Ty.getSizeInBits());
1348
1351 CSKYCP::TLSGD, true, CSKYPCLabelIndex);
1352 SDValue Addr = DAG.getTargetConstantPool(CPV, Ty);
1353 SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);
1354
1355 auto *LRWGRS =
1356 DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty}, {Addr, PICLabel});
1357
1358 auto Load =
1359 DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));
1360
1361 // Prepare argument list to generate call.
1363 ArgListEntry Entry;
1364 Entry.Node = Load;
1365 Entry.Ty = CallTy;
1366 Args.push_back(Entry);
1367
1368 // Setup call to __tls_get_addr.
1370 CLI.setDebugLoc(DL)
1371 .setChain(DAG.getEntryNode())
1372 .setLibCallee(CallingConv::C, CallTy,
1373 DAG.getExternalSymbol("__tls_get_addr", Ty),
1374 std::move(Args));
1375 SDValue V = LowerCallTo(CLI).first;
1376
1377 return V;
1378}
1379
1380bool CSKYTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
1381 SDValue C) const {
1382 if (!VT.isScalarInteger())
1383 return false;
1384
1385 // Omit if data size exceeds.
1386 if (VT.getSizeInBits() > Subtarget.XLen)
1387 return false;
1388
1389 if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode())) {
1390 const APInt &Imm = ConstNode->getAPIntValue();
1391 // Break MULT to LSLI + ADDU/SUBU.
1392 if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2() ||
1393 (1 - Imm).isPowerOf2())
1394 return true;
1395 // Only break MULT for sub targets without MULT32, since an extra
1396 // instruction will be generated against the above 3 cases. We leave it
1397 // unchanged on sub targets with MULT32, since not sure it is better.
1398 if (!Subtarget.hasE2() && (-1 - Imm).isPowerOf2())
1399 return true;
1400 // Break (MULT x, imm) to ([IXH32|IXW32|IXD32] (LSLI32 x, i0), x) when
1401 // imm=(1<<i0)+[2|4|8] and imm has to be composed via a MOVIH32/ORI32 pair.
1402 if (Imm.ugt(0xffff) && ((Imm - 2).isPowerOf2() || (Imm - 4).isPowerOf2()) &&
1403 Subtarget.hasE2())
1404 return true;
1405 if (Imm.ugt(0xffff) && (Imm - 8).isPowerOf2() && Subtarget.has2E3())
1406 return true;
1407 }
1408
1409 return false;
1410}
1411
1412bool CSKYTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
1413 return Subtarget.has2E3();
1414}
1415
1416bool CSKYTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {
1417 return Subtarget.hasE2();
1418}
static const MCPhysReg GPRArgRegs[]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
basic Basic Alias true
static SDValue unpack64(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)
static const MCPhysReg GPRArgRegs[]
static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static CSKYCP::CSKYCPModifier getModifier(unsigned Flags)
static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static MachineBasicBlock * emitSelectPseudo(MachineInstr &MI, MachineBasicBlock *BB, unsigned Opcode)
static SDValue unpackFromRegLoc(const CSKYSubtarget &Subtarget, SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Addr
uint64_t Size
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
Class for arbitrary precision integers.
Definition: APInt.h:76
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
LLVM Basic Block Representation.
Definition: BasicBlock.h:56
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
bool isMemLoc() const
int64_t getLocMemOffset() const
static CSKYConstantPoolConstant * Create(const Constant *C, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, unsigned ID=0)
static CSKYConstantPoolJT * Create(Type *Ty, int JTI, unsigned PCAdj, CSKYCP::CSKYCPModifier Modifier)
static CSKYConstantPoolSymbol * Create(Type *Ty, const char *S, unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier)
CSKYConstantPoolValue - CSKY specific constantpool value.
Register getFrameRegister(const MachineFunction &MF) const override
bool hasFPUv2SingleFloat() const
bool hasFPUv3SingleFloat() const
const CSKYRegisterInfo * getRegisterInfo() const override
const unsigned XLen
bool hasE2() const
bool hasFPUv2DoubleFloat() const
bool useHardFloatABI() const
bool useHardFloat() const
bool hasFPUv3DoubleFloat() const
bool has2E3() const
CSKYTargetLowering(const TargetMachine &TM, const CSKYSubtarget &STI)
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
Return the ValueType of the result of SETCC operations.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
This is an important base class in LLVM.
Definition: Constant.h:41
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:110
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
Definition: DataLayout.h:410
A debug info location.
Definition: DebugLoc.h:33
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:645
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:652
Class to represent integer types.
Definition: DerivedTypes.h:40
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
Machine Value Type.
SimpleValueType SimpleTy
static MVT getIntegerVT(unsigned BitWidth)
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
Definition: MachineInstr.h:68
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:225
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:720
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:730
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:472
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getExternalSymbol(const char *Sym, EVT VT)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:771
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:674
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:766
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:469
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:797
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
Definition: SelectionDAG.h:485
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:737
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:554
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
std::string lower() const
Definition: StringRef.cpp:111
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:90
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
std::vector< ArgListEntry > ArgListTy
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:78
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
Definition: Value.h:74
self_iterator getIterator()
Definition: ilist_node.h:82
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:119
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition: ISDOpcodes.h:40
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1121
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1117
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:250
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:714
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1150
@ ConstantFP
Definition: ISDOpcodes.h:77
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
@ RETURNADDR
Definition: ISDOpcodes.h:95
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition: ISDOpcodes.h:688
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
Definition: ISDOpcodes.h:1222
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:255
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
Definition: ISDOpcodes.h:910
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:900
@ GlobalTLSAddress
Definition: ISDOpcodes.h:79
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
Definition: ISDOpcodes.h:983
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1072
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1051
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1146
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:651
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:742
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1036
@ ConstantPool
Definition: ISDOpcodes.h:82
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:303
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:94
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ ExternalSymbol
Definition: ISDOpcodes.h:83
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1141
@ BlockAddress
Definition: ISDOpcodes.h:84
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:763
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition: ISDOpcodes.h:493
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1503
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Definition: ISDOpcodes.h:1483
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:148
@ GeneralDynamic
Definition: CodeGen.h:46
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Extended Value Type.
Definition: ValueTypes.h:34
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition: ValueTypes.h:93
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:351
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:299
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:160
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
Definition: ValueTypes.h:149
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.