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