LLVM 24.0.0git
LanaiISelLowering.cpp
Go to the documentation of this file.
1//===-- LanaiISelLowering.cpp - Lanai 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 LanaiTargetLowering class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "LanaiISelLowering.h"
14#include "LanaiCondCode.h"
16#include "LanaiSubtarget.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/StringRef.h"
34#include "llvm/IR/CallingConv.h"
36#include "llvm/IR/Function.h"
37#include "llvm/IR/GlobalValue.h"
40#include "llvm/Support/Debug.h"
46#include <cassert>
47#include <cmath>
48#include <cstdint>
49#include <cstdlib>
50#include <utility>
51
52#define DEBUG_TYPE "lanai-lower"
53
54using namespace llvm;
55
57 const LanaiSubtarget &STI)
58 : TargetLowering(TM, STI) {
59 // Set up the register classes.
60 addRegisterClass(MVT::i32, &Lanai::GPRRegClass);
61
62 // Compute derived properties from the register classes
63 TRI = STI.getRegisterInfo();
65
67
74
79
83
88
95
101
107
112
116
117 // Extended load operations for i1 types must be promoted
118 for (MVT VT : MVT::integer_valuetypes()) {
122 }
123
125
126 // Function alignments
129
130 setJumpIsExpensive(true);
131
132 // TODO: Setting the minimum jump table entries needed before a
133 // switch is transformed to a jump table to 100 to avoid creating jump tables
134 // as this was causing bad performance compared to a large group of if
135 // statements. Re-evaluate this on new benchmarks.
137
138 MaxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores
140 MaxStoresPerMemcpy = 16; // For @llvm.memcpy -> sequence of stores
142 MaxStoresPerMemmove = 16; // For @llvm.memmove -> sequence of stores
144
145 // Booleans always contain 0 or 1.
147
149}
150
152 SelectionDAG &DAG) const {
153 switch (Op.getOpcode()) {
154 case ISD::MUL:
155 return LowerMUL(Op, DAG);
156 case ISD::BR_CC:
157 return LowerBR_CC(Op, DAG);
159 return LowerConstantPool(Op, DAG);
161 return LowerGlobalAddress(Op, DAG);
163 return LowerBlockAddress(Op, DAG);
164 case ISD::JumpTable:
165 return LowerJumpTable(Op, DAG);
166 case ISD::SELECT_CC:
167 return LowerSELECT_CC(Op, DAG);
168 case ISD::SETCC:
169 return LowerSETCC(Op, DAG);
170 case ISD::SHL_PARTS:
171 return LowerSHL_PARTS(Op, DAG);
172 case ISD::SRL_PARTS:
173 return LowerSRL_PARTS(Op, DAG);
174 case ISD::VASTART:
175 return LowerVASTART(Op, DAG);
177 return LowerDYNAMIC_STACKALLOC(Op, DAG);
178 case ISD::RETURNADDR:
179 return LowerRETURNADDR(Op, DAG);
180 case ISD::FRAMEADDR:
181 return LowerFRAMEADDR(Op, DAG);
182 default:
183 llvm_unreachable("unimplemented operand");
184 }
185}
186
187//===----------------------------------------------------------------------===//
188// Lanai Inline Assembly Support
189//===----------------------------------------------------------------------===//
190
192 const char *RegName, LLT /*VT*/,
193 const MachineFunction & /*MF*/) const {
194 // Only unallocatable registers should be matched here.
196 .Case("pc", Lanai::PC)
197 .Case("sp", Lanai::SP)
198 .Case("fp", Lanai::FP)
199 .Case("rr1", Lanai::RR1)
200 .Case("r10", Lanai::R10)
201 .Case("rr2", Lanai::RR2)
202 .Case("r11", Lanai::R11)
203 .Case("rca", Lanai::RCA)
204 .Default(Register());
205 return Reg;
206}
207
208std::pair<unsigned, const TargetRegisterClass *>
210 StringRef Constraint,
211 MVT VT) const {
212 if (Constraint.size() == 1)
213 // GCC Constraint Letters
214 switch (Constraint[0]) {
215 case 'r': // GENERAL_REGS
216 return std::make_pair(0U, &Lanai::GPRRegClass);
217 default:
218 break;
219 }
220
221 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
222}
223
224// Examine constraint type and operand type and determine a weight value.
225// This object must already have been set up with the operand type
226// and the current alternative constraint selected.
229 AsmOperandInfo &Info, const char *Constraint) const {
231 Value *CallOperandVal = Info.CallOperandVal;
232 // If we don't have a value, we can't do a match,
233 // but allow it at the lowest weight.
234 if (CallOperandVal == nullptr)
235 return CW_Default;
236 // Look at the constraint type.
237 switch (*Constraint) {
238 case 'I': // signed 16 bit immediate
239 case 'J': // integer zero
240 case 'K': // unsigned 16 bit immediate
241 case 'L': // immediate in the range 0 to 31
242 case 'M': // signed 32 bit immediate where lower 16 bits are 0
243 case 'N': // signed 26 bit immediate
244 case 'O': // integer zero
245 if (isa<ConstantInt>(CallOperandVal))
246 Weight = CW_Constant;
247 break;
248 default:
249 Weight = TargetLowering::getSingleConstraintMatchWeight(Info, Constraint);
250 break;
251 }
252 return Weight;
253}
254
255// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
256// vector. If it is invalid, don't add anything to Ops.
258 SDValue Op, StringRef Constraint, std::vector<SDValue> &Ops,
259 SelectionDAG &DAG) const {
260 SDValue Result;
261
262 // Only support length 1 constraints for now.
263 if (Constraint.size() > 1)
264 return;
265
266 char ConstraintLetter = Constraint[0];
267 switch (ConstraintLetter) {
268 case 'I': // Signed 16 bit constant
269 // If this fails, the parent routine will give an error
271 if (isInt<16>(C->getSExtValue())) {
272 Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(C),
273 Op.getValueType());
274 break;
275 }
276 }
277 return;
278 case 'J': // integer zero
279 case 'O':
281 if (C->getZExtValue() == 0) {
282 Result = DAG.getTargetConstant(0, SDLoc(C), Op.getValueType());
283 break;
284 }
285 }
286 return;
287 case 'K': // unsigned 16 bit immediate
289 if (isUInt<16>(C->getZExtValue())) {
290 Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(C),
291 Op.getValueType());
292 break;
293 }
294 }
295 return;
296 case 'L': // immediate in the range 0 to 31
298 if (C->getZExtValue() <= 31) {
299 Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(C),
300 Op.getValueType());
301 break;
302 }
303 }
304 return;
305 case 'M': // signed 32 bit immediate where lower 16 bits are 0
307 int64_t Val = C->getSExtValue();
308 if ((isInt<32>(Val)) && ((Val & 0xffff) == 0)) {
309 Result = DAG.getTargetConstant(Val, SDLoc(C), Op.getValueType());
310 break;
311 }
312 }
313 return;
314 case 'N': // signed 26 bit immediate
316 int64_t Val = C->getSExtValue();
317 if ((Val >= -33554432) && (Val <= 33554431)) {
318 Result = DAG.getTargetConstant(Val, SDLoc(C), Op.getValueType());
319 break;
320 }
321 }
322 return;
323 default:
324 break; // This will fall through to the generic implementation
325 }
326
327 if (Result.getNode()) {
328 Ops.push_back(Result);
329 return;
330 }
331
333}
334
335//===----------------------------------------------------------------------===//
336// Calling Convention Implementation
337//===----------------------------------------------------------------------===//
338
339#define GET_CALLING_CONV_IMPL
340#include "LanaiGenCallingConv.inc"
341
342static bool CC_Lanai32_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT,
343 CCValAssign::LocInfo LocInfo,
344 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,
345 CCState &State) {
346 // Handle fixed arguments with default CC.
347 // Note: Both the default and fast CC handle VarArg the same and hence the
348 // calling convention of the function is not considered here.
349 if (!ArgFlags.isVarArg())
350 return CC_Lanai32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State);
351
352 // Promote i8/i16 args to i32
353 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
354 LocVT = MVT::i32;
355 if (ArgFlags.isSExt())
356 LocInfo = CCValAssign::SExt;
357 else if (ArgFlags.isZExt())
358 LocInfo = CCValAssign::ZExt;
359 else
360 LocInfo = CCValAssign::AExt;
361 }
362
363 // VarArgs get passed on stack
364 unsigned Offset = State.AllocateStack(4, Align(4));
365 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
366 return false;
367}
368
369SDValue LanaiTargetLowering::LowerFormalArguments(
370 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
371 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
372 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
373 switch (CallConv) {
374 case CallingConv::C:
376 return LowerCCCArguments(Chain, CallConv, IsVarArg, Ins, DL, DAG, InVals);
377 default:
378 report_fatal_error("Unsupported calling convention");
379 }
380}
381
382SDValue LanaiTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
383 SmallVectorImpl<SDValue> &InVals) const {
384 SelectionDAG &DAG = CLI.DAG;
385 SDLoc &DL = CLI.DL;
386 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
387 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
388 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
389 SDValue Chain = CLI.Chain;
390 SDValue Callee = CLI.Callee;
391 bool &IsTailCall = CLI.IsTailCall;
392 CallingConv::ID CallConv = CLI.CallConv;
393 bool IsVarArg = CLI.IsVarArg;
394
395 // Lanai target does not yet support tail call optimization.
396 IsTailCall = false;
397
398 switch (CallConv) {
400 case CallingConv::C:
401 return LowerCCCCallTo(Chain, Callee, CallConv, IsVarArg, IsTailCall, Outs,
402 OutVals, Ins, DL, DAG, InVals);
403 default:
404 report_fatal_error("Unsupported calling convention");
405 }
406}
407
408// LowerCCCArguments - transform physical registers into virtual registers and
409// generate load operations for arguments places on the stack.
410SDValue LanaiTargetLowering::LowerCCCArguments(
411 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
412 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
413 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
415 MachineFrameInfo &MFI = MF.getFrameInfo();
416 MachineRegisterInfo &RegInfo = MF.getRegInfo();
417 LanaiMachineFunctionInfo *LanaiMFI = MF.getInfo<LanaiMachineFunctionInfo>();
418
419 // Assign locations to all of the incoming arguments.
421 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
422 *DAG.getContext());
423 if (CallConv == CallingConv::Fast) {
424 CCInfo.AnalyzeFormalArguments(Ins, CC_Lanai32_Fast);
425 } else {
426 CCInfo.AnalyzeFormalArguments(Ins, CC_Lanai32);
427 }
428
429 for (const CCValAssign &VA : ArgLocs) {
430 if (VA.isRegLoc()) {
431 // Arguments passed in registers
432 EVT RegVT = VA.getLocVT();
433 switch (RegVT.getSimpleVT().SimpleTy) {
434 case MVT::i32: {
435 Register VReg = RegInfo.createVirtualRegister(&Lanai::GPRRegClass);
436 RegInfo.addLiveIn(VA.getLocReg(), VReg);
437 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
438
439 // If this is an 8/16-bit value, it is really passed promoted to 32
440 // bits. Insert an assert[sz]ext to capture this, then truncate to the
441 // right size.
442 if (VA.getLocInfo() == CCValAssign::SExt)
443 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
444 DAG.getValueType(VA.getValVT()));
445 else if (VA.getLocInfo() == CCValAssign::ZExt)
446 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
447 DAG.getValueType(VA.getValVT()));
448
449 if (VA.getLocInfo() != CCValAssign::Full)
450 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
451
452 InVals.push_back(ArgValue);
453 break;
454 }
455 default:
456 LLVM_DEBUG(dbgs() << "LowerFormalArguments Unhandled argument type: "
457 << RegVT << "\n");
458 llvm_unreachable("unhandled argument type");
459 }
460 } else {
461 // Only arguments passed on the stack should make it here.
462 assert(VA.isMemLoc());
463 // Load the argument to a virtual register
464 unsigned ObjSize = VA.getLocVT().getSizeInBits() / 8;
465 // Check that the argument fits in stack slot
466 if (ObjSize > 4) {
467 errs() << "LowerFormalArguments Unhandled argument type: "
468 << VA.getLocVT() << "\n";
469 }
470 // Create the frame index object for this incoming parameter...
471 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
472
473 // Create the SelectionDAG nodes corresponding to a load
474 // from this parameter
475 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
476 InVals.push_back(DAG.getLoad(
477 VA.getLocVT(), DL, Chain, FIN,
479 }
480 }
481
482 // The Lanai ABI for returning structs by value requires that we copy
483 // the sret argument into rv for the return. Save the argument into
484 // a virtual register so that we can access it from the return points.
485 if (MF.getFunction().hasStructRetAttr()) {
486 Register Reg = LanaiMFI->getSRetReturnReg();
487 if (!Reg) {
489 LanaiMFI->setSRetReturnReg(Reg);
490 }
491 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals[0]);
492 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain);
493 }
494
495 if (IsVarArg) {
496 // Record the frame index of the first variable argument
497 // which is a value necessary to VASTART.
498 int FI = MFI.CreateFixedObject(4, CCInfo.getStackSize(), true);
499 LanaiMFI->setVarArgsFrameIndex(FI);
500 }
501
502 return Chain;
503}
504
506 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
507 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
508 const Type *RetTy) const {
510 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
511
512 return CCInfo.CheckReturn(Outs, RetCC_Lanai32);
513}
514
516LanaiTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
517 bool IsVarArg,
519 const SmallVectorImpl<SDValue> &OutVals,
520 const SDLoc &DL, SelectionDAG &DAG) const {
521 // CCValAssign - represent the assignment of the return value to a location
523
524 // CCState - Info about the registers and stack slot.
525 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
526 *DAG.getContext());
527
528 // Analize return values.
529 CCInfo.AnalyzeReturn(Outs, RetCC_Lanai32);
530
531 SDValue Glue;
532 SmallVector<SDValue, 4> RetOps(1, Chain);
533
534 // Copy the result values into the output registers.
535 for (unsigned i = 0; i != RVLocs.size(); ++i) {
536 CCValAssign &VA = RVLocs[i];
537 assert(VA.isRegLoc() && "Can only return in registers!");
538
539 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Glue);
540
541 // Guarantee that all emitted copies are stuck together with flags.
542 Glue = Chain.getValue(1);
543 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
544 }
545
546 // The Lanai ABI for returning structs by value requires that we copy
547 // the sret argument into rv for the return. We saved the argument into
548 // a virtual register in the entry block, so now we copy the value out
549 // and into rv.
553 Register Reg = LanaiMFI->getSRetReturnReg();
554 assert(Reg &&
555 "SRetReturnReg should have been set in LowerFormalArguments().");
556 SDValue Val =
557 DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy(DAG.getDataLayout()));
558
559 Chain = DAG.getCopyToReg(Chain, DL, Lanai::RV, Val, Glue);
560 Glue = Chain.getValue(1);
561 RetOps.push_back(
562 DAG.getRegister(Lanai::RV, getPointerTy(DAG.getDataLayout())));
563 }
564
565 RetOps[0] = Chain; // Update chain
566
567 unsigned Opc = LanaiISD::RET_GLUE;
568 if (Glue.getNode())
569 RetOps.push_back(Glue);
570
571 // Return Void
572 return DAG.getNode(Opc, DL, MVT::Other,
573 ArrayRef<SDValue>(&RetOps[0], RetOps.size()));
574}
575
576// LowerCCCCallTo - functions arguments are copied from virtual regs to
577// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
578SDValue LanaiTargetLowering::LowerCCCCallTo(
579 SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool IsVarArg,
580 bool /*IsTailCall*/, const SmallVectorImpl<ISD::OutputArg> &Outs,
581 const SmallVectorImpl<SDValue> &OutVals,
582 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
583 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
584 // Analyze operands of the call, assigning locations to each operand.
586 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
587 *DAG.getContext());
588 GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
589 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
590
591 if (IsVarArg) {
592 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32_VarArg);
593 } else {
594 if (CallConv == CallingConv::Fast)
595 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32_Fast);
596 else
597 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32);
598 }
599
600 // Get a count of how many bytes are to be pushed on the stack.
601 unsigned NumBytes = CCInfo.getStackSize();
602
603 // Create local copies for byval args.
604 SmallVector<SDValue, 8> ByValArgs;
605 for (unsigned I = 0, E = Outs.size(); I != E; ++I) {
606 ISD::ArgFlagsTy Flags = Outs[I].Flags;
607 if (!Flags.isByVal())
608 continue;
609
610 SDValue Arg = OutVals[I];
611 unsigned Size = Flags.getByValSize();
612 Align Alignment = Flags.getNonZeroByValAlign();
613
614 int FI = MFI.CreateStackObject(Size, Alignment, false);
615 SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
616 SDValue SizeNode = DAG.getConstant(Size, DL, MVT::i32);
617
618 Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment, Alignment,
619 /*IsVolatile=*/false,
620 /*AlwaysInline=*/false,
621 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(),
622 MachinePointerInfo());
623 ByValArgs.push_back(FIPtr);
624 }
625
626 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, DL);
627
629 SmallVector<SDValue, 12> MemOpChains;
630 SDValue StackPtr;
631
632 // Walk the register/memloc assignments, inserting copies/loads.
633 for (unsigned I = 0, J = 0, E = ArgLocs.size(); I != E; ++I) {
634 CCValAssign &VA = ArgLocs[I];
635 SDValue Arg = OutVals[I];
636 ISD::ArgFlagsTy Flags = Outs[I].Flags;
637
638 // Promote the value if needed.
639 switch (VA.getLocInfo()) {
641 break;
643 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
644 break;
646 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
647 break;
649 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
650 break;
651 default:
652 llvm_unreachable("Unknown loc info!");
653 }
654
655 // Use local copy if it is a byval arg.
656 if (Flags.isByVal())
657 Arg = ByValArgs[J++];
658
659 // Arguments that can be passed on register must be kept at RegsToPass
660 // vector
661 if (VA.isRegLoc()) {
662 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
663 } else {
664 assert(VA.isMemLoc());
665
666 if (StackPtr.getNode() == nullptr)
667 StackPtr = DAG.getCopyFromReg(Chain, DL, Lanai::SP,
669
670 SDValue PtrOff =
671 DAG.getNode(ISD::ADD, DL, getPointerTy(DAG.getDataLayout()), StackPtr,
673
674 MemOpChains.push_back(
675 DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo()));
676 }
677 }
678
679 // Transform all store nodes into one single node because all store nodes are
680 // independent of each other.
681 if (!MemOpChains.empty())
682 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
683 ArrayRef<SDValue>(&MemOpChains[0], MemOpChains.size()));
684
685 SDValue InGlue;
686
687 // Build a sequence of copy-to-reg nodes chained together with token chain and
688 // flag operands which copy the outgoing args into registers. The InGlue in
689 // necessary since all emitted instructions must be stuck together.
690 for (const auto &[Reg, N] : RegsToPass) {
691 Chain = DAG.getCopyToReg(Chain, DL, Reg, N, InGlue);
692 InGlue = Chain.getValue(1);
693 }
694
695 // If the callee is a GlobalAddress node (quite common, every direct call is)
696 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
697 // Likewise ExternalSymbol -> TargetExternalSymbol.
698 uint8_t OpFlag = LanaiII::MO_NO_FLAG;
699 if (G) {
701 G->getGlobal(), DL, getPointerTy(DAG.getDataLayout()), 0, OpFlag);
702 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
704 E->getSymbol(), getPointerTy(DAG.getDataLayout()), OpFlag);
705 }
706
707 // Returns a chain & a flag for retval copy to use.
708 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
710 Ops.push_back(Chain);
711 Ops.push_back(Callee);
712
713 // Add a register mask operand representing the call-preserved registers.
714 // TODO: Should return-twice functions be handled?
715 const uint32_t *Mask =
716 TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);
717 assert(Mask && "Missing call preserved mask for calling convention");
718 Ops.push_back(DAG.getRegisterMask(Mask));
719
720 // Add argument registers to the end of the list so that they are
721 // known live into the call.
722 for (const auto &[Reg, N] : RegsToPass)
723 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
724
725 if (InGlue.getNode())
726 Ops.push_back(InGlue);
727
728 Chain = DAG.getNode(LanaiISD::CALL, DL, NodeTys,
729 ArrayRef<SDValue>(&Ops[0], Ops.size()));
730 InGlue = Chain.getValue(1);
731
732 // Create the CALLSEQ_END node.
733 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, DL);
734 InGlue = Chain.getValue(1);
735
736 // Handle result values, copying them out of physregs into vregs that we
737 // return.
738 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, DL, DAG,
739 InVals);
740}
741
742// LowerCallResult - Lower the result values of a call into the
743// appropriate copies out of appropriate physical registers.
744SDValue LanaiTargetLowering::LowerCallResult(
745 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
746 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
747 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
748 // Assign locations to each value returned by this call.
750 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
751 *DAG.getContext());
752
753 CCInfo.AnalyzeCallResult(Ins, RetCC_Lanai32);
754
755 // Copy all of the result registers out of their specified physreg.
756 for (unsigned I = 0; I != RVLocs.size(); ++I) {
757 Chain = DAG.getCopyFromReg(Chain, DL, RVLocs[I].getLocReg(),
758 RVLocs[I].getValVT(), InGlue)
759 .getValue(1);
760 InGlue = Chain.getValue(2);
761 InVals.push_back(Chain.getValue(0));
762 }
763
764 return Chain;
765}
766
767//===----------------------------------------------------------------------===//
768// Custom Lowerings
769//===----------------------------------------------------------------------===//
770
772 SDValue &RHS, SelectionDAG &DAG) {
773 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
774
775 // For integer, only the SETEQ, SETNE, SETLT, SETLE, SETGT, SETGE, SETULT,
776 // SETULE, SETUGT, and SETUGE opcodes are used (see CodeGen/ISDOpcodes.h)
777 // and Lanai only supports integer comparisons, so only provide definitions
778 // for them.
779 switch (SetCCOpcode) {
780 case ISD::SETEQ:
781 return LPCC::ICC_EQ;
782 case ISD::SETGT:
784 if (RHSC->getZExtValue() == 0xFFFFFFFF) {
785 // X > -1 -> X >= 0 -> is_plus(X)
786 RHS = DAG.getConstant(0, DL, RHS.getValueType());
787 return LPCC::ICC_PL;
788 }
789 return LPCC::ICC_GT;
790 case ISD::SETUGT:
791 return LPCC::ICC_UGT;
792 case ISD::SETLT:
794 if (RHSC->getZExtValue() == 0)
795 // X < 0 -> is_minus(X)
796 return LPCC::ICC_MI;
797 return LPCC::ICC_LT;
798 case ISD::SETULT:
799 return LPCC::ICC_ULT;
800 case ISD::SETLE:
802 if (RHSC->getZExtValue() == 0xFFFFFFFF) {
803 // X <= -1 -> X < 0 -> is_minus(X)
804 RHS = DAG.getConstant(0, DL, RHS.getValueType());
805 return LPCC::ICC_MI;
806 }
807 return LPCC::ICC_LE;
808 case ISD::SETULE:
809 return LPCC::ICC_ULE;
810 case ISD::SETGE:
812 if (RHSC->getZExtValue() == 0)
813 // X >= 0 -> is_plus(X)
814 return LPCC::ICC_PL;
815 return LPCC::ICC_GE;
816 case ISD::SETUGE:
817 return LPCC::ICC_UGE;
818 case ISD::SETNE:
819 return LPCC::ICC_NE;
820 case ISD::SETONE:
821 case ISD::SETUNE:
822 case ISD::SETOGE:
823 case ISD::SETOLE:
824 case ISD::SETOLT:
825 case ISD::SETOGT:
826 case ISD::SETOEQ:
827 case ISD::SETUEQ:
828 case ISD::SETO:
829 case ISD::SETUO:
830 llvm_unreachable("Unsupported comparison.");
831 default:
832 llvm_unreachable("Unknown integer condition code!");
833 }
834}
835
837 SDValue Chain = Op.getOperand(0);
838 SDValue Cond = Op.getOperand(1);
839 SDValue LHS = Op.getOperand(2);
840 SDValue RHS = Op.getOperand(3);
841 SDValue Dest = Op.getOperand(4);
842 SDLoc DL(Op);
843
844 LPCC::CondCode CC = IntCondCCodeToICC(Cond, DL, RHS, DAG);
845 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
846 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
847
848 return DAG.getNode(LanaiISD::BR_CC, DL, Op.getValueType(), Chain, Dest,
849 TargetCC, Glue);
850}
851
853 EVT VT = Op->getValueType(0);
854 if (VT != MVT::i32)
855 return SDValue();
856
857 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op->getOperand(1));
858 if (!C)
859 return SDValue();
860
861 int64_t MulAmt = C->getSExtValue();
862 int32_t HighestOne = -1;
863 uint32_t NonzeroEntries = 0;
864 int SignedDigit[32] = {0};
865
866 // Convert to non-adjacent form (NAF) signed-digit representation.
867 // NAF is a signed-digit form where no adjacent digits are non-zero. It is the
868 // minimal Hamming weight representation of a number (on average 1/3 of the
869 // digits will be non-zero vs 1/2 for regular binary representation). And as
870 // the non-zero digits will be the only digits contributing to the instruction
871 // count, this is desirable. The next loop converts it to NAF (following the
872 // approach in 'Guide to Elliptic Curve Cryptography' [ISBN: 038795273X]) by
873 // choosing the non-zero coefficients such that the resulting quotient is
874 // divisible by 2 which will cause the next coefficient to be zero.
875 int64_t E = std::abs(MulAmt);
876 int S = (MulAmt < 0 ? -1 : 1);
877 int I = 0;
878 while (E > 0) {
879 int ZI = 0;
880 if (E % 2 == 1) {
881 ZI = 2 - (E % 4);
882 if (ZI != 0)
883 ++NonzeroEntries;
884 }
885 SignedDigit[I] = S * ZI;
886 if (SignedDigit[I] == 1)
887 HighestOne = I;
888 E = (E - ZI) / 2;
889 ++I;
890 }
891
892 // Compute number of instructions required. Due to differences in lowering
893 // between the different processors this count is not exact.
894 // Start by assuming a shift and a add/sub for every non-zero entry (hence
895 // every non-zero entry requires 1 shift and 1 add/sub except for the first
896 // entry).
897 int32_t InstrRequired = 2 * NonzeroEntries - 1;
898 // Correct possible over-adding due to shift by 0 (which is not emitted).
899 if (std::abs(MulAmt) % 2 == 1)
900 --InstrRequired;
901 // Return if the form generated would exceed the instruction threshold.
902 if (InstrRequired >
903 DAG.getSubtarget<LanaiSubtarget>().getCLOpts().constant_mul_threshold)
904 return SDValue();
905
906 SDValue Res;
907 SDLoc DL(Op);
908 SDValue V = Op->getOperand(0);
909
910 // Initialize the running sum. Set the running sum to the maximal shifted
911 // positive value (i.e., largest i such that zi == 1 and MulAmt has V<<i as a
912 // term NAF).
913 if (HighestOne == -1)
914 Res = DAG.getConstant(0, DL, MVT::i32);
915 else {
916 Res = DAG.getNode(ISD::SHL, DL, VT, V,
917 DAG.getConstant(HighestOne, DL, MVT::i32));
918 SignedDigit[HighestOne] = 0;
919 }
920
921 // Assemble multiplication from shift, add, sub using NAF form and running
922 // sum.
923 for (unsigned int I = 0; I < std::size(SignedDigit); ++I) {
924 if (SignedDigit[I] == 0)
925 continue;
926
927 // Shifted multiplicand (v<<i).
928 SDValue Op =
929 DAG.getNode(ISD::SHL, DL, VT, V, DAG.getConstant(I, DL, MVT::i32));
930 if (SignedDigit[I] == 1)
931 Res = DAG.getNode(ISD::ADD, DL, VT, Res, Op);
932 else if (SignedDigit[I] == -1)
933 Res = DAG.getNode(ISD::SUB, DL, VT, Res, Op);
934 }
935 return Res;
936}
937
939 SDValue LHS = Op.getOperand(0);
940 SDValue RHS = Op.getOperand(1);
941 SDValue Cond = Op.getOperand(2);
942 SDLoc DL(Op);
943
944 LPCC::CondCode CC = IntCondCCodeToICC(Cond, DL, RHS, DAG);
945 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
946 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
947
948 return DAG.getNode(LanaiISD::SETCC, DL, Op.getValueType(), TargetCC, Glue);
949}
950
952 SelectionDAG &DAG) const {
953 SDValue LHS = Op.getOperand(0);
954 SDValue RHS = Op.getOperand(1);
955 SDValue TrueV = Op.getOperand(2);
956 SDValue FalseV = Op.getOperand(3);
957 SDValue Cond = Op.getOperand(4);
958 SDLoc DL(Op);
959
960 LPCC::CondCode CC = IntCondCCodeToICC(Cond, DL, RHS, DAG);
961 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
962 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
963
964 return DAG.getNode(LanaiISD::SELECT_CC, DL, Op.getValueType(), TrueV, FalseV,
965 TargetCC, Glue);
966}
967
971
972 SDLoc DL(Op);
973 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
975
976 // vastart just stores the address of the VarArgsFrameIndex slot into the
977 // memory location argument.
978 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
979 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
981}
982
984 SelectionDAG &DAG) const {
985 SDValue Chain = Op.getOperand(0);
986 SDValue Size = Op.getOperand(1);
987 SDLoc DL(Op);
988
990
991 // Get a reference to the stack pointer.
992 SDValue StackPointer = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
993
994 // Subtract the dynamic size from the actual stack size to
995 // obtain the new stack size.
996 SDValue Sub = DAG.getNode(ISD::SUB, DL, MVT::i32, StackPointer, Size);
997
998 // For Lanai, the outgoing memory arguments area should be on top of the
999 // alloca area on the stack i.e., the outgoing memory arguments should be
1000 // at a lower address than the alloca area. Move the alloca area down the
1001 // stack by adding back the space reserved for outgoing arguments to SP
1002 // here.
1003 //
1004 // We do not know what the size of the outgoing args is at this point.
1005 // So, we add a pseudo instruction ADJDYNALLOC that will adjust the
1006 // stack pointer. We replace this instruction with on that has the correct,
1007 // known offset in emitPrologue().
1008 SDValue ArgAdjust = DAG.getNode(LanaiISD::ADJDYNALLOC, DL, MVT::i32, Sub);
1009
1010 // The Sub result contains the new stack start address, so it
1011 // must be placed in the stack pointer register.
1012 SDValue CopyChain = DAG.getCopyToReg(Chain, DL, SPReg, Sub);
1013
1014 SDValue Ops[2] = {ArgAdjust, CopyChain};
1015 return DAG.getMergeValues(Ops, DL);
1016}
1017
1019 SelectionDAG &DAG) const {
1021 MachineFrameInfo &MFI = MF.getFrameInfo();
1022 MFI.setReturnAddressIsTaken(true);
1023
1024 EVT VT = Op.getValueType();
1025 SDLoc DL(Op);
1026 unsigned Depth = Op.getConstantOperandVal(0);
1027 if (Depth) {
1028 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1029 const unsigned Offset = -4;
1030 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
1032 return DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
1033 }
1034
1035 // Return the link register, which contains the return address.
1036 // Mark it an implicit live-in.
1037 Register Reg = MF.addLiveIn(TRI->getRARegister(), getRegClassFor(MVT::i32));
1038 return DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, VT);
1039}
1040
1042 SelectionDAG &DAG) const {
1044 MFI.setFrameAddressIsTaken(true);
1045
1046 EVT VT = Op.getValueType();
1047 SDLoc DL(Op);
1048 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, Lanai::FP, VT);
1049 unsigned Depth = Op.getConstantOperandVal(0);
1050 while (Depth--) {
1051 const unsigned Offset = -8;
1052 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
1054 FrameAddr =
1055 DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
1056 }
1057 return FrameAddr;
1058}
1059
1061 SelectionDAG &DAG) const {
1062 SDLoc DL(Op);
1064 const Constant *C = N->getConstVal();
1065 const LanaiTargetObjectFile *TLOF =
1066 static_cast<const LanaiTargetObjectFile *>(
1068
1069 // If the code model is small or constant will be placed in the small section,
1070 // then assume address will fit in 21-bits.
1073 SDValue Small = DAG.getTargetConstantPool(
1074 C, MVT::i32, N->getAlign(), N->getOffset(), LanaiII::MO_NO_FLAG);
1075 return DAG.getNode(ISD::OR, DL, MVT::i32,
1076 DAG.getRegister(Lanai::R0, MVT::i32),
1077 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1078 } else {
1079 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1080 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1081
1082 SDValue Hi = DAG.getTargetConstantPool(C, MVT::i32, N->getAlign(),
1083 N->getOffset(), OpFlagHi);
1084 SDValue Lo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlign(),
1085 N->getOffset(), OpFlagLo);
1086 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1087 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1088 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1089 return Result;
1090 }
1091}
1092
1094 SelectionDAG &DAG) const {
1095 SDLoc DL(Op);
1096 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
1097 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
1098
1099 const LanaiTargetObjectFile *TLOF =
1100 static_cast<const LanaiTargetObjectFile *>(
1102
1103 // If the code model is small or global variable will be placed in the small
1104 // section, then assume address will fit in 21-bits.
1105 const GlobalObject *GO = GV->getAliaseeObject();
1106 if (TLOF->isGlobalInSmallSection(GO, getTargetMachine())) {
1107 SDValue Small = DAG.getTargetGlobalAddress(
1109 return DAG.getNode(ISD::OR, DL, MVT::i32,
1110 DAG.getRegister(Lanai::R0, MVT::i32),
1111 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1112 } else {
1113 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1114 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1115
1116 // Create the TargetGlobalAddress node, folding in the constant offset.
1118 GV, DL, getPointerTy(DAG.getDataLayout()), Offset, OpFlagHi);
1120 GV, DL, getPointerTy(DAG.getDataLayout()), Offset, OpFlagLo);
1121 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1122 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1123 return DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1124 }
1125}
1126
1128 SelectionDAG &DAG) const {
1129 SDLoc DL(Op);
1130 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1131
1132 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1133 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1134
1135 SDValue Hi = DAG.getBlockAddress(BA, MVT::i32, true, OpFlagHi);
1136 SDValue Lo = DAG.getBlockAddress(BA, MVT::i32, true, OpFlagLo);
1137 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1138 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1139 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1140 return Result;
1141}
1142
1144 SelectionDAG &DAG) const {
1145 SDLoc DL(Op);
1147
1148 // If the code model is small assume address will fit in 21-bits.
1150 SDValue Small = DAG.getTargetJumpTable(
1152 return DAG.getNode(ISD::OR, DL, MVT::i32,
1153 DAG.getRegister(Lanai::R0, MVT::i32),
1154 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1155 } else {
1156 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1157 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1158
1160 JT->getIndex(), getPointerTy(DAG.getDataLayout()), OpFlagHi);
1162 JT->getIndex(), getPointerTy(DAG.getDataLayout()), OpFlagLo);
1163 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1164 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1165 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1166 return Result;
1167 }
1168}
1169
1171 SelectionDAG &DAG) const {
1172 EVT VT = Op.getValueType();
1173 unsigned VTBits = VT.getSizeInBits();
1174 SDLoc dl(Op);
1175 assert(Op.getNumOperands() == 3 && "Unexpected SHL!");
1176 SDValue ShOpLo = Op.getOperand(0);
1177 SDValue ShOpHi = Op.getOperand(1);
1178 SDValue ShAmt = Op.getOperand(2);
1179
1180 // Performs the following for (ShOpLo + (ShOpHi << 32)) << ShAmt:
1181 // LoBitsForHi = (ShAmt == 0) ? 0 : (ShOpLo >> (32-ShAmt))
1182 // HiBitsForHi = ShOpHi << ShAmt
1183 // Hi = (ShAmt >= 32) ? (ShOpLo << (ShAmt-32)) : (LoBitsForHi | HiBitsForHi)
1184 // Lo = (ShAmt >= 32) ? 0 : (ShOpLo << ShAmt)
1185 // return (Hi << 32) | Lo;
1186
1187 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
1188 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
1189 SDValue LoBitsForHi = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, RevShAmt);
1190
1191 // If ShAmt == 0, we just calculated "(SRL ShOpLo, 32)" which is "undef". We
1192 // wanted 0, so CSEL it directly.
1193 SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
1194 SDValue SetCC = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
1195 LoBitsForHi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, LoBitsForHi);
1196
1197 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
1198 DAG.getConstant(VTBits, dl, MVT::i32));
1199 SDValue HiBitsForHi = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, ShAmt);
1200 SDValue HiForNormalShift =
1201 DAG.getNode(ISD::OR, dl, VT, LoBitsForHi, HiBitsForHi);
1202
1203 SDValue HiForBigShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ExtraShAmt);
1204
1205 SetCC = DAG.getSetCC(dl, MVT::i32, ExtraShAmt, Zero, ISD::SETGE);
1206 SDValue Hi =
1207 DAG.getSelect(dl, MVT::i32, SetCC, HiForBigShift, HiForNormalShift);
1208
1209 // Lanai shifts of larger than register sizes are wrapped rather than
1210 // clamped, so we can't just emit "lo << b" if b is too big.
1211 SDValue LoForNormalShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ShAmt);
1212 SDValue Lo = DAG.getSelect(
1213 dl, MVT::i32, SetCC, DAG.getConstant(0, dl, MVT::i32), LoForNormalShift);
1214
1215 SDValue Ops[2] = {Lo, Hi};
1216 return DAG.getMergeValues(Ops, dl);
1217}
1218
1220 SelectionDAG &DAG) const {
1221 MVT VT = Op.getSimpleValueType();
1222 unsigned VTBits = VT.getSizeInBits();
1223 SDLoc dl(Op);
1224 SDValue ShOpLo = Op.getOperand(0);
1225 SDValue ShOpHi = Op.getOperand(1);
1226 SDValue ShAmt = Op.getOperand(2);
1227
1228 // Performs the following for a >> b:
1229 // unsigned r_high = a_high >> b;
1230 // r_high = (32 - b <= 0) ? 0 : r_high;
1231 //
1232 // unsigned r_low = a_low >> b;
1233 // r_low = (32 - b <= 0) ? r_high : r_low;
1234 // r_low = (b == 0) ? r_low : r_low | (a_high << (32 - b));
1235 // return (unsigned long long)r_high << 32 | r_low;
1236 // Note: This takes advantage of Lanai's shift behavior to avoid needing to
1237 // mask the shift amount.
1238
1239 SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
1240 SDValue NegatedPlus32 = DAG.getNode(
1241 ISD::SUB, dl, MVT::i32, DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
1242 SDValue SetCC = DAG.getSetCC(dl, MVT::i32, NegatedPlus32, Zero, ISD::SETLE);
1243
1244 SDValue Hi = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpHi, ShAmt);
1245 Hi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, Hi);
1246
1247 SDValue Lo = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpLo, ShAmt);
1248 Lo = DAG.getSelect(dl, MVT::i32, SetCC, Hi, Lo);
1249 SDValue CarryBits =
1250 DAG.getNode(ISD::SHL, dl, MVT::i32, ShOpHi, NegatedPlus32);
1251 SDValue ShiftIsZero = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
1252 Lo = DAG.getSelect(dl, MVT::i32, ShiftIsZero, Lo,
1253 DAG.getNode(ISD::OR, dl, MVT::i32, Lo, CarryBits));
1254
1255 SDValue Ops[2] = {Lo, Hi};
1256 return DAG.getMergeValues(Ops, dl);
1257}
1258
1259// Helper function that checks if N is a null or all ones constant.
1260static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
1262}
1263
1264// Return true if N is conditionally 0 or all ones.
1265// Detects these expressions where cc is an i1 value:
1266//
1267// (select cc 0, y) [AllOnes=0]
1268// (select cc y, 0) [AllOnes=0]
1269// (zext cc) [AllOnes=0]
1270// (sext cc) [AllOnes=0/1]
1271// (select cc -1, y) [AllOnes=1]
1272// (select cc y, -1) [AllOnes=1]
1273//
1274// * AllOnes determines whether to check for an all zero (AllOnes false) or an
1275// all ones operand (AllOnes true).
1276// * Invert is set when N is the all zero/ones constant when CC is false.
1277// * OtherOp is set to the alternative value of N.
1278//
1279// For example, for (select cc X, Y) and AllOnes = 0 if:
1280// * X = 0, Invert = False and OtherOp = Y
1281// * Y = 0, Invert = True and OtherOp = X
1283 bool &Invert, SDValue &OtherOp,
1284 SelectionDAG &DAG) {
1285 switch (N->getOpcode()) {
1286 default:
1287 return false;
1288 case ISD::SELECT: {
1289 CC = N->getOperand(0);
1290 SDValue N1 = N->getOperand(1);
1291 SDValue N2 = N->getOperand(2);
1292 if (isZeroOrAllOnes(N1, AllOnes)) {
1293 Invert = false;
1294 OtherOp = N2;
1295 return true;
1296 }
1297 if (isZeroOrAllOnes(N2, AllOnes)) {
1298 Invert = true;
1299 OtherOp = N1;
1300 return true;
1301 }
1302 return false;
1303 }
1304 case ISD::ZERO_EXTEND: {
1305 // (zext cc) can never be the all ones value.
1306 if (AllOnes)
1307 return false;
1308 CC = N->getOperand(0);
1309 if (CC.getValueType() != MVT::i1)
1310 return false;
1311 SDLoc dl(N);
1312 EVT VT = N->getValueType(0);
1313 OtherOp = DAG.getConstant(1, dl, VT);
1314 Invert = true;
1315 return true;
1316 }
1317 case ISD::SIGN_EXTEND: {
1318 CC = N->getOperand(0);
1319 if (CC.getValueType() != MVT::i1)
1320 return false;
1321 SDLoc dl(N);
1322 EVT VT = N->getValueType(0);
1323 Invert = !AllOnes;
1324 if (AllOnes)
1325 // When looking for an AllOnes constant, N is an sext, and the 'other'
1326 // value is 0.
1327 OtherOp = DAG.getConstant(0, dl, VT);
1328 else
1329 OtherOp = DAG.getAllOnesConstant(dl, VT);
1330 return true;
1331 }
1332 }
1333}
1334
1335// Combine a constant select operand into its use:
1336//
1337// (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
1338// (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
1339// (and (select cc, -1, c), x) -> (select cc, x, (and, x, c)) [AllOnes=1]
1340// (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
1341// (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
1342//
1343// The transform is rejected if the select doesn't have a constant operand that
1344// is null, or all ones when AllOnes is set.
1345//
1346// Also recognize sext/zext from i1:
1347//
1348// (add (zext cc), x) -> (select cc (add x, 1), x)
1349// (add (sext cc), x) -> (select cc (add x, -1), x)
1350//
1351// These transformations eventually create predicated instructions.
1354 bool AllOnes) {
1355 SelectionDAG &DAG = DCI.DAG;
1356 EVT VT = N->getValueType(0);
1357 SDValue NonConstantVal;
1358 SDValue CCOp;
1359 bool SwapSelectOps;
1360 if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
1361 NonConstantVal, DAG))
1362 return SDValue();
1363
1364 // Slct is now know to be the desired identity constant when CC is true.
1365 SDValue TrueVal = OtherOp;
1366 SDValue FalseVal =
1367 DAG.getNode(N->getOpcode(), SDLoc(N), VT, OtherOp, NonConstantVal);
1368 // Unless SwapSelectOps says CC should be false.
1369 if (SwapSelectOps)
1370 std::swap(TrueVal, FalseVal);
1371
1372 return DAG.getNode(ISD::SELECT, SDLoc(N), VT, CCOp, TrueVal, FalseVal);
1373}
1374
1375// Attempt combineSelectAndUse on each operand of a commutative operator N.
1376static SDValue
1378 bool AllOnes) {
1379 SDValue N0 = N->getOperand(0);
1380 SDValue N1 = N->getOperand(1);
1381 if (N0.getNode()->hasOneUse())
1382 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
1383 return Result;
1384 if (N1.getNode()->hasOneUse())
1385 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
1386 return Result;
1387 return SDValue();
1388}
1389
1390// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
1393 SDValue N0 = N->getOperand(0);
1394 SDValue N1 = N->getOperand(1);
1395
1396 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
1397 if (N1.getNode()->hasOneUse())
1398 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, /*AllOnes=*/false))
1399 return Result;
1400
1401 return SDValue();
1402}
1403
1405 DAGCombinerInfo &DCI) const {
1406 switch (N->getOpcode()) {
1407 default:
1408 break;
1409 case ISD::ADD:
1410 case ISD::OR:
1411 case ISD::XOR:
1412 return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/false);
1413 case ISD::AND:
1414 return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/true);
1415 case ISD::SUB:
1416 return PerformSUBCombine(N, DCI);
1417 }
1418
1419 return SDValue();
1420}
1421
1423 const SDValue Op, KnownBits &Known, const APInt &DemandedElts,
1424 const SelectionDAG &DAG, unsigned Depth) const {
1425 unsigned BitWidth = Known.getBitWidth();
1426 switch (Op.getOpcode()) {
1427 default:
1428 break;
1429 case LanaiISD::SETCC:
1431 Known.Zero.setBits(1, BitWidth);
1432 break;
1433 case LanaiISD::SELECT_CC:
1434 KnownBits Known2;
1435 Known = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
1436 Known2 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
1437 Known = Known.intersectWith(Known2);
1438 break;
1439 }
1440}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isZeroOrAllOnes(SDValue N, bool AllOnes)
static SDValue PerformSUBCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
static SDValue combineSelectAndUseCommutative(SDNode *N, bool AllOnes, TargetLowering::DAGCombinerInfo &DCI)
static bool isConditionalZeroOrAllOnes(SDNode *N, bool AllOnes, SDValue &CC, bool &Invert, SDValue &OtherOp, SelectionDAG &DAG)
static SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp, TargetLowering::DAGCombinerInfo &DCI, bool AllOnes=false)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
static LPCC::CondCode IntCondCCodeToICC(SDValue CC, const SDLoc &DL, SDValue &RHS, SelectionDAG &DAG)
static bool CC_Lanai32_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h:119
Value * RHS
Class for arbitrary precision integers.
Definition APInt.h:78
The address of a basic block.
Definition Constants.h:1088
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
This is an important base class in LLVM.
Definition Constant.h:43
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition Function.h:673
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition Globals.cpp:521
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
const LanaiOptions & getCLOpts() const
const LanaiRegisterInfo * getRegisterInfo() const override
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const
SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
SDValue LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) const
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const
LanaiTargetLowering(const TargetMachine &TM, const LanaiSubtarget &STI)
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const
SDValue LowerGlobalAddress(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 LowerSETCC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &Info, const char *Constraint) const override
Examine constraint string and operand type and determine a weight value.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
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...
bool isConstantInSmallSection(const DataLayout &DL, const Constant *CN) const
Return true if this constant should be placed into small data section.
Machine Value Type.
SimpleValueType SimpleTy
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setReturnAddressIsTaken(bool s)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool hasOneUse() const
Return true if there is exactly one use of this node.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the 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...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, bool isTarget=false, unsigned TargetFlags=0)
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
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...
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
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...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
Primary interface to the complete machine description for the target machine.
virtual TargetLoweringObjectFile * getObjFileLowering() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:845
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:277
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:805
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:879
@ GlobalAddress
Definition ISDOpcodes.h:90
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:282
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:870
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:822
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:714
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:876
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:837
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:914
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:112
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:55
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:882
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:859
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:64
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs