LLVM 23.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#define GET_CALLING_CONV_IMPL
33#include "CSKYGenCallingConv.inc"
34
35static const MCPhysReg GPRArgRegs[] = {CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3};
36
38 const CSKYSubtarget &STI)
39 : TargetLowering(TM, STI), Subtarget(STI) {
40 // Register Class
41 addRegisterClass(MVT::i32, &CSKY::GPRRegClass);
42
43 if (STI.useHardFloat()) {
44 if (STI.hasFPUv2SingleFloat())
45 addRegisterClass(MVT::f32, &CSKY::sFPR32RegClass);
46 else if (STI.hasFPUv3SingleFloat())
47 addRegisterClass(MVT::f32, &CSKY::FPR32RegClass);
48
49 if (STI.hasFPUv2DoubleFloat())
50 addRegisterClass(MVT::f64, &CSKY::sFPR64RegClass);
51 else if (STI.hasFPUv3DoubleFloat())
52 addRegisterClass(MVT::f64, &CSKY::FPR64RegClass);
53 }
54
58
81
82 setLoadExtAction(ISD::EXTLOAD, MVT::i32, MVT::i1, Promote);
83 setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i1, Promote);
84 setLoadExtAction(ISD::ZEXTLOAD, MVT::i32, MVT::i1, Promote);
85
90 if (!Subtarget.hasE2()) {
92 }
95
96 if (!Subtarget.hasE2()) {
97 setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i8, Expand);
98 setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i16, Expand);
101 }
102
103 if (!Subtarget.has2E3()) {
109 }
110
112
113 // Float
114
115 ISD::CondCode FPCCToExtend[] = {
118 };
119
120 ISD::NodeType FPOpToExpand[] = {
123
124 if (STI.useHardFloat()) {
125
126 MVT AllVTy[] = {MVT::f32, MVT::f64};
127
128 for (auto VT : AllVTy) {
132
133 for (auto CC : FPCCToExtend)
134 setCondCodeAction(CC, VT, Expand);
135 for (auto Op : FPOpToExpand)
137 }
138
139 if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat()) {
141 setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Expand);
142 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
143 }
144 if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat()) {
145 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f32, Expand);
146 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
147 setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Expand);
148 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
149 }
150 }
151
152 // Compute derived properties from the register classes.
154
157
158 // TODO: Add atomic support fully.
160
164}
165
167 SelectionDAG &DAG) const {
168 switch (Op.getOpcode()) {
169 default:
170 llvm_unreachable("unimplemented op");
172 return LowerGlobalAddress(Op, DAG);
174 return LowerExternalSymbol(Op, DAG);
176 return LowerGlobalTLSAddress(Op, DAG);
177 case ISD::JumpTable:
178 return LowerJumpTable(Op, DAG);
180 return LowerBlockAddress(Op, DAG);
182 return LowerConstantPool(Op, DAG);
183 case ISD::VASTART:
184 return LowerVASTART(Op, DAG);
185 case ISD::FRAMEADDR:
186 return LowerFRAMEADDR(Op, DAG);
187 case ISD::RETURNADDR:
188 return LowerRETURNADDR(Op, DAG);
189 }
190}
191
193 LLVMContext &Context, EVT VT) const {
194 if (!VT.isVector())
195 return MVT::i32;
196
198}
199
201 const CCValAssign &VA, const SDLoc &DL) {
202 EVT LocVT = VA.getLocVT();
203
204 switch (VA.getLocInfo()) {
205 default:
206 llvm_unreachable("Unexpected CCValAssign::LocInfo");
208 break;
210 Val = DAG.getNode(ISD::BITCAST, DL, LocVT, Val);
211 break;
212 }
213 return Val;
214}
215
217 const CCValAssign &VA, const SDLoc &DL) {
218 switch (VA.getLocInfo()) {
219 default:
220 llvm_unreachable("Unexpected CCValAssign::LocInfo");
222 break;
224 Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val);
225 break;
226 }
227 return Val;
228}
229
230static SDValue unpackFromRegLoc(const CSKYSubtarget &Subtarget,
231 SelectionDAG &DAG, SDValue Chain,
232 const CCValAssign &VA, const SDLoc &DL) {
235 EVT LocVT = VA.getLocVT();
236 SDValue Val;
237 const TargetRegisterClass *RC;
238
239 switch (LocVT.getSimpleVT().SimpleTy) {
240 default:
241 llvm_unreachable("Unexpected register type");
242 case MVT::i32:
243 RC = &CSKY::GPRRegClass;
244 break;
245 case MVT::f32:
246 RC = Subtarget.hasFPUv2SingleFloat() ? &CSKY::sFPR32RegClass
247 : &CSKY::FPR32RegClass;
248 break;
249 case MVT::f64:
250 RC = Subtarget.hasFPUv2DoubleFloat() ? &CSKY::sFPR64RegClass
251 : &CSKY::FPR64RegClass;
252 break;
253 }
254
255 Register VReg = RegInfo.createVirtualRegister(RC);
256 RegInfo.addLiveIn(VA.getLocReg(), VReg);
257 Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
258
259 return convertLocVTToValVT(DAG, Val, VA, DL);
260}
261
263 const CCValAssign &VA, const SDLoc &DL) {
265 MachineFrameInfo &MFI = MF.getFrameInfo();
266 EVT LocVT = VA.getLocVT();
267 EVT ValVT = VA.getValVT();
269 int FI = MFI.CreateFixedObject(ValVT.getSizeInBits() / 8,
270 VA.getLocMemOffset(), /*Immutable=*/true);
271 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
272 SDValue Val;
273
274 ISD::LoadExtType ExtType;
275 switch (VA.getLocInfo()) {
276 default:
277 llvm_unreachable("Unexpected CCValAssign::LocInfo");
280 ExtType = ISD::NON_EXTLOAD;
281 break;
282 }
283 Val = DAG.getExtLoad(
284 ExtType, DL, LocVT, Chain, FIN,
286 return Val;
287}
288
289static SDValue unpack64(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA,
290 const SDLoc &DL) {
291 assert(VA.getLocVT() == MVT::i32 &&
292 (VA.getValVT() == MVT::f64 || VA.getValVT() == MVT::i64) &&
293 "Unexpected VA");
295 MachineFrameInfo &MFI = MF.getFrameInfo();
297
298 if (VA.isMemLoc()) {
299 // f64/i64 is passed on the stack.
300 int FI = MFI.CreateFixedObject(8, VA.getLocMemOffset(), /*Immutable=*/true);
301 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
302 return DAG.getLoad(VA.getValVT(), DL, Chain, FIN,
304 }
305
306 assert(VA.isRegLoc() && "Expected register VA assignment");
307
308 Register LoVReg = RegInfo.createVirtualRegister(&CSKY::GPRRegClass);
309 RegInfo.addLiveIn(VA.getLocReg(), LoVReg);
310 SDValue Lo = DAG.getCopyFromReg(Chain, DL, LoVReg, MVT::i32);
311 SDValue Hi;
312 if (VA.getLocReg() == CSKY::R3) {
313 // Second half of f64/i64 is passed on the stack.
314 int FI = MFI.CreateFixedObject(4, 0, /*Immutable=*/true);
315 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
316 Hi = DAG.getLoad(MVT::i32, DL, Chain, FIN,
318 } else {
319 // Second half of f64/i64 is passed in another GPR.
320 Register HiVReg = RegInfo.createVirtualRegister(&CSKY::GPRRegClass);
321 RegInfo.addLiveIn(VA.getLocReg() + 1, HiVReg);
322 Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i32);
323 }
324 return DAG.getNode(CSKYISD::BITCAST_FROM_LOHI, DL, VA.getValVT(), Lo, Hi);
325}
326
327// Transform physical registers into virtual registers.
328SDValue CSKYTargetLowering::LowerFormalArguments(
329 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
330 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
331 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
332
333 switch (CallConv) {
334 default:
335 report_fatal_error("Unsupported calling convention");
336 case CallingConv::C:
338 break;
339 }
340
341 MachineFunction &MF = DAG.getMachineFunction();
342
343 // Used with vargs to acumulate store chains.
344 std::vector<SDValue> OutChains;
345
346 // Assign locations to all of the incoming arguments.
348 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
349
350 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));
351
352 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
353 CCValAssign &VA = ArgLocs[i];
354 SDValue ArgValue;
355
356 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
357
358 if (IsF64OnCSKY)
359 ArgValue = unpack64(DAG, Chain, VA, DL);
360 else if (VA.isRegLoc())
361 ArgValue = unpackFromRegLoc(Subtarget, DAG, Chain, VA, DL);
362 else
363 ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
364
365 InVals.push_back(ArgValue);
366 }
367
368 if (IsVarArg) {
369 const unsigned XLenInBytes = 4;
370 const MVT XLenVT = MVT::i32;
371
373 unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
374 const TargetRegisterClass *RC = &CSKY::GPRRegClass;
375 MachineFrameInfo &MFI = MF.getFrameInfo();
376 MachineRegisterInfo &RegInfo = MF.getRegInfo();
377 CSKYMachineFunctionInfo *CSKYFI = MF.getInfo<CSKYMachineFunctionInfo>();
378
379 // Offset of the first variable argument from stack pointer, and size of
380 // the vararg save area. For now, the varargs save area is either zero or
381 // large enough to hold a0-a4.
382 int VaArgOffset, VarArgsSaveSize;
383
384 // If all registers are allocated, then all varargs must be passed on the
385 // stack and we don't need to save any argregs.
386 if (ArgRegs.size() == Idx) {
387 VaArgOffset = CCInfo.getStackSize();
388 VarArgsSaveSize = 0;
389 } else {
390 VarArgsSaveSize = XLenInBytes * (ArgRegs.size() - Idx);
391 VaArgOffset = -VarArgsSaveSize;
392 }
393
394 // Record the frame index of the first variable argument
395 // which is a value necessary to VASTART.
396 int FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
397 CSKYFI->setVarArgsFrameIndex(FI);
398
399 // Copy the integer registers that may have been used for passing varargs
400 // to the vararg save area.
401 for (unsigned I = Idx; I < ArgRegs.size();
402 ++I, VaArgOffset += XLenInBytes) {
403 const Register Reg = RegInfo.createVirtualRegister(RC);
404 RegInfo.addLiveIn(ArgRegs[I], Reg);
405 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, XLenVT);
406 FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
407 SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
408 SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,
410 cast<StoreSDNode>(Store.getNode())
411 ->getMemOperand()
412 ->setValue((Value *)nullptr);
413 OutChains.push_back(Store);
414 }
415 CSKYFI->setVarArgsSaveSize(VarArgsSaveSize);
416 }
417
418 // All stores are grouped in one node to allow the matching between
419 // the size of Ins and InVals. This only happens for vararg functions.
420 if (!OutChains.empty()) {
421 OutChains.push_back(Chain);
422 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
423 }
424
425 return Chain;
426}
427
428bool CSKYTargetLowering::CanLowerReturn(
429 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
431 const Type *RetTy) const {
433 CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context);
434 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
435}
436
438CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
439 bool IsVarArg,
441 const SmallVectorImpl<SDValue> &OutVals,
442 const SDLoc &DL, SelectionDAG &DAG) const {
443 // Stores the assignment of the return value to a location.
445
446 // Info about the registers and stack slot.
447 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), CSKYLocs,
448 *DAG.getContext());
449 CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
450
451 SDValue Glue;
452 SmallVector<SDValue, 4> RetOps(1, Chain);
453
454 // Copy the result values into the output registers.
455 for (unsigned i = 0, e = CSKYLocs.size(); i < e; ++i) {
456 SDValue Val = OutVals[i];
457 CCValAssign &VA = CSKYLocs[i];
458 assert(VA.isRegLoc() && "Can only return in registers!");
459
460 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
461
462 if (IsF64OnCSKY) {
463
464 assert(VA.isRegLoc() && "Expected return via registers");
465 SDValue Split64 = DAG.getNode(CSKYISD::BITCAST_TO_LOHI, DL,
466 DAG.getVTList(MVT::i32, MVT::i32), Val);
467 SDValue Lo = Split64.getValue(0);
468 SDValue Hi = Split64.getValue(1);
469
470 Register RegLo = VA.getLocReg();
471 assert(RegLo < CSKY::R31 && "Invalid register pair");
472 Register RegHi = RegLo + 1;
473
474 Chain = DAG.getCopyToReg(Chain, DL, RegLo, Lo, Glue);
475 Glue = Chain.getValue(1);
476 RetOps.push_back(DAG.getRegister(RegLo, MVT::i32));
477 Chain = DAG.getCopyToReg(Chain, DL, RegHi, Hi, Glue);
478 Glue = Chain.getValue(1);
479 RetOps.push_back(DAG.getRegister(RegHi, MVT::i32));
480 } else {
481 // Handle a 'normal' return.
482 Val = convertValVTToLocVT(DAG, Val, VA, DL);
483 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue);
484
485 // Guarantee that all emitted copies are stuck together.
486 Glue = Chain.getValue(1);
487 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
488 }
489 }
490
491 RetOps[0] = Chain; // Update chain.
492
493 // Add the glue node if we have it.
494 if (Glue.getNode()) {
495 RetOps.push_back(Glue);
496 }
497
498 // Interrupt service routines use different return instructions.
499 if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt"))
500 return DAG.getNode(CSKYISD::NIR, DL, MVT::Other, RetOps);
501
502 return DAG.getNode(CSKYISD::RET, DL, MVT::Other, RetOps);
503}
504
505// Lower a call to a callseq_start + CALL + callseq_end chain, and add input
506// and output parameter nodes.
507SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,
508 SmallVectorImpl<SDValue> &InVals) const {
509 SelectionDAG &DAG = CLI.DAG;
510 SDLoc &DL = CLI.DL;
511 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
512 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
513 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
514 SDValue Chain = CLI.Chain;
515 SDValue Callee = CLI.Callee;
516 bool &IsTailCall = CLI.IsTailCall;
517 CallingConv::ID CallConv = CLI.CallConv;
518 bool IsVarArg = CLI.IsVarArg;
519 EVT PtrVT = getPointerTy(DAG.getDataLayout());
520 MVT XLenVT = MVT::i32;
521
522 MachineFunction &MF = DAG.getMachineFunction();
523
524 // Analyze the operands of the call, assigning locations to each operand.
526 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
527
528 ArgCCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, IsVarArg));
529
530 // Check if it's really possible to do a tail call.
531 if (IsTailCall)
532 IsTailCall = false; // TODO: TailCallOptimization;
533
534 if (IsTailCall)
535 ++NumTailCalls;
536 else if (CLI.CB && CLI.CB->isMustTailCall())
537 report_fatal_error("failed to perform tail call elimination on a call "
538 "site marked musttail");
539
540 // Get a count of how many bytes are to be pushed on the stack.
541 unsigned NumBytes = ArgCCInfo.getStackSize();
542
543 // Create local copies for byval args
544 SmallVector<SDValue, 8> ByValArgs;
545 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
546 ISD::ArgFlagsTy Flags = Outs[i].Flags;
547 if (!Flags.isByVal())
548 continue;
549
550 SDValue Arg = OutVals[i];
551 unsigned Size = Flags.getByValSize();
552 Align Alignment = Flags.getNonZeroByValAlign();
553
554 int FI =
555 MF.getFrameInfo().CreateStackObject(Size, Alignment, /*isSS=*/false);
556 SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
557 SDValue SizeNode = DAG.getConstant(Size, DL, XLenVT);
558
559 Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment, Alignment,
560 /*IsVolatile=*/false,
561 /*AlwaysInline=*/false, /*CI=*/nullptr, IsTailCall,
562 MachinePointerInfo(), MachinePointerInfo());
563 ByValArgs.push_back(FIPtr);
564 }
565
566 if (!IsTailCall)
567 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
568
569 // Copy argument values to their designated locations.
571 SmallVector<SDValue, 8> MemOpChains;
573 for (unsigned i = 0, j = 0, e = ArgLocs.size(); i != e; ++i) {
574 CCValAssign &VA = ArgLocs[i];
575 SDValue ArgValue = OutVals[i];
576 ISD::ArgFlagsTy Flags = Outs[i].Flags;
577
578 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
579
580 if (IsF64OnCSKY && VA.isRegLoc()) {
581 SDValue Split64 =
582 DAG.getNode(CSKYISD::BITCAST_TO_LOHI, DL,
583 DAG.getVTList(MVT::i32, MVT::i32), ArgValue);
584 SDValue Lo = Split64.getValue(0);
585 SDValue Hi = Split64.getValue(1);
586
587 Register RegLo = VA.getLocReg();
588 RegsToPass.push_back(std::make_pair(RegLo, Lo));
589
590 if (RegLo == CSKY::R3) {
591 // Second half of f64/i64 is passed on the stack.
592 // Work out the address of the stack slot.
593 if (!StackPtr.getNode())
594 StackPtr = DAG.getCopyFromReg(Chain, DL, CSKY::R14, PtrVT);
595 // Emit the store.
596 MemOpChains.push_back(
597 DAG.getStore(Chain, DL, Hi, StackPtr, MachinePointerInfo()));
598 } else {
599 // Second half of f64/i64 is passed in another GPR.
600 assert(RegLo < CSKY::R31 && "Invalid register pair");
601 Register RegHigh = RegLo + 1;
602 RegsToPass.push_back(std::make_pair(RegHigh, Hi));
603 }
604 continue;
605 }
606
607 ArgValue = convertValVTToLocVT(DAG, ArgValue, VA, DL);
608
609 // Use local copy if it is a byval arg.
610 if (Flags.isByVal())
611 ArgValue = ByValArgs[j++];
612
613 if (VA.isRegLoc()) {
614 // Queue up the argument copies and emit them at the end.
615 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
616 } else {
617 assert(VA.isMemLoc() && "Argument not register or memory");
618 assert(!IsTailCall && "Tail call not allowed if stack is used "
619 "for passing parameters");
620
621 // Work out the address of the stack slot.
622 if (!StackPtr.getNode())
623 StackPtr = DAG.getCopyFromReg(Chain, DL, CSKY::R14, PtrVT);
625 DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
627
628 // Emit the store.
629 MemOpChains.push_back(
630 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
631 }
632 }
633
634 // Join the stores, which are independent of one another.
635 if (!MemOpChains.empty())
636 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
637
638 SDValue Glue;
639
640 // Build a sequence of copy-to-reg nodes, chained and glued together.
641 for (auto &Reg : RegsToPass) {
642 Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, Glue);
643 Glue = Chain.getValue(1);
644 }
645
647 EVT Ty = getPointerTy(DAG.getDataLayout());
648 bool IsRegCall = false;
649
650 Ops.push_back(Chain);
651
652 if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
653 const GlobalValue *GV = S->getGlobal();
654 bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(GV);
655
656 if (isPositionIndependent() || !Subtarget.has2E3()) {
657 IsRegCall = true;
658 Ops.push_back(getAddr<GlobalAddressSDNode, true>(S, DAG, IsLocal));
659 } else {
660 Ops.push_back(getTargetNode(cast<GlobalAddressSDNode>(Callee), DL, Ty,
661 DAG, CSKYII::MO_None));
662 Ops.push_back(getTargetConstantPoolValue(
663 cast<GlobalAddressSDNode>(Callee), Ty, DAG, CSKYII::MO_None));
664 }
665 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
666 bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(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(
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 {
788 CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(
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 {
1049 CSKYConstantPoolValue *CPV =
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 {
1060 CSKYConstantPoolValue *CPV =
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);
1071 CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(
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);
1082 CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(
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
1121SDValue CSKYTargetLowering::LowerGlobalAddress(SDValue Op,
1122 SelectionDAG &DAG) const {
1123 SDLoc DL(Op);
1124 EVT Ty = Op.getValueType();
1125 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
1126 int64_t Offset = N->getOffset();
1127
1128 const GlobalValue *GV = N->getGlobal();
1129 bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(GV);
1130 SDValue Addr = getAddr<GlobalAddressSDNode, false>(N, DAG, IsLocal);
1131
1132 // In order to maximise the opportunity for common subexpression elimination,
1133 // emit a separate ADD node for the global address offset instead of folding
1134 // it in the global address node. Later peephole optimisations may choose to
1135 // fold it back in when profitable.
1136 if (Offset != 0)
1137 return DAG.getNode(ISD::ADD, DL, Ty, Addr,
1138 DAG.getConstant(Offset, DL, MVT::i32));
1139 return Addr;
1140}
1141
1142SDValue CSKYTargetLowering::LowerExternalSymbol(SDValue Op,
1143 SelectionDAG &DAG) const {
1144 ExternalSymbolSDNode *N = cast<ExternalSymbolSDNode>(Op);
1145
1146 return getAddr(N, DAG, false);
1147}
1148
1149SDValue CSKYTargetLowering::LowerJumpTable(SDValue Op,
1150 SelectionDAG &DAG) const {
1151 JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
1152
1153 return getAddr<JumpTableSDNode, false>(N, DAG);
1154}
1155
1156SDValue CSKYTargetLowering::LowerBlockAddress(SDValue Op,
1157 SelectionDAG &DAG) const {
1158 BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
1159
1160 return getAddr(N, DAG);
1161}
1162
1163SDValue CSKYTargetLowering::LowerConstantPool(SDValue Op,
1164 SelectionDAG &DAG) const {
1165 assert(!Subtarget.hasE2());
1166 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
1167
1168 return getAddr(N, DAG);
1169}
1170
1171SDValue CSKYTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
1172 MachineFunction &MF = DAG.getMachineFunction();
1173 CSKYMachineFunctionInfo *FuncInfo = MF.getInfo<CSKYMachineFunctionInfo>();
1174
1175 SDLoc DL(Op);
1176 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
1178
1179 // vastart just stores the address of the VarArgsFrameIndex slot into the
1180 // memory location argument.
1181 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1182 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
1183 MachinePointerInfo(SV));
1184}
1185
1186SDValue CSKYTargetLowering::LowerFRAMEADDR(SDValue Op,
1187 SelectionDAG &DAG) const {
1188 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();
1189 MachineFunction &MF = DAG.getMachineFunction();
1190 MachineFrameInfo &MFI = MF.getFrameInfo();
1191 MFI.setFrameAddressIsTaken(true);
1192
1193 EVT VT = Op.getValueType();
1194 SDLoc dl(Op);
1195 unsigned Depth = Op.getConstantOperandVal(0);
1196 Register FrameReg = RI.getFrameRegister(MF);
1197 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
1198 while (Depth--)
1199 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1200 MachinePointerInfo());
1201 return FrameAddr;
1202}
1203
1204SDValue CSKYTargetLowering::LowerRETURNADDR(SDValue Op,
1205 SelectionDAG &DAG) const {
1206 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();
1207 MachineFunction &MF = DAG.getMachineFunction();
1208 MachineFrameInfo &MFI = MF.getFrameInfo();
1209 MFI.setReturnAddressIsTaken(true);
1210
1211 EVT VT = Op.getValueType();
1212 SDLoc dl(Op);
1213 unsigned Depth = Op.getConstantOperandVal(0);
1214 if (Depth) {
1215 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1216 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
1217 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
1218 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
1219 MachinePointerInfo());
1220 }
1221 // Return the value of the return address register, marking it an implicit
1222 // live-in.
1223 unsigned Reg = MF.addLiveIn(RI.getRARegister(), getRegClassFor(MVT::i32));
1224 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
1225}
1226
1227Register CSKYTargetLowering::getExceptionPointerRegister(
1228 const Constant *PersonalityFn) const {
1229 return CSKY::R0;
1230}
1231
1232Register CSKYTargetLowering::getExceptionSelectorRegister(
1233 const Constant *PersonalityFn) const {
1234 return CSKY::R1;
1235}
1236
1237SDValue CSKYTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1238 SelectionDAG &DAG) const {
1239 SDLoc DL(Op);
1240 EVT Ty = Op.getValueType();
1241 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
1242 int64_t Offset = N->getOffset();
1243 MVT XLenVT = MVT::i32;
1244
1246 SDValue Addr;
1247 switch (Model) {
1249 Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/false);
1250 break;
1252 Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/true);
1253 break;
1256 Addr = getDynamicTLSAddr(N, DAG);
1257 break;
1258 }
1259
1260 // In order to maximise the opportunity for common subexpression elimination,
1261 // emit a separate ADD node for the global address offset instead of folding
1262 // it in the global address node. Later peephole optimisations may choose to
1263 // fold it back in when profitable.
1264 if (Offset != 0)
1265 return DAG.getNode(ISD::ADD, DL, Ty, Addr,
1266 DAG.getConstant(Offset, DL, XLenVT));
1267 return Addr;
1268}
1269
1270SDValue CSKYTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
1271 SelectionDAG &DAG,
1272 bool UseGOT) const {
1273 MachineFunction &MF = DAG.getMachineFunction();
1274 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
1275
1276 unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();
1277
1278 SDLoc DL(N);
1279 EVT Ty = getPointerTy(DAG.getDataLayout());
1280
1282 bool AddCurrentAddr = UseGOT ? true : false;
1283 unsigned char PCAjust = UseGOT ? 4 : 0;
1284
1285 CSKYConstantPoolValue *CPV =
1286 CSKYConstantPoolConstant::Create(N->getGlobal(), CSKYCP::CPValue, PCAjust,
1287 Flag, AddCurrentAddr, CSKYPCLabelIndex);
1288 SDValue CAddr = DAG.getTargetConstantPool(CPV, Ty);
1289
1290 SDValue Load;
1291 if (UseGOT) {
1292 SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);
1293 auto *LRWGRS = DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty},
1294 {CAddr, PICLabel});
1295 auto LRWADDGRS =
1296 DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));
1297 Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), LRWADDGRS,
1298 MachinePointerInfo(N->getGlobal()));
1299 } else {
1300 Load = SDValue(DAG.getMachineNode(CSKY::LRW32, DL, Ty, CAddr), 0);
1301 }
1302
1303 // Add the thread pointer.
1304 SDValue TPReg = DAG.getRegister(CSKY::R31, MVT::i32);
1305 return DAG.getNode(ISD::ADD, DL, Ty, Load, TPReg);
1306}
1307
1308SDValue CSKYTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N,
1309 SelectionDAG &DAG) const {
1310 MachineFunction &MF = DAG.getMachineFunction();
1311 CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
1312
1313 unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();
1314
1315 SDLoc DL(N);
1316 EVT Ty = getPointerTy(DAG.getDataLayout());
1317 IntegerType *CallTy = Type::getIntNTy(*DAG.getContext(), Ty.getSizeInBits());
1318
1319 CSKYConstantPoolValue *CPV =
1321 CSKYCP::TLSGD, true, CSKYPCLabelIndex);
1322 SDValue Addr = DAG.getTargetConstantPool(CPV, Ty);
1323 SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);
1324
1325 auto *LRWGRS =
1326 DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty}, {Addr, PICLabel});
1327
1328 auto Load =
1329 DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));
1330
1331 // Prepare argument list to generate call.
1333 Args.emplace_back(Load, CallTy);
1334
1335 // Setup call to __tls_get_addr.
1336 TargetLowering::CallLoweringInfo CLI(DAG);
1337 CLI.setDebugLoc(DL)
1338 .setChain(DAG.getEntryNode())
1339 .setLibCallee(CallingConv::C, CallTy,
1340 DAG.getExternalSymbol("__tls_get_addr", Ty),
1341 std::move(Args));
1342 SDValue V = LowerCallTo(CLI).first;
1343
1344 return V;
1345}
1346
1347bool CSKYTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
1348 SDValue C) const {
1349 if (!VT.isScalarInteger())
1350 return false;
1351
1352 // Omit if data size exceeds.
1353 if (VT.getSizeInBits() > Subtarget.XLen)
1354 return false;
1355
1356 if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode())) {
1357 const APInt &Imm = ConstNode->getAPIntValue();
1358 // Break MULT to LSLI + ADDU/SUBU.
1359 if ((Imm + 1).isPowerOf2() || (Imm - 1).isPowerOf2() ||
1360 (1 - Imm).isPowerOf2())
1361 return true;
1362 // Only break MULT for sub targets without MULT32, since an extra
1363 // instruction will be generated against the above 3 cases. We leave it
1364 // unchanged on sub targets with MULT32, since not sure it is better.
1365 if (!Subtarget.hasE2() && (-1 - Imm).isPowerOf2())
1366 return true;
1367 // Break (MULT x, imm) to ([IXH32|IXW32|IXD32] (LSLI32 x, i0), x) when
1368 // imm=(1<<i0)+[2|4|8] and imm has to be composed via a MOVIH32/ORI32 pair.
1369 if (Imm.ugt(0xffff) && ((Imm - 2).isPowerOf2() || (Imm - 4).isPowerOf2()) &&
1370 Subtarget.hasE2())
1371 return true;
1372 if (Imm.ugt(0xffff) && (Imm - 8).isPowerOf2() && Subtarget.has2E3())
1373 return true;
1374 }
1375
1376 return false;
1377}
1378
1379bool CSKYTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
1380 return Subtarget.has2E3();
1381}
1382
1383bool CSKYTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {
1384 return Subtarget.hasE2();
1385}
return SDValue()
static const MCPhysReg GPRArgRegs[]
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
basic Basic Alias true
static SDValue unpack64(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)
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)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
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:171
size_t size() const
Get the array size.
Definition ArrayRef.h:141
LLVM Basic Block Representation.
Definition BasicBlock.h:62
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() 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)
Register getFrameRegister(const MachineFunction &MF) const override
bool hasFPUv2SingleFloat() const
bool hasFPUv3SingleFloat() const
const CSKYRegisterInfo * getRegisterInfo() const override
bool hasFPUv2DoubleFloat() const
bool useHardFloat() const
bool hasFPUv3DoubleFloat() 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:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
unsigned getPointerSizeInBits(unsigned AS=0) const
The size in bits of the pointer representation in a given address space.
Definition DataLayout.h:501
A debug info location.
Definition DebugLoc.h:126
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition Function.cpp:723
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Machine Value Type.
SimpleValueType SimpleTy
static MVT getIntegerVT(unsigned BitWidth)
LLVM_ABI 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.
LLVM_ABI 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 '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI 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.
BasicBlockListType::iterator iterator
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, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
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...
LLVM_ABI 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)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI 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),...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI 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.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
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)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI 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 ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI 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)
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
LLVM_ABI 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)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
LLVM_ABI std::string lower() const
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.
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.
TargetLowering(const TargetLowering &)=delete
Primary interface to the complete machine description for the target machine.
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:46
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:309
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:313
self_iterator getIterator()
Definition ilist_node.h:123
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ 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:41
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:275
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ GlobalAddress
Definition ISDOpcodes.h:88
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition ISDOpcodes.h:749
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ GlobalTLSAddress
Definition ISDOpcodes.h:89
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:706
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:821
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition ISDOpcodes.h:328
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:110
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ ExternalSymbol
Definition ISDOpcodes.h:93
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:843
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:536
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Flag
These should be considered private to the implementation of the MCInstrDesc class.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:573
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
@ Default
The result value is uniform if and only if all operands are uniform.
Definition Uniformity.h:20
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
#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:90
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
bool isVector() const
Return true if this is a vector value type.
Definition ValueTypes.h:176
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
Definition ValueTypes.h:165
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.