LLVM 17.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
81
85
90 if (!Subtarget.hasE2()) {
92 }
95
96 if (!Subtarget.hasE2()) {
101 }
102
103 if (!Subtarget.has2E3()) {
108 }
109
111
112 // Float
113
114 ISD::CondCode FPCCToExtend[] = {
117 };
118
119 ISD::NodeType FPOpToExpand[] = {ISD::FSIN, ISD::FCOS, ISD::FSINCOS,
121
122 if (STI.useHardFloat()) {
123
124 MVT AllVTy[] = {MVT::f32, MVT::f64};
125
126 for (auto VT : AllVTy) {
130
131 for (auto CC : FPCCToExtend)
133 for (auto Op : FPOpToExpand)
134 setOperationAction(Op, VT, Expand);
135 }
136
137 if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat()) {
139 }
140 if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat()) {
143 }
144 }
145
146 // Compute derived properties from the register classes.
148
151
152 // TODO: Add atomic support fully.
154
158}
159
161 SelectionDAG &DAG) const {
162 switch (Op.getOpcode()) {
163 default:
164 llvm_unreachable("unimplemented op");
166 return LowerGlobalAddress(Op, DAG);
168 return LowerExternalSymbol(Op, DAG);
170 return LowerGlobalTLSAddress(Op, DAG);
171 case ISD::JumpTable:
172 return LowerJumpTable(Op, DAG);
174 return LowerBlockAddress(Op, DAG);
176 return LowerConstantPool(Op, DAG);
177 case ISD::VASTART:
178 return LowerVASTART(Op, DAG);
179 case ISD::FRAMEADDR:
180 return LowerFRAMEADDR(Op, DAG);
181 case ISD::RETURNADDR:
182 return LowerRETURNADDR(Op, DAG);
183 }
184}
185
187 LLVMContext &Context, EVT VT) const {
188 if (!VT.isVector())
189 return MVT::i32;
190
192}
193
195 const CCValAssign &VA, const SDLoc &DL) {
196 EVT LocVT = VA.getLocVT();
197
198 switch (VA.getLocInfo()) {
199 default:
200 llvm_unreachable("Unexpected CCValAssign::LocInfo");
202 break;
204 Val = DAG.getNode(ISD::BITCAST, DL, LocVT, Val);
205 break;
206 }
207 return Val;
208}
209
211 const CCValAssign &VA, const SDLoc &DL) {
212 switch (VA.getLocInfo()) {
213 default:
214 llvm_unreachable("Unexpected CCValAssign::LocInfo");
216 break;
218 Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val);
219 break;
220 }
221 return Val;
222}
223
224static SDValue unpackFromRegLoc(const CSKYSubtarget &Subtarget,
225 SelectionDAG &DAG, SDValue Chain,
226 const CCValAssign &VA, const SDLoc &DL) {
229 EVT LocVT = VA.getLocVT();
230 SDValue Val;
231 const TargetRegisterClass *RC;
232
233 switch (LocVT.getSimpleVT().SimpleTy) {
234 default:
235 llvm_unreachable("Unexpected register type");
236 case MVT::i32:
237 RC = &CSKY::GPRRegClass;
238 break;
239 case MVT::f32:
240 RC = Subtarget.hasFPUv2SingleFloat() ? &CSKY::sFPR32RegClass
241 : &CSKY::FPR32RegClass;
242 break;
243 case MVT::f64:
244 RC = Subtarget.hasFPUv2DoubleFloat() ? &CSKY::sFPR64RegClass
245 : &CSKY::FPR64RegClass;
246 break;
247 }
248
249 Register VReg = RegInfo.createVirtualRegister(RC);
250 RegInfo.addLiveIn(VA.getLocReg(), VReg);
251 Val = DAG.getCopyFromReg(Chain, DL, VReg, LocVT);
252
253 return convertLocVTToValVT(DAG, Val, VA, DL);
254}
255
257 const CCValAssign &VA, const SDLoc &DL) {
259 MachineFrameInfo &MFI = MF.getFrameInfo();
260 EVT LocVT = VA.getLocVT();
261 EVT ValVT = VA.getValVT();
263 int FI = MFI.CreateFixedObject(ValVT.getSizeInBits() / 8,
264 VA.getLocMemOffset(), /*Immutable=*/true);
265 SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
266 SDValue Val;
267
268 ISD::LoadExtType ExtType;
269 switch (VA.getLocInfo()) {
270 default:
271 llvm_unreachable("Unexpected CCValAssign::LocInfo");
274 ExtType = ISD::NON_EXTLOAD;
275 break;
276 }
277 Val = DAG.getExtLoad(
278 ExtType, DL, LocVT, Chain, FIN,
280 return Val;
281}
282
283static SDValue unpack64(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA,
284 const SDLoc &DL) {
285 assert(VA.getLocVT() == MVT::i32 &&
286 (VA.getValVT() == MVT::f64 || VA.getValVT() == MVT::i64) &&
287 "Unexpected VA");
289 MachineFrameInfo &MFI = MF.getFrameInfo();
291
292 if (VA.isMemLoc()) {
293 // f64/i64 is passed on the stack.
294 int FI = MFI.CreateFixedObject(8, VA.getLocMemOffset(), /*Immutable=*/true);
295 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
296 return DAG.getLoad(VA.getValVT(), DL, Chain, FIN,
298 }
299
300 assert(VA.isRegLoc() && "Expected register VA assignment");
301
302 Register LoVReg = RegInfo.createVirtualRegister(&CSKY::GPRRegClass);
303 RegInfo.addLiveIn(VA.getLocReg(), LoVReg);
304 SDValue Lo = DAG.getCopyFromReg(Chain, DL, LoVReg, MVT::i32);
305 SDValue Hi;
306 if (VA.getLocReg() == CSKY::R3) {
307 // Second half of f64/i64 is passed on the stack.
308 int FI = MFI.CreateFixedObject(4, 0, /*Immutable=*/true);
309 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
310 Hi = DAG.getLoad(MVT::i32, DL, Chain, FIN,
312 } else {
313 // Second half of f64/i64 is passed in another GPR.
314 Register HiVReg = RegInfo.createVirtualRegister(&CSKY::GPRRegClass);
315 RegInfo.addLiveIn(VA.getLocReg() + 1, HiVReg);
316 Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i32);
317 }
318 return DAG.getNode(CSKYISD::BITCAST_FROM_LOHI, DL, VA.getValVT(), Lo, Hi);
319}
320
321// Transform physical registers into virtual registers.
322SDValue CSKYTargetLowering::LowerFormalArguments(
323 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
324 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
325 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
326
327 switch (CallConv) {
328 default:
329 report_fatal_error("Unsupported calling convention");
330 case CallingConv::C:
332 break;
333 }
334
336
337 // Used with vargs to acumulate store chains.
338 std::vector<SDValue> OutChains;
339
340 // Assign locations to all of the incoming arguments.
342 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
343
344 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));
345
346 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
347 CCValAssign &VA = ArgLocs[i];
348 SDValue ArgValue;
349
350 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
351
352 if (IsF64OnCSKY)
353 ArgValue = unpack64(DAG, Chain, VA, DL);
354 else if (VA.isRegLoc())
355 ArgValue = unpackFromRegLoc(Subtarget, DAG, Chain, VA, DL);
356 else
357 ArgValue = unpackFromMemLoc(DAG, Chain, VA, DL);
358
359 InVals.push_back(ArgValue);
360 }
361
362 if (IsVarArg) {
363 const unsigned XLenInBytes = 4;
364 const MVT XLenVT = MVT::i32;
365
367 unsigned Idx = CCInfo.getFirstUnallocated(ArgRegs);
368 const TargetRegisterClass *RC = &CSKY::GPRRegClass;
369 MachineFrameInfo &MFI = MF.getFrameInfo();
372
373 // Offset of the first variable argument from stack pointer, and size of
374 // the vararg save area. For now, the varargs save area is either zero or
375 // large enough to hold a0-a4.
376 int VaArgOffset, VarArgsSaveSize;
377
378 // If all registers are allocated, then all varargs must be passed on the
379 // stack and we don't need to save any argregs.
380 if (ArgRegs.size() == Idx) {
381 VaArgOffset = CCInfo.getNextStackOffset();
382 VarArgsSaveSize = 0;
383 } else {
384 VarArgsSaveSize = XLenInBytes * (ArgRegs.size() - Idx);
385 VaArgOffset = -VarArgsSaveSize;
386 }
387
388 // Record the frame index of the first variable argument
389 // which is a value necessary to VASTART.
390 int FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
391 CSKYFI->setVarArgsFrameIndex(FI);
392
393 // Copy the integer registers that may have been used for passing varargs
394 // to the vararg save area.
395 for (unsigned I = Idx; I < ArgRegs.size();
396 ++I, VaArgOffset += XLenInBytes) {
397 const Register Reg = RegInfo.createVirtualRegister(RC);
398 RegInfo.addLiveIn(ArgRegs[I], Reg);
399 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, XLenVT);
400 FI = MFI.CreateFixedObject(XLenInBytes, VaArgOffset, true);
401 SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
402 SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,
404 cast<StoreSDNode>(Store.getNode())
405 ->getMemOperand()
406 ->setValue((Value *)nullptr);
407 OutChains.push_back(Store);
408 }
409 CSKYFI->setVarArgsSaveSize(VarArgsSaveSize);
410 }
411
412 // All stores are grouped in one node to allow the matching between
413 // the size of Ins and InVals. This only happens for vararg functions.
414 if (!OutChains.empty()) {
415 OutChains.push_back(Chain);
416 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
417 }
418
419 return Chain;
420}
421
422bool CSKYTargetLowering::CanLowerReturn(
423 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
424 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
426 CCState CCInfo(CallConv, IsVarArg, MF, CSKYLocs, Context);
427 return CCInfo.CheckReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
428}
429
431CSKYTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
432 bool IsVarArg,
434 const SmallVectorImpl<SDValue> &OutVals,
435 const SDLoc &DL, SelectionDAG &DAG) const {
436 // Stores the assignment of the return value to a location.
438
439 // Info about the registers and stack slot.
440 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), CSKYLocs,
441 *DAG.getContext());
442 CCInfo.AnalyzeReturn(Outs, CCAssignFnForReturn(CallConv, IsVarArg));
443
444 SDValue Glue;
445 SmallVector<SDValue, 4> RetOps(1, Chain);
446
447 // Copy the result values into the output registers.
448 for (unsigned i = 0, e = CSKYLocs.size(); i < e; ++i) {
449 SDValue Val = OutVals[i];
450 CCValAssign &VA = CSKYLocs[i];
451 assert(VA.isRegLoc() && "Can only return in registers!");
452
453 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
454
455 if (IsF64OnCSKY) {
456
457 assert(VA.isRegLoc() && "Expected return via registers");
459 DAG.getVTList(MVT::i32, MVT::i32), Val);
460 SDValue Lo = Split64.getValue(0);
461 SDValue Hi = Split64.getValue(1);
462
463 Register RegLo = VA.getLocReg();
464 assert(RegLo < CSKY::R31 && "Invalid register pair");
465 Register RegHi = RegLo + 1;
466
467 Chain = DAG.getCopyToReg(Chain, DL, RegLo, Lo, Glue);
468 Glue = Chain.getValue(1);
469 RetOps.push_back(DAG.getRegister(RegLo, MVT::i32));
470 Chain = DAG.getCopyToReg(Chain, DL, RegHi, Hi, Glue);
471 Glue = Chain.getValue(1);
472 RetOps.push_back(DAG.getRegister(RegHi, MVT::i32));
473 } else {
474 // Handle a 'normal' return.
475 Val = convertValVTToLocVT(DAG, Val, VA, DL);
476 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue);
477
478 // Guarantee that all emitted copies are stuck together.
479 Glue = Chain.getValue(1);
480 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
481 }
482 }
483
484 RetOps[0] = Chain; // Update chain.
485
486 // Add the glue node if we have it.
487 if (Glue.getNode()) {
488 RetOps.push_back(Glue);
489 }
490
491 // Interrupt service routines use different return instructions.
492 if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt"))
493 return DAG.getNode(CSKYISD::NIR, DL, MVT::Other, RetOps);
494
495 return DAG.getNode(CSKYISD::RET, DL, MVT::Other, RetOps);
496}
497
498// Lower a call to a callseq_start + CALL + callseq_end chain, and add input
499// and output parameter nodes.
500SDValue CSKYTargetLowering::LowerCall(CallLoweringInfo &CLI,
501 SmallVectorImpl<SDValue> &InVals) const {
502 SelectionDAG &DAG = CLI.DAG;
503 SDLoc &DL = CLI.DL;
504 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
505 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
507 SDValue Chain = CLI.Chain;
508 SDValue Callee = CLI.Callee;
509 bool &IsTailCall = CLI.IsTailCall;
510 CallingConv::ID CallConv = CLI.CallConv;
511 bool IsVarArg = CLI.IsVarArg;
512 EVT PtrVT = getPointerTy(DAG.getDataLayout());
513 MVT XLenVT = MVT::i32;
514
516
517 // Analyze the operands of the call, assigning locations to each operand.
519 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
520
521 ArgCCInfo.AnalyzeCallOperands(Outs, CCAssignFnForCall(CallConv, IsVarArg));
522
523 // Check if it's really possible to do a tail call.
524 if (IsTailCall)
525 IsTailCall = false; // TODO: TailCallOptimization;
526
527 if (IsTailCall)
528 ++NumTailCalls;
529 else if (CLI.CB && CLI.CB->isMustTailCall())
530 report_fatal_error("failed to perform tail call elimination on a call "
531 "site marked musttail");
532
533 // Get a count of how many bytes are to be pushed on the stack.
534 unsigned NumBytes = ArgCCInfo.getNextStackOffset();
535
536 // Create local copies for byval args
537 SmallVector<SDValue, 8> ByValArgs;
538 for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
539 ISD::ArgFlagsTy Flags = Outs[i].Flags;
540 if (!Flags.isByVal())
541 continue;
542
543 SDValue Arg = OutVals[i];
544 unsigned Size = Flags.getByValSize();
545 Align Alignment = Flags.getNonZeroByValAlign();
546
547 int FI =
548 MF.getFrameInfo().CreateStackObject(Size, Alignment, /*isSS=*/false);
549 SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
550 SDValue SizeNode = DAG.getConstant(Size, DL, XLenVT);
551
552 Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment,
553 /*IsVolatile=*/false,
554 /*AlwaysInline=*/false, IsTailCall,
556 ByValArgs.push_back(FIPtr);
557 }
558
559 if (!IsTailCall)
560 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, CLI.DL);
561
562 // Copy argument values to their designated locations.
564 SmallVector<SDValue, 8> MemOpChains;
566 for (unsigned i = 0, j = 0, e = ArgLocs.size(); i != e; ++i) {
567 CCValAssign &VA = ArgLocs[i];
568 SDValue ArgValue = OutVals[i];
569 ISD::ArgFlagsTy Flags = Outs[i].Flags;
570
571 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
572
573 if (IsF64OnCSKY && VA.isRegLoc()) {
574 SDValue Split64 =
576 DAG.getVTList(MVT::i32, MVT::i32), ArgValue);
577 SDValue Lo = Split64.getValue(0);
578 SDValue Hi = Split64.getValue(1);
579
580 Register RegLo = VA.getLocReg();
581 RegsToPass.push_back(std::make_pair(RegLo, Lo));
582
583 if (RegLo == CSKY::R3) {
584 // Second half of f64/i64 is passed on the stack.
585 // Work out the address of the stack slot.
586 if (!StackPtr.getNode())
587 StackPtr = DAG.getCopyFromReg(Chain, DL, CSKY::R14, PtrVT);
588 // Emit the store.
589 MemOpChains.push_back(
590 DAG.getStore(Chain, DL, Hi, StackPtr, MachinePointerInfo()));
591 } else {
592 // Second half of f64/i64 is passed in another GPR.
593 assert(RegLo < CSKY::R31 && "Invalid register pair");
594 Register RegHigh = RegLo + 1;
595 RegsToPass.push_back(std::make_pair(RegHigh, Hi));
596 }
597 continue;
598 }
599
600 ArgValue = convertValVTToLocVT(DAG, ArgValue, VA, DL);
601
602 // Use local copy if it is a byval arg.
603 if (Flags.isByVal())
604 ArgValue = ByValArgs[j++];
605
606 if (VA.isRegLoc()) {
607 // Queue up the argument copies and emit them at the end.
608 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
609 } else {
610 assert(VA.isMemLoc() && "Argument not register or memory");
611 assert(!IsTailCall && "Tail call not allowed if stack is used "
612 "for passing parameters");
613
614 // Work out the address of the stack slot.
615 if (!StackPtr.getNode())
616 StackPtr = DAG.getCopyFromReg(Chain, DL, CSKY::R14, PtrVT);
618 DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
620
621 // Emit the store.
622 MemOpChains.push_back(
623 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
624 }
625 }
626
627 // Join the stores, which are independent of one another.
628 if (!MemOpChains.empty())
629 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
630
631 SDValue Glue;
632
633 // Build a sequence of copy-to-reg nodes, chained and glued together.
634 for (auto &Reg : RegsToPass) {
635 Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, Glue);
636 Glue = Chain.getValue(1);
637 }
638
640 EVT Ty = getPointerTy(DAG.getDataLayout());
641 bool IsRegCall = false;
642
643 Ops.push_back(Chain);
644
645 if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
646 const GlobalValue *GV = S->getGlobal();
647 bool IsLocal =
649
650 if (isPositionIndependent() || !Subtarget.has2E3()) {
651 IsRegCall = true;
652 Ops.push_back(getAddr<GlobalAddressSDNode, true>(S, DAG, IsLocal));
653 } else {
654 Ops.push_back(getTargetNode(cast<GlobalAddressSDNode>(Callee), DL, Ty,
655 DAG, CSKYII::MO_None));
656 Ops.push_back(getTargetConstantPoolValue(
657 cast<GlobalAddressSDNode>(Callee), Ty, DAG, CSKYII::MO_None));
658 }
659 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
660 bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(
661 *MF.getFunction().getParent(), nullptr);
662
663 if (isPositionIndependent() || !Subtarget.has2E3()) {
664 IsRegCall = true;
665 Ops.push_back(getAddr<ExternalSymbolSDNode, true>(S, DAG, IsLocal));
666 } else {
667 Ops.push_back(getTargetNode(cast<ExternalSymbolSDNode>(Callee), DL, Ty,
668 DAG, CSKYII::MO_None));
669 Ops.push_back(getTargetConstantPoolValue(
670 cast<ExternalSymbolSDNode>(Callee), Ty, DAG, CSKYII::MO_None));
671 }
672 } else {
673 IsRegCall = true;
674 Ops.push_back(Callee);
675 }
676
677 // Add argument registers to the end of the list so that they are
678 // known live into the call.
679 for (auto &Reg : RegsToPass)
680 Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
681
682 if (!IsTailCall) {
683 // Add a register mask operand representing the call-preserved registers.
684 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
685 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
686 assert(Mask && "Missing call preserved mask for calling convention");
687 Ops.push_back(DAG.getRegisterMask(Mask));
688 }
689
690 // Glue the call to the argument copies, if any.
691 if (Glue.getNode())
692 Ops.push_back(Glue);
693
694 // Emit the call.
695 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
696
697 if (IsTailCall) {
699 return DAG.getNode(IsRegCall ? CSKYISD::TAILReg : CSKYISD::TAIL, DL,
700 NodeTys, Ops);
701 }
702
703 Chain = DAG.getNode(IsRegCall ? CSKYISD::CALLReg : CSKYISD::CALL, DL, NodeTys,
704 Ops);
705 DAG.addNoMergeSiteInfo(Chain.getNode(), CLI.NoMerge);
706 Glue = Chain.getValue(1);
707
708 // Mark the end of the call, which is glued to the call itself.
709 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, DL);
710 Glue = Chain.getValue(1);
711
712 // Assign locations to each value returned by this call.
714 CCState RetCCInfo(CallConv, IsVarArg, MF, CSKYLocs, *DAG.getContext());
715 RetCCInfo.AnalyzeCallResult(Ins, CCAssignFnForReturn(CallConv, IsVarArg));
716
717 // Copy all of the result registers out of their specified physreg.
718 for (auto &VA : CSKYLocs) {
719 // Copy the value out
720 SDValue RetValue =
721 DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue);
722 // Glue the RetValue to the end of the call sequence
723 Chain = RetValue.getValue(1);
724 Glue = RetValue.getValue(2);
725
726 bool IsF64OnCSKY = VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64;
727
728 if (IsF64OnCSKY) {
729 assert(VA.getLocReg() == GPRArgRegs[0] && "Unexpected reg assignment");
730 SDValue RetValue2 =
731 DAG.getCopyFromReg(Chain, DL, GPRArgRegs[1], MVT::i32, Glue);
732 Chain = RetValue2.getValue(1);
733 Glue = RetValue2.getValue(2);
734 RetValue = DAG.getNode(CSKYISD::BITCAST_FROM_LOHI, DL, VA.getValVT(),
735 RetValue, RetValue2);
736 }
737
738 RetValue = convertLocVTToValVT(DAG, RetValue, VA, DL);
739
740 InVals.push_back(RetValue);
741 }
742
743 return Chain;
744}
745
746CCAssignFn *CSKYTargetLowering::CCAssignFnForReturn(CallingConv::ID CC,
747 bool IsVarArg) const {
748 if (IsVarArg || !Subtarget.useHardFloatABI())
749 return RetCC_CSKY_ABIV2_SOFT;
750 else
751 return RetCC_CSKY_ABIV2_FP;
752}
753
754CCAssignFn *CSKYTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
755 bool IsVarArg) const {
756 if (IsVarArg || !Subtarget.useHardFloatABI())
757 return CC_CSKY_ABIV2_SOFT;
758 else
759 return CC_CSKY_ABIV2_FP;
760}
761
762static CSKYCP::CSKYCPModifier getModifier(unsigned Flags) {
763
765 return CSKYCP::ADDR;
766 else if (Flags == CSKYII::MO_GOT32)
767 return CSKYCP::GOT;
768 else if (Flags == CSKYII::MO_GOTOFF)
769 return CSKYCP::GOTOFF;
770 else if (Flags == CSKYII::MO_PLT32)
771 return CSKYCP::PLT;
772 else if (Flags == CSKYII::MO_None)
773 return CSKYCP::NO_MOD;
774 else
775 assert(0 && "unknown CSKYII Modifier");
776 return CSKYCP::NO_MOD;
777}
778
779SDValue CSKYTargetLowering::getTargetConstantPoolValue(GlobalAddressSDNode *N,
780 EVT Ty,
781 SelectionDAG &DAG,
782 unsigned Flags) const {
784 N->getGlobal(), CSKYCP::CPValue, 0, getModifier(Flags), false);
785
786 return DAG.getTargetConstantPool(CPV, Ty);
787}
788
790CSKYTargetLowering::getConstraintType(StringRef Constraint) const {
791 if (Constraint.size() == 1) {
792 switch (Constraint[0]) {
793 default:
794 break;
795 case 'a':
796 case 'b':
797 case 'v':
798 case 'w':
799 case 'y':
800 return C_RegisterClass;
801 case 'c':
802 case 'l':
803 case 'h':
804 case 'z':
805 return C_Register;
806 }
807 }
808 return TargetLowering::getConstraintType(Constraint);
809}
810
811std::pair<unsigned, const TargetRegisterClass *>
812CSKYTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
813 StringRef Constraint,
814 MVT VT) const {
815 if (Constraint.size() == 1) {
816 switch (Constraint[0]) {
817 case 'r':
818 return std::make_pair(0U, &CSKY::GPRRegClass);
819 case 'a':
820 return std::make_pair(0U, &CSKY::mGPRRegClass);
821 case 'b':
822 return std::make_pair(0U, &CSKY::sGPRRegClass);
823 case 'z':
824 return std::make_pair(CSKY::R14, &CSKY::GPRRegClass);
825 case 'c':
826 return std::make_pair(CSKY::C, &CSKY::CARRYRegClass);
827 case 'w':
828 if ((Subtarget.hasFPUv2SingleFloat() ||
829 Subtarget.hasFPUv3SingleFloat()) &&
830 VT == MVT::f32)
831 return std::make_pair(0U, &CSKY::sFPR32RegClass);
832 if ((Subtarget.hasFPUv2DoubleFloat() ||
833 Subtarget.hasFPUv3DoubleFloat()) &&
834 VT == MVT::f64)
835 return std::make_pair(0U, &CSKY::sFPR64RegClass);
836 break;
837 case 'v':
838 if (Subtarget.hasFPUv2SingleFloat() && VT == MVT::f32)
839 return std::make_pair(0U, &CSKY::sFPR32RegClass);
840 if (Subtarget.hasFPUv3SingleFloat() && VT == MVT::f32)
841 return std::make_pair(0U, &CSKY::FPR32RegClass);
842 if (Subtarget.hasFPUv2DoubleFloat() && VT == MVT::f64)
843 return std::make_pair(0U, &CSKY::sFPR64RegClass);
844 if (Subtarget.hasFPUv3DoubleFloat() && VT == MVT::f64)
845 return std::make_pair(0U, &CSKY::FPR64RegClass);
846 break;
847 default:
848 break;
849 }
850 }
851
852 if (Constraint == "{c}")
853 return std::make_pair(CSKY::C, &CSKY::CARRYRegClass);
854
855 // Clang will correctly decode the usage of register name aliases into their
856 // official names. However, other frontends like `rustc` do not. This allows
857 // users of these frontends to use the ABI names for registers in LLVM-style
858 // register constraints.
859 unsigned XRegFromAlias = StringSwitch<unsigned>(Constraint.lower())
860 .Case("{a0}", CSKY::R0)
861 .Case("{a1}", CSKY::R1)
862 .Case("{a2}", CSKY::R2)
863 .Case("{a3}", CSKY::R3)
864 .Case("{l0}", CSKY::R4)
865 .Case("{l1}", CSKY::R5)
866 .Case("{l2}", CSKY::R6)
867 .Case("{l3}", CSKY::R7)
868 .Case("{l4}", CSKY::R8)
869 .Case("{l5}", CSKY::R9)
870 .Case("{l6}", CSKY::R10)
871 .Case("{l7}", CSKY::R11)
872 .Case("{t0}", CSKY::R12)
873 .Case("{t1}", CSKY::R13)
874 .Case("{sp}", CSKY::R14)
875 .Case("{lr}", CSKY::R15)
876 .Case("{l8}", CSKY::R16)
877 .Case("{l9}", CSKY::R17)
878 .Case("{t2}", CSKY::R18)
879 .Case("{t3}", CSKY::R19)
880 .Case("{t4}", CSKY::R20)
881 .Case("{t5}", CSKY::R21)
882 .Case("{t6}", CSKY::R22)
883 .Cases("{t7}", "{fp}", CSKY::R23)
884 .Cases("{t8}", "{top}", CSKY::R24)
885 .Cases("{t9}", "{bsp}", CSKY::R25)
886 .Case("{r26}", CSKY::R26)
887 .Case("{r27}", CSKY::R27)
888 .Cases("{gb}", "{rgb}", "{rdb}", CSKY::R28)
889 .Cases("{tb}", "{rtb}", CSKY::R29)
890 .Case("{svbr}", CSKY::R30)
891 .Case("{tls}", CSKY::R31)
892 .Default(CSKY::NoRegister);
893
894 if (XRegFromAlias != CSKY::NoRegister)
895 return std::make_pair(XRegFromAlias, &CSKY::GPRRegClass);
896
897 // Since TargetLowering::getRegForInlineAsmConstraint uses the name of the
898 // TableGen record rather than the AsmName to choose registers for InlineAsm
899 // constraints, plus we want to match those names to the widest floating point
900 // register type available, manually select floating point registers here.
901 //
902 // The second case is the ABI name of the register, so that frontends can also
903 // use the ABI names in register constraint lists.
904 if (Subtarget.useHardFloat()) {
905 unsigned FReg = StringSwitch<unsigned>(Constraint.lower())
906 .Cases("{fr0}", "{vr0}", CSKY::F0_32)
907 .Cases("{fr1}", "{vr1}", CSKY::F1_32)
908 .Cases("{fr2}", "{vr2}", CSKY::F2_32)
909 .Cases("{fr3}", "{vr3}", CSKY::F3_32)
910 .Cases("{fr4}", "{vr4}", CSKY::F4_32)
911 .Cases("{fr5}", "{vr5}", CSKY::F5_32)
912 .Cases("{fr6}", "{vr6}", CSKY::F6_32)
913 .Cases("{fr7}", "{vr7}", CSKY::F7_32)
914 .Cases("{fr8}", "{vr8}", CSKY::F8_32)
915 .Cases("{fr9}", "{vr9}", CSKY::F9_32)
916 .Cases("{fr10}", "{vr10}", CSKY::F10_32)
917 .Cases("{fr11}", "{vr11}", CSKY::F11_32)
918 .Cases("{fr12}", "{vr12}", CSKY::F12_32)
919 .Cases("{fr13}", "{vr13}", CSKY::F13_32)
920 .Cases("{fr14}", "{vr14}", CSKY::F14_32)
921 .Cases("{fr15}", "{vr15}", CSKY::F15_32)
922 .Cases("{fr16}", "{vr16}", CSKY::F16_32)
923 .Cases("{fr17}", "{vr17}", CSKY::F17_32)
924 .Cases("{fr18}", "{vr18}", CSKY::F18_32)
925 .Cases("{fr19}", "{vr19}", CSKY::F19_32)
926 .Cases("{fr20}", "{vr20}", CSKY::F20_32)
927 .Cases("{fr21}", "{vr21}", CSKY::F21_32)
928 .Cases("{fr22}", "{vr22}", CSKY::F22_32)
929 .Cases("{fr23}", "{vr23}", CSKY::F23_32)
930 .Cases("{fr24}", "{vr24}", CSKY::F24_32)
931 .Cases("{fr25}", "{vr25}", CSKY::F25_32)
932 .Cases("{fr26}", "{vr26}", CSKY::F26_32)
933 .Cases("{fr27}", "{vr27}", CSKY::F27_32)
934 .Cases("{fr28}", "{vr28}", CSKY::F28_32)
935 .Cases("{fr29}", "{vr29}", CSKY::F29_32)
936 .Cases("{fr30}", "{vr30}", CSKY::F30_32)
937 .Cases("{fr31}", "{vr31}", CSKY::F31_32)
938 .Default(CSKY::NoRegister);
939 if (FReg != CSKY::NoRegister) {
940 assert(CSKY::F0_32 <= FReg && FReg <= CSKY::F31_32 && "Unknown fp-reg");
941 unsigned RegNo = FReg - CSKY::F0_32;
942 unsigned DReg = CSKY::F0_64 + RegNo;
943
944 if (Subtarget.hasFPUv2DoubleFloat())
945 return std::make_pair(DReg, &CSKY::sFPR64RegClass);
946 else if (Subtarget.hasFPUv3DoubleFloat())
947 return std::make_pair(DReg, &CSKY::FPR64RegClass);
948 else if (Subtarget.hasFPUv2SingleFloat())
949 return std::make_pair(FReg, &CSKY::sFPR32RegClass);
950 else if (Subtarget.hasFPUv3SingleFloat())
951 return std::make_pair(FReg, &CSKY::FPR32RegClass);
952 }
953 }
954
956}
957
958static MachineBasicBlock *
960
962 DebugLoc DL = MI.getDebugLoc();
963
964 // To "insert" a SELECT instruction, we actually have to insert the
965 // diamond control-flow pattern. The incoming instruction knows the
966 // destination vreg to set, the condition code register to branch on, the
967 // true/false values to select between, and a branch opcode to use.
968 const BasicBlock *LLVM_BB = BB->getBasicBlock();
970
971 // thisMBB:
972 // ...
973 // TrueVal = ...
974 // bt32 c, sinkMBB
975 // fallthrough --> copyMBB
976 MachineBasicBlock *thisMBB = BB;
977 MachineFunction *F = BB->getParent();
978 MachineBasicBlock *copyMBB = F->CreateMachineBasicBlock(LLVM_BB);
979 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
980 F->insert(It, copyMBB);
981 F->insert(It, sinkMBB);
982
983 // Transfer the remainder of BB and its successor edges to sinkMBB.
984 sinkMBB->splice(sinkMBB->begin(), BB,
985 std::next(MachineBasicBlock::iterator(MI)), BB->end());
987
988 // Next, add the true and fallthrough blocks as its successors.
989 BB->addSuccessor(copyMBB);
990 BB->addSuccessor(sinkMBB);
991
992 // bt32 condition, sinkMBB
993 BuildMI(BB, DL, TII.get(Opcode))
994 .addReg(MI.getOperand(1).getReg())
995 .addMBB(sinkMBB);
996
997 // copyMBB:
998 // %FalseValue = ...
999 // # fallthrough to sinkMBB
1000 BB = copyMBB;
1001
1002 // Update machine-CFG edges
1003 BB->addSuccessor(sinkMBB);
1004
1005 // sinkMBB:
1006 // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copyMBB ]
1007 // ...
1008 BB = sinkMBB;
1009
1010 BuildMI(*BB, BB->begin(), DL, TII.get(CSKY::PHI), MI.getOperand(0).getReg())
1011 .addReg(MI.getOperand(2).getReg())
1012 .addMBB(thisMBB)
1013 .addReg(MI.getOperand(3).getReg())
1014 .addMBB(copyMBB);
1015
1016 MI.eraseFromParent(); // The pseudo instruction is gone now.
1017
1018 return BB;
1019}
1020
1022CSKYTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1023 MachineBasicBlock *BB) const {
1024 switch (MI.getOpcode()) {
1025 default:
1026 llvm_unreachable("Unexpected instr type to insert");
1027 case CSKY::FSELS:
1028 case CSKY::FSELD:
1029 if (Subtarget.hasE2())
1030 return emitSelectPseudo(MI, BB, CSKY::BT32);
1031 else
1032 return emitSelectPseudo(MI, BB, CSKY::BT16);
1033 case CSKY::ISEL32:
1034 return emitSelectPseudo(MI, BB, CSKY::BT32);
1035 case CSKY::ISEL16:
1036 return emitSelectPseudo(MI, BB, CSKY::BT16);
1037 }
1038}
1039
1040SDValue CSKYTargetLowering::getTargetConstantPoolValue(ExternalSymbolSDNode *N,
1041 EVT Ty,
1042 SelectionDAG &DAG,
1043 unsigned Flags) const {
1046 N->getSymbol(), 0, getModifier(Flags));
1047
1048 return DAG.getTargetConstantPool(CPV, Ty);
1049}
1050
1051SDValue CSKYTargetLowering::getTargetConstantPoolValue(JumpTableSDNode *N,
1052 EVT Ty,
1053 SelectionDAG &DAG,
1054 unsigned Flags) const {
1057 N->getIndex(), 0, getModifier(Flags));
1058 return DAG.getTargetConstantPool(CPV, Ty);
1059}
1060
1061SDValue CSKYTargetLowering::getTargetConstantPoolValue(BlockAddressSDNode *N,
1062 EVT Ty,
1063 SelectionDAG &DAG,
1064 unsigned Flags) const {
1065 assert(N->getOffset() == 0);
1067 N->getBlockAddress(), CSKYCP::CPBlockAddress, 0, getModifier(Flags),
1068 false);
1069 return DAG.getTargetConstantPool(CPV, Ty);
1070}
1071
1072SDValue CSKYTargetLowering::getTargetConstantPoolValue(ConstantPoolSDNode *N,
1073 EVT Ty,
1074 SelectionDAG &DAG,
1075 unsigned Flags) const {
1076 assert(N->getOffset() == 0);
1078 N->getConstVal(), Type::getInt32Ty(*DAG.getContext()),
1079 CSKYCP::CPConstPool, 0, getModifier(Flags), false);
1080 return DAG.getTargetConstantPool(CPV, Ty);
1081}
1082
1083SDValue CSKYTargetLowering::getTargetNode(GlobalAddressSDNode *N, SDLoc DL,
1084 EVT Ty, SelectionDAG &DAG,
1085 unsigned Flags) const {
1086 return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags);
1087}
1088
1089SDValue CSKYTargetLowering::getTargetNode(ExternalSymbolSDNode *N, SDLoc DL,
1090 EVT Ty, SelectionDAG &DAG,
1091 unsigned Flags) const {
1092 return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flags);
1093}
1094
1095SDValue CSKYTargetLowering::getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty,
1096 SelectionDAG &DAG,
1097 unsigned Flags) const {
1098 return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
1099}
1100
1101SDValue CSKYTargetLowering::getTargetNode(BlockAddressSDNode *N, SDLoc DL,
1102 EVT Ty, SelectionDAG &DAG,
1103 unsigned Flags) const {
1104 return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, N->getOffset(),
1105 Flags);
1106}
1107
1108SDValue CSKYTargetLowering::getTargetNode(ConstantPoolSDNode *N, SDLoc DL,
1109 EVT Ty, SelectionDAG &DAG,
1110 unsigned Flags) const {
1111
1112 return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),
1113 N->getOffset(), Flags);
1114}
1115
1116const char *CSKYTargetLowering::getTargetNodeName(unsigned Opcode) const {
1117 switch (Opcode) {
1118 default:
1119 llvm_unreachable("unknown CSKYISD node");
1120 case CSKYISD::NIE:
1121 return "CSKYISD::NIE";
1122 case CSKYISD::NIR:
1123 return "CSKYISD::NIR";
1124 case CSKYISD::RET:
1125 return "CSKYISD::RET";
1126 case CSKYISD::CALL:
1127 return "CSKYISD::CALL";
1128 case CSKYISD::CALLReg:
1129 return "CSKYISD::CALLReg";
1130 case CSKYISD::TAIL:
1131 return "CSKYISD::TAIL";
1132 case CSKYISD::TAILReg:
1133 return "CSKYISD::TAILReg";
1134 case CSKYISD::LOAD_ADDR:
1135 return "CSKYISD::LOAD_ADDR";
1137 return "CSKYISD::BITCAST_TO_LOHI";
1139 return "CSKYISD::BITCAST_FROM_LOHI";
1140 }
1141}
1142
1143SDValue CSKYTargetLowering::LowerGlobalAddress(SDValue Op,
1144 SelectionDAG &DAG) const {
1145 SDLoc DL(Op);
1146 EVT Ty = Op.getValueType();
1147 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
1148 int64_t Offset = N->getOffset();
1149
1150 const GlobalValue *GV = N->getGlobal();
1151 bool IsLocal = getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV);
1152 SDValue Addr = getAddr<GlobalAddressSDNode, false>(N, DAG, IsLocal);
1153
1154 // In order to maximise the opportunity for common subexpression elimination,
1155 // emit a separate ADD node for the global address offset instead of folding
1156 // it in the global address node. Later peephole optimisations may choose to
1157 // fold it back in when profitable.
1158 if (Offset != 0)
1159 return DAG.getNode(ISD::ADD, DL, Ty, Addr,
1160 DAG.getConstant(Offset, DL, MVT::i32));
1161 return Addr;
1162}
1163
1164SDValue CSKYTargetLowering::LowerExternalSymbol(SDValue Op,
1165 SelectionDAG &DAG) const {
1166 ExternalSymbolSDNode *N = cast<ExternalSymbolSDNode>(Op);
1167
1168 return getAddr(N, DAG, false);
1169}
1170
1171SDValue CSKYTargetLowering::LowerJumpTable(SDValue Op,
1172 SelectionDAG &DAG) const {
1173 JumpTableSDNode *N = cast<JumpTableSDNode>(Op);
1174
1175 return getAddr<JumpTableSDNode, false>(N, DAG);
1176}
1177
1178SDValue CSKYTargetLowering::LowerBlockAddress(SDValue Op,
1179 SelectionDAG &DAG) const {
1180 BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);
1181
1182 return getAddr(N, DAG);
1183}
1184
1185SDValue CSKYTargetLowering::LowerConstantPool(SDValue Op,
1186 SelectionDAG &DAG) const {
1187 assert(!Subtarget.hasE2());
1188 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
1189
1190 return getAddr(N, DAG);
1191}
1192
1193SDValue CSKYTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
1196
1197 SDLoc DL(Op);
1198 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
1200
1201 // vastart just stores the address of the VarArgsFrameIndex slot into the
1202 // memory location argument.
1203 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1204 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
1205 MachinePointerInfo(SV));
1206}
1207
1208SDValue CSKYTargetLowering::LowerFRAMEADDR(SDValue Op,
1209 SelectionDAG &DAG) const {
1210 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();
1212 MachineFrameInfo &MFI = MF.getFrameInfo();
1213 MFI.setFrameAddressIsTaken(true);
1214
1215 EVT VT = Op.getValueType();
1216 SDLoc dl(Op);
1217 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1218 Register FrameReg = RI.getFrameRegister(MF);
1219 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
1220 while (Depth--)
1221 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1223 return FrameAddr;
1224}
1225
1226SDValue CSKYTargetLowering::LowerRETURNADDR(SDValue Op,
1227 SelectionDAG &DAG) const {
1228 const CSKYRegisterInfo &RI = *Subtarget.getRegisterInfo();
1230 MachineFrameInfo &MFI = MF.getFrameInfo();
1231 MFI.setReturnAddressIsTaken(true);
1232
1234 return SDValue();
1235
1236 EVT VT = Op.getValueType();
1237 SDLoc dl(Op);
1238 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1239 if (Depth) {
1240 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1241 SDValue Offset = DAG.getConstant(4, dl, MVT::i32);
1242 return DAG.getLoad(VT, dl, DAG.getEntryNode(),
1243 DAG.getNode(ISD::ADD, dl, VT, FrameAddr, Offset),
1245 }
1246 // Return the value of the return address register, marking it an implicit
1247 // live-in.
1248 unsigned Reg = MF.addLiveIn(RI.getRARegister(), getRegClassFor(MVT::i32));
1249 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, VT);
1250}
1251
1252Register CSKYTargetLowering::getExceptionPointerRegister(
1253 const Constant *PersonalityFn) const {
1254 return CSKY::R0;
1255}
1256
1257Register CSKYTargetLowering::getExceptionSelectorRegister(
1258 const Constant *PersonalityFn) const {
1259 return CSKY::R1;
1260}
1261
1262SDValue CSKYTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1263 SelectionDAG &DAG) const {
1264 SDLoc DL(Op);
1265 EVT Ty = Op.getValueType();
1266 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
1267 int64_t Offset = N->getOffset();
1268 MVT XLenVT = MVT::i32;
1269
1271 SDValue Addr;
1272 switch (Model) {
1274 Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/false);
1275 break;
1277 Addr = getStaticTLSAddr(N, DAG, /*UseGOT=*/true);
1278 break;
1281 Addr = getDynamicTLSAddr(N, DAG);
1282 break;
1283 }
1284
1285 // In order to maximise the opportunity for common subexpression elimination,
1286 // emit a separate ADD node for the global address offset instead of folding
1287 // it in the global address node. Later peephole optimisations may choose to
1288 // fold it back in when profitable.
1289 if (Offset != 0)
1290 return DAG.getNode(ISD::ADD, DL, Ty, Addr,
1291 DAG.getConstant(Offset, DL, XLenVT));
1292 return Addr;
1293}
1294
1295SDValue CSKYTargetLowering::getStaticTLSAddr(GlobalAddressSDNode *N,
1296 SelectionDAG &DAG,
1297 bool UseGOT) const {
1300
1301 unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();
1302
1303 SDLoc DL(N);
1304 EVT Ty = getPointerTy(DAG.getDataLayout());
1305
1307 bool AddCurrentAddr = UseGOT ? true : false;
1308 unsigned char PCAjust = UseGOT ? 4 : 0;
1309
1311 CSKYConstantPoolConstant::Create(N->getGlobal(), CSKYCP::CPValue, PCAjust,
1312 Flag, AddCurrentAddr, CSKYPCLabelIndex);
1313 SDValue CAddr = DAG.getTargetConstantPool(CPV, Ty);
1314
1315 SDValue Load;
1316 if (UseGOT) {
1317 SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);
1318 auto *LRWGRS = DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty},
1319 {CAddr, PICLabel});
1320 auto LRWADDGRS =
1321 DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));
1322 Load = DAG.getLoad(Ty, DL, DAG.getEntryNode(), LRWADDGRS,
1323 MachinePointerInfo(N->getGlobal()));
1324 } else {
1325 Load = SDValue(DAG.getMachineNode(CSKY::LRW32, DL, Ty, CAddr), 0);
1326 }
1327
1328 // Add the thread pointer.
1329 SDValue TPReg = DAG.getRegister(CSKY::R31, MVT::i32);
1330 return DAG.getNode(ISD::ADD, DL, Ty, Load, TPReg);
1331}
1332
1333SDValue CSKYTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N,
1334 SelectionDAG &DAG) const {
1337
1338 unsigned CSKYPCLabelIndex = CFI->createPICLabelUId();
1339
1340 SDLoc DL(N);
1341 EVT Ty = getPointerTy(DAG.getDataLayout());
1342 IntegerType *CallTy = Type::getIntNTy(*DAG.getContext(), Ty.getSizeInBits());
1343
1346 CSKYCP::TLSGD, true, CSKYPCLabelIndex);
1347 SDValue Addr = DAG.getTargetConstantPool(CPV, Ty);
1348 SDValue PICLabel = DAG.getTargetConstant(CSKYPCLabelIndex, DL, MVT::i32);
1349
1350 auto *LRWGRS =
1351 DAG.getMachineNode(CSKY::PseudoTLSLA32, DL, {Ty, Ty}, {Addr, PICLabel});
1352
1353 auto Load =
1354 DAG.getNode(ISD::ADD, DL, Ty, SDValue(LRWGRS, 0), SDValue(LRWGRS, 1));
1355
1356 // Prepare argument list to generate call.
1358 ArgListEntry Entry;
1359 Entry.Node = Load;
1360 Entry.Ty = CallTy;
1361 Args.push_back(Entry);
1362
1363 // Setup call to __tls_get_addr.
1365 CLI.setDebugLoc(DL)
1366 .setChain(DAG.getEntryNode())
1367 .setLibCallee(CallingConv::C, CallTy,
1368 DAG.getExternalSymbol("__tls_get_addr", Ty),
1369 std::move(Args));
1370 SDValue V = LowerCallTo(CLI).first;
1371
1372 return V;
1373}
static const MCPhysReg GPRArgRegs[]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
basic Basic Alias true
static SDValue unpack64(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)
static const MCPhysReg GPRArgRegs[]
static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static CSKYCP::CSKYCPModifier getModifier(unsigned Flags)
static SDValue unpackFromMemLoc(SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static MachineBasicBlock * emitSelectPseudo(MachineInstr &MI, MachineBasicBlock *BB, unsigned Opcode)
static SDValue unpackFromRegLoc(const CSKYSubtarget &Subtarget, SelectionDAG &DAG, SDValue Chain, const CCValAssign &VA, const SDLoc &DL)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Addr
uint64_t Size
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
typename CallsiteContextGraph< DerivedCCG, FuncTy, CallTy >::FuncInfo FuncInfo
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
@ Flags
Definition: TextStubV5.cpp:93
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:163
LLVM Basic Block Representation.
Definition: BasicBlock.h:56
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
unsigned getLocMemOffset() const
Register getLocReg() const
LocInfo getLocInfo() const
bool isMemLoc() 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
bool hasE2() const
bool hasFPUv2DoubleFloat() const
bool useHardFloatABI() const
bool useHardFloat() const
bool hasFPUv3DoubleFloat() const
bool has2E3() const
CSKYTargetLowering(const TargetMachine &TM, const CSKYSubtarget &STI)
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
Return the ValueType of the result of SETCC operations.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
This is an important base class in LLVM.
Definition: Constant.h:41
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:110
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
Definition: DataLayout.h:406
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:644
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:652
Class to represent integer types.
Definition: DerivedTypes.h:40
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
Machine Value Type.
SimpleValueType SimpleTy
static MVT getIntegerVT(unsigned BitWidth)
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
Definition: MachineInstr.h:68
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:225
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:721
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:731
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:472
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getExternalSymbol(const char *Sym, EVT VT)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:773
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:675
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:768
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:469
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:799
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
Definition: SelectionDAG.h:485
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:737
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:554
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
std::string lower() const
Definition: StringRef.cpp:111
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:90
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
std::vector< ArgListEntry > ArgListTy
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:78
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
Definition: Value.h:74
self_iterator getIterator()
Definition: ilist_node.h:82
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:119
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition: ISDOpcodes.h:40
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1069
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1065
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:250
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:713
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1098
@ ConstantFP
Definition: ISDOpcodes.h:77
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
@ RETURNADDR
Definition: ISDOpcodes.h:95
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
Definition: ISDOpcodes.h:687
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
Definition: ISDOpcodes.h:1170
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:255
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:898
@ GlobalTLSAddress
Definition: ISDOpcodes.h:79
@ ADDCARRY
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:303
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
Definition: ISDOpcodes.h:972
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1020
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1003
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1094
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:650
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:741
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:988
@ ConstantPool
Definition: ISDOpcodes.h:82
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:94
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ ExternalSymbol
Definition: ISDOpcodes.h:83
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1089
@ 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:762
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition: ISDOpcodes.h:492
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1447
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Definition: ISDOpcodes.h:1427
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:406
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:145
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Extended Value Type.
Definition: ValueTypes.h:34
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition: ValueTypes.h:93
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:351
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:299
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:160
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.