LLVM 20.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,
430 const Type *RetTy) const {
432 CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context);
433 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
434}
435
437CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
438 bool IsVarArg,
440 const SmallVectorImpl<SDValue> &OutVals,
441 const SDLoc &DL, SelectionDAG &DAG) const {
442 // Stores the assignment of the return value to a location.
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");
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 input
505// 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;
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
522
523 // Analyze the operands of the call, assigning locations to each operand.
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 args
543 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,
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.
570 SmallVector<SDValue, 8> MemOpChains;
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 =
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);
624 DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
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
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 are
682 // 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) {
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.
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 out
724 SDValue RetValue =
725 DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue);
726 // Glue the RetValue to the end of the call sequence
727 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 else
755 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 else
763 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 else
779 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 {
788 N->getGlobal(), CSKYCP::CPValue, 0, getModifier(Flags), false);
789
790 return DAG.getTargetConstantPool(CPV, Ty);
791}
792
794CSKYTargetLowering::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 their
860 // official names. However, other frontends like `rustc` do not. This allows
861 // users of these frontends to use the ABI names for registers in LLVM-style
862 // 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 the
902 // TableGen record rather than the AsmName to choose registers for InlineAsm
903 // constraints, plus we want to match those names to the widest floating point
904 // 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 also
907 // 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
960}
961
962static MachineBasicBlock *
964
966 DebugLoc DL = MI.getDebugLoc();
967
968 // To "insert" a SELECT instruction, we actually have to insert the
969 // diamond control-flow pattern. The incoming instruction knows the
970 // destination vreg to set, the condition code register to branch on, the
971 // true/false values to select between, and a branch opcode to use.
972 const BasicBlock *LLVM_BB = BB->getBasicBlock();
974
975 // thisMBB:
976 // ...
977 // TrueVal = ...
978 // bt32 c, sinkMBB
979 // fallthrough --> copyMBB
980 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());
991
992 // Next, add the true and fallthrough blocks as its successors.
993 BB->addSuccessor(copyMBB);
994 BB->addSuccessor(sinkMBB);
995
996 // bt32 condition, sinkMBB
997 BuildMI(BB, DL, TII.get(Opcode))
998 .addReg(MI.getOperand(1).getReg())
999 .addMBB(sinkMBB);
1000
1001 // copyMBB:
1002 // %FalseValue = ...
1003 // # fallthrough to sinkMBB
1004 BB = copyMBB;
1005
1006 // Update machine-CFG edges
1007 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
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 else
1036 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 {
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 {
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);
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);
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
1120const char *CSKYTargetLowering::getTargetNodeName(unsigned Opcode) const {
1121 switch (Opcode) {
1122 default:
1123 llvm_unreachable("unknown CSKYISD node");
1124 case CSKYISD::NIE:
1125 return "CSKYISD::NIE";
1126 case CSKYISD::NIR:
1127 return "CSKYISD::NIR";
1128 case CSKYISD::RET:
1129 return "CSKYISD::RET";
1130 case CSKYISD::CALL:
1131 return "CSKYISD::CALL";
1132 case CSKYISD::CALLReg:
1133 return "CSKYISD::CALLReg";
1134 case CSKYISD::TAIL:
1135 return "CSKYISD::TAIL";
1136 case CSKYISD::TAILReg:
1137 return "CSKYISD::TAILReg";
1138 case CSKYISD::LOAD_ADDR:
1139 return "CSKYISD::LOAD_ADDR";
1141 return "CSKYISD::BITCAST_TO_LOHI";
1143 return "CSKYISD::BITCAST_FROM_LOHI";
1144 }
1145}
1146
1147SDValue CSKYTargetLowering::LowerGlobalAddress(SDValue Op,
1148 SelectionDAG &DAG) const {
1149 SDLoc DL(Op);
1150 EVT Ty = Op.getValueType();
1151 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
1152 int64_t Offset = N->getOffset();
1153
1154 const GlobalValue *GV = N->getGlobal();
1155 bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(GV);
1156 SDValue Addr = getAddr<GlobalAddressSDNode, false>(N, DAG, IsLocal);
1157
1158 // In order to maximise the opportunity for common subexpression elimination,
1159 // emit a separate ADD node for the global address offset instead of folding
1160 // it in the global address node. Later peephole optimisations may choose to
1161 // fold it back in when profitable.
1162 if (Offset != 0)
1163 return DAG.getNode(ISD::ADD, DL, Ty, Addr,
1164 DAG.getConstant(Offset, DL, MVT::i32));
1165 return Addr;
1166}
1167
1168SDValue CSKYTargetLowering::LowerExternalSymbol(SDValue Op,
1169 SelectionDAG &DAG) const {
1170 ExternalSymbolSDNode *N = cast<ExternalSymbolSDNode>(Op);
1171
1172 return getAddr(N, DAG, false);
1173}
1174
1175SDValue CSKYTargetLowering::LowerJumpTable(SDValue Op,
1176 SelectionDAG &DAG) const {
1177 JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
1178
1179 return getAddr<JumpTableSDNode, false>(N, DAG);
1180}
1181
1182SDValue CSKYTargetLowering::LowerBlockAddress(SDValue Op,
1183 SelectionDAG &DAG) const {
1184 BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
1185
1186 return getAddr(N, DAG);
1187}
1188
1189SDValue CSKYTargetLowering::LowerConstantPool(SDValue Op,
1190 SelectionDAG &DAG) const {
1191 assert(!Subtarget.hasE2());
1192 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
1193
1194 return getAddr(N, DAG);
1195}
1196
1197SDValue CSKYTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
1200
1201 SDLoc DL(Op);
1202 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
1204
1205 // vastart just stores the address of the VarArgsFrameIndex slot into the
1206 // memory location argument.
1207 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1208 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
1209 MachinePointerInfo(SV));
1210}
1211
1212SDValue CSKYTargetLowering::LowerFRAMEADDR(SDValue Op,
1213 SelectionDAG &DAG) const {
1214 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();
1216 MachineFrameInfo &MFI = MF.getFrameInfo();
1217 MFI.setFrameAddressIsTaken(true);
1218
1219 EVT VT = Op.getValueType();
1220 SDLoc dl(Op);
1221 unsigned Depth = Op.getConstantOperandVal(0);
1222 Register FrameReg = RI.getFrameRegister(MF);
1223 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
1224 while (Depth--)
1225 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1227 return FrameAddr;
1228}
1229
1230SDValue CSKYTargetLowering::LowerRETURNADDR(SDValue Op,
1231 SelectionDAG &DAG) const {
1232 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();
1234 MachineFrameInfo &MFI = MF.getFrameInfo();
1235 MFI.setReturnAddressIsTaken(true);
1236
1238 return SDValue();
1239
1240 EVT VT = Op.getValueType();
1241 SDLoc dl(Op);
1242 unsigned Depth = Op.getConstantOperandVal(0);
1243 if (Depth) {
1244 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1245 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
1246 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
1247 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
1249 }
1250 // Return the value of the return address register, marking it an implicit
1251 // live-in.
1252 unsigned Reg = MF.addLiveIn(RI.getRARegister(), getRegClassFor(MVT::i32));
1253 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
1254}
1255
1256Register CSKYTargetLowering::getExceptionPointerRegister(
1257 const Constant *PersonalityFn) const {
1258 return CSKY::R0;
1259}
1260
1261Register CSKYTargetLowering::getExceptionSelectorRegister(
1262 const Constant *PersonalityFn) const {
1263 return CSKY::R1;
1264}
1265
1266SDValue CSKYTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1267 SelectionDAG &DAG) const {
1268 SDLoc DL(Op);
1269 EVT Ty = Op.getValueType();
1270 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
1271 int64_t Offset = N->getOffset();
1272 MVT XLenVT = MVT::i32;
1273
1275 SDValue Addr;
1276 switch (Model) {
1278 Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/false);
1279 break;
1281 Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/true);
1282 break;
1285 Addr = getDynamicTLSAddr(N, DAG);
1286 break;
1287 }
1288
1289 // In order to maximise the opportunity for common subexpression elimination,
1290 // emit a separate ADD node for the global address offset instead of folding
1291 // it in the global address node. Later peephole optimisations may choose to
1292 // fold it back in when profitable.
1293 if (Offset != 0)
1294 return DAG.getNode(ISD::ADD, DL, Ty, Addr,
1295 DAG.getConstant(Offset, DL, XLenVT));
1296 return Addr;
1297}
1298
1299SDValue CSKYTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
1300 SelectionDAG &DAG,
1301 bool UseGOT) const {
1304
1305 unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();
1306
1307 SDLoc DL(N);
1308 EVT Ty = getPointerTy(DAG.getDataLayout());
1309
1311 bool AddCurrentAddr = UseGOT ? true : false;
1312 unsigned char PCAjust = UseGOT ? 4 : 0;
1313
1315 CSKYConstantPoolConstant::Create(N->getGlobal(), CSKYCP::CPValue, PCAjust,
1316 Flag, AddCurrentAddr, CSKYPCLabelIndex);
1317 SDValue CAddr = DAG.getTargetConstantPool(CPV, Ty);
1318
1319 SDValue Load;
1320 if (UseGOT) {
1321 SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);
1322 auto *LRWGRS = DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty},
1323 {CAddr, PICLabel});
1324 auto LRWADDGRS =
1325 DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));
1326 Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), LRWADDGRS,
1327 MachinePointerInfo(N->getGlobal()));
1328 } else {
1329 Load = SDValue(DAG.getMachineNode(CSKY::LRW32, DL, Ty, CAddr), 0);
1330 }
1331
1332 // Add the thread pointer.
1333 SDValue TPReg = DAG.getRegister(CSKY::R31, MVT::i32);
1334 return DAG.getNode(ISD::ADD, DL, Ty, Load, TPReg);
1335}
1336
1337SDValue CSKYTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N,
1338 SelectionDAG &DAG) const {
1341
1342 unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();
1343
1344 SDLoc DL(N);
1345 EVT Ty = getPointerTy(DAG.getDataLayout());
1346 IntegerType *CallTy = Type::getIntNTy(*DAG.getContext(), Ty.getSizeInBits());
1347
1350 CSKYCP::TLSGD, true, CSKYPCLabelIndex);
1351 SDValue Addr = DAG.getTargetConstantPool(CPV, Ty);
1352 SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);
1353
1354 auto *LRWGRS =
1355 DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty}, {Addr, PICLabel});
1356
1357 auto Load =
1358 DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));
1359
1360 // Prepare argument list to generate call.
1362 ArgListEntry Entry;
1363 Entry.Node = Load;
1364 Entry.Ty = CallTy;
1365 Args.push_back(Entry);
1366
1367 // Setup call to __tls_get_addr.
1369 CLI.setDebugLoc(DL)
1370 .setChain(DAG.getEntryNode())
1371 .setLibCallee(CallingConv::C, CallTy,
1372 DAG.getExternalSymbol("__tls_get_addr", Ty),
1373 std::move(Args));
1374 SDValue V = LowerCallTo(CLI).first;
1375
1376 return V;
1377}
1378
1379bool CSKYTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
1380 SDValue C) const {
1381 if (!VT.isScalarInteger())
1382 return false;
1383
1384 // Omit if data size exceeds.
1385 if (VT.getSizeInBits() > Subtarget.XLen)
1386 return false;
1387
1388 if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode())) {
1389 const APInt &Imm = ConstNode->getAPIntValue();
1390 // Break MULT to LSLI + ADDU/SUBU.
1391 if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2() ||
1392 (1 - Imm).isPowerOf2())
1393 return true;
1394 // Only break MULT for sub targets without MULT32, since an extra
1395 // instruction will be generated against the above 3 cases. We leave it
1396 // unchanged on sub targets with MULT32, since not sure it is better.
1397 if (!Subtarget.hasE2() && (-1 - Imm).isPowerOf2())
1398 return true;
1399 // Break (MULT x, imm) to ([IXH32|IXW32|IXD32] (LSLI32 x, i0), x) when
1400 // imm=(1<<i0)+[2|4|8] and imm has to be composed via a MOVIH32/ORI32 pair.
1401 if (Imm.ugt(0xffff) && ((Imm - 2).isPowerOf2() || (Imm - 4).isPowerOf2()) &&
1402 Subtarget.hasE2())
1403 return true;
1404 if (Imm.ugt(0xffff) && (Imm - 8).isPowerOf2() && Subtarget.has2E3())
1405 return true;
1406 }
1407
1408 return false;
1409}
1410
1411bool CSKYTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
1412 return Subtarget.has2E3();
1413}
1414
1415bool CSKYTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {
1416 return Subtarget.hasE2();
1417}
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)
return RetTy
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
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:166
Class for arbitrary precision integers.
Definition: APInt.h:78
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:168
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
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:42
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:63
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:364
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:731
Class to represent integer types.
Definition: DerivedTypes.h:42
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:69
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:228
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:750
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
Definition: SelectionDAG.h:801
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 getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
SDValue getRegister(Register Reg, EVT VT)
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:760
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 getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
Definition: SelectionDAG.h:827
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:497
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 getExternalSymbol(const char *Sym, EVT VT)
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:700
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:796
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:492
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
Definition: SelectionDAG.h:510
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:767
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:580
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
std::string lower() const
Definition: StringRef.cpp:113
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:77
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool shouldAssumeDSOLocal(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:132
#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:125
@ Entry
Definition: COFF.h:844
@ 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:1197
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1193
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:257
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:744
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1226
@ ConstantFP
Definition: ISDOpcodes.h:77
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:246
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition: ISDOpcodes.h:717
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
Definition: ISDOpcodes.h:1304
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:262
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
Definition: ISDOpcodes.h:964
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:954
@ GlobalTLSAddress
Definition: ISDOpcodes.h:79
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
Definition: ISDOpcodes.h:1059
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1148
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1127
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1222
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:674
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:772
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1112
@ ConstantPool
Definition: ISDOpcodes.h:82
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:310
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:100
@ 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:1217
@ 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:794
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition: ISDOpcodes.h:508
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1610
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Definition: ISDOpcodes.h:1590
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:480
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:167
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:35
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition: ValueTypes.h:94
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:368
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:168
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
Definition: ValueTypes.h:157
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.