LLVM 22.0.0git
VEISelLowering.cpp
Go to the documentation of this file.
1//===-- VEISelLowering.cpp - VE 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 implements the interfaces that VE uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "VEISelLowering.h"
16#include "VECustomDAG.h"
17#include "VEInstrBuilder.h"
19#include "VERegisterInfo.h"
20#include "VETargetMachine.h"
32#include "llvm/IR/Function.h"
33#include "llvm/IR/IRBuilder.h"
34#include "llvm/IR/Module.h"
36using namespace llvm;
37
38#define DEBUG_TYPE "ve-lower"
39
40//===----------------------------------------------------------------------===//
41// Calling Convention Implementation
42//===----------------------------------------------------------------------===//
43
44#include "VEGenCallingConv.inc"
45
47 switch (CallConv) {
48 default:
49 return RetCC_VE_C;
51 return RetCC_VE_Fast;
52 }
53}
54
55CCAssignFn *getParamCC(CallingConv::ID CallConv, bool IsVarArg) {
56 if (IsVarArg)
57 return CC_VE2;
58 switch (CallConv) {
59 default:
60 return CC_VE_C;
62 return CC_VE_Fast;
63 }
64}
65
67 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
68 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
69 const Type *RetTy) const {
70 CCAssignFn *RetCC = getReturnCC(CallConv);
72 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
73 return CCInfo.CheckReturn(Outs, RetCC);
74}
75
76static const MVT AllVectorVTs[] = {MVT::v256i32, MVT::v512i32, MVT::v256i64,
77 MVT::v256f32, MVT::v512f32, MVT::v256f64};
78
79static const MVT AllMaskVTs[] = {MVT::v256i1, MVT::v512i1};
80
81static const MVT AllPackedVTs[] = {MVT::v512i32, MVT::v512f32};
82
83void VETargetLowering::initRegisterClasses() {
84 // Set up the register classes.
85 addRegisterClass(MVT::i32, &VE::I32RegClass);
86 addRegisterClass(MVT::i64, &VE::I64RegClass);
87 addRegisterClass(MVT::f32, &VE::F32RegClass);
88 addRegisterClass(MVT::f64, &VE::I64RegClass);
89 addRegisterClass(MVT::f128, &VE::F128RegClass);
90
91 if (Subtarget->enableVPU()) {
92 for (MVT VecVT : AllVectorVTs)
93 addRegisterClass(VecVT, &VE::V64RegClass);
94 addRegisterClass(MVT::v256i1, &VE::VMRegClass);
95 addRegisterClass(MVT::v512i1, &VE::VM512RegClass);
96 }
97}
98
99void VETargetLowering::initSPUActions() {
100 const auto &TM = getTargetMachine();
101 /// Load & Store {
102
103 // VE doesn't have i1 sign extending load.
104 for (MVT VT : MVT::integer_valuetypes()) {
108 setTruncStoreAction(VT, MVT::i1, Expand);
109 }
110
111 // VE doesn't have floating point extload/truncstore, so expand them.
112 for (MVT FPVT : MVT::fp_valuetypes()) {
113 for (MVT OtherFPVT : MVT::fp_valuetypes()) {
114 setLoadExtAction(ISD::EXTLOAD, FPVT, OtherFPVT, Expand);
115 setTruncStoreAction(FPVT, OtherFPVT, Expand);
116 }
117 }
118
119 // VE doesn't have fp128 load/store, so expand them in custom lower.
122
123 /// } Load & Store
124
125 // Custom legalize address nodes into LO/HI parts.
126 MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));
132
133 /// VAARG handling {
135 // VAARG needs to be lowered to access with 8 bytes alignment.
137 // Use the default implementation.
140 /// } VAARG handling
141
142 /// Stack {
145
146 // Use the default implementation.
149 /// } Stack
150
151 /// Branch {
152
153 // VE doesn't have BRCOND
155
156 // BR_JT is not implemented yet.
158
159 /// } Branch
160
161 /// Int Ops {
162 for (MVT IntVT : {MVT::i32, MVT::i64}) {
163 // VE has no REM or DIVREM operations.
168
169 // VE has no SHL_PARTS/SRA_PARTS/SRL_PARTS operations.
173
174 // VE has no MULHU/S or U/SMUL_LOHI operations.
175 // TODO: Use MPD instruction to implement SMUL_LOHI for i32 type.
180
181 // VE has no CTTZ, ROTL, ROTR operations.
185
186 // VE has 64 bits instruction which works as i64 BSWAP operation. This
187 // instruction works fine as i32 BSWAP operation with an additional
188 // parameter. Use isel patterns to lower BSWAP.
190
191 // VE has only 64 bits instructions which work as i64 BITREVERSE/CTLZ/CTPOP
192 // operations. Use isel patterns for i64, promote for i32.
193 LegalizeAction Act = (IntVT == MVT::i32) ? Promote : Legal;
195 setOperationAction(ISD::CTLZ, IntVT, Act);
197 setOperationAction(ISD::CTPOP, IntVT, Act);
198
199 // VE has only 64 bits instructions which work as i64 AND/OR/XOR operations.
200 // Use isel patterns for i64, promote for i32.
201 setOperationAction(ISD::AND, IntVT, Act);
202 setOperationAction(ISD::OR, IntVT, Act);
203 setOperationAction(ISD::XOR, IntVT, Act);
204
205 // Legal smax and smin
208 }
209 /// } Int Ops
210
211 /// Conversion {
212 // VE doesn't have instructions for fp<->uint, so expand them by llvm
213 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); // use i64
214 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); // use i64
217
218 // fp16 not supported
219 for (MVT FPVT : MVT::fp_valuetypes()) {
222 }
223 /// } Conversion
224
225 /// Floating-point Ops {
226 /// Note: Floating-point operations are fneg, fadd, fsub, fmul, fdiv, frem,
227 /// and fcmp.
228
229 // VE doesn't have following floating point operations.
230 for (MVT VT : MVT::fp_valuetypes()) {
233 }
234
235 // VE doesn't have fdiv of f128.
237
238 for (MVT FPVT : {MVT::f32, MVT::f64}) {
239 // f32 and f64 uses ConstantFP. f128 uses ConstantPool.
241 }
242 /// } Floating-point Ops
243
244 /// Floating-point math functions {
245
246 // VE doesn't have following floating point math functions.
247 for (MVT VT : MVT::fp_valuetypes()) {
255 }
256
257 // VE has single and double FMINNUM and FMAXNUM
258 for (MVT VT : {MVT::f32, MVT::f64}) {
260 }
261
262 /// } Floating-point math functions
263
264 /// Atomic instructions {
265
269
270 // Use custom inserter for ATOMIC_FENCE.
272
273 // Other atomic instructions.
274 for (MVT VT : MVT::integer_valuetypes()) {
275 // Support i8/i16 atomic swap.
277
278 // FIXME: Support "atmam" instructions.
283
284 // VE doesn't have follwing instructions.
293 }
294
295 /// } Atomic instructions
296
297 /// SJLJ instructions {
301 /// } SJLJ instructions
302
303 // Intrinsic instructions
305}
306
307void VETargetLowering::initVPUActions() {
308 for (MVT LegalMaskVT : AllMaskVTs)
310
311 for (unsigned Opc : {ISD::AND, ISD::OR, ISD::XOR})
312 setOperationAction(Opc, MVT::v512i1, Custom);
313
314 for (MVT LegalVecVT : AllVectorVTs) {
318 // Translate all vector instructions with legal element types to VVP_*
319 // nodes.
320 // TODO We will custom-widen into VVP_* nodes in the future. While we are
321 // buildling the infrastructure for this, we only do this for legal vector
322 // VTs.
323#define HANDLE_VP_TO_VVP(VP_OPC, VVP_NAME) \
324 setOperationAction(ISD::VP_OPC, LegalVecVT, Custom);
325#define ADD_VVP_OP(VVP_NAME, ISD_NAME) \
326 setOperationAction(ISD::ISD_NAME, LegalVecVT, Custom);
327 setOperationAction(ISD::EXPERIMENTAL_VP_STRIDED_LOAD, LegalVecVT, Custom);
328 setOperationAction(ISD::EXPERIMENTAL_VP_STRIDED_STORE, LegalVecVT, Custom);
329#include "VVPNodes.def"
330 }
331
332 for (MVT LegalPackedVT : AllPackedVTs) {
335 }
336
337 // vNt32, vNt64 ops (legal element types)
338 for (MVT VT : MVT::vector_valuetypes()) {
339 MVT ElemVT = VT.getVectorElementType();
340 unsigned ElemBits = ElemVT.getScalarSizeInBits();
341 if (ElemBits != 32 && ElemBits != 64)
342 continue;
343
344 for (unsigned MemOpc : {ISD::MLOAD, ISD::MSTORE, ISD::LOAD, ISD::STORE})
345 setOperationAction(MemOpc, VT, Custom);
346
347 const ISD::NodeType IntReductionOCs[] = {
351
352 for (unsigned IntRedOpc : IntReductionOCs)
353 setOperationAction(IntRedOpc, VT, Custom);
354 }
355
356 // v256i1 and v512i1 ops
357 for (MVT MaskVT : AllMaskVTs) {
358 // Custom lower mask ops
361 }
362}
363
366 bool IsVarArg,
368 const SmallVectorImpl<SDValue> &OutVals,
369 const SDLoc &DL, SelectionDAG &DAG) const {
370 // CCValAssign - represent the assignment of the return value to locations.
372
373 // CCState - Info about the registers and stack slot.
374 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
375 *DAG.getContext());
376
377 // Analyze return values.
378 CCInfo.AnalyzeReturn(Outs, getReturnCC(CallConv));
379
380 SDValue Glue;
381 SmallVector<SDValue, 4> RetOps(1, Chain);
382
383 // Copy the result values into the output registers.
384 for (unsigned i = 0; i != RVLocs.size(); ++i) {
385 CCValAssign &VA = RVLocs[i];
386 assert(VA.isRegLoc() && "Can only return in registers!");
387 assert(!VA.needsCustom() && "Unexpected custom lowering");
388 SDValue OutVal = OutVals[i];
389
390 // Integer return values must be sign or zero extended by the callee.
391 switch (VA.getLocInfo()) {
393 break;
395 OutVal = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), OutVal);
396 break;
398 OutVal = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), OutVal);
399 break;
401 OutVal = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), OutVal);
402 break;
403 case CCValAssign::BCvt: {
404 // Convert a float return value to i64 with padding.
405 // 63 31 0
406 // +------+------+
407 // | float| 0 |
408 // +------+------+
409 assert(VA.getLocVT() == MVT::i64);
410 assert(VA.getValVT() == MVT::f32);
411 SDValue Undef = SDValue(
412 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64), 0);
413 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32);
414 OutVal = SDValue(DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL,
415 MVT::i64, Undef, OutVal, Sub_f32),
416 0);
417 break;
418 }
419 default:
420 llvm_unreachable("Unknown loc info!");
421 }
422
423 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVal, Glue);
424
425 // Guarantee that all emitted copies are stuck together with flags.
426 Glue = Chain.getValue(1);
427 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
428 }
429
430 RetOps[0] = Chain; // Update chain.
431
432 // Add the glue if we have it.
433 if (Glue.getNode())
434 RetOps.push_back(Glue);
435
436 return DAG.getNode(VEISD::RET_GLUE, DL, MVT::Other, RetOps);
437}
438
440 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
441 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
442 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
444
445 // Get the base offset of the incoming arguments stack space.
446 unsigned ArgsBaseOffset = Subtarget->getRsaSize();
447 // Get the size of the preserved arguments area
448 unsigned ArgsPreserved = 64;
449
450 // Analyze arguments according to CC_VE.
452 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
453 *DAG.getContext());
454 // Allocate the preserved area first.
455 CCInfo.AllocateStack(ArgsPreserved, Align(8));
456 // We already allocated the preserved area, so the stack offset computed
457 // by CC_VE would be correct now.
458 CCInfo.AnalyzeFormalArguments(Ins, getParamCC(CallConv, false));
459
460 for (const CCValAssign &VA : ArgLocs) {
461 assert(!VA.needsCustom() && "Unexpected custom lowering");
462 if (VA.isRegLoc()) {
463 // This argument is passed in a register.
464 // All integer register arguments are promoted by the caller to i64.
465
466 // Create a virtual register for the promoted live-in value.
467 Register VReg =
468 MF.addLiveIn(VA.getLocReg(), getRegClassFor(VA.getLocVT()));
469 SDValue Arg = DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT());
470
471 // The caller promoted the argument, so insert an Assert?ext SDNode so we
472 // won't promote the value again in this function.
473 switch (VA.getLocInfo()) {
475 Arg = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Arg,
476 DAG.getValueType(VA.getValVT()));
477 break;
479 Arg = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Arg,
480 DAG.getValueType(VA.getValVT()));
481 break;
482 case CCValAssign::BCvt: {
483 // Extract a float argument from i64 with padding.
484 // 63 31 0
485 // +------+------+
486 // | float| 0 |
487 // +------+------+
488 assert(VA.getLocVT() == MVT::i64);
489 assert(VA.getValVT() == MVT::f32);
490 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32);
491 Arg = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL,
492 MVT::f32, Arg, Sub_f32),
493 0);
494 break;
495 }
496 default:
497 break;
498 }
499
500 // Truncate the register down to the argument type.
501 if (VA.isExtInLoc())
502 Arg = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Arg);
503
504 InVals.push_back(Arg);
505 continue;
506 }
507
508 // The registers are exhausted. This argument was passed on the stack.
509 assert(VA.isMemLoc());
510 // The CC_VE_Full/Half functions compute stack offsets relative to the
511 // beginning of the arguments area at %fp + the size of reserved area.
512 unsigned Offset = VA.getLocMemOffset() + ArgsBaseOffset;
513 unsigned ValSize = VA.getValVT().getSizeInBits() / 8;
514
515 // Adjust offset for a float argument by adding 4 since the argument is
516 // stored in 8 bytes buffer with offset like below. LLVM generates
517 // 4 bytes load instruction, so need to adjust offset here. This
518 // adjustment is required in only LowerFormalArguments. In LowerCall,
519 // a float argument is converted to i64 first, and stored as 8 bytes
520 // data, which is required by ABI, so no need for adjustment.
521 // 0 4
522 // +------+------+
523 // | empty| float|
524 // +------+------+
525 if (VA.getValVT() == MVT::f32)
526 Offset += 4;
527
528 int FI = MF.getFrameInfo().CreateFixedObject(ValSize, Offset, true);
529 InVals.push_back(
530 DAG.getLoad(VA.getValVT(), DL, Chain,
533 }
534
535 if (!IsVarArg)
536 return Chain;
537
538 // This function takes variable arguments, some of which may have been passed
539 // in registers %s0-%s8.
540 //
541 // The va_start intrinsic needs to know the offset to the first variable
542 // argument.
543 // TODO: need to calculate offset correctly once we support f128.
544 unsigned ArgOffset = ArgLocs.size() * 8;
546 // Skip the reserved area at the top of stack.
547 FuncInfo->setVarArgsFrameOffset(ArgOffset + ArgsBaseOffset);
548
549 return Chain;
550}
551
552// FIXME? Maybe this could be a TableGen attribute on some registers and
553// this table could be generated automatically from RegInfo.
555 const MachineFunction &MF) const {
557 .Case("sp", VE::SX11) // Stack pointer
558 .Case("fp", VE::SX9) // Frame pointer
559 .Case("sl", VE::SX8) // Stack limit
560 .Case("lr", VE::SX10) // Link register
561 .Case("tp", VE::SX14) // Thread pointer
562 .Case("outer", VE::SX12) // Outer regiser
563 .Case("info", VE::SX17) // Info area register
564 .Case("got", VE::SX15) // Global offset table register
565 .Case("plt", VE::SX16) // Procedure linkage table register
566 .Default(Register());
567 return Reg;
568}
569
570//===----------------------------------------------------------------------===//
571// TargetLowering Implementation
572//===----------------------------------------------------------------------===//
573
575 SmallVectorImpl<SDValue> &InVals) const {
576 SelectionDAG &DAG = CLI.DAG;
577 SDLoc DL = CLI.DL;
578 SDValue Chain = CLI.Chain;
579 auto PtrVT = getPointerTy(DAG.getDataLayout());
580
581 // VE target does not yet support tail call optimization.
582 CLI.IsTailCall = false;
583
584 // Get the base offset of the outgoing arguments stack space.
585 unsigned ArgsBaseOffset = Subtarget->getRsaSize();
586 // Get the size of the preserved arguments area
587 unsigned ArgsPreserved = 8 * 8u;
588
589 // Analyze operands of the call, assigning locations to each operand.
591 CCState CCInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), ArgLocs,
592 *DAG.getContext());
593 // Allocate the preserved area first.
594 CCInfo.AllocateStack(ArgsPreserved, Align(8));
595 // We already allocated the preserved area, so the stack offset computed
596 // by CC_VE would be correct now.
597 CCInfo.AnalyzeCallOperands(CLI.Outs, getParamCC(CLI.CallConv, false));
598
599 // VE requires to use both register and stack for varargs or no-prototyped
600 // functions.
601 bool UseBoth = CLI.IsVarArg;
602
603 // Analyze operands again if it is required to store BOTH.
605 CCState CCInfo2(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(),
606 ArgLocs2, *DAG.getContext());
607 if (UseBoth)
608 CCInfo2.AnalyzeCallOperands(CLI.Outs, getParamCC(CLI.CallConv, true));
609
610 // Get the size of the outgoing arguments stack space requirement.
611 unsigned ArgsSize = CCInfo.getStackSize();
612
613 // Keep stack frames 16-byte aligned.
614 ArgsSize = alignTo(ArgsSize, 16);
615
616 // Adjust the stack pointer to make room for the arguments.
617 // FIXME: Use hasReservedCallFrame to avoid %sp adjustments around all calls
618 // with more than 6 arguments.
619 Chain = DAG.getCALLSEQ_START(Chain, ArgsSize, 0, DL);
620
621 // Collect the set of registers to pass to the function and their values.
622 // This will be emitted as a sequence of CopyToReg nodes glued to the call
623 // instruction.
625
626 // Collect chains from all the memory opeations that copy arguments to the
627 // stack. They must follow the stack pointer adjustment above and precede the
628 // call instruction itself.
629 SmallVector<SDValue, 8> MemOpChains;
630
631 // VE needs to get address of callee function in a register
632 // So, prepare to copy it to SX12 here.
633
634 // If the callee is a GlobalAddress node (quite common, every direct call is)
635 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
636 // Likewise ExternalSymbol -> TargetExternalSymbol.
637 SDValue Callee = CLI.Callee;
638
639 bool IsPICCall = isPositionIndependent();
640
641 // PC-relative references to external symbols should go through $stub.
642 // If so, we need to prepare GlobalBaseReg first.
643 const TargetMachine &TM = DAG.getTarget();
644 const GlobalValue *GV = nullptr;
645 auto *CalleeG = dyn_cast<GlobalAddressSDNode>(Callee);
646 if (CalleeG)
647 GV = CalleeG->getGlobal();
648 bool Local = TM.shouldAssumeDSOLocal(GV);
649 bool UsePlt = !Local;
651
652 // Turn GlobalAddress/ExternalSymbol node into a value node
653 // containing the address of them here.
654 if (CalleeG) {
655 if (IsPICCall) {
656 if (UsePlt)
657 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF);
658 Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, 0);
659 Callee = DAG.getNode(VEISD::GETFUNPLT, DL, PtrVT, Callee);
660 } else {
661 Callee = makeHiLoPair(Callee, VE::S_HI32, VE::S_LO32, DAG);
662 }
663 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
664 if (IsPICCall) {
665 if (UsePlt)
666 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF);
667 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
668 Callee = DAG.getNode(VEISD::GETFUNPLT, DL, PtrVT, Callee);
669 } else {
670 Callee = makeHiLoPair(Callee, VE::S_HI32, VE::S_LO32, DAG);
671 }
672 }
673
674 RegsToPass.push_back(std::make_pair(VE::SX12, Callee));
675
676 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
677 CCValAssign &VA = ArgLocs[i];
678 SDValue Arg = CLI.OutVals[i];
679
680 // Promote the value if needed.
681 switch (VA.getLocInfo()) {
682 default:
683 llvm_unreachable("Unknown location info!");
685 break;
687 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
688 break;
690 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
691 break;
693 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
694 break;
695 case CCValAssign::BCvt: {
696 // Convert a float argument to i64 with padding.
697 // 63 31 0
698 // +------+------+
699 // | float| 0 |
700 // +------+------+
701 assert(VA.getLocVT() == MVT::i64);
702 assert(VA.getValVT() == MVT::f32);
703 SDValue Undef = SDValue(
704 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::i64), 0);
705 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32);
706 Arg = SDValue(DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL,
707 MVT::i64, Undef, Arg, Sub_f32),
708 0);
709 break;
710 }
711 }
712
713 if (VA.isRegLoc()) {
714 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
715 if (!UseBoth)
716 continue;
717 VA = ArgLocs2[i];
718 }
719
720 assert(VA.isMemLoc());
721
722 // Create a store off the stack pointer for this argument.
723 SDValue StackPtr = DAG.getRegister(VE::SX11, PtrVT);
724 // The argument area starts at %fp/%sp + the size of reserved area.
725 SDValue PtrOff =
726 DAG.getIntPtrConstant(VA.getLocMemOffset() + ArgsBaseOffset, DL);
727 PtrOff = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr, PtrOff);
728 MemOpChains.push_back(
729 DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo()));
730 }
731
732 // Emit all stores, make sure they occur before the call.
733 if (!MemOpChains.empty())
734 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
735
736 // Build a sequence of CopyToReg nodes glued together with token chain and
737 // glue operands which copy the outgoing args into registers. The InGlue is
738 // necessary since all emitted instructions must be stuck together in order
739 // to pass the live physical registers.
740 SDValue InGlue;
741 for (const auto &[Reg, N] : RegsToPass) {
742 Chain = DAG.getCopyToReg(Chain, DL, Reg, N, InGlue);
743 InGlue = Chain.getValue(1);
744 }
745
746 // Build the operands for the call instruction itself.
748 Ops.push_back(Chain);
749 for (const auto &[Reg, N] : RegsToPass)
750 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
751
752 // Add a register mask operand representing the call-preserved registers.
753 const VERegisterInfo *TRI = Subtarget->getRegisterInfo();
754 const uint32_t *Mask =
755 TRI->getCallPreservedMask(DAG.getMachineFunction(), CLI.CallConv);
756 assert(Mask && "Missing call preserved mask for calling convention");
757 Ops.push_back(DAG.getRegisterMask(Mask));
758
759 // Make sure the CopyToReg nodes are glued to the call instruction which
760 // consumes the registers.
761 if (InGlue.getNode())
762 Ops.push_back(InGlue);
763
764 // Now the call itself.
765 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
766 Chain = DAG.getNode(VEISD::CALL, DL, NodeTys, Ops);
767 InGlue = Chain.getValue(1);
768
769 // Revert the stack pointer immediately after the call.
770 Chain = DAG.getCALLSEQ_END(Chain, ArgsSize, 0, InGlue, DL);
771 InGlue = Chain.getValue(1);
772
773 // Now extract the return values. This is more or less the same as
774 // LowerFormalArguments.
775
776 // Assign locations to each value returned by this call.
778 CCState RVInfo(CLI.CallConv, CLI.IsVarArg, DAG.getMachineFunction(), RVLocs,
779 *DAG.getContext());
780
781 // Set inreg flag manually for codegen generated library calls that
782 // return float.
783 if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && !CLI.CB)
784 CLI.Ins[0].Flags.setInReg();
785
786 RVInfo.AnalyzeCallResult(CLI.Ins, getReturnCC(CLI.CallConv));
787
788 // Copy all of the result registers out of their specified physreg.
789 for (unsigned i = 0; i != RVLocs.size(); ++i) {
790 CCValAssign &VA = RVLocs[i];
791 assert(!VA.needsCustom() && "Unexpected custom lowering");
792 Register Reg = VA.getLocReg();
793
794 // When returning 'inreg {i32, i32 }', two consecutive i32 arguments can
795 // reside in the same register in the high and low bits. Reuse the
796 // CopyFromReg previous node to avoid duplicate copies.
797 SDValue RV;
798 if (RegisterSDNode *SrcReg = dyn_cast<RegisterSDNode>(Chain.getOperand(1)))
799 if (SrcReg->getReg() == Reg && Chain->getOpcode() == ISD::CopyFromReg)
800 RV = Chain.getValue(0);
801
802 // But usually we'll create a new CopyFromReg for a different register.
803 if (!RV.getNode()) {
804 RV = DAG.getCopyFromReg(Chain, DL, Reg, RVLocs[i].getLocVT(), InGlue);
805 Chain = RV.getValue(1);
806 InGlue = Chain.getValue(2);
807 }
808
809 // The callee promoted the return value, so insert an Assert?ext SDNode so
810 // we won't promote the value again in this function.
811 switch (VA.getLocInfo()) {
813 RV = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), RV,
814 DAG.getValueType(VA.getValVT()));
815 break;
817 RV = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), RV,
818 DAG.getValueType(VA.getValVT()));
819 break;
820 case CCValAssign::BCvt: {
821 // Extract a float return value from i64 with padding.
822 // 63 31 0
823 // +------+------+
824 // | float| 0 |
825 // +------+------+
826 assert(VA.getLocVT() == MVT::i64);
827 assert(VA.getValVT() == MVT::f32);
828 SDValue Sub_f32 = DAG.getTargetConstant(VE::sub_f32, DL, MVT::i32);
829 RV = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL,
830 MVT::f32, RV, Sub_f32),
831 0);
832 break;
833 }
834 default:
835 break;
836 }
837
838 // Truncate the register down to the return value type.
839 if (VA.isExtInLoc())
840 RV = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), RV);
841
842 InVals.push_back(RV);
843 }
844
845 return Chain;
846}
847
849 const GlobalAddressSDNode *GA) const {
850 // VE uses 64 bit addressing, so we need multiple instructions to generate
851 // an address. Folding address with offset increases the number of
852 // instructions, so that we disable it here. Offsets will be folded in
853 // the DAG combine later if it worth to do so.
854 return false;
855}
856
857/// isFPImmLegal - Returns true if the target can instruction select the
858/// specified FP immediate natively. If false, the legalizer will
859/// materialize the FP immediate as a load from a constant pool.
861 bool ForCodeSize) const {
862 return VT == MVT::f32 || VT == MVT::f64;
863}
864
865/// Determine if the target supports unaligned memory accesses.
866///
867/// This function returns true if the target allows unaligned memory accesses
868/// of the specified type in the given address space. If true, it also returns
869/// whether the unaligned memory access is "fast" in the last argument by
870/// reference. This is used, for example, in situations where an array
871/// copy/move/set is converted to a sequence of store operations. Its use
872/// helps to ensure that such replacements don't generate code that causes an
873/// alignment error (trap) on the target machine.
875 unsigned AddrSpace,
876 Align A,
878 unsigned *Fast) const {
879 if (Fast) {
880 // It's fast anytime on VE
881 *Fast = 1;
882 }
883 return true;
884}
885
887 const VESubtarget &STI)
888 : TargetLowering(TM), Subtarget(&STI) {
889 // Instructions which use registers as conditionals examine all the
890 // bits (as does the pseudo SELECT_CC expansion). I don't think it
891 // matters much whether it's ZeroOrOneBooleanContent, or
892 // ZeroOrNegativeOneBooleanContent, so, arbitrarily choose the
893 // former.
896
897 initRegisterClasses();
898 initSPUActions();
899 initVPUActions();
900
902
903 // We have target-specific dag combine patterns for the following nodes:
907
908 // Set function alignment to 16 bytes
910
911 // VE stores all argument by 8 bytes alignment
913
915}
916
917const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const {
918#define TARGET_NODE_CASE(NAME) \
919 case VEISD::NAME: \
920 return "VEISD::" #NAME;
921 switch ((VEISD::NodeType)Opcode) {
923 break;
924 TARGET_NODE_CASE(CMPI)
925 TARGET_NODE_CASE(CMPU)
926 TARGET_NODE_CASE(CMPF)
927 TARGET_NODE_CASE(CMPQ)
928 TARGET_NODE_CASE(CMOV)
929 TARGET_NODE_CASE(CALL)
930 TARGET_NODE_CASE(EH_SJLJ_LONGJMP)
931 TARGET_NODE_CASE(EH_SJLJ_SETJMP)
932 TARGET_NODE_CASE(EH_SJLJ_SETUP_DISPATCH)
933 TARGET_NODE_CASE(GETFUNPLT)
934 TARGET_NODE_CASE(GETSTACKTOP)
935 TARGET_NODE_CASE(GETTLSADDR)
936 TARGET_NODE_CASE(GLOBAL_BASE_REG)
939 TARGET_NODE_CASE(RET_GLUE)
940 TARGET_NODE_CASE(TS1AM)
941 TARGET_NODE_CASE(VEC_UNPACK_LO)
942 TARGET_NODE_CASE(VEC_UNPACK_HI)
943 TARGET_NODE_CASE(VEC_PACK)
944 TARGET_NODE_CASE(VEC_BROADCAST)
945 TARGET_NODE_CASE(REPL_I32)
946 TARGET_NODE_CASE(REPL_F32)
947
948 TARGET_NODE_CASE(LEGALAVL)
949
950 // Register the VVP_* SDNodes.
951#define ADD_VVP_OP(VVP_NAME, ...) TARGET_NODE_CASE(VVP_NAME)
952#include "VVPNodes.def"
953 }
954#undef TARGET_NODE_CASE
955 return nullptr;
956}
957
959 EVT VT) const {
960 return MVT::i32;
961}
962
963// Convert to a target node and set target flags.
965 SelectionDAG &DAG) const {
966 if (const GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Op))
967 return DAG.getTargetGlobalAddress(GA->getGlobal(), SDLoc(GA),
968 GA->getValueType(0), GA->getOffset(), TF);
969
970 if (const BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op))
971 return DAG.getTargetBlockAddress(BA->getBlockAddress(), Op.getValueType(),
972 0, TF);
973
974 if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op))
975 return DAG.getTargetConstantPool(CP->getConstVal(), CP->getValueType(0),
976 CP->getAlign(), CP->getOffset(), TF);
977
978 if (const ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op))
979 return DAG.getTargetExternalSymbol(ES->getSymbol(), ES->getValueType(0),
980 TF);
981
982 if (const JumpTableSDNode *JT = dyn_cast<JumpTableSDNode>(Op))
983 return DAG.getTargetJumpTable(JT->getIndex(), JT->getValueType(0), TF);
984
985 llvm_unreachable("Unhandled address SDNode");
986}
987
988// Split Op into high and low parts according to HiTF and LoTF.
989// Return an ADD node combining the parts.
990SDValue VETargetLowering::makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF,
991 SelectionDAG &DAG) const {
992 SDLoc DL(Op);
993 EVT VT = Op.getValueType();
994 SDValue Hi = DAG.getNode(VEISD::Hi, DL, VT, withTargetFlags(Op, HiTF, DAG));
995 SDValue Lo = DAG.getNode(VEISD::Lo, DL, VT, withTargetFlags(Op, LoTF, DAG));
996 return DAG.getNode(ISD::ADD, DL, VT, Hi, Lo);
997}
998
999// Build SDNodes for producing an address from a GlobalAddress, ConstantPool,
1000// or ExternalSymbol SDNode.
1002 SDLoc DL(Op);
1003 EVT PtrVT = Op.getValueType();
1004
1005 // Handle PIC mode first. VE needs a got load for every variable!
1006 if (isPositionIndependent()) {
1007 auto GlobalN = dyn_cast<GlobalAddressSDNode>(Op);
1008
1009 if (isa<ConstantPoolSDNode>(Op) || isa<JumpTableSDNode>(Op) ||
1010 (GlobalN && GlobalN->getGlobal()->hasLocalLinkage())) {
1011 // Create following instructions for local linkage PIC code.
1012 // lea %reg, label@gotoff_lo
1013 // and %reg, %reg, (32)0
1014 // lea.sl %reg, label@gotoff_hi(%reg, %got)
1015 SDValue HiLo =
1017 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrVT);
1018 return DAG.getNode(ISD::ADD, DL, PtrVT, GlobalBase, HiLo);
1019 }
1020 // Create following instructions for not local linkage PIC code.
1021 // lea %reg, label@got_lo
1022 // and %reg, %reg, (32)0
1023 // lea.sl %reg, label@got_hi(%reg)
1024 // ld %reg, (%reg, %got)
1026 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrVT);
1027 SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, PtrVT, GlobalBase, HiLo);
1028 return DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), AbsAddr,
1030 }
1031
1032 // This is one of the absolute code models.
1033 switch (getTargetMachine().getCodeModel()) {
1034 default:
1035 llvm_unreachable("Unsupported absolute code model");
1036 case CodeModel::Small:
1037 case CodeModel::Medium:
1038 case CodeModel::Large:
1039 // abs64.
1040 return makeHiLoPair(Op, VE::S_HI32, VE::S_LO32, DAG);
1041 }
1042}
1043
1044/// Custom Lower {
1045
1046// The mappings for emitLeading/TrailingFence for VE is designed by following
1047// http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
1049 Instruction *Inst,
1050 AtomicOrdering Ord) const {
1051 switch (Ord) {
1054 llvm_unreachable("Invalid fence: unordered/non-atomic");
1057 return nullptr; // Nothing to do
1060 return Builder.CreateFence(AtomicOrdering::Release);
1062 if (!Inst->hasAtomicStore())
1063 return nullptr; // Nothing to do
1065 }
1066 llvm_unreachable("Unknown fence ordering in emitLeadingFence");
1067}
1068
1070 Instruction *Inst,
1071 AtomicOrdering Ord) const {
1072 switch (Ord) {
1075 llvm_unreachable("Invalid fence: unordered/not-atomic");
1078 return nullptr; // Nothing to do
1081 return Builder.CreateFence(AtomicOrdering::Acquire);
1084 }
1085 llvm_unreachable("Unknown fence ordering in emitTrailingFence");
1086}
1087
1089 SelectionDAG &DAG) const {
1090 SDLoc DL(Op);
1091 AtomicOrdering FenceOrdering =
1092 static_cast<AtomicOrdering>(Op.getConstantOperandVal(1));
1093 SyncScope::ID FenceSSID =
1094 static_cast<SyncScope::ID>(Op.getConstantOperandVal(2));
1095
1096 // VE uses Release consistency, so need a fence instruction if it is a
1097 // cross-thread fence.
1098 if (FenceSSID == SyncScope::System) {
1099 switch (FenceOrdering) {
1103 // No need to generate fencem instruction here.
1104 break;
1106 // Generate "fencem 2" as acquire fence.
1107 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other,
1108 DAG.getTargetConstant(2, DL, MVT::i32),
1109 Op.getOperand(0)),
1110 0);
1112 // Generate "fencem 1" as release fence.
1113 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other,
1114 DAG.getTargetConstant(1, DL, MVT::i32),
1115 Op.getOperand(0)),
1116 0);
1119 // Generate "fencem 3" as acq_rel and seq_cst fence.
1120 // FIXME: "fencem 3" doesn't wait for PCIe deveices accesses,
1121 // so seq_cst may require more instruction for them.
1122 return SDValue(DAG.getMachineNode(VE::FENCEM, DL, MVT::Other,
1123 DAG.getTargetConstant(3, DL, MVT::i32),
1124 Op.getOperand(0)),
1125 0);
1126 }
1127 }
1128
1129 // MEMBARRIER is a compiler barrier; it codegens to a no-op.
1130 return DAG.getNode(ISD::MEMBARRIER, DL, MVT::Other, Op.getOperand(0));
1131}
1132
1135 // We have TS1AM implementation for i8/i16/i32/i64, so use it.
1136 if (AI->getOperation() == AtomicRMWInst::Xchg) {
1138 }
1139 // FIXME: Support "ATMAM" instruction for LOAD_ADD/SUB/AND/OR.
1140
1141 // Otherwise, expand it using compare and exchange instruction to not call
1142 // __sync_fetch_and_* functions.
1144}
1145
1147 SDValue &Bits) {
1148 SDLoc DL(Op);
1149 AtomicSDNode *N = cast<AtomicSDNode>(Op);
1150 SDValue Ptr = N->getOperand(1);
1151 SDValue Val = N->getOperand(2);
1152 EVT PtrVT = Ptr.getValueType();
1153 bool Byte = N->getMemoryVT() == MVT::i8;
1154 // Remainder = AND Ptr, 3
1155 // Flag = 1 << Remainder ; If Byte is true (1 byte swap flag)
1156 // Flag = 3 << Remainder ; If Byte is false (2 bytes swap flag)
1157 // Bits = Remainder << 3
1158 // NewVal = Val << Bits
1159 SDValue Const3 = DAG.getConstant(3, DL, PtrVT);
1160 SDValue Remainder = DAG.getNode(ISD::AND, DL, PtrVT, {Ptr, Const3});
1161 SDValue Mask = Byte ? DAG.getConstant(1, DL, MVT::i32)
1162 : DAG.getConstant(3, DL, MVT::i32);
1163 Flag = DAG.getNode(ISD::SHL, DL, MVT::i32, {Mask, Remainder});
1164 Bits = DAG.getNode(ISD::SHL, DL, PtrVT, {Remainder, Const3});
1165 return DAG.getNode(ISD::SHL, DL, Val.getValueType(), {Val, Bits});
1166}
1167
1169 SDValue Bits) {
1170 SDLoc DL(Op);
1171 EVT VT = Data.getValueType();
1172 bool Byte = cast<AtomicSDNode>(Op)->getMemoryVT() == MVT::i8;
1173 // NewData = Data >> Bits
1174 // Result = NewData & 0xff ; If Byte is true (1 byte)
1175 // Result = NewData & 0xffff ; If Byte is false (2 bytes)
1176
1177 SDValue NewData = DAG.getNode(ISD::SRL, DL, VT, Data, Bits);
1178 return DAG.getNode(ISD::AND, DL, VT,
1179 {NewData, DAG.getConstant(Byte ? 0xff : 0xffff, DL, VT)});
1180}
1181
1183 SelectionDAG &DAG) const {
1184 SDLoc DL(Op);
1185 AtomicSDNode *N = cast<AtomicSDNode>(Op);
1186
1187 if (N->getMemoryVT() == MVT::i8) {
1188 // For i8, use "ts1am"
1189 // Input:
1190 // ATOMIC_SWAP Ptr, Val, Order
1191 //
1192 // Output:
1193 // Remainder = AND Ptr, 3
1194 // Flag = 1 << Remainder ; 1 byte swap flag for TS1AM inst.
1195 // Bits = Remainder << 3
1196 // NewVal = Val << Bits
1197 //
1198 // Aligned = AND Ptr, -4
1199 // Data = TS1AM Aligned, Flag, NewVal
1200 //
1201 // NewData = Data >> Bits
1202 // Result = NewData & 0xff ; 1 byte result
1203 SDValue Flag;
1204 SDValue Bits;
1205 SDValue NewVal = prepareTS1AM(Op, DAG, Flag, Bits);
1206
1207 SDValue Ptr = N->getOperand(1);
1209 DAG.getNode(ISD::AND, DL, Ptr.getValueType(),
1210 {Ptr, DAG.getSignedConstant(-4, DL, MVT::i64)});
1211 SDValue TS1AM = DAG.getAtomic(VEISD::TS1AM, DL, N->getMemoryVT(),
1212 DAG.getVTList(Op.getNode()->getValueType(0),
1213 Op.getNode()->getValueType(1)),
1214 {N->getChain(), Aligned, Flag, NewVal},
1215 N->getMemOperand());
1216
1217 SDValue Result = finalizeTS1AM(Op, DAG, TS1AM, Bits);
1218 SDValue Chain = TS1AM.getValue(1);
1219 return DAG.getMergeValues({Result, Chain}, DL);
1220 }
1221 if (N->getMemoryVT() == MVT::i16) {
1222 // For i16, use "ts1am"
1223 SDValue Flag;
1224 SDValue Bits;
1225 SDValue NewVal = prepareTS1AM(Op, DAG, Flag, Bits);
1226
1227 SDValue Ptr = N->getOperand(1);
1229 DAG.getNode(ISD::AND, DL, Ptr.getValueType(),
1230 {Ptr, DAG.getSignedConstant(-4, DL, MVT::i64)});
1231 SDValue TS1AM = DAG.getAtomic(VEISD::TS1AM, DL, N->getMemoryVT(),
1232 DAG.getVTList(Op.getNode()->getValueType(0),
1233 Op.getNode()->getValueType(1)),
1234 {N->getChain(), Aligned, Flag, NewVal},
1235 N->getMemOperand());
1236
1237 SDValue Result = finalizeTS1AM(Op, DAG, TS1AM, Bits);
1238 SDValue Chain = TS1AM.getValue(1);
1239 return DAG.getMergeValues({Result, Chain}, DL);
1240 }
1241 // Otherwise, let llvm legalize it.
1242 return Op;
1243}
1244
1246 SelectionDAG &DAG) const {
1247 return makeAddress(Op, DAG);
1248}
1249
1251 SelectionDAG &DAG) const {
1252 return makeAddress(Op, DAG);
1253}
1254
1256 SelectionDAG &DAG) const {
1257 return makeAddress(Op, DAG);
1258}
1259
1260SDValue
1262 SelectionDAG &DAG) const {
1263 SDLoc DL(Op);
1264
1265 // Generate the following code:
1266 // t1: ch,glue = callseq_start t0, 0, 0
1267 // t2: i64,ch,glue = VEISD::GETTLSADDR t1, label, t1:1
1268 // t3: ch,glue = callseq_end t2, 0, 0, t2:2
1269 // t4: i64,ch,glue = CopyFromReg t3, Register:i64 $sx0, t3:1
1270 SDValue Label = withTargetFlags(Op, 0, DAG);
1271 EVT PtrVT = Op.getValueType();
1272
1273 // Lowering the machine isd will make sure everything is in the right
1274 // location.
1275 SDValue Chain = DAG.getEntryNode();
1276 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
1277 const uint32_t *Mask = Subtarget->getRegisterInfo()->getCallPreservedMask(
1279 Chain = DAG.getCALLSEQ_START(Chain, 64, 0, DL);
1280 SDValue Args[] = {Chain, Label, DAG.getRegisterMask(Mask), Chain.getValue(1)};
1281 Chain = DAG.getNode(VEISD::GETTLSADDR, DL, NodeTys, Args);
1282 Chain = DAG.getCALLSEQ_END(Chain, 64, 0, Chain.getValue(1), DL);
1283 Chain = DAG.getCopyFromReg(Chain, DL, VE::SX0, PtrVT, Chain.getValue(1));
1284
1285 // GETTLSADDR will be codegen'ed as call. Inform MFI that function has calls.
1287 MFI.setHasCalls(true);
1288
1289 // Also generate code to prepare a GOT register if it is PIC.
1290 if (isPositionIndependent()) {
1292 Subtarget->getInstrInfo()->getGlobalBaseReg(&MF);
1293 }
1294
1295 return Chain;
1296}
1297
1299 SelectionDAG &DAG) const {
1300 // The current implementation of nld (2.26) doesn't allow local exec model
1301 // code described in VE-tls_v1.1.pdf (*1) as its input. Instead, we always
1302 // generate the general dynamic model code sequence.
1303 //
1304 // *1: https://www.nec.com/en/global/prod/hpc/aurora/document/VE-tls_v1.1.pdf
1305 return lowerToTLSGeneralDynamicModel(Op, DAG);
1306}
1307
1309 return makeAddress(Op, DAG);
1310}
1311
1312// Lower a f128 load into two f64 loads.
1314 SDLoc DL(Op);
1315 LoadSDNode *LdNode = dyn_cast<LoadSDNode>(Op.getNode());
1316 assert(LdNode && LdNode->getOffset().isUndef() && "Unexpected node type");
1317 Align Alignment = LdNode->getAlign();
1318 if (Alignment > 8)
1319 Alignment = Align(8);
1320
1321 SDValue Lo64 =
1322 DAG.getLoad(MVT::f64, DL, LdNode->getChain(), LdNode->getBasePtr(),
1323 LdNode->getPointerInfo(), Alignment,
1326 EVT AddrVT = LdNode->getBasePtr().getValueType();
1327 SDValue HiPtr = DAG.getNode(ISD::ADD, DL, AddrVT, LdNode->getBasePtr(),
1328 DAG.getConstant(8, DL, AddrVT));
1329 SDValue Hi64 =
1330 DAG.getLoad(MVT::f64, DL, LdNode->getChain(), HiPtr,
1331 LdNode->getPointerInfo(), Alignment,
1334
1335 SDValue SubRegEven = DAG.getTargetConstant(VE::sub_even, DL, MVT::i32);
1336 SDValue SubRegOdd = DAG.getTargetConstant(VE::sub_odd, DL, MVT::i32);
1337
1338 // VE stores Hi64 to 8(addr) and Lo64 to 0(addr)
1339 SDNode *InFP128 =
1340 DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MVT::f128);
1341 InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::f128,
1342 SDValue(InFP128, 0), Hi64, SubRegEven);
1343 InFP128 = DAG.getMachineNode(TargetOpcode::INSERT_SUBREG, DL, MVT::f128,
1344 SDValue(InFP128, 0), Lo64, SubRegOdd);
1345 SDValue OutChains[2] = {SDValue(Lo64.getNode(), 1),
1346 SDValue(Hi64.getNode(), 1)};
1347 SDValue OutChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1348 SDValue Ops[2] = {SDValue(InFP128, 0), OutChain};
1349 return DAG.getMergeValues(Ops, DL);
1350}
1351
1352// Lower a vXi1 load into following instructions
1353// LDrii %1, (,%addr)
1354// LVMxir %vm, 0, %1
1355// LDrii %2, 8(,%addr)
1356// LVMxir %vm, 0, %2
1357// ...
1359 SDLoc DL(Op);
1360 LoadSDNode *LdNode = dyn_cast<LoadSDNode>(Op.getNode());
1361 assert(LdNode && LdNode->getOffset().isUndef() && "Unexpected node type");
1362
1363 SDValue BasePtr = LdNode->getBasePtr();
1364 Align Alignment = LdNode->getAlign();
1365 if (Alignment > 8)
1366 Alignment = Align(8);
1367
1368 EVT AddrVT = BasePtr.getValueType();
1369 EVT MemVT = LdNode->getMemoryVT();
1370 if (MemVT == MVT::v256i1 || MemVT == MVT::v4i64) {
1371 SDValue OutChains[4];
1372 SDNode *VM = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MemVT);
1373 for (int i = 0; i < 4; ++i) {
1374 // Generate load dag and prepare chains.
1375 SDValue Addr = DAG.getNode(ISD::ADD, DL, AddrVT, BasePtr,
1376 DAG.getConstant(8 * i, DL, AddrVT));
1377 SDValue Val =
1378 DAG.getLoad(MVT::i64, DL, LdNode->getChain(), Addr,
1379 LdNode->getPointerInfo(), Alignment,
1382 OutChains[i] = SDValue(Val.getNode(), 1);
1383
1384 VM = DAG.getMachineNode(VE::LVMir_m, DL, MVT::i64,
1385 DAG.getTargetConstant(i, DL, MVT::i64), Val,
1386 SDValue(VM, 0));
1387 }
1388 SDValue OutChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1389 SDValue Ops[2] = {SDValue(VM, 0), OutChain};
1390 return DAG.getMergeValues(Ops, DL);
1391 } else if (MemVT == MVT::v512i1 || MemVT == MVT::v8i64) {
1392 SDValue OutChains[8];
1393 SDNode *VM = DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, MemVT);
1394 for (int i = 0; i < 8; ++i) {
1395 // Generate load dag and prepare chains.
1396 SDValue Addr = DAG.getNode(ISD::ADD, DL, AddrVT, BasePtr,
1397 DAG.getConstant(8 * i, DL, AddrVT));
1398 SDValue Val =
1399 DAG.getLoad(MVT::i64, DL, LdNode->getChain(), Addr,
1400 LdNode->getPointerInfo(), Alignment,
1403 OutChains[i] = SDValue(Val.getNode(), 1);
1404
1405 VM = DAG.getMachineNode(VE::LVMyir_y, DL, MVT::i64,
1406 DAG.getTargetConstant(i, DL, MVT::i64), Val,
1407 SDValue(VM, 0));
1408 }
1409 SDValue OutChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1410 SDValue Ops[2] = {SDValue(VM, 0), OutChain};
1411 return DAG.getMergeValues(Ops, DL);
1412 } else {
1413 // Otherwise, ask llvm to expand it.
1414 return SDValue();
1415 }
1416}
1417
1419 LoadSDNode *LdNode = cast<LoadSDNode>(Op.getNode());
1420 EVT MemVT = LdNode->getMemoryVT();
1421
1422 // If VPU is enabled, always expand non-mask vector loads to VVP
1423 if (Subtarget->enableVPU() && MemVT.isVector() && !isMaskType(MemVT))
1424 return lowerToVVP(Op, DAG);
1425
1426 SDValue BasePtr = LdNode->getBasePtr();
1427 if (isa<FrameIndexSDNode>(BasePtr.getNode())) {
1428 // Do not expand store instruction with frame index here because of
1429 // dependency problems. We expand it later in eliminateFrameIndex().
1430 return Op;
1431 }
1432
1433 if (MemVT == MVT::f128)
1434 return lowerLoadF128(Op, DAG);
1435 if (isMaskType(MemVT))
1436 return lowerLoadI1(Op, DAG);
1437
1438 return Op;
1439}
1440
1441// Lower a f128 store into two f64 stores.
1443 SDLoc DL(Op);
1444 StoreSDNode *StNode = dyn_cast<StoreSDNode>(Op.getNode());
1445 assert(StNode && StNode->getOffset().isUndef() && "Unexpected node type");
1446
1447 SDValue SubRegEven = DAG.getTargetConstant(VE::sub_even, DL, MVT::i32);
1448 SDValue SubRegOdd = DAG.getTargetConstant(VE::sub_odd, DL, MVT::i32);
1449
1450 SDNode *Hi64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i64,
1451 StNode->getValue(), SubRegEven);
1452 SDNode *Lo64 = DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, MVT::i64,
1453 StNode->getValue(), SubRegOdd);
1454
1455 Align Alignment = StNode->getAlign();
1456 if (Alignment > 8)
1457 Alignment = Align(8);
1458
1459 // VE stores Hi64 to 8(addr) and Lo64 to 0(addr)
1460 SDValue OutChains[2];
1461 OutChains[0] =
1462 DAG.getStore(StNode->getChain(), DL, SDValue(Lo64, 0),
1463 StNode->getBasePtr(), MachinePointerInfo(), Alignment,
1466 EVT AddrVT = StNode->getBasePtr().getValueType();
1467 SDValue HiPtr = DAG.getNode(ISD::ADD, DL, AddrVT, StNode->getBasePtr(),
1468 DAG.getConstant(8, DL, AddrVT));
1469 OutChains[1] =
1470 DAG.getStore(StNode->getChain(), DL, SDValue(Hi64, 0), HiPtr,
1471 MachinePointerInfo(), Alignment,
1474 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1475}
1476
1477// Lower a vXi1 store into following instructions
1478// SVMi %1, %vm, 0
1479// STrii %1, (,%addr)
1480// SVMi %2, %vm, 1
1481// STrii %2, 8(,%addr)
1482// ...
1484 SDLoc DL(Op);
1485 StoreSDNode *StNode = dyn_cast<StoreSDNode>(Op.getNode());
1486 assert(StNode && StNode->getOffset().isUndef() && "Unexpected node type");
1487
1488 SDValue BasePtr = StNode->getBasePtr();
1489 Align Alignment = StNode->getAlign();
1490 if (Alignment > 8)
1491 Alignment = Align(8);
1492 EVT AddrVT = BasePtr.getValueType();
1493 EVT MemVT = StNode->getMemoryVT();
1494 if (MemVT == MVT::v256i1 || MemVT == MVT::v4i64) {
1495 SDValue OutChains[4];
1496 for (int i = 0; i < 4; ++i) {
1497 SDNode *V =
1498 DAG.getMachineNode(VE::SVMmi, DL, MVT::i64, StNode->getValue(),
1499 DAG.getTargetConstant(i, DL, MVT::i64));
1500 SDValue Addr = DAG.getNode(ISD::ADD, DL, AddrVT, BasePtr,
1501 DAG.getConstant(8 * i, DL, AddrVT));
1502 OutChains[i] =
1503 DAG.getStore(StNode->getChain(), DL, SDValue(V, 0), Addr,
1504 MachinePointerInfo(), Alignment,
1507 }
1508 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1509 } else if (MemVT == MVT::v512i1 || MemVT == MVT::v8i64) {
1510 SDValue OutChains[8];
1511 for (int i = 0; i < 8; ++i) {
1512 SDNode *V =
1513 DAG.getMachineNode(VE::SVMyi, DL, MVT::i64, StNode->getValue(),
1514 DAG.getTargetConstant(i, DL, MVT::i64));
1515 SDValue Addr = DAG.getNode(ISD::ADD, DL, AddrVT, BasePtr,
1516 DAG.getConstant(8 * i, DL, AddrVT));
1517 OutChains[i] =
1518 DAG.getStore(StNode->getChain(), DL, SDValue(V, 0), Addr,
1519 MachinePointerInfo(), Alignment,
1522 }
1523 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
1524 } else {
1525 // Otherwise, ask llvm to expand it.
1526 return SDValue();
1527 }
1528}
1529
1531 StoreSDNode *StNode = cast<StoreSDNode>(Op.getNode());
1532 assert(StNode && StNode->getOffset().isUndef() && "Unexpected node type");
1533 EVT MemVT = StNode->getMemoryVT();
1534
1535 // If VPU is enabled, always expand non-mask vector stores to VVP
1536 if (Subtarget->enableVPU() && MemVT.isVector() && !isMaskType(MemVT))
1537 return lowerToVVP(Op, DAG);
1538
1539 SDValue BasePtr = StNode->getBasePtr();
1540 if (isa<FrameIndexSDNode>(BasePtr.getNode())) {
1541 // Do not expand store instruction with frame index here because of
1542 // dependency problems. We expand it later in eliminateFrameIndex().
1543 return Op;
1544 }
1545
1546 if (MemVT == MVT::f128)
1547 return lowerStoreF128(Op, DAG);
1548 if (isMaskType(MemVT))
1549 return lowerStoreI1(Op, DAG);
1550
1551 // Otherwise, ask llvm to expand it.
1552 return SDValue();
1553}
1554
1558 auto PtrVT = getPointerTy(DAG.getDataLayout());
1559
1560 // Need frame address to find the address of VarArgsFrameIndex.
1562
1563 // vastart just stores the address of the VarArgsFrameIndex slot into the
1564 // memory location argument.
1565 SDLoc DL(Op);
1566 SDValue Offset =
1567 DAG.getNode(ISD::ADD, DL, PtrVT, DAG.getRegister(VE::SX9, PtrVT),
1568 DAG.getIntPtrConstant(FuncInfo->getVarArgsFrameOffset(), DL));
1569 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1570 return DAG.getStore(Op.getOperand(0), DL, Offset, Op.getOperand(1),
1571 MachinePointerInfo(SV));
1572}
1573
1575 SDNode *Node = Op.getNode();
1576 EVT VT = Node->getValueType(0);
1577 SDValue InChain = Node->getOperand(0);
1578 SDValue VAListPtr = Node->getOperand(1);
1579 EVT PtrVT = VAListPtr.getValueType();
1580 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
1581 SDLoc DL(Node);
1582 SDValue VAList =
1583 DAG.getLoad(PtrVT, DL, InChain, VAListPtr, MachinePointerInfo(SV));
1584 SDValue Chain = VAList.getValue(1);
1585 SDValue NextPtr;
1586
1587 if (VT == MVT::f128) {
1588 // VE f128 values must be stored with 16 bytes alignment. We don't
1589 // know the actual alignment of VAList, so we take alignment of it
1590 // dynamically.
1591 int Align = 16;
1592 VAList = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
1593 DAG.getConstant(Align - 1, DL, PtrVT));
1594 VAList = DAG.getNode(ISD::AND, DL, PtrVT, VAList,
1595 DAG.getSignedConstant(-Align, DL, PtrVT));
1596 // Increment the pointer, VAList, by 16 to the next vaarg.
1597 NextPtr =
1598 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(16, DL));
1599 } else if (VT == MVT::f32) {
1600 // float --> need special handling like below.
1601 // 0 4
1602 // +------+------+
1603 // | empty| float|
1604 // +------+------+
1605 // Increment the pointer, VAList, by 8 to the next vaarg.
1606 NextPtr =
1607 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(8, DL));
1608 // Then, adjust VAList.
1609 unsigned InternalOffset = 4;
1610 VAList = DAG.getNode(ISD::ADD, DL, PtrVT, VAList,
1611 DAG.getConstant(InternalOffset, DL, PtrVT));
1612 } else {
1613 // Increment the pointer, VAList, by 8 to the next vaarg.
1614 NextPtr =
1615 DAG.getNode(ISD::ADD, DL, PtrVT, VAList, DAG.getIntPtrConstant(8, DL));
1616 }
1617
1618 // Store the incremented VAList to the legalized pointer.
1619 InChain = DAG.getStore(Chain, DL, NextPtr, VAListPtr, MachinePointerInfo(SV));
1620
1621 // Load the actual argument out of the pointer VAList.
1622 // We can't count on greater alignment than the word size.
1623 return DAG.getLoad(
1624 VT, DL, InChain, VAList, MachinePointerInfo(),
1625 Align(std::min(PtrVT.getSizeInBits(), VT.getSizeInBits()) / 8));
1626}
1627
1629 SelectionDAG &DAG) const {
1630 // Generate following code.
1631 // (void)__llvm_grow_stack(size);
1632 // ret = GETSTACKTOP; // pseudo instruction
1633 SDLoc DL(Op);
1634
1635 // Get the inputs.
1636 SDNode *Node = Op.getNode();
1637 SDValue Chain = Op.getOperand(0);
1638 SDValue Size = Op.getOperand(1);
1639 MaybeAlign Alignment(Op.getConstantOperandVal(2));
1640 EVT VT = Node->getValueType(0);
1641
1642 // Chain the dynamic stack allocation so that it doesn't modify the stack
1643 // pointer when other instructions are using the stack.
1644 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, DL);
1645
1646 const TargetFrameLowering &TFI = *Subtarget->getFrameLowering();
1647 Align StackAlign = TFI.getStackAlign();
1648 bool NeedsAlign = Alignment.valueOrOne() > StackAlign;
1649
1650 // Prepare arguments
1652 Args.emplace_back(Size, Size.getValueType().getTypeForEVT(*DAG.getContext()));
1653 if (NeedsAlign) {
1654 SDValue Align = DAG.getConstant(~(Alignment->value() - 1ULL), DL, VT);
1655 Args.emplace_back(Align,
1656 Align.getValueType().getTypeForEVT(*DAG.getContext()));
1657 }
1659
1660 EVT PtrVT = Op.getValueType();
1661 SDValue Callee;
1662 if (NeedsAlign) {
1663 Callee = DAG.getTargetExternalSymbol("__ve_grow_stack_align", PtrVT, 0);
1664 } else {
1665 Callee = DAG.getTargetExternalSymbol("__ve_grow_stack", PtrVT, 0);
1666 }
1667
1669 CLI.setDebugLoc(DL)
1670 .setChain(Chain)
1671 .setCallee(CallingConv::PreserveAll, RetTy, Callee, std::move(Args))
1672 .setDiscardResult(true);
1673 std::pair<SDValue, SDValue> pair = LowerCallTo(CLI);
1674 Chain = pair.second;
1675 SDValue Result = DAG.getNode(VEISD::GETSTACKTOP, DL, VT, Chain);
1676 if (NeedsAlign) {
1677 Result = DAG.getNode(ISD::ADD, DL, VT, Result,
1678 DAG.getConstant((Alignment->value() - 1ULL), DL, VT));
1679 Result = DAG.getNode(ISD::AND, DL, VT, Result,
1680 DAG.getConstant(~(Alignment->value() - 1ULL), DL, VT));
1681 }
1682 // Chain = Result.getValue(1);
1683 Chain = DAG.getCALLSEQ_END(Chain, 0, 0, SDValue(), DL);
1684
1685 SDValue Ops[2] = {Result, Chain};
1686 return DAG.getMergeValues(Ops, DL);
1687}
1688
1690 SelectionDAG &DAG) const {
1691 SDLoc DL(Op);
1692 return DAG.getNode(VEISD::EH_SJLJ_LONGJMP, DL, MVT::Other, Op.getOperand(0),
1693 Op.getOperand(1));
1694}
1695
1697 SelectionDAG &DAG) const {
1698 SDLoc DL(Op);
1699 return DAG.getNode(VEISD::EH_SJLJ_SETJMP, DL,
1700 DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0),
1701 Op.getOperand(1));
1702}
1703
1705 SelectionDAG &DAG) const {
1706 SDLoc DL(Op);
1707 return DAG.getNode(VEISD::EH_SJLJ_SETUP_DISPATCH, DL, MVT::Other,
1708 Op.getOperand(0));
1709}
1710
1712 const VETargetLowering &TLI,
1713 const VESubtarget *Subtarget) {
1714 SDLoc DL(Op);
1716 EVT PtrVT = TLI.getPointerTy(MF.getDataLayout());
1717
1718 MachineFrameInfo &MFI = MF.getFrameInfo();
1719 MFI.setFrameAddressIsTaken(true);
1720
1721 unsigned Depth = Op.getConstantOperandVal(0);
1722 const VERegisterInfo *RegInfo = Subtarget->getRegisterInfo();
1723 Register FrameReg = RegInfo->getFrameRegister(MF);
1724 SDValue FrameAddr =
1725 DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameReg, PtrVT);
1726 while (Depth--)
1727 FrameAddr = DAG.getLoad(Op.getValueType(), DL, DAG.getEntryNode(),
1728 FrameAddr, MachinePointerInfo());
1729 return FrameAddr;
1730}
1731
1733 const VETargetLowering &TLI,
1734 const VESubtarget *Subtarget) {
1736 MachineFrameInfo &MFI = MF.getFrameInfo();
1737 MFI.setReturnAddressIsTaken(true);
1738
1739 SDValue FrameAddr = lowerFRAMEADDR(Op, DAG, TLI, Subtarget);
1740
1741 SDLoc DL(Op);
1742 EVT VT = Op.getValueType();
1743 SDValue Offset = DAG.getConstant(8, DL, VT);
1744 return DAG.getLoad(VT, DL, DAG.getEntryNode(),
1745 DAG.getNode(ISD::ADD, DL, VT, FrameAddr, Offset),
1747}
1748
1750 SelectionDAG &DAG) const {
1751 SDLoc DL(Op);
1752 unsigned IntNo = Op.getConstantOperandVal(0);
1753 switch (IntNo) {
1754 default: // Don't custom lower most intrinsics.
1755 return SDValue();
1756 case Intrinsic::eh_sjlj_lsda: {
1758 MVT VT = Op.getSimpleValueType();
1759 const VETargetMachine *TM =
1760 static_cast<const VETargetMachine *>(&DAG.getTarget());
1761
1762 // Create GCC_except_tableXX string. The real symbol for that will be
1763 // generated in EHStreamer::emitExceptionTable() later. So, we just
1764 // borrow it's name here.
1765 TM->getStrList()->push_back(std::string(
1766 (Twine("GCC_except_table") + Twine(MF.getFunctionNumber())).str()));
1767 SDValue Addr =
1768 DAG.getTargetExternalSymbol(TM->getStrList()->back().c_str(), VT, 0);
1769 if (isPositionIndependent()) {
1771 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, VT);
1772 return DAG.getNode(ISD::ADD, DL, VT, GlobalBase, Addr);
1773 }
1774 return makeHiLoPair(Addr, VE::S_HI32, VE::S_LO32, DAG);
1775 }
1776 }
1777}
1778
1779static bool getUniqueInsertion(SDNode *N, unsigned &UniqueIdx) {
1780 if (!isa<BuildVectorSDNode>(N))
1781 return false;
1782 const auto *BVN = cast<BuildVectorSDNode>(N);
1783
1784 // Find first non-undef insertion.
1785 unsigned Idx;
1786 for (Idx = 0; Idx < BVN->getNumOperands(); ++Idx) {
1787 auto ElemV = BVN->getOperand(Idx);
1788 if (!ElemV->isUndef())
1789 break;
1790 }
1791 // Catch the (hypothetical) all-undef case.
1792 if (Idx == BVN->getNumOperands())
1793 return false;
1794 // Remember insertion.
1795 UniqueIdx = Idx++;
1796 // Verify that all other insertions are undef.
1797 for (; Idx < BVN->getNumOperands(); ++Idx) {
1798 auto ElemV = BVN->getOperand(Idx);
1799 if (!ElemV->isUndef())
1800 return false;
1801 }
1802 return true;
1803}
1804
1806 if (auto *BuildVec = dyn_cast<BuildVectorSDNode>(N)) {
1807 return BuildVec->getSplatValue();
1808 }
1809 return SDValue();
1810}
1811
1813 SelectionDAG &DAG) const {
1814 VECustomDAG CDAG(DAG, Op);
1815 MVT ResultVT = Op.getSimpleValueType();
1816
1817 // If there is just one element, expand to INSERT_VECTOR_ELT.
1818 unsigned UniqueIdx;
1819 if (getUniqueInsertion(Op.getNode(), UniqueIdx)) {
1820 SDValue AccuV = CDAG.getUNDEF(Op.getValueType());
1821 auto ElemV = Op->getOperand(UniqueIdx);
1822 SDValue IdxV = CDAG.getConstant(UniqueIdx, MVT::i64);
1823 return CDAG.getNode(ISD::INSERT_VECTOR_ELT, ResultVT, {AccuV, ElemV, IdxV});
1824 }
1825
1826 // Else emit a broadcast.
1827 if (SDValue ScalarV = getSplatValue(Op.getNode())) {
1828 unsigned NumEls = ResultVT.getVectorNumElements();
1829 auto AVL = CDAG.getConstant(NumEls, MVT::i32);
1830 return CDAG.getBroadcast(ResultVT, ScalarV, AVL);
1831 }
1832
1833 // Expand
1834 return SDValue();
1835}
1836
1839 // Custom legalization on VVP_* and VEC_* opcodes is required to pack-legalize
1840 // these operations (transform nodes such that their AVL parameter refers to
1841 // packs of 64bit, instead of number of elements.
1842
1843 // Packing opcodes are created with a pack-legal AVL (LEGALAVL). No need to
1844 // re-visit them.
1845 if (isPackingSupportOpcode(Op.getOpcode()))
1846 return Legal;
1847
1848 // Custom lower to legalize AVL for packed mode.
1849 if (isVVPOrVEC(Op.getOpcode()))
1850 return Custom;
1851 return Legal;
1852}
1853
1855 LLVM_DEBUG(dbgs() << "::LowerOperation "; Op.dump(&DAG));
1856 unsigned Opcode = Op.getOpcode();
1857
1858 /// Scalar isel.
1859 switch (Opcode) {
1860 case ISD::ATOMIC_FENCE:
1861 return lowerATOMIC_FENCE(Op, DAG);
1862 case ISD::ATOMIC_SWAP:
1863 return lowerATOMIC_SWAP(Op, DAG);
1864 case ISD::BlockAddress:
1865 return lowerBlockAddress(Op, DAG);
1866 case ISD::ConstantPool:
1867 return lowerConstantPool(Op, DAG);
1869 return lowerDYNAMIC_STACKALLOC(Op, DAG);
1871 return lowerEH_SJLJ_LONGJMP(Op, DAG);
1873 return lowerEH_SJLJ_SETJMP(Op, DAG);
1875 return lowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
1876 case ISD::FRAMEADDR:
1877 return lowerFRAMEADDR(Op, DAG, *this, Subtarget);
1878 case ISD::GlobalAddress:
1879 return lowerGlobalAddress(Op, DAG);
1881 return lowerGlobalTLSAddress(Op, DAG);
1883 return lowerINTRINSIC_WO_CHAIN(Op, DAG);
1884 case ISD::JumpTable:
1885 return lowerJumpTable(Op, DAG);
1886 case ISD::LOAD:
1887 return lowerLOAD(Op, DAG);
1888 case ISD::RETURNADDR:
1889 return lowerRETURNADDR(Op, DAG, *this, Subtarget);
1890 case ISD::BUILD_VECTOR:
1891 return lowerBUILD_VECTOR(Op, DAG);
1892 case ISD::STORE:
1893 return lowerSTORE(Op, DAG);
1894 case ISD::VASTART:
1895 return lowerVASTART(Op, DAG);
1896 case ISD::VAARG:
1897 return lowerVAARG(Op, DAG);
1898
1900 return lowerINSERT_VECTOR_ELT(Op, DAG);
1902 return lowerEXTRACT_VECTOR_ELT(Op, DAG);
1903 }
1904
1905 /// Vector isel.
1906 if (ISD::isVPOpcode(Opcode))
1907 return lowerToVVP(Op, DAG);
1908
1909 switch (Opcode) {
1910 default:
1911 llvm_unreachable("Should not custom lower this!");
1912
1913 // Legalize the AVL of this internal node.
1915#define ADD_VVP_OP(VVP_NAME, ...) case VEISD::VVP_NAME:
1916#include "VVPNodes.def"
1917 // AVL already legalized.
1918 if (getAnnotatedNodeAVL(Op).second)
1919 return Op;
1920 return legalizeInternalVectorOp(Op, DAG);
1921
1922 // Translate into a VEC_*/VVP_* layer operation.
1923 case ISD::MLOAD:
1924 case ISD::MSTORE:
1925#define ADD_VVP_OP(VVP_NAME, ISD_NAME) case ISD::ISD_NAME:
1926#include "VVPNodes.def"
1927 if (isMaskArithmetic(Op) && isPackedVectorType(Op.getValueType()))
1928 return splitMaskArithmetic(Op, DAG);
1929 return lowerToVVP(Op, DAG);
1930 }
1931}
1932/// } Custom Lower
1933
1936 SelectionDAG &DAG) const {
1937 switch (N->getOpcode()) {
1938 case ISD::ATOMIC_SWAP:
1939 // Let LLVM expand atomic swap instruction through LowerOperation.
1940 return;
1941 default:
1942 LLVM_DEBUG(N->dumpr(&DAG));
1943 llvm_unreachable("Do not know how to custom type legalize this operation!");
1944 }
1945}
1946
1947/// JumpTable for VE.
1948///
1949/// VE cannot generate relocatable symbol in jump table. VE cannot
1950/// generate expressions using symbols in both text segment and data
1951/// segment like below.
1952/// .4byte .LBB0_2-.LJTI0_0
1953/// So, we generate offset from the top of function like below as
1954/// a custom label.
1955/// .4byte .LBB0_2-<function name>
1956
1958 // Use custom label for PIC.
1961
1962 // Otherwise, use the normal jump table encoding heuristics.
1964}
1965
1967 const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB,
1968 unsigned Uid, MCContext &Ctx) const {
1970
1971 // Generate custom label for PIC like below.
1972 // .4bytes .LBB0_2-<function name>
1973 const auto *Value = MCSymbolRefExpr::create(MBB->getSymbol(), Ctx);
1975 const auto *Base = MCSymbolRefExpr::create(Sym, Ctx);
1976 return MCBinaryExpr::createSub(Value, Base, Ctx);
1977}
1978
1980 SelectionDAG &DAG) const {
1982 SDLoc DL(Table);
1984 assert(Function != nullptr);
1985 auto PtrTy = getPointerTy(DAG.getDataLayout(), Function->getAddressSpace());
1986
1987 // In the jump table, we have following values in PIC mode.
1988 // .4bytes .LBB0_2-<function name>
1989 // We need to add this value and the address of this function to generate
1990 // .LBB0_2 label correctly under PIC mode. So, we want to generate following
1991 // instructions:
1992 // lea %reg, fun@gotoff_lo
1993 // and %reg, %reg, (32)0
1994 // lea.sl %reg, fun@gotoff_hi(%reg, %got)
1995 // In order to do so, we need to genarate correctly marked DAG node using
1996 // makeHiLoPair.
1997 SDValue Op = DAG.getGlobalAddress(Function, DL, PtrTy);
1999 SDValue GlobalBase = DAG.getNode(VEISD::GLOBAL_BASE_REG, DL, PtrTy);
2000 return DAG.getNode(ISD::ADD, DL, PtrTy, GlobalBase, HiLo);
2001}
2002
2005 MachineBasicBlock *TargetBB,
2006 const DebugLoc &DL) const {
2009 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2010
2011 const TargetRegisterClass *RC = &VE::I64RegClass;
2012 Register Tmp1 = MRI.createVirtualRegister(RC);
2013 Register Tmp2 = MRI.createVirtualRegister(RC);
2014 Register Result = MRI.createVirtualRegister(RC);
2015
2016 if (isPositionIndependent()) {
2017 // Create following instructions for local linkage PIC code.
2018 // lea %Tmp1, TargetBB@gotoff_lo
2019 // and %Tmp2, %Tmp1, (32)0
2020 // lea.sl %Result, TargetBB@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2021 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2022 .addImm(0)
2023 .addImm(0)
2024 .addMBB(TargetBB, VE::S_GOTOFF_LO32);
2025 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2026 .addReg(Tmp1, getKillRegState(true))
2027 .addImm(M0(32));
2028 BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Result)
2029 .addReg(VE::SX15)
2030 .addReg(Tmp2, getKillRegState(true))
2031 .addMBB(TargetBB, VE::S_GOTOFF_HI32);
2032 } else {
2033 // Create following instructions for non-PIC code.
2034 // lea %Tmp1, TargetBB@lo
2035 // and %Tmp2, %Tmp1, (32)0
2036 // lea.sl %Result, TargetBB@hi(%Tmp2)
2037 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2038 .addImm(0)
2039 .addImm(0)
2040 .addMBB(TargetBB, VE::S_LO32);
2041 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2042 .addReg(Tmp1, getKillRegState(true))
2043 .addImm(M0(32));
2044 BuildMI(MBB, I, DL, TII->get(VE::LEASLrii), Result)
2045 .addReg(Tmp2, getKillRegState(true))
2046 .addImm(0)
2047 .addMBB(TargetBB, VE::S_HI32);
2048 }
2049 return Result;
2050}
2051
2054 StringRef Symbol, const DebugLoc &DL,
2055 bool IsLocal = false,
2056 bool IsCall = false) const {
2059 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2060
2061 const TargetRegisterClass *RC = &VE::I64RegClass;
2062 Register Result = MRI.createVirtualRegister(RC);
2063
2064 if (isPositionIndependent()) {
2065 if (IsCall && !IsLocal) {
2066 // Create following instructions for non-local linkage PIC code function
2067 // calls. These instructions uses IC and magic number -24, so we expand
2068 // them in VEAsmPrinter.cpp from GETFUNPLT pseudo instruction.
2069 // lea %Reg, Symbol@plt_lo(-24)
2070 // and %Reg, %Reg, (32)0
2071 // sic %s16
2072 // lea.sl %Result, Symbol@plt_hi(%Reg, %s16) ; %s16 is PLT
2073 BuildMI(MBB, I, DL, TII->get(VE::GETFUNPLT), Result)
2074 .addExternalSymbol("abort");
2075 } else if (IsLocal) {
2076 Register Tmp1 = MRI.createVirtualRegister(RC);
2077 Register Tmp2 = MRI.createVirtualRegister(RC);
2078 // Create following instructions for local linkage PIC code.
2079 // lea %Tmp1, Symbol@gotoff_lo
2080 // and %Tmp2, %Tmp1, (32)0
2081 // lea.sl %Result, Symbol@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2082 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2083 .addImm(0)
2084 .addImm(0)
2085 .addExternalSymbol(Symbol.data(), VE::S_GOTOFF_LO32);
2086 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2087 .addReg(Tmp1, getKillRegState(true))
2088 .addImm(M0(32));
2089 BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Result)
2090 .addReg(VE::SX15)
2091 .addReg(Tmp2, getKillRegState(true))
2092 .addExternalSymbol(Symbol.data(), VE::S_GOTOFF_HI32);
2093 } else {
2094 Register Tmp1 = MRI.createVirtualRegister(RC);
2095 Register Tmp2 = MRI.createVirtualRegister(RC);
2096 // Create following instructions for not local linkage PIC code.
2097 // lea %Tmp1, Symbol@got_lo
2098 // and %Tmp2, %Tmp1, (32)0
2099 // lea.sl %Tmp3, Symbol@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2100 // ld %Result, 0(%Tmp3)
2101 Register Tmp3 = MRI.createVirtualRegister(RC);
2102 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2103 .addImm(0)
2104 .addImm(0)
2105 .addExternalSymbol(Symbol.data(), VE::S_GOT_LO32);
2106 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2107 .addReg(Tmp1, getKillRegState(true))
2108 .addImm(M0(32));
2109 BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Tmp3)
2110 .addReg(VE::SX15)
2111 .addReg(Tmp2, getKillRegState(true))
2112 .addExternalSymbol(Symbol.data(), VE::S_GOT_HI32);
2113 BuildMI(MBB, I, DL, TII->get(VE::LDrii), Result)
2114 .addReg(Tmp3, getKillRegState(true))
2115 .addImm(0)
2116 .addImm(0);
2117 }
2118 } else {
2119 Register Tmp1 = MRI.createVirtualRegister(RC);
2120 Register Tmp2 = MRI.createVirtualRegister(RC);
2121 // Create following instructions for non-PIC code.
2122 // lea %Tmp1, Symbol@lo
2123 // and %Tmp2, %Tmp1, (32)0
2124 // lea.sl %Result, Symbol@hi(%Tmp2)
2125 BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
2126 .addImm(0)
2127 .addImm(0)
2128 .addExternalSymbol(Symbol.data(), VE::S_LO32);
2129 BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
2130 .addReg(Tmp1, getKillRegState(true))
2131 .addImm(M0(32));
2132 BuildMI(MBB, I, DL, TII->get(VE::LEASLrii), Result)
2133 .addReg(Tmp2, getKillRegState(true))
2134 .addImm(0)
2135 .addExternalSymbol(Symbol.data(), VE::S_HI32);
2136 }
2137 return Result;
2138}
2139
2142 MachineBasicBlock *DispatchBB,
2143 int FI, int Offset) const {
2144 DebugLoc DL = MI.getDebugLoc();
2145 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2146
2147 Register LabelReg =
2149
2150 // Store an address of DispatchBB to a given jmpbuf[1] where has next IC
2151 // referenced by longjmp (throw) later.
2152 MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
2153 addFrameReference(MIB, FI, Offset); // jmpbuf[1]
2154 MIB.addReg(LabelReg, getKillRegState(true));
2155}
2156
2159 MachineBasicBlock *MBB) const {
2160 DebugLoc DL = MI.getDebugLoc();
2161 MachineFunction *MF = MBB->getParent();
2162 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
2163 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
2165
2166 const BasicBlock *BB = MBB->getBasicBlock();
2168
2169 // Memory Reference.
2170 SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands());
2171 Register BufReg = MI.getOperand(1).getReg();
2172
2173 Register DstReg;
2174
2175 DstReg = MI.getOperand(0).getReg();
2176 const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
2177 assert(TRI->isTypeLegalForClass(*RC, MVT::i32) && "Invalid destination!");
2178 (void)TRI;
2179 Register MainDestReg = MRI.createVirtualRegister(RC);
2180 Register RestoreDestReg = MRI.createVirtualRegister(RC);
2181
2182 // For `v = call @llvm.eh.sjlj.setjmp(buf)`, we generate following
2183 // instructions. SP/FP must be saved in jmpbuf before `llvm.eh.sjlj.setjmp`.
2184 //
2185 // ThisMBB:
2186 // buf[3] = %s17 iff %s17 is used as BP
2187 // buf[1] = RestoreMBB as IC after longjmp
2188 // # SjLjSetup RestoreMBB
2189 //
2190 // MainMBB:
2191 // v_main = 0
2192 //
2193 // SinkMBB:
2194 // v = phi(v_main, MainMBB, v_restore, RestoreMBB)
2195 // ...
2196 //
2197 // RestoreMBB:
2198 // %s17 = buf[3] = iff %s17 is used as BP
2199 // v_restore = 1
2200 // goto SinkMBB
2201
2202 MachineBasicBlock *ThisMBB = MBB;
2203 MachineBasicBlock *MainMBB = MF->CreateMachineBasicBlock(BB);
2204 MachineBasicBlock *SinkMBB = MF->CreateMachineBasicBlock(BB);
2205 MachineBasicBlock *RestoreMBB = MF->CreateMachineBasicBlock(BB);
2206 MF->insert(I, MainMBB);
2207 MF->insert(I, SinkMBB);
2208 MF->push_back(RestoreMBB);
2209 RestoreMBB->setMachineBlockAddressTaken();
2210
2211 // Transfer the remainder of BB and its successor edges to SinkMBB.
2212 SinkMBB->splice(SinkMBB->begin(), MBB,
2213 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
2215
2216 // ThisMBB:
2217 Register LabelReg =
2219
2220 // Store BP in buf[3] iff this function is using BP.
2221 const VEFrameLowering *TFI = Subtarget->getFrameLowering();
2222 if (TFI->hasBP(*MF)) {
2223 MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
2224 MIB.addReg(BufReg);
2225 MIB.addImm(0);
2226 MIB.addImm(24);
2227 MIB.addReg(VE::SX17);
2228 MIB.setMemRefs(MMOs);
2229 }
2230
2231 // Store IP in buf[1].
2232 MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
2233 MIB.add(MI.getOperand(1)); // we can preserve the kill flags here.
2234 MIB.addImm(0);
2235 MIB.addImm(8);
2236 MIB.addReg(LabelReg, getKillRegState(true));
2237 MIB.setMemRefs(MMOs);
2238
2239 // SP/FP are already stored in jmpbuf before `llvm.eh.sjlj.setjmp`.
2240
2241 // Insert setup.
2242 MIB =
2243 BuildMI(*ThisMBB, MI, DL, TII->get(VE::EH_SjLj_Setup)).addMBB(RestoreMBB);
2244
2245 const VERegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2246 MIB.addRegMask(RegInfo->getNoPreservedMask());
2247 ThisMBB->addSuccessor(MainMBB);
2248 ThisMBB->addSuccessor(RestoreMBB);
2249
2250 // MainMBB:
2251 BuildMI(MainMBB, DL, TII->get(VE::LEAzii), MainDestReg)
2252 .addImm(0)
2253 .addImm(0)
2254 .addImm(0);
2255 MainMBB->addSuccessor(SinkMBB);
2256
2257 // SinkMBB:
2258 BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII->get(VE::PHI), DstReg)
2259 .addReg(MainDestReg)
2260 .addMBB(MainMBB)
2261 .addReg(RestoreDestReg)
2262 .addMBB(RestoreMBB);
2263
2264 // RestoreMBB:
2265 // Restore BP from buf[3] iff this function is using BP. The address of
2266 // buf is in SX10.
2267 // FIXME: Better to not use SX10 here
2268 if (TFI->hasBP(*MF)) {
2270 BuildMI(RestoreMBB, DL, TII->get(VE::LDrii), VE::SX17);
2271 MIB.addReg(VE::SX10);
2272 MIB.addImm(0);
2273 MIB.addImm(24);
2274 MIB.setMemRefs(MMOs);
2275 }
2276 BuildMI(RestoreMBB, DL, TII->get(VE::LEAzii), RestoreDestReg)
2277 .addImm(0)
2278 .addImm(0)
2279 .addImm(1);
2280 BuildMI(RestoreMBB, DL, TII->get(VE::BRCFLa_t)).addMBB(SinkMBB);
2281 RestoreMBB->addSuccessor(SinkMBB);
2282
2283 MI.eraseFromParent();
2284 return SinkMBB;
2285}
2286
2289 MachineBasicBlock *MBB) const {
2290 DebugLoc DL = MI.getDebugLoc();
2291 MachineFunction *MF = MBB->getParent();
2292 const TargetInstrInfo *TII = Subtarget->getInstrInfo();
2294
2295 // Memory Reference.
2296 SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands());
2297 Register BufReg = MI.getOperand(0).getReg();
2298
2299 Register Tmp = MRI.createVirtualRegister(&VE::I64RegClass);
2300 // Since FP is only updated here but NOT referenced, it's treated as GPR.
2301 Register FP = VE::SX9;
2302 Register SP = VE::SX11;
2303
2305
2306 MachineBasicBlock *ThisMBB = MBB;
2307
2308 // For `call @llvm.eh.sjlj.longjmp(buf)`, we generate following instructions.
2309 //
2310 // ThisMBB:
2311 // %fp = load buf[0]
2312 // %jmp = load buf[1]
2313 // %s10 = buf ; Store an address of buf to SX10 for RestoreMBB
2314 // %sp = load buf[2] ; generated by llvm.eh.sjlj.setjmp.
2315 // jmp %jmp
2316
2317 // Reload FP.
2318 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), FP);
2319 MIB.addReg(BufReg);
2320 MIB.addImm(0);
2321 MIB.addImm(0);
2322 MIB.setMemRefs(MMOs);
2323
2324 // Reload IP.
2325 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), Tmp);
2326 MIB.addReg(BufReg);
2327 MIB.addImm(0);
2328 MIB.addImm(8);
2329 MIB.setMemRefs(MMOs);
2330
2331 // Copy BufReg to SX10 for later use in setjmp.
2332 // FIXME: Better to not use SX10 here
2333 BuildMI(*ThisMBB, MI, DL, TII->get(VE::ORri), VE::SX10)
2334 .addReg(BufReg)
2335 .addImm(0);
2336
2337 // Reload SP.
2338 MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), SP);
2339 MIB.add(MI.getOperand(0)); // we can preserve the kill flags here.
2340 MIB.addImm(0);
2341 MIB.addImm(16);
2342 MIB.setMemRefs(MMOs);
2343
2344 // Jump.
2345 BuildMI(*ThisMBB, MI, DL, TII->get(VE::BCFLari_t))
2346 .addReg(Tmp, getKillRegState(true))
2347 .addImm(0);
2348
2349 MI.eraseFromParent();
2350 return ThisMBB;
2351}
2352
2355 MachineBasicBlock *BB) const {
2356 DebugLoc DL = MI.getDebugLoc();
2357 MachineFunction *MF = BB->getParent();
2358 MachineFrameInfo &MFI = MF->getFrameInfo();
2360 const VEInstrInfo *TII = Subtarget->getInstrInfo();
2361 int FI = MFI.getFunctionContextIndex();
2362
2363 // Get a mapping of the call site numbers to all of the landing pads they're
2364 // associated with.
2366 unsigned MaxCSNum = 0;
2367 for (auto &MBB : *MF) {
2368 if (!MBB.isEHPad())
2369 continue;
2370
2371 MCSymbol *Sym = nullptr;
2372 for (const auto &MI : MBB) {
2373 if (MI.isDebugInstr())
2374 continue;
2375
2376 assert(MI.isEHLabel() && "expected EH_LABEL");
2377 Sym = MI.getOperand(0).getMCSymbol();
2378 break;
2379 }
2380
2381 if (!MF->hasCallSiteLandingPad(Sym))
2382 continue;
2383
2384 for (unsigned CSI : MF->getCallSiteLandingPad(Sym)) {
2385 CallSiteNumToLPad[CSI].push_back(&MBB);
2386 MaxCSNum = std::max(MaxCSNum, CSI);
2387 }
2388 }
2389
2390 // Get an ordered list of the machine basic blocks for the jump table.
2391 std::vector<MachineBasicBlock *> LPadList;
2393 LPadList.reserve(CallSiteNumToLPad.size());
2394
2395 for (unsigned CSI = 1; CSI <= MaxCSNum; ++CSI) {
2396 for (auto &LP : CallSiteNumToLPad[CSI]) {
2397 LPadList.push_back(LP);
2398 InvokeBBs.insert_range(LP->predecessors());
2399 }
2400 }
2401
2402 assert(!LPadList.empty() &&
2403 "No landing pad destinations for the dispatch jump table!");
2404
2405 // The %fn_context is allocated like below (from --print-after=sjljehprepare):
2406 // %fn_context = alloca { i8*, i64, [4 x i64], i8*, i8*, [5 x i8*] }
2407 //
2408 // This `[5 x i8*]` is jmpbuf, so jmpbuf[1] is FI+72.
2409 // First `i64` is callsite, so callsite is FI+8.
2410 static const int OffsetIC = 72;
2411 static const int OffsetCS = 8;
2412
2413 // Create the MBBs for the dispatch code like following:
2414 //
2415 // ThisMBB:
2416 // Prepare DispatchBB address and store it to buf[1].
2417 // ...
2418 //
2419 // DispatchBB:
2420 // %s15 = GETGOT iff isPositionIndependent
2421 // %callsite = load callsite
2422 // brgt.l.t #size of callsites, %callsite, DispContBB
2423 //
2424 // TrapBB:
2425 // Call abort.
2426 //
2427 // DispContBB:
2428 // %breg = address of jump table
2429 // %pc = load and calculate next pc from %breg and %callsite
2430 // jmp %pc
2431
2432 // Shove the dispatch's address into the return slot in the function context.
2433 MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
2434 DispatchBB->setIsEHPad(true);
2435
2436 // Trap BB will causes trap like `assert(0)`.
2438 DispatchBB->addSuccessor(TrapBB);
2439
2440 MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock();
2441 DispatchBB->addSuccessor(DispContBB);
2442
2443 // Insert MBBs.
2444 MF->push_back(DispatchBB);
2445 MF->push_back(DispContBB);
2446 MF->push_back(TrapBB);
2447
2448 // Insert code to call abort in the TrapBB.
2449 Register Abort = prepareSymbol(*TrapBB, TrapBB->end(), "abort", DL,
2450 /* Local */ false, /* Call */ true);
2451 BuildMI(TrapBB, DL, TII->get(VE::BSICrii), VE::SX10)
2452 .addReg(Abort, getKillRegState(true))
2453 .addImm(0)
2454 .addImm(0);
2455
2456 // Insert code into the entry block that creates and registers the function
2457 // context.
2458 setupEntryBlockForSjLj(MI, BB, DispatchBB, FI, OffsetIC);
2459
2460 // Create the jump table and associated information
2461 unsigned JTE = getJumpTableEncoding();
2463 unsigned MJTI = JTI->createJumpTableIndex(LPadList);
2464
2465 const VERegisterInfo &RI = TII->getRegisterInfo();
2466 // Add a register mask with no preserved registers. This results in all
2467 // registers being marked as clobbered.
2468 BuildMI(DispatchBB, DL, TII->get(VE::NOP))
2470
2471 if (isPositionIndependent()) {
2472 // Force to generate GETGOT, since current implementation doesn't store GOT
2473 // register.
2474 BuildMI(DispatchBB, DL, TII->get(VE::GETGOT), VE::SX15);
2475 }
2476
2477 // IReg is used as an index in a memory operand and therefore can't be SP
2478 const TargetRegisterClass *RC = &VE::I64RegClass;
2479 Register IReg = MRI.createVirtualRegister(RC);
2480 addFrameReference(BuildMI(DispatchBB, DL, TII->get(VE::LDLZXrii), IReg), FI,
2481 OffsetCS);
2482 if (LPadList.size() < 64) {
2483 BuildMI(DispatchBB, DL, TII->get(VE::BRCFLir_t))
2485 .addImm(LPadList.size())
2486 .addReg(IReg)
2487 .addMBB(TrapBB);
2488 } else {
2489 assert(LPadList.size() <= 0x7FFFFFFF && "Too large Landing Pad!");
2490 Register TmpReg = MRI.createVirtualRegister(RC);
2491 BuildMI(DispatchBB, DL, TII->get(VE::LEAzii), TmpReg)
2492 .addImm(0)
2493 .addImm(0)
2494 .addImm(LPadList.size());
2495 BuildMI(DispatchBB, DL, TII->get(VE::BRCFLrr_t))
2497 .addReg(TmpReg, getKillRegState(true))
2498 .addReg(IReg)
2499 .addMBB(TrapBB);
2500 }
2501
2502 Register BReg = MRI.createVirtualRegister(RC);
2503 Register Tmp1 = MRI.createVirtualRegister(RC);
2504 Register Tmp2 = MRI.createVirtualRegister(RC);
2505
2506 if (isPositionIndependent()) {
2507 // Create following instructions for local linkage PIC code.
2508 // lea %Tmp1, .LJTI0_0@gotoff_lo
2509 // and %Tmp2, %Tmp1, (32)0
2510 // lea.sl %BReg, .LJTI0_0@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
2511 BuildMI(DispContBB, DL, TII->get(VE::LEAzii), Tmp1)
2512 .addImm(0)
2513 .addImm(0)
2515 BuildMI(DispContBB, DL, TII->get(VE::ANDrm), Tmp2)
2516 .addReg(Tmp1, getKillRegState(true))
2517 .addImm(M0(32));
2518 BuildMI(DispContBB, DL, TII->get(VE::LEASLrri), BReg)
2519 .addReg(VE::SX15)
2520 .addReg(Tmp2, getKillRegState(true))
2522 } else {
2523 // Create following instructions for non-PIC code.
2524 // lea %Tmp1, .LJTI0_0@lo
2525 // and %Tmp2, %Tmp1, (32)0
2526 // lea.sl %BReg, .LJTI0_0@hi(%Tmp2)
2527 BuildMI(DispContBB, DL, TII->get(VE::LEAzii), Tmp1)
2528 .addImm(0)
2529 .addImm(0)
2531 BuildMI(DispContBB, DL, TII->get(VE::ANDrm), Tmp2)
2532 .addReg(Tmp1, getKillRegState(true))
2533 .addImm(M0(32));
2534 BuildMI(DispContBB, DL, TII->get(VE::LEASLrii), BReg)
2535 .addReg(Tmp2, getKillRegState(true))
2536 .addImm(0)
2538 }
2539
2540 switch (JTE) {
2542 // Generate simple block address code for no-PIC model.
2543 // sll %Tmp1, %IReg, 3
2544 // lds %TReg, 0(%Tmp1, %BReg)
2545 // bcfla %TReg
2546
2547 Register TReg = MRI.createVirtualRegister(RC);
2548 Register Tmp1 = MRI.createVirtualRegister(RC);
2549
2550 BuildMI(DispContBB, DL, TII->get(VE::SLLri), Tmp1)
2551 .addReg(IReg, getKillRegState(true))
2552 .addImm(3);
2553 BuildMI(DispContBB, DL, TII->get(VE::LDrri), TReg)
2554 .addReg(BReg, getKillRegState(true))
2555 .addReg(Tmp1, getKillRegState(true))
2556 .addImm(0);
2557 BuildMI(DispContBB, DL, TII->get(VE::BCFLari_t))
2558 .addReg(TReg, getKillRegState(true))
2559 .addImm(0);
2560 break;
2561 }
2563 // Generate block address code using differences from the function pointer
2564 // for PIC model.
2565 // sll %Tmp1, %IReg, 2
2566 // ldl.zx %OReg, 0(%Tmp1, %BReg)
2567 // Prepare function address in BReg2.
2568 // adds.l %TReg, %BReg2, %OReg
2569 // bcfla %TReg
2570
2572 Register OReg = MRI.createVirtualRegister(RC);
2573 Register TReg = MRI.createVirtualRegister(RC);
2574 Register Tmp1 = MRI.createVirtualRegister(RC);
2575
2576 BuildMI(DispContBB, DL, TII->get(VE::SLLri), Tmp1)
2577 .addReg(IReg, getKillRegState(true))
2578 .addImm(2);
2579 BuildMI(DispContBB, DL, TII->get(VE::LDLZXrri), OReg)
2580 .addReg(BReg, getKillRegState(true))
2581 .addReg(Tmp1, getKillRegState(true))
2582 .addImm(0);
2583 Register BReg2 =
2584 prepareSymbol(*DispContBB, DispContBB->end(),
2585 DispContBB->getParent()->getName(), DL, /* Local */ true);
2586 BuildMI(DispContBB, DL, TII->get(VE::ADDSLrr), TReg)
2587 .addReg(OReg, getKillRegState(true))
2588 .addReg(BReg2, getKillRegState(true));
2589 BuildMI(DispContBB, DL, TII->get(VE::BCFLari_t))
2590 .addReg(TReg, getKillRegState(true))
2591 .addImm(0);
2592 break;
2593 }
2594 default:
2595 llvm_unreachable("Unexpected jump table encoding");
2596 }
2597
2598 // Add the jump table entries as successors to the MBB.
2600 for (auto &LP : LPadList)
2601 if (SeenMBBs.insert(LP).second)
2602 DispContBB->addSuccessor(LP);
2603
2604 // N.B. the order the invoke BBs are processed in doesn't matter here.
2606 const MCPhysReg *SavedRegs = MF->getRegInfo().getCalleeSavedRegs();
2607 for (MachineBasicBlock *MBB : InvokeBBs) {
2608 // Remove the landing pad successor from the invoke block and replace it
2609 // with the new dispatch block.
2610 // Keep a copy of Successors since it's modified inside the loop.
2612 MBB->succ_rend());
2613 // FIXME: Avoid quadratic complexity.
2614 for (auto *MBBS : Successors) {
2615 if (MBBS->isEHPad()) {
2616 MBB->removeSuccessor(MBBS);
2617 MBBLPads.push_back(MBBS);
2618 }
2619 }
2620
2621 MBB->addSuccessor(DispatchBB);
2622
2623 // Find the invoke call and mark all of the callee-saved registers as
2624 // 'implicit defined' so that they're spilled. This prevents code from
2625 // moving instructions to before the EH block, where they will never be
2626 // executed.
2627 for (auto &II : reverse(*MBB)) {
2628 if (!II.isCall())
2629 continue;
2630
2631 DenseSet<Register> DefRegs;
2632 for (auto &MOp : II.operands())
2633 if (MOp.isReg())
2634 DefRegs.insert(MOp.getReg());
2635
2636 MachineInstrBuilder MIB(*MF, &II);
2637 for (unsigned RI = 0; SavedRegs[RI]; ++RI) {
2638 Register Reg = SavedRegs[RI];
2639 if (!DefRegs.contains(Reg))
2641 }
2642
2643 break;
2644 }
2645 }
2646
2647 // Mark all former landing pads as non-landing pads. The dispatch is the only
2648 // landing pad now.
2649 for (auto &LP : MBBLPads)
2650 LP->setIsEHPad(false);
2651
2652 // The instruction is gone now.
2653 MI.eraseFromParent();
2654 return BB;
2655}
2656
2659 MachineBasicBlock *BB) const {
2660 switch (MI.getOpcode()) {
2661 default:
2662 llvm_unreachable("Unknown Custom Instruction!");
2663 case VE::EH_SjLj_LongJmp:
2664 return emitEHSjLjLongJmp(MI, BB);
2665 case VE::EH_SjLj_SetJmp:
2666 return emitEHSjLjSetJmp(MI, BB);
2667 case VE::EH_SjLj_Setup_Dispatch:
2668 return emitSjLjDispatchBlock(MI, BB);
2669 }
2670}
2671
2672static bool isSimm7(SDValue V) {
2673 EVT VT = V.getValueType();
2674 if (VT.isVector())
2675 return false;
2676
2677 if (VT.isInteger()) {
2678 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V))
2679 return isInt<7>(C->getSExtValue());
2680 } else if (VT.isFloatingPoint()) {
2681 if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(V)) {
2682 if (VT == MVT::f32 || VT == MVT::f64) {
2683 const APInt &Imm = C->getValueAPF().bitcastToAPInt();
2684 uint64_t Val = Imm.getSExtValue();
2685 if (Imm.getBitWidth() == 32)
2686 Val <<= 32; // Immediate value of float place at higher bits on VE.
2687 return isInt<7>(Val);
2688 }
2689 }
2690 }
2691 return false;
2692}
2693
2694static bool isMImm(SDValue V) {
2695 EVT VT = V.getValueType();
2696 if (VT.isVector())
2697 return false;
2698
2699 if (VT.isInteger()) {
2700 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(V))
2701 return isMImmVal(getImmVal(C));
2702 } else if (VT.isFloatingPoint()) {
2703 if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(V)) {
2704 if (VT == MVT::f32) {
2705 // Float value places at higher bits, so ignore lower 32 bits.
2706 return isMImm32Val(getFpImmVal(C) >> 32);
2707 } else if (VT == MVT::f64) {
2708 return isMImmVal(getFpImmVal(C));
2709 }
2710 }
2711 }
2712 return false;
2713}
2714
2715static unsigned decideComp(EVT SrcVT, ISD::CondCode CC) {
2716 if (SrcVT.isFloatingPoint()) {
2717 if (SrcVT == MVT::f128)
2718 return VEISD::CMPQ;
2719 return VEISD::CMPF;
2720 }
2721 return isSignedIntSetCC(CC) ? VEISD::CMPI : VEISD::CMPU;
2722}
2723
2724static EVT decideCompType(EVT SrcVT) {
2725 if (SrcVT == MVT::f128)
2726 return MVT::f64;
2727 return SrcVT;
2728}
2729
2731 bool WithCMov) {
2732 if (SrcVT.isFloatingPoint()) {
2733 // For the case of floating point setcc, only unordered comparison
2734 // or general comparison with -enable-no-nans-fp-math option reach
2735 // here, so it is safe even if values are NaN. Only f128 doesn't
2736 // safe since VE uses f64 result of f128 comparison.
2737 return SrcVT != MVT::f128;
2738 }
2739 if (isIntEqualitySetCC(CC)) {
2740 // For the case of equal or not equal, it is safe without comparison with 0.
2741 return true;
2742 }
2743 if (WithCMov) {
2744 // For the case of integer setcc with cmov, all signed comparison with 0
2745 // are safe.
2746 return isSignedIntSetCC(CC);
2747 }
2748 // For the case of integer setcc, only signed 64 bits comparison is safe.
2749 // For unsigned, "CMPU 0x80000000, 0" has to be greater than 0, but it becomes
2750 // less than 0 witout CMPU. For 32 bits, other half of 32 bits are
2751 // uncoditional, so it is not safe too without CMPI..
2752 return isSignedIntSetCC(CC) && SrcVT == MVT::i64;
2753}
2754
2756 ISD::CondCode CC, bool WithCMov,
2757 const SDLoc &DL, SelectionDAG &DAG) {
2758 // Compare values. If RHS is 0 and it is safe to calculate without
2759 // comparison, we don't generate an instruction for comparison.
2760 EVT CompVT = decideCompType(VT);
2761 if (CompVT == VT && safeWithoutCompWithNull(VT, CC, WithCMov) &&
2763 return LHS;
2764 }
2765 return DAG.getNode(decideComp(VT, CC), DL, CompVT, LHS, RHS);
2766}
2767
2769 DAGCombinerInfo &DCI) const {
2770 assert(N->getOpcode() == ISD::SELECT &&
2771 "Should be called with a SELECT node");
2773 SDValue Cond = N->getOperand(0);
2774 SDValue True = N->getOperand(1);
2775 SDValue False = N->getOperand(2);
2776
2777 // We handle only scalar SELECT.
2778 EVT VT = N->getValueType(0);
2779 if (VT.isVector())
2780 return SDValue();
2781
2782 // Peform combineSelect after leagalize DAG.
2783 if (!DCI.isAfterLegalizeDAG())
2784 return SDValue();
2785
2786 EVT VT0 = Cond.getValueType();
2787 if (isMImm(True)) {
2788 // VE's condition move can handle MImm in True clause, so nothing to do.
2789 } else if (isMImm(False)) {
2790 // VE's condition move can handle MImm in True clause, so swap True and
2791 // False clauses if False has MImm value. And, update condition code.
2792 std::swap(True, False);
2793 CC = getSetCCInverse(CC, VT0);
2794 }
2795
2796 SDLoc DL(N);
2797 SelectionDAG &DAG = DCI.DAG;
2798 VECC::CondCode VECCVal;
2799 if (VT0.isFloatingPoint()) {
2800 VECCVal = fpCondCode2Fcc(CC);
2801 } else {
2802 VECCVal = intCondCode2Icc(CC);
2803 }
2804 SDValue Ops[] = {Cond, True, False,
2805 DAG.getConstant(VECCVal, DL, MVT::i32)};
2806 return DAG.getNode(VEISD::CMOV, DL, VT, Ops);
2807}
2808
2810 DAGCombinerInfo &DCI) const {
2811 assert(N->getOpcode() == ISD::SELECT_CC &&
2812 "Should be called with a SELECT_CC node");
2813 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(4))->get();
2814 SDValue LHS = N->getOperand(0);
2815 SDValue RHS = N->getOperand(1);
2816 SDValue True = N->getOperand(2);
2817 SDValue False = N->getOperand(3);
2818
2819 // We handle only scalar SELECT_CC.
2820 EVT VT = N->getValueType(0);
2821 if (VT.isVector())
2822 return SDValue();
2823
2824 // Peform combineSelectCC after leagalize DAG.
2825 if (!DCI.isAfterLegalizeDAG())
2826 return SDValue();
2827
2828 // We handle only i32/i64/f32/f64/f128 comparisons.
2829 EVT LHSVT = LHS.getValueType();
2830 assert(LHSVT == RHS.getValueType());
2831 switch (LHSVT.getSimpleVT().SimpleTy) {
2832 case MVT::i32:
2833 case MVT::i64:
2834 case MVT::f32:
2835 case MVT::f64:
2836 case MVT::f128:
2837 break;
2838 default:
2839 // Return SDValue to let llvm handle other types.
2840 return SDValue();
2841 }
2842
2843 if (isMImm(RHS)) {
2844 // VE's comparison can handle MImm in RHS, so nothing to do.
2845 } else if (isSimm7(RHS)) {
2846 // VE's comparison can handle Simm7 in LHS, so swap LHS and RHS, and
2847 // update condition code.
2848 std::swap(LHS, RHS);
2849 CC = getSetCCSwappedOperands(CC);
2850 }
2851 if (isMImm(True)) {
2852 // VE's condition move can handle MImm in True clause, so nothing to do.
2853 } else if (isMImm(False)) {
2854 // VE's condition move can handle MImm in True clause, so swap True and
2855 // False clauses if False has MImm value. And, update condition code.
2856 std::swap(True, False);
2857 CC = getSetCCInverse(CC, LHSVT);
2858 }
2859
2860 SDLoc DL(N);
2861 SelectionDAG &DAG = DCI.DAG;
2862
2863 bool WithCMov = true;
2864 SDValue CompNode = generateComparison(LHSVT, LHS, RHS, CC, WithCMov, DL, DAG);
2865
2866 VECC::CondCode VECCVal;
2867 if (LHSVT.isFloatingPoint()) {
2868 VECCVal = fpCondCode2Fcc(CC);
2869 } else {
2870 VECCVal = intCondCode2Icc(CC);
2871 }
2872 SDValue Ops[] = {CompNode, True, False,
2873 DAG.getConstant(VECCVal, DL, MVT::i32)};
2874 return DAG.getNode(VEISD::CMOV, DL, VT, Ops);
2875}
2876
2877static bool isI32InsnAllUses(const SDNode *User, const SDNode *N);
2878static bool isI32Insn(const SDNode *User, const SDNode *N) {
2879 switch (User->getOpcode()) {
2880 default:
2881 return false;
2882 case ISD::ADD:
2883 case ISD::SUB:
2884 case ISD::MUL:
2885 case ISD::SDIV:
2886 case ISD::UDIV:
2887 case ISD::SETCC:
2888 case ISD::SMIN:
2889 case ISD::SMAX:
2890 case ISD::SHL:
2891 case ISD::SRA:
2892 case ISD::BSWAP:
2893 case ISD::SINT_TO_FP:
2894 case ISD::UINT_TO_FP:
2895 case ISD::BR_CC:
2896 case ISD::BITCAST:
2898 case ISD::ATOMIC_SWAP:
2899 case VEISD::CMPU:
2900 case VEISD::CMPI:
2901 return true;
2902 case ISD::SRL:
2903 if (N->getOperand(0).getOpcode() != ISD::SRL)
2904 return true;
2905 // (srl (trunc (srl ...))) may be optimized by combining srl, so
2906 // doesn't optimize trunc now.
2907 return false;
2908 case ISD::SELECT_CC:
2909 if (User->getOperand(2).getNode() != N &&
2910 User->getOperand(3).getNode() != N)
2911 return true;
2912 return isI32InsnAllUses(User, N);
2913 case VEISD::CMOV:
2914 // CMOV in (cmov (trunc ...), true, false, int-comparison) is safe.
2915 // However, trunc in true or false clauses is not safe.
2916 if (User->getOperand(1).getNode() != N &&
2917 User->getOperand(2).getNode() != N &&
2918 isa<ConstantSDNode>(User->getOperand(3))) {
2919 VECC::CondCode VECCVal =
2920 static_cast<VECC::CondCode>(User->getConstantOperandVal(3));
2921 return isIntVECondCode(VECCVal);
2922 }
2923 [[fallthrough]];
2924 case ISD::AND:
2925 case ISD::OR:
2926 case ISD::XOR:
2927 case ISD::SELECT:
2928 case ISD::CopyToReg:
2929 // Check all use of selections, bit operations, and copies. If all of them
2930 // are safe, optimize truncate to extract_subreg.
2931 return isI32InsnAllUses(User, N);
2932 }
2933}
2934
2935static bool isI32InsnAllUses(const SDNode *User, const SDNode *N) {
2936 // Check all use of User node. If all of them are safe, optimize
2937 // truncate to extract_subreg.
2938 for (const SDNode *U : User->users()) {
2939 switch (U->getOpcode()) {
2940 default:
2941 // If the use is an instruction which treats the source operand as i32,
2942 // it is safe to avoid truncate here.
2943 if (isI32Insn(U, N))
2944 continue;
2945 break;
2946 case ISD::ANY_EXTEND:
2947 case ISD::SIGN_EXTEND:
2948 case ISD::ZERO_EXTEND: {
2949 // Special optimizations to the combination of ext and trunc.
2950 // (ext ... (select ... (trunc ...))) is safe to avoid truncate here
2951 // since this truncate instruction clears higher 32 bits which is filled
2952 // by one of ext instructions later.
2953 assert(N->getValueType(0) == MVT::i32 &&
2954 "find truncate to not i32 integer");
2955 if (User->getOpcode() == ISD::SELECT_CC ||
2956 User->getOpcode() == ISD::SELECT || User->getOpcode() == VEISD::CMOV)
2957 continue;
2958 break;
2959 }
2960 }
2961 return false;
2962 }
2963 return true;
2964}
2965
2966// Optimize TRUNCATE in DAG combining. Optimizing it in CUSTOM lower is
2967// sometime too early. Optimizing it in DAG pattern matching in VEInstrInfo.td
2968// is sometime too late. So, doing it at here.
2970 DAGCombinerInfo &DCI) const {
2971 assert(N->getOpcode() == ISD::TRUNCATE &&
2972 "Should be called with a TRUNCATE node");
2973
2974 SelectionDAG &DAG = DCI.DAG;
2975 SDLoc DL(N);
2976 EVT VT = N->getValueType(0);
2977
2978 // We prefer to do this when all types are legal.
2979 if (!DCI.isAfterLegalizeDAG())
2980 return SDValue();
2981
2982 // Skip combine TRUNCATE atm if the operand of TRUNCATE might be a constant.
2983 if (N->getOperand(0)->getOpcode() == ISD::SELECT_CC &&
2984 isa<ConstantSDNode>(N->getOperand(0)->getOperand(0)) &&
2985 isa<ConstantSDNode>(N->getOperand(0)->getOperand(1)))
2986 return SDValue();
2987
2988 // Check all use of this TRUNCATE.
2989 for (const SDNode *User : N->users()) {
2990 // Make sure that we're not going to replace TRUNCATE for non i32
2991 // instructions.
2992 //
2993 // FIXME: Although we could sometimes handle this, and it does occur in
2994 // practice that one of the condition inputs to the select is also one of
2995 // the outputs, we currently can't deal with this.
2996 if (isI32Insn(User, N))
2997 continue;
2998
2999 return SDValue();
3000 }
3001
3002 SDValue SubI32 = DAG.getTargetConstant(VE::sub_i32, DL, MVT::i32);
3003 return SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, VT,
3004 N->getOperand(0), SubI32),
3005 0);
3006}
3007
3009 DAGCombinerInfo &DCI) const {
3010 switch (N->getOpcode()) {
3011 default:
3012 break;
3013 case ISD::SELECT:
3014 return combineSelect(N, DCI);
3015 case ISD::SELECT_CC:
3016 return combineSelectCC(N, DCI);
3017 case ISD::TRUNCATE:
3018 return combineTRUNCATE(N, DCI);
3019 }
3020
3021 return SDValue();
3022}
3023
3024//===----------------------------------------------------------------------===//
3025// VE Inline Assembly Support
3026//===----------------------------------------------------------------------===//
3027
3030 if (Constraint.size() == 1) {
3031 switch (Constraint[0]) {
3032 default:
3033 break;
3034 case 'v': // vector registers
3035 return C_RegisterClass;
3036 }
3037 }
3038 return TargetLowering::getConstraintType(Constraint);
3039}
3040
3041std::pair<unsigned, const TargetRegisterClass *>
3043 StringRef Constraint,
3044 MVT VT) const {
3045 const TargetRegisterClass *RC = nullptr;
3046 if (Constraint.size() == 1) {
3047 switch (Constraint[0]) {
3048 default:
3049 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
3050 case 'r':
3051 RC = &VE::I64RegClass;
3052 break;
3053 case 'v':
3054 RC = &VE::V64RegClass;
3055 break;
3056 }
3057 return std::make_pair(0U, RC);
3058 }
3059
3060 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
3061}
3062
3063//===----------------------------------------------------------------------===//
3064// VE Target Optimization Support
3065//===----------------------------------------------------------------------===//
3066
3068 // Specify 8 for PIC model to relieve the impact of PIC load instructions.
3069 if (isJumpTableRelative())
3070 return 8;
3071
3073}
3074
3076 EVT VT = Y.getValueType();
3077
3078 // VE doesn't have vector and not instruction.
3079 if (VT.isVector())
3080 return false;
3081
3082 // VE allows different immediate values for X and Y where ~X & Y.
3083 // Only simm7 works for X, and only mimm works for Y on VE. However, this
3084 // function is used to check whether an immediate value is OK for and-not
3085 // instruction as both X and Y. Generating additional instruction to
3086 // retrieve an immediate value is no good since the purpose of this
3087 // function is to convert a series of 3 instructions to another series of
3088 // 3 instructions with better parallelism. Therefore, we return false
3089 // for all immediate values now.
3090 // FIXME: Change hasAndNot function to have two operands to make it work
3091 // correctly with Aurora VE.
3092 if (isa<ConstantSDNode>(Y))
3093 return false;
3094
3095 // It's ok for generic registers.
3096 return true;
3097}
3098
3100 SelectionDAG &DAG) const {
3101 assert(Op.getOpcode() == ISD::EXTRACT_VECTOR_ELT && "Unknown opcode!");
3102 MVT VT = Op.getOperand(0).getSimpleValueType();
3103
3104 // Special treatment for packed V64 types.
3105 assert(VT == MVT::v512i32 || VT == MVT::v512f32);
3106 (void)VT;
3107 // Example of codes:
3108 // %packed_v = extractelt %vr, %idx / 2
3109 // %v = %packed_v >> (%idx % 2 * 32)
3110 // %res = %v & 0xffffffff
3111
3112 SDValue Vec = Op.getOperand(0);
3113 SDValue Idx = Op.getOperand(1);
3114 SDLoc DL(Op);
3115 SDValue Result = Op;
3116 if (false /* Idx->isConstant() */) {
3117 // TODO: optimized implementation using constant values
3118 } else {
3119 SDValue Const1 = DAG.getConstant(1, DL, MVT::i64);
3120 SDValue HalfIdx = DAG.getNode(ISD::SRL, DL, MVT::i64, {Idx, Const1});
3121 SDValue PackedElt =
3122 SDValue(DAG.getMachineNode(VE::LVSvr, DL, MVT::i64, {Vec, HalfIdx}), 0);
3123 SDValue AndIdx = DAG.getNode(ISD::AND, DL, MVT::i64, {Idx, Const1});
3124 SDValue Shift = DAG.getNode(ISD::XOR, DL, MVT::i64, {AndIdx, Const1});
3125 SDValue Const5 = DAG.getConstant(5, DL, MVT::i64);
3126 Shift = DAG.getNode(ISD::SHL, DL, MVT::i64, {Shift, Const5});
3127 PackedElt = DAG.getNode(ISD::SRL, DL, MVT::i64, {PackedElt, Shift});
3128 SDValue Mask = DAG.getConstant(0xFFFFFFFFL, DL, MVT::i64);
3129 PackedElt = DAG.getNode(ISD::AND, DL, MVT::i64, {PackedElt, Mask});
3130 SDValue SubI32 = DAG.getTargetConstant(VE::sub_i32, DL, MVT::i32);
3131 Result = SDValue(DAG.getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL,
3132 MVT::i32, PackedElt, SubI32),
3133 0);
3134
3135 if (Op.getSimpleValueType() == MVT::f32) {
3136 Result = DAG.getBitcast(MVT::f32, Result);
3137 } else {
3138 assert(Op.getSimpleValueType() == MVT::i32);
3139 }
3140 }
3141 return Result;
3142}
3143
3145 SelectionDAG &DAG) const {
3146 assert(Op.getOpcode() == ISD::INSERT_VECTOR_ELT && "Unknown opcode!");
3147 MVT VT = Op.getOperand(0).getSimpleValueType();
3148
3149 // Special treatment for packed V64 types.
3150 assert(VT == MVT::v512i32 || VT == MVT::v512f32);
3151 (void)VT;
3152 // The v512i32 and v512f32 starts from upper bits (0..31). This "upper
3153 // bits" required `val << 32` from C implementation's point of view.
3154 //
3155 // Example of codes:
3156 // %packed_elt = extractelt %vr, (%idx >> 1)
3157 // %shift = ((%idx & 1) ^ 1) << 5
3158 // %packed_elt &= 0xffffffff00000000 >> shift
3159 // %packed_elt |= (zext %val) << shift
3160 // %vr = insertelt %vr, %packed_elt, (%idx >> 1)
3161
3162 SDLoc DL(Op);
3163 SDValue Vec = Op.getOperand(0);
3164 SDValue Val = Op.getOperand(1);
3165 SDValue Idx = Op.getOperand(2);
3166 if (Idx.getSimpleValueType() == MVT::i32)
3167 Idx = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Idx);
3168 if (Val.getSimpleValueType() == MVT::f32)
3169 Val = DAG.getBitcast(MVT::i32, Val);
3170 assert(Val.getSimpleValueType() == MVT::i32);
3171 Val = DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Val);
3172
3173 SDValue Result = Op;
3174 if (false /* Idx->isConstant()*/) {
3175 // TODO: optimized implementation using constant values
3176 } else {
3177 SDValue Const1 = DAG.getConstant(1, DL, MVT::i64);
3178 SDValue HalfIdx = DAG.getNode(ISD::SRL, DL, MVT::i64, {Idx, Const1});
3179 SDValue PackedElt =
3180 SDValue(DAG.getMachineNode(VE::LVSvr, DL, MVT::i64, {Vec, HalfIdx}), 0);
3181 SDValue AndIdx = DAG.getNode(ISD::AND, DL, MVT::i64, {Idx, Const1});
3182 SDValue Shift = DAG.getNode(ISD::XOR, DL, MVT::i64, {AndIdx, Const1});
3183 SDValue Const5 = DAG.getConstant(5, DL, MVT::i64);
3184 Shift = DAG.getNode(ISD::SHL, DL, MVT::i64, {Shift, Const5});
3185 SDValue Mask = DAG.getConstant(0xFFFFFFFF00000000L, DL, MVT::i64);
3186 Mask = DAG.getNode(ISD::SRL, DL, MVT::i64, {Mask, Shift});
3187 PackedElt = DAG.getNode(ISD::AND, DL, MVT::i64, {PackedElt, Mask});
3188 Val = DAG.getNode(ISD::SHL, DL, MVT::i64, {Val, Shift});
3189 PackedElt = DAG.getNode(ISD::OR, DL, MVT::i64, {PackedElt, Val});
3190 Result =
3191 SDValue(DAG.getMachineNode(VE::LSVrr_v, DL, Vec.getSimpleValueType(),
3192 {HalfIdx, PackedElt, Vec}),
3193 0);
3194 }
3195 return Result;
3196}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
return RetTy
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Addr
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define RegName(no)
#define I(x, y, z)
Definition: MD5.cpp:58
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
const SmallVectorImpl< MachineOperand > & Cond
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition: Debug.h:119
static unsigned decideComp(EVT SrcVT, ISD::CondCode CC)
static bool isSimm7(SDValue V)
CCAssignFn * getParamCC(CallingConv::ID CallConv, bool IsVarArg)
static SDValue lowerLoadF128(SDValue Op, SelectionDAG &DAG)
static bool isMImm(SDValue V)
static SDValue prepareTS1AM(SDValue Op, SelectionDAG &DAG, SDValue &Flag, SDValue &Bits)
CCAssignFn * getReturnCC(CallingConv::ID CallConv)
static bool safeWithoutCompWithNull(EVT SrcVT, ISD::CondCode CC, bool WithCMov)
static bool isI32InsnAllUses(const SDNode *User, const SDNode *N)
static SDValue lowerLoadI1(SDValue Op, SelectionDAG &DAG)
static SDValue generateComparison(EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode CC, bool WithCMov, const SDLoc &DL, SelectionDAG &DAG)
static EVT decideCompType(EVT SrcVT)
static bool isI32Insn(const SDNode *User, const SDNode *N)
static SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const VETargetLowering &TLI, const VESubtarget *Subtarget)
static const MVT AllMaskVTs[]
static bool getUniqueInsertion(SDNode *N, unsigned &UniqueIdx)
static SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG, const VETargetLowering &TLI, const VESubtarget *Subtarget)
static const MVT AllVectorVTs[]
static const MVT AllPackedVTs[]
static SDValue finalizeTS1AM(SDValue Op, SelectionDAG &DAG, SDValue Data, SDValue Bits)
static SDValue lowerStoreF128(SDValue Op, SelectionDAG &DAG)
static SDValue lowerStoreI1(SDValue Op, SelectionDAG &DAG)
#define TARGET_NODE_CASE(NAME)
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:78
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:709
BinOp getOperation() const
Definition: Instructions.h:819
This is an SDNode representing atomic operations.
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
bool needsCustom() const
bool isMemLoc() const
bool isExtInLoc() const
int64_t getLocMemOffset() const
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
A debug info location.
Definition: DebugLoc.h:124
unsigned size() const
Definition: DenseMap.h:120
Implements a dense probed hash-table based set.
Definition: DenseSet.h:263
unsigned getAddressSpace() const
Definition: GlobalValue.h:207
Common base class shared among various IRBuilders.
Definition: IRBuilder.h:114
FenceInst * CreateFence(AtomicOrdering Ordering, SyncScope::ID SSID=SyncScope::System, const Twine &Name="")
Definition: IRBuilder.h:1891
LLVM_ABI bool hasAtomicStore() const LLVM_READONLY
Return true if this atomic instruction stores to memory.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:428
Context object for machine code objects.
Definition: MCContext.h:83
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:203
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
Machine Value Type.
SimpleValueType SimpleTy
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
static auto integer_valuetypes()
static auto vector_valuetypes()
MVT getVectorElementType() const
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
bool isEHPad() const
Returns true if the block is a landing pad.
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
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.
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
succ_reverse_iterator succ_rbegin()
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 '...
succ_reverse_iterator succ_rend()
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
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.
void setFrameAddressIsTaken(bool T)
void setReturnAddressIsTaken(bool s)
int getFunctionContextIndex() const
Return the index for the function context object.
unsigned getFunctionNumber() const
getFunctionNumber - Return a unique ID for the current function.
MachineJumpTableInfo * getOrCreateJumpTableInfo(unsigned JTEntryKind)
getOrCreateJumpTableInfo - Get the JumpTableInfo for this function, if it does already exist,...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
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...
bool hasCallSiteLandingPad(MCSymbol *Sym)
Return true if the landing pad Eh symbol has an associated call site.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
SmallVectorImpl< unsigned > & getCallSiteLandingPad(MCSymbol *Sym)
Get the call site indexes for a landing pad EH symbol.
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addJumpTableIndex(unsigned Idx, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
Definition: MachineInstr.h:72
LLVM_ABI unsigned createJumpTableIndex(const std::vector< MachineBasicBlock * > &DestBBs)
createJumpTableIndex - Create a new jump table.
@ EK_Custom32
EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the TargetLowering::LowerCustomJ...
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
Align getAlign() const
bool isVolatile() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
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...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isUndef() const
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:229
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:758
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
Definition: SelectionDAG.h:813
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
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,...
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:768
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).
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
Definition: SelectionDAG.h:839
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:498
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 getGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, bool isTargetGA=false, unsigned TargetFlags=0)
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.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
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 ...
const TargetMachine & getTarget() const
Definition: SelectionDAG.h:499
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
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)
Definition: SelectionDAG.h:707
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:808
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:493
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
Definition: SelectionDAG.h:511
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)
Definition: SelectionDAG.h:777
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:581
void reserve(size_type NewNumEntries)
Definition: SmallPtrSet.h:117
void insert_range(Range &&R)
Definition: SmallPtrSet.h:490
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:401
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:154
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:148
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:68
R Default(T Value)
Definition: StringSwitch.h:177
Information about stack frame layout on the target.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
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...
LegalizeAction
This enum indicates whether operations are valid for a target, and if not, what action should be used...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual unsigned getMinimumJumpTableEntries() const
Return lower limit for number of blocks in a jump table.
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.
void setSupportsUnalignedAtomics(bool UnalignedSupported)
Sets whether unaligned atomic operations are supported.
virtual bool isJumpTableRelative() const
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 setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
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
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.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:83
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Value * getOperand(unsigned i) const
Definition: User.h:232
SDValue getBroadcast(EVT ResultVT, SDValue Scalar, SDValue AVL) const
SDValue getNode(unsigned OC, SDVTList VTL, ArrayRef< SDValue > OpV, std::optional< SDNodeFlags > Flags=std::nullopt) const
getNode {
Definition: VECustomDAG.h:156
SDValue getUNDEF(EVT VT) const
Definition: VECustomDAG.h:180
SDValue getConstant(uint64_t Val, EVT VT, bool IsTarget=false, bool IsOpaque=false) const
bool hasBP(const MachineFunction &MF) const
Register getGlobalBaseReg(MachineFunction *MF) const
} Optimization
bool enableVPU() const
Definition: VESubtarget.h:65
unsigned getRsaSize() const
Get the size of RSA, return address, and frame pointer as described in VEFrameLowering....
Definition: VESubtarget.h:79
const VEInstrInfo * getInstrInfo() const override
Definition: VESubtarget.h:51
const VEFrameLowering * getFrameLowering() const override
Definition: VESubtarget.h:52
const VERegisterInfo * getRegisterInfo() const override
Definition: VESubtarget.h:55
SDValue splitMaskArithmetic(SDValue Op, SelectionDAG &DAG) const
SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const
} Custom Inserter
SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
bool hasAndNot(SDValue Y) const override
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
SDValue lowerVAARG(SDValue Op, SelectionDAG &DAG) const
SDValue combineSelect(SDNode *N, DAGCombinerInfo &DCI) const
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
isFPImmLegal - Returns true if the target can instruction select the specified FP immediate natively.
VETargetLowering(const TargetMachine &TM, const VESubtarget &STI)
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Custom Lower {.
SDValue lowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const
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...
SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
} VVPLowering
TargetLoweringBase::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
SDValue lowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const
SDValue combineSelectCC(SDNode *N, DAGCombinerInfo &DCI) const
SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const
unsigned getMinimumJumpTableEntries() const override
} Inline Assembly
SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &dl, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
MachineBasicBlock * emitSjLjDispatchBlock(MachineInstr &MI, MachineBasicBlock *BB) const
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineBasicBlock *TargetBB, const DebugLoc &DL) const
void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB, MachineBasicBlock *DispatchBB, int FI, int Offset) const
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
Custom Inserter {.
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align A, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Returns true if the target allows unaligned memory accesses of the specified type.
SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const
SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const
TargetLoweringBase::LegalizeAction getCustomOperationAction(SDNode &) const override
Custom Lower {.
SDValue makeAddress(SDValue Op, SelectionDAG &DAG) const
SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const
SDValue lowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const
SDValue legalizeInternalVectorOp(SDValue Op, SelectionDAG &DAG) const
Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, StringRef Symbol, const DebugLoc &DL, bool IsLocal, bool IsCall) const
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
} Custom Lower
SDValue lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
SDValue withTargetFlags(SDValue Op, unsigned TF, SelectionDAG &DAG) const
} Custom DAGCombine
SDValue combineTRUNCATE(SDNode *N, DAGCombinerInfo &DCI) const
const MCExpr * LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned Uid, MCContext &Ctx) const override
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &ArgsFlags, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const
unsigned getJumpTableEncoding() const override
JumpTable for VE.
SDValue lowerATOMIC_SWAP(SDValue Op, SelectionDAG &DAG) const
SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
SDValue makeHiLoPair(SDValue Op, unsigned HiTF, unsigned LoTF, SelectionDAG &DAG) const
ConstraintType getConstraintType(StringRef Constraint) const override
Inline Assembly {.
SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const
SDValue lowerToTLSGeneralDynamicModel(SDValue Op, SelectionDAG &DAG) const
LLVM Value Representation.
Definition: Value.h:75
iterator_range< user_iterator > users()
Definition: Value.h:426
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:194
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:169
self_iterator getIterator()
Definition: ilist_node.h:134
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
Definition: CallingConv.h:66
@ 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
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:801
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1236
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1232
@ CTLZ_ZERO_UNDEF
Definition: ISDOpcodes.h:774
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
Definition: ISDOpcodes.h:1401
@ VECREDUCE_SMIN
Definition: ISDOpcodes.h:1491
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
Definition: ISDOpcodes.h:163
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:270
@ ATOMIC_LOAD_NAND
Definition: ISDOpcodes.h:1379
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:765
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1265
@ ConstantFP
Definition: ISDOpcodes.h:87
@ ATOMIC_LOAD_MAX
Definition: ISDOpcodes.h:1381
@ ATOMIC_LOAD_UMIN
Definition: ISDOpcodes.h:1382
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:259
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:1141
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:835
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition: ISDOpcodes.h:511
@ EH_SJLJ_SETUP_DISPATCH
OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN) The target initializes the dispatch table here.
Definition: ISDOpcodes.h:167
@ GlobalAddress
Definition: ISDOpcodes.h:88
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
Definition: ISDOpcodes.h:1364
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition: ISDOpcodes.h:862
@ MEMBARRIER
MEMBARRIER - Compiler barrier only; generate a no-op.
Definition: ISDOpcodes.h:1338
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
Definition: ISDOpcodes.h:1343
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:275
@ VECREDUCE_SMAX
Definition: ISDOpcodes.h:1490
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
Definition: ISDOpcodes.h:985
@ ATOMIC_LOAD_OR
Definition: ISDOpcodes.h:1377
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:975
@ ATOMIC_LOAD_XOR
Definition: ISDOpcodes.h:1378
@ GlobalTLSAddress
Definition: ISDOpcodes.h:89
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:826
@ FNEG
Perform various unary floating-point operations inspired by libm.
Definition: ISDOpcodes.h:1002
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1187
@ ATOMIC_LOAD_MIN
Definition: ISDOpcodes.h:1380
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1166
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:778
@ VECREDUCE_UMAX
Definition: ISDOpcodes.h:1492
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1261
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition: ISDOpcodes.h:225
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
Definition: ISDOpcodes.h:1485
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:695
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:756
@ ATOMIC_LOAD_CLR
Definition: ISDOpcodes.h:1376
@ ATOMIC_LOAD_AND
Definition: ISDOpcodes.h:1375
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition: ISDOpcodes.h:563
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition: ISDOpcodes.h:219
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:832
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:793
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
Definition: ISDOpcodes.h:1358
@ ATOMIC_LOAD_UMAX
Definition: ISDOpcodes.h:1383
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
Definition: ISDOpcodes.h:1059
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1151
@ ConstantPool
Definition: ISDOpcodes.h:92
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition: ISDOpcodes.h:718
@ VECREDUCE_UMIN
Definition: ISDOpcodes.h:1493
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:110
@ ATOMIC_LOAD_ADD
Definition: ISDOpcodes.h:1373
@ ATOMIC_LOAD_SUB
Definition: ISDOpcodes.h:1374
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:730
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
Definition: ISDOpcodes.h:200
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition: ISDOpcodes.h:552
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:53
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
Definition: ISDOpcodes.h:1372
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
Definition: ISDOpcodes.h:157
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:838
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1256
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1180
@ BlockAddress
Definition: ISDOpcodes.h:94
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:815
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:62
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition: ISDOpcodes.h:521
@ AssertZext
Definition: ISDOpcodes.h:63
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:543
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1685
LLVM_ABI bool isVPOpcode(unsigned Opcode)
Whether this is a vector-predicated Opcode.
@ Dead
Unused definition.
@ System
Synchronized with respect to all concurrently executing threads.
Definition: LLVMContext.h:58
CondCode
Definition: VE.h:43
@ CC_ILE
Definition: VE.h:50
@ EH_SJLJ_SETUP_DISPATCH
@ S_GOT_LO32
Definition: VEMCAsmInfo.h:45
@ S_GOTOFF_LO32
Definition: VEMCAsmInfo.h:47
@ S_GOT_HI32
Definition: VEMCAsmInfo.h:44
@ S_GOTOFF_HI32
Definition: VEMCAsmInfo.h:46
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
static uint64_t getFpImmVal(const ConstantFPSDNode *N)
getFpImmVal - get immediate representation of floating point value
bool isPackedVectorType(EVT SomeVT)
Definition: VECustomDAG.cpp:22
@ Offset
Definition: DWP.cpp:477
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
static bool isIntVECondCode(VECC::CondCode CC)
Definition: VE.h:151
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.
static uint64_t getImmVal(const ConstantSDNode *N)
getImmVal - get immediate representation of integer value
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
LLVM_ABI Value * getSplatValue(const Value *V)
Get splat value if the input is a splat vector or return nullptr.
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:428
bool isMaskArithmetic(SDValue Op)
Definition: VECustomDAG.cpp:50
static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC)
Convert a DAG floating point condition code to a VE FCC condition.
bool isMaskType(EVT SomeVT)
Definition: VECustomDAG.cpp:44
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isVVPOrVEC(unsigned Opcode)
unsigned getKillRegState(bool B)
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
bool isPackingSupportOpcode(unsigned Opc)
std::pair< SDValue, bool > getAnnotatedNodeAVL(SDValue Op)
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
Definition: VE.h:376
static VECC::CondCode intCondCode2Icc(ISD::CondCode CC)
Convert a DAG integer condition code to a VE ICC condition.
LLVM_ABI bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
static bool isMImmVal(uint64_t Val)
Definition: VE.h:332
static bool isMImm32Val(uint32_t Val)
Definition: VE.h:345
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:858
#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
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition: ValueTypes.h:147
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:368
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:168
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:152
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition: Alignment.h:141
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.
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setDiscardResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
CallLoweringInfo & setCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList, AttributeSet ResultAttrs={})
const uint32_t * getNoPreservedMask() const override
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID CC) const override