LLVM 20.0.0git
M68kISelLowering.cpp
Go to the documentation of this file.
1//===-- M68kISelLowering.cpp - M68k DAG Lowering Impl -----------*- C++ -*-===//
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/// \file
10/// This file defines the interfaces that M68k uses to lower LLVM code into a
11/// selection DAG.
12///
13//===----------------------------------------------------------------------===//
14
15#include "M68kISelLowering.h"
16#include "M68kCallingConv.h"
17#include "M68kMachineFunction.h"
18#include "M68kSubtarget.h"
19#include "M68kTargetMachine.h"
21
22#include "llvm/ADT/Statistic.h"
31#include "llvm/IR/CallingConv.h"
35#include "llvm/Support/Debug.h"
39
40using namespace llvm;
41
42#define DEBUG_TYPE "M68k-isel"
43
44STATISTIC(NumTailCalls, "Number of tail calls");
45
47 const M68kSubtarget &STI)
48 : TargetLowering(TM), Subtarget(STI), TM(TM) {
49
50 MVT PtrVT = MVT::i32;
51
53
54 auto *RegInfo = Subtarget.getRegisterInfo();
55 setStackPointerRegisterToSaveRestore(RegInfo->getStackRegister());
56
57 // Set up the register classes.
58 addRegisterClass(MVT::i8, &M68k::DR8RegClass);
59 addRegisterClass(MVT::i16, &M68k::XR16RegClass);
60 addRegisterClass(MVT::i32, &M68k::XR32RegClass);
61
62 for (auto VT : MVT::integer_valuetypes()) {
66 }
67
68 // We don't accept any truncstore of integer registers.
69 setTruncStoreAction(MVT::i64, MVT::i32, Expand);
70 setTruncStoreAction(MVT::i64, MVT::i16, Expand);
71 setTruncStoreAction(MVT::i64, MVT::i8, Expand);
72 setTruncStoreAction(MVT::i32, MVT::i16, Expand);
73 setTruncStoreAction(MVT::i32, MVT::i8, Expand);
74 setTruncStoreAction(MVT::i16, MVT::i8, Expand);
75
78 if (Subtarget.atLeastM68020())
80 else
83
84 for (auto OP :
87 setOperationAction(OP, MVT::i8, Promote);
88 setOperationAction(OP, MVT::i16, Legal);
89 setOperationAction(OP, MVT::i32, LibCall);
90 }
91
92 for (auto OP : {ISD::UMUL_LOHI, ISD::SMUL_LOHI}) {
93 setOperationAction(OP, MVT::i8, Expand);
94 setOperationAction(OP, MVT::i16, Expand);
95 }
96
97 for (auto OP : {ISD::SMULO, ISD::UMULO}) {
98 setOperationAction(OP, MVT::i8, Custom);
99 setOperationAction(OP, MVT::i16, Custom);
100 setOperationAction(OP, MVT::i32, Custom);
101 }
102
104 setOperationAction(OP, MVT::i32, Custom);
105
106 // Add/Sub overflow ops with MVT::Glues are lowered to CCR dependences.
107 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
112 }
113
114 // SADDO and friends are legal with this setup, i hope
115 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
120 }
121
124
125 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
131 }
132
133 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
138 }
139
146
151
154
156
158
159 // We lower the `atomic-compare-and-swap` to `__sync_val_compare_and_swap`
160 // for subtarget < M68020
162 setOperationAction(ISD::ATOMIC_CMP_SWAP, {MVT::i8, MVT::i16, MVT::i32},
163 Subtarget.atLeastM68020() ? Legal : LibCall);
164
166
167 // M68k does not have native read-modify-write support, so expand all of them
168 // to `__sync_fetch_*` for target < M68020, otherwise expand to CmpxChg.
169 // See `shouldExpandAtomicRMWInIR` below.
171 {
183 },
184 {MVT::i8, MVT::i16, MVT::i32}, LibCall);
185
187}
188
191 return Subtarget.atLeastM68020()
194}
195
198 return M68k::D0;
199}
200
203 return M68k::D1;
204}
205
208 return StringSwitch<InlineAsm::ConstraintCode>(ConstraintCode)
210 // We borrow ConstraintCode::Um for 'U'.
213}
214
216 LLVMContext &Context, EVT VT) const {
217 // M68k SETcc producess either 0x00 or 0xFF
218 return MVT::i8;
219}
220
222 EVT Ty) const {
223 if (Ty.isSimple()) {
224 return Ty.getSimpleVT();
225 }
226 return MVT::getIntegerVT(DL.getPointerSizeInBits(0));
227}
228
229#include "M68kGenCallingConv.inc"
230
232
233static StructReturnType
235 if (Outs.empty())
236 return NotStructReturn;
237
238 const ISD::ArgFlagsTy &Flags = Outs[0].Flags;
239 if (!Flags.isSRet())
240 return NotStructReturn;
241 if (Flags.isInReg())
242 return RegStructReturn;
243 return StackStructReturn;
244}
245
246/// Determines whether a function uses struct return semantics.
247static StructReturnType
249 if (Ins.empty())
250 return NotStructReturn;
251
252 const ISD::ArgFlagsTy &Flags = Ins[0].Flags;
253 if (!Flags.isSRet())
254 return NotStructReturn;
255 if (Flags.isInReg())
256 return RegStructReturn;
257 return StackStructReturn;
258}
259
260/// Make a copy of an aggregate at address specified by "Src" to address
261/// "Dst" with size and alignment information specified by the specific
262/// parameter attribute. The copy will be passed as a byval function parameter.
264 SDValue Chain, ISD::ArgFlagsTy Flags,
265 SelectionDAG &DAG, const SDLoc &DL) {
266 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), DL, MVT::i32);
267
268 return DAG.getMemcpy(
269 Chain, DL, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
270 /*isVolatile=*/false, /*AlwaysInline=*/true,
271 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(), MachinePointerInfo());
272}
273
274/// Return true if the calling convention is one that we can guarantee TCO for.
275static bool canGuaranteeTCO(CallingConv::ID CC) { return false; }
276
277/// Return true if we might ever do TCO for calls with this calling convention.
279 switch (CC) {
280 // C calling conventions:
281 case CallingConv::C:
282 return true;
283 default:
284 return canGuaranteeTCO(CC);
285 }
286}
287
288/// Return true if the function is being made into a tailcall target by
289/// changing its ABI.
290static bool shouldGuaranteeTCO(CallingConv::ID CC, bool GuaranteedTailCallOpt) {
291 return GuaranteedTailCallOpt && canGuaranteeTCO(CC);
292}
293
294/// Return true if the given stack call argument is already available in the
295/// same position (relatively) of the caller's incoming argument stack.
296static bool MatchingStackOffset(SDValue Arg, unsigned Offset,
299 const M68kInstrInfo *TII,
300 const CCValAssign &VA) {
301 unsigned Bytes = Arg.getValueType().getSizeInBits() / 8;
302
303 for (;;) {
304 // Look through nodes that don't alter the bits of the incoming value.
305 unsigned Op = Arg.getOpcode();
307 Arg = Arg.getOperand(0);
308 continue;
309 }
310 if (Op == ISD::TRUNCATE) {
311 const SDValue &TruncInput = Arg.getOperand(0);
312 if (TruncInput.getOpcode() == ISD::AssertZext &&
313 cast<VTSDNode>(TruncInput.getOperand(1))->getVT() ==
314 Arg.getValueType()) {
315 Arg = TruncInput.getOperand(0);
316 continue;
317 }
318 }
319 break;
320 }
321
322 int FI = INT_MAX;
323 if (Arg.getOpcode() == ISD::CopyFromReg) {
324 Register VR = cast<RegisterSDNode>(Arg.getOperand(1))->getReg();
326 return false;
327 MachineInstr *Def = MRI->getVRegDef(VR);
328 if (!Def)
329 return false;
330 if (!Flags.isByVal()) {
331 if (!TII->isLoadFromStackSlot(*Def, FI))
332 return false;
333 } else {
334 unsigned Opcode = Def->getOpcode();
335 if ((Opcode == M68k::LEA32p || Opcode == M68k::LEA32f) &&
336 Def->getOperand(1).isFI()) {
337 FI = Def->getOperand(1).getIndex();
338 Bytes = Flags.getByValSize();
339 } else
340 return false;
341 }
342 } else if (auto *Ld = dyn_cast<LoadSDNode>(Arg)) {
343 if (Flags.isByVal())
344 // ByVal argument is passed in as a pointer but it's now being
345 // dereferenced. e.g.
346 // define @foo(%struct.X* %A) {
347 // tail call @bar(%struct.X* byval %A)
348 // }
349 return false;
350 SDValue Ptr = Ld->getBasePtr();
351 FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(Ptr);
352 if (!FINode)
353 return false;
354 FI = FINode->getIndex();
355 } else if (Arg.getOpcode() == ISD::FrameIndex && Flags.isByVal()) {
356 FrameIndexSDNode *FINode = cast<FrameIndexSDNode>(Arg);
357 FI = FINode->getIndex();
358 Bytes = Flags.getByValSize();
359 } else
360 return false;
361
362 assert(FI != INT_MAX);
363 if (!MFI.isFixedObjectIndex(FI))
364 return false;
365
366 if (Offset != MFI.getObjectOffset(FI))
367 return false;
368
369 if (VA.getLocVT().getSizeInBits() > Arg.getValueType().getSizeInBits()) {
370 // If the argument location is wider than the argument type, check that any
371 // extension flags match.
372 if (Flags.isZExt() != MFI.isObjectZExt(FI) ||
373 Flags.isSExt() != MFI.isObjectSExt(FI)) {
374 return false;
375 }
376 }
377
378 return Bytes == MFI.getObjectSize(FI);
379}
380
382M68kTargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
385 int ReturnAddrIndex = FuncInfo->getRAIndex();
386
387 if (ReturnAddrIndex == 0) {
388 // Set up a frame object for the return address.
389 unsigned SlotSize = Subtarget.getSlotSize();
390 ReturnAddrIndex = MF.getFrameInfo().CreateFixedObject(
391 SlotSize, -(int64_t)SlotSize, false);
392 FuncInfo->setRAIndex(ReturnAddrIndex);
393 }
394
395 return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy(DAG.getDataLayout()));
396}
397
398SDValue M68kTargetLowering::EmitTailCallLoadRetAddr(SelectionDAG &DAG,
399 SDValue &OutRetAddr,
400 SDValue Chain,
401 bool IsTailCall, int FPDiff,
402 const SDLoc &DL) const {
403 EVT VT = getPointerTy(DAG.getDataLayout());
404 OutRetAddr = getReturnAddressFrameIndex(DAG);
405
406 // Load the "old" Return address.
407 OutRetAddr = DAG.getLoad(VT, DL, Chain, OutRetAddr, MachinePointerInfo());
408 return SDValue(OutRetAddr.getNode(), 1);
409}
410
411SDValue M68kTargetLowering::EmitTailCallStoreRetAddr(
412 SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue RetFI,
413 EVT PtrVT, unsigned SlotSize, int FPDiff, const SDLoc &DL) const {
414 if (!FPDiff)
415 return Chain;
416
417 // Calculate the new stack slot for the return address.
418 int NewFO = MF.getFrameInfo().CreateFixedObject(
419 SlotSize, (int64_t)FPDiff - SlotSize, false);
420
421 SDValue NewFI = DAG.getFrameIndex(NewFO, PtrVT);
422 // Store the return address to the appropriate stack slot.
423 Chain = DAG.getStore(
424 Chain, DL, RetFI, NewFI,
426 return Chain;
427}
428
430M68kTargetLowering::LowerMemArgument(SDValue Chain, CallingConv::ID CallConv,
432 const SDLoc &DL, SelectionDAG &DAG,
433 const CCValAssign &VA,
434 MachineFrameInfo &MFI,
435 unsigned ArgIdx) const {
436 // Create the nodes corresponding to a load from this parameter slot.
437 ISD::ArgFlagsTy Flags = Ins[ArgIdx].Flags;
438 EVT ValVT;
439
440 // If value is passed by pointer we have address passed instead of the value
441 // itself.
443 ValVT = VA.getLocVT();
444 else
445 ValVT = VA.getValVT();
446
447 // Because we are dealing with BE architecture we need to offset loading of
448 // partial types
449 int Offset = VA.getLocMemOffset();
450 if (VA.getValVT() == MVT::i8) {
451 Offset += 3;
452 } else if (VA.getValVT() == MVT::i16) {
453 Offset += 2;
454 }
455
456 // TODO Interrupt handlers
457 // Calculate SP offset of interrupt parameter, re-arrange the slot normally
458 // taken by a return address.
459
460 // FIXME For now, all byval parameter objects are marked mutable. This can
461 // be changed with more analysis. In case of tail call optimization mark all
462 // arguments mutable. Since they could be overwritten by lowering of arguments
463 // in case of a tail call.
464 bool AlwaysUseMutable = shouldGuaranteeTCO(
465 CallConv, DAG.getTarget().Options.GuaranteedTailCallOpt);
466 bool IsImmutable = !AlwaysUseMutable && !Flags.isByVal();
467
468 if (Flags.isByVal()) {
469 unsigned Bytes = Flags.getByValSize();
470 if (Bytes == 0)
471 Bytes = 1; // Don't create zero-sized stack objects.
472 int FI = MFI.CreateFixedObject(Bytes, Offset, IsImmutable);
473 // TODO Interrupt handlers
474 // Adjust SP offset of interrupt parameter.
475 return DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
476 } else {
477 int FI =
478 MFI.CreateFixedObject(ValVT.getSizeInBits() / 8, Offset, IsImmutable);
479
480 // Set SExt or ZExt flag.
481 if (VA.getLocInfo() == CCValAssign::ZExt) {
482 MFI.setObjectZExt(FI, true);
483 } else if (VA.getLocInfo() == CCValAssign::SExt) {
484 MFI.setObjectSExt(FI, true);
485 }
486
487 // TODO Interrupt handlers
488 // Adjust SP offset of interrupt parameter.
489
490 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
491 SDValue Val = DAG.getLoad(
492 ValVT, DL, Chain, FIN,
494 return VA.isExtInLoc() ? DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val)
495 : Val;
496 }
497}
498
499SDValue M68kTargetLowering::LowerMemOpCallTo(SDValue Chain, SDValue StackPtr,
500 SDValue Arg, const SDLoc &DL,
501 SelectionDAG &DAG,
502 const CCValAssign &VA,
503 ISD::ArgFlagsTy Flags) const {
504 unsigned LocMemOffset = VA.getLocMemOffset();
505 SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset, DL);
506 PtrOff = DAG.getNode(ISD::ADD, DL, getPointerTy(DAG.getDataLayout()),
507 StackPtr, PtrOff);
508 if (Flags.isByVal())
509 return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG, DL);
510
511 return DAG.getStore(
512 Chain, DL, Arg, PtrOff,
514}
515
516//===----------------------------------------------------------------------===//
517// Call
518//===----------------------------------------------------------------------===//
519
520SDValue M68kTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
521 SmallVectorImpl<SDValue> &InVals) const {
522 SelectionDAG &DAG = CLI.DAG;
523 SDLoc &DL = CLI.DL;
525 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
527 SDValue Chain = CLI.Chain;
528 SDValue Callee = CLI.Callee;
529 CallingConv::ID CallConv = CLI.CallConv;
530 bool &IsTailCall = CLI.IsTailCall;
531 bool IsVarArg = CLI.IsVarArg;
532
535 bool IsSibcall = false;
537 // const M68kRegisterInfo *TRI = Subtarget.getRegisterInfo();
538
539 if (CallConv == CallingConv::M68k_INTR)
540 report_fatal_error("M68k interrupts may not be called directly");
541
542 auto Attr = MF.getFunction().getFnAttribute("disable-tail-calls");
543 if (Attr.getValueAsBool())
544 IsTailCall = false;
545
546 // FIXME Add tailcalls support
547
548 bool IsMustTail = CLI.CB && CLI.CB->isMustTailCall();
549 if (IsMustTail) {
550 // Force this to be a tail call. The verifier rules are enough to ensure
551 // that we can lower this successfully without moving the return address
552 // around.
553 IsTailCall = true;
554 } else if (IsTailCall) {
555 // Check if it's really possible to do a tail call.
556 IsTailCall = IsEligibleForTailCallOptimization(
557 Callee, CallConv, IsVarArg, SR != NotStructReturn,
558 MF.getFunction().hasStructRetAttr(), CLI.RetTy, Outs, OutVals, Ins,
559 DAG);
560
561 // Sibcalls are automatically detected tailcalls which do not require
562 // ABI changes.
563 if (!MF.getTarget().Options.GuaranteedTailCallOpt && IsTailCall)
564 IsSibcall = true;
565
566 if (IsTailCall)
567 ++NumTailCalls;
568 }
569
570 assert(!(IsVarArg && canGuaranteeTCO(CallConv)) &&
571 "Var args not supported with calling convention fastcc");
572
573 // Analyze operands of the call, assigning locations to each operand.
575 SmallVector<Type *, 4> ArgTypes;
576 for (const auto &Arg : CLI.getArgs())
577 ArgTypes.emplace_back(Arg.Ty);
578 M68kCCState CCInfo(ArgTypes, CallConv, IsVarArg, MF, ArgLocs,
579 *DAG.getContext());
580 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);
581
582 // Get a count of how many bytes are to be pushed on the stack.
583 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
584 if (IsSibcall) {
585 // This is a sibcall. The memory operands are available in caller's
586 // own caller's stack.
587 NumBytes = 0;
588 } else if (MF.getTarget().Options.GuaranteedTailCallOpt &&
589 canGuaranteeTCO(CallConv)) {
590 NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);
591 }
592
593 int FPDiff = 0;
594 if (IsTailCall && !IsSibcall && !IsMustTail) {
595 // Lower arguments at fp - stackoffset + fpdiff.
596 unsigned NumBytesCallerPushed = MFI->getBytesToPopOnReturn();
597
598 FPDiff = NumBytesCallerPushed - NumBytes;
599
600 // Set the delta of movement of the returnaddr stackslot.
601 // But only set if delta is greater than previous delta.
602 if (FPDiff < MFI->getTCReturnAddrDelta())
603 MFI->setTCReturnAddrDelta(FPDiff);
604 }
605
606 unsigned NumBytesToPush = NumBytes;
607 unsigned NumBytesToPop = NumBytes;
608
609 // If we have an inalloca argument, all stack space has already been allocated
610 // for us and be right at the top of the stack. We don't support multiple
611 // arguments passed in memory when using inalloca.
612 if (!Outs.empty() && Outs.back().Flags.isInAlloca()) {
613 NumBytesToPush = 0;
614 if (!ArgLocs.back().isMemLoc())
615 report_fatal_error("cannot use inalloca attribute on a register "
616 "parameter");
617 if (ArgLocs.back().getLocMemOffset() != 0)
618 report_fatal_error("any parameter with the inalloca attribute must be "
619 "the only memory argument");
620 }
621
622 if (!IsSibcall)
623 Chain = DAG.getCALLSEQ_START(Chain, NumBytesToPush,
624 NumBytes - NumBytesToPush, DL);
625
626 SDValue RetFI;
627 // Load return address for tail calls.
628 if (IsTailCall && FPDiff)
629 Chain = EmitTailCallLoadRetAddr(DAG, RetFI, Chain, IsTailCall, FPDiff, DL);
630
632 SmallVector<SDValue, 8> MemOpChains;
634
635 // Walk the register/memloc assignments, inserting copies/loads. In the case
636 // of tail call optimization arguments are handle later.
637 const M68kRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
638 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
639 ISD::ArgFlagsTy Flags = Outs[i].Flags;
640
641 // Skip inalloca arguments, they have already been written.
642 if (Flags.isInAlloca())
643 continue;
644
645 CCValAssign &VA = ArgLocs[i];
646 EVT RegVT = VA.getLocVT();
647 SDValue Arg = OutVals[i];
648 bool IsByVal = Flags.isByVal();
649
650 // Promote the value if needed.
651 switch (VA.getLocInfo()) {
652 default:
653 llvm_unreachable("Unknown loc info!");
655 break;
657 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, RegVT, Arg);
658 break;
660 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, RegVT, Arg);
661 break;
663 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, RegVT, Arg);
664 break;
666 Arg = DAG.getBitcast(RegVT, Arg);
667 break;
669 // Store the argument.
670 SDValue SpillSlot = DAG.CreateStackTemporary(VA.getValVT());
671 int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
672 Chain = DAG.getStore(
673 Chain, DL, Arg, SpillSlot,
675 Arg = SpillSlot;
676 break;
677 }
678 }
679
680 if (VA.isRegLoc()) {
681 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
682 } else if (!IsSibcall && (!IsTailCall || IsByVal)) {
683 assert(VA.isMemLoc());
684 if (!StackPtr.getNode()) {
685 StackPtr = DAG.getCopyFromReg(Chain, DL, RegInfo->getStackRegister(),
687 }
688 MemOpChains.push_back(
689 LowerMemOpCallTo(Chain, StackPtr, Arg, DL, DAG, VA, Flags));
690 }
691 }
692
693 if (!MemOpChains.empty())
694 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
695
696 // FIXME Make sure PIC style GOT works as expected
697 // The only time GOT is really needed is for Medium-PIC static data
698 // otherwise we are happy with pc-rel or static references
699
700 if (IsVarArg && IsMustTail) {
701 const auto &Forwards = MFI->getForwardedMustTailRegParms();
702 for (const auto &F : Forwards) {
703 SDValue Val = DAG.getCopyFromReg(Chain, DL, F.VReg, F.VT);
704 RegsToPass.push_back(std::make_pair(unsigned(F.PReg), Val));
705 }
706 }
707
708 // For tail calls lower the arguments to the 'real' stack slots. Sibcalls
709 // don't need this because the eligibility check rejects calls that require
710 // shuffling arguments passed in memory.
711 if (!IsSibcall && IsTailCall) {
712 // Force all the incoming stack arguments to be loaded from the stack
713 // before any new outgoing arguments are stored to the stack, because the
714 // outgoing stack slots may alias the incoming argument stack slots, and
715 // the alias isn't otherwise explicit. This is slightly more conservative
716 // than necessary, because it means that each store effectively depends
717 // on every argument instead of just those arguments it would clobber.
718 SDValue ArgChain = DAG.getStackArgumentTokenFactor(Chain);
719
720 SmallVector<SDValue, 8> MemOpChains2;
721 SDValue FIN;
722 int FI = 0;
723 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
724 CCValAssign &VA = ArgLocs[i];
725 if (VA.isRegLoc())
726 continue;
727 assert(VA.isMemLoc());
728 SDValue Arg = OutVals[i];
729 ISD::ArgFlagsTy Flags = Outs[i].Flags;
730 // Skip inalloca arguments. They don't require any work.
731 if (Flags.isInAlloca())
732 continue;
733 // Create frame index.
734 int32_t Offset = VA.getLocMemOffset() + FPDiff;
735 uint32_t OpSize = (VA.getLocVT().getSizeInBits() + 7) / 8;
736 FI = MF.getFrameInfo().CreateFixedObject(OpSize, Offset, true);
737 FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
738
739 if (Flags.isByVal()) {
740 // Copy relative to framepointer.
742 if (!StackPtr.getNode()) {
743 StackPtr = DAG.getCopyFromReg(Chain, DL, RegInfo->getStackRegister(),
745 }
748
749 MemOpChains2.push_back(
750 CreateCopyOfByValArgument(Source, FIN, ArgChain, Flags, DAG, DL));
751 } else {
752 // Store relative to framepointer.
753 MemOpChains2.push_back(DAG.getStore(
754 ArgChain, DL, Arg, FIN,
756 }
757 }
758
759 if (!MemOpChains2.empty())
760 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains2);
761
762 // Store the return address to the appropriate stack slot.
763 Chain = EmitTailCallStoreRetAddr(DAG, MF, Chain, RetFI,
765 Subtarget.getSlotSize(), FPDiff, DL);
766 }
767
768 // Build a sequence of copy-to-reg nodes chained together with token chain
769 // and flag operands which copy the outgoing args into registers.
770 SDValue InGlue;
771 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
772 Chain = DAG.getCopyToReg(Chain, DL, RegsToPass[i].first,
773 RegsToPass[i].second, InGlue);
774 InGlue = Chain.getValue(1);
775 }
776
777 if (Callee->getOpcode() == ISD::GlobalAddress) {
778 // If the callee is a GlobalAddress node (quite common, every direct call
779 // is) turn it into a TargetGlobalAddress node so that legalize doesn't hack
780 // it.
781 GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Callee);
782
783 // We should use extra load for direct calls to dllimported functions in
784 // non-JIT mode.
785 const GlobalValue *GV = G->getGlobal();
786 if (!GV->hasDLLImportStorageClass()) {
787 unsigned char OpFlags = Subtarget.classifyGlobalFunctionReference(GV);
788
790 GV, DL, getPointerTy(DAG.getDataLayout()), G->getOffset(), OpFlags);
791
792 if (OpFlags == M68kII::MO_GOTPCREL) {
793
794 // Add a wrapper.
796 getPointerTy(DAG.getDataLayout()), Callee);
797
798 // Add extra indirection
799 Callee = DAG.getLoad(
800 getPointerTy(DAG.getDataLayout()), DL, DAG.getEntryNode(), Callee,
802 }
803 }
804 } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
806 unsigned char OpFlags =
807 Subtarget.classifyGlobalFunctionReference(nullptr, *Mod);
808
810 S->getSymbol(), getPointerTy(DAG.getDataLayout()), OpFlags);
811 }
812
814
815 if (!IsSibcall && IsTailCall) {
816 Chain = DAG.getCALLSEQ_END(Chain, NumBytesToPop, 0, InGlue, DL);
817 InGlue = Chain.getValue(1);
818 }
819
820 Ops.push_back(Chain);
821 Ops.push_back(Callee);
822
823 if (IsTailCall)
824 Ops.push_back(DAG.getConstant(FPDiff, DL, MVT::i32));
825
826 // Add argument registers to the end of the list so that they are known live
827 // into the call.
828 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
829 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
830 RegsToPass[i].second.getValueType()));
831
832 // Add a register mask operand representing the call-preserved registers.
833 const uint32_t *Mask = RegInfo->getCallPreservedMask(MF, CallConv);
834 assert(Mask && "Missing call preserved mask for calling convention");
835
836 Ops.push_back(DAG.getRegisterMask(Mask));
837
838 if (InGlue.getNode())
839 Ops.push_back(InGlue);
840
841 if (IsTailCall) {
843 return DAG.getNode(M68kISD::TC_RETURN, DL, MVT::Other, Ops);
844 }
845
846 // Returns a chain & a flag for retval copy to use.
847 Chain = DAG.getNode(M68kISD::CALL, DL, {MVT::Other, MVT::Glue}, Ops);
848 InGlue = Chain.getValue(1);
849
850 // Create the CALLSEQ_END node.
851 unsigned NumBytesForCalleeToPop;
852 if (M68k::isCalleePop(CallConv, IsVarArg,
854 NumBytesForCalleeToPop = NumBytes; // Callee pops everything
855 } else if (!canGuaranteeTCO(CallConv) && SR == StackStructReturn) {
856 // If this is a call to a struct-return function, the callee
857 // pops the hidden struct pointer, so we have to push it back.
858 NumBytesForCalleeToPop = 4;
859 } else {
860 NumBytesForCalleeToPop = 0; // Callee pops nothing.
861 }
862
863 if (CLI.DoesNotReturn && !getTargetMachine().Options.TrapUnreachable) {
864 // No need to reset the stack after the call if the call doesn't return. To
865 // make the MI verify, we'll pretend the callee does it for us.
866 NumBytesForCalleeToPop = NumBytes;
867 }
868
869 // Returns a flag for retval copy to use.
870 if (!IsSibcall) {
871 Chain = DAG.getCALLSEQ_END(Chain, NumBytesToPop, NumBytesForCalleeToPop,
872 InGlue, DL);
873 InGlue = Chain.getValue(1);
874 }
875
876 // Handle result values, copying them out of physregs into vregs that we
877 // return.
878 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, DL, DAG,
879 InVals);
880}
881
882SDValue M68kTargetLowering::LowerCallResult(
883 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
884 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
885 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
886
887 // Assign locations to each value returned by this call.
889 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
890 *DAG.getContext());
891 CCInfo.AnalyzeCallResult(Ins, RetCC_M68k);
892
893 // Copy all of the result registers out of their specified physreg.
894 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
895 CCValAssign &VA = RVLocs[i];
896 EVT CopyVT = VA.getLocVT();
897
898 /// ??? is this correct?
899 Chain = DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), CopyVT, InGlue)
900 .getValue(1);
901 SDValue Val = Chain.getValue(0);
902
903 if (VA.isExtInLoc() && VA.getValVT().getScalarType() == MVT::i1)
904 Val = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val);
905
906 InGlue = Chain.getValue(2);
907 InVals.push_back(Val);
908 }
909
910 return Chain;
911}
912
913//===----------------------------------------------------------------------===//
914// Formal Arguments Calling Convention Implementation
915//===----------------------------------------------------------------------===//
916
917SDValue M68kTargetLowering::LowerFormalArguments(
918 SDValue Chain, CallingConv::ID CCID, bool IsVarArg,
919 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
920 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
923 // const TargetFrameLowering &TFL = *Subtarget.getFrameLowering();
924
925 MachineFrameInfo &MFI = MF.getFrameInfo();
926
927 // Assign locations to all of the incoming arguments.
929 SmallVector<Type *, 4> ArgTypes;
930 for (const Argument &Arg : MF.getFunction().args())
931 ArgTypes.emplace_back(Arg.getType());
932 M68kCCState CCInfo(ArgTypes, CCID, IsVarArg, MF, ArgLocs, *DAG.getContext());
933
934 CCInfo.AnalyzeFormalArguments(Ins, CC_M68k);
935
936 unsigned LastVal = ~0U;
937 SDValue ArgValue;
938 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
939 CCValAssign &VA = ArgLocs[i];
940 assert(VA.getValNo() != LastVal && "Same value in different locations");
941 (void)LastVal;
942
943 LastVal = VA.getValNo();
944
945 if (VA.isRegLoc()) {
946 EVT RegVT = VA.getLocVT();
947 const TargetRegisterClass *RC;
948 if (RegVT == MVT::i32)
949 RC = &M68k::XR32RegClass;
950 else
951 llvm_unreachable("Unknown argument type!");
952
953 Register Reg = MF.addLiveIn(VA.getLocReg(), RC);
954 ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT);
955
956 // If this is an 8 or 16-bit value, it is really passed promoted to 32
957 // bits. Insert an assert[sz]ext to capture this, then truncate to the
958 // right size.
959 if (VA.getLocInfo() == CCValAssign::SExt) {
960 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
961 DAG.getValueType(VA.getValVT()));
962 } else if (VA.getLocInfo() == CCValAssign::ZExt) {
963 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
964 DAG.getValueType(VA.getValVT()));
965 } else if (VA.getLocInfo() == CCValAssign::BCvt) {
966 ArgValue = DAG.getBitcast(VA.getValVT(), ArgValue);
967 }
968
969 if (VA.isExtInLoc()) {
970 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
971 }
972 } else {
973 assert(VA.isMemLoc());
974 ArgValue = LowerMemArgument(Chain, CCID, Ins, DL, DAG, VA, MFI, i);
975 }
976
977 // If value is passed via pointer - do a load.
978 // TODO Make sure this handling on indirect arguments is correct
980 ArgValue =
981 DAG.getLoad(VA.getValVT(), DL, Chain, ArgValue, MachinePointerInfo());
982
983 InVals.push_back(ArgValue);
984 }
985
986 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
987 // Swift calling convention does not require we copy the sret argument
988 // into %D0 for the return. We don't set SRetReturnReg for Swift.
989 if (CCID == CallingConv::Swift)
990 continue;
991
992 // ABI require that for returning structs by value we copy the sret argument
993 // into %D0 for the return. Save the argument into a virtual register so
994 // that we can access it from the return points.
995 if (Ins[i].Flags.isSRet()) {
996 unsigned Reg = MMFI->getSRetReturnReg();
997 if (!Reg) {
998 MVT PtrTy = getPointerTy(DAG.getDataLayout());
1000 MMFI->setSRetReturnReg(Reg);
1001 }
1002 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals[i]);
1003 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain);
1004 break;
1005 }
1006 }
1007
1008 unsigned StackSize = CCInfo.getStackSize();
1009 // Align stack specially for tail calls.
1011 StackSize = GetAlignedArgumentStackSize(StackSize, DAG);
1012
1013 // If the function takes variable number of arguments, make a frame index for
1014 // the start of the first vararg value... for expansion of llvm.va_start. We
1015 // can skip this if there are no va_start calls.
1016 if (MFI.hasVAStart()) {
1017 MMFI->setVarArgsFrameIndex(MFI.CreateFixedObject(1, StackSize, true));
1018 }
1019
1020 if (IsVarArg && MFI.hasMustTailInVarArgFunc()) {
1021 // We forward some GPRs and some vector types.
1022 SmallVector<MVT, 2> RegParmTypes;
1023 MVT IntVT = MVT::i32;
1024 RegParmTypes.push_back(IntVT);
1025
1026 // Compute the set of forwarded registers. The rest are scratch.
1027 // ??? what is this for?
1030 CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, CC_M68k);
1031
1032 // Copy all forwards from physical to virtual registers.
1033 for (ForwardedRegister &F : Forwards) {
1034 // FIXME Can we use a less constrained schedule?
1035 SDValue RegVal = DAG.getCopyFromReg(Chain, DL, F.VReg, F.VT);
1037 Chain = DAG.getCopyToReg(Chain, DL, F.VReg, RegVal);
1038 }
1039 }
1040
1041 // Some CCs need callee pop.
1042 if (M68k::isCalleePop(CCID, IsVarArg,
1044 MMFI->setBytesToPopOnReturn(StackSize); // Callee pops everything.
1045 } else {
1046 MMFI->setBytesToPopOnReturn(0); // Callee pops nothing.
1047 // If this is an sret function, the return should pop the hidden pointer.
1049 MMFI->setBytesToPopOnReturn(4);
1050 }
1051
1052 MMFI->setArgumentStackSize(StackSize);
1053
1054 return Chain;
1055}
1056
1057//===----------------------------------------------------------------------===//
1058// Return Value Calling Convention Implementation
1059//===----------------------------------------------------------------------===//
1060
1061bool M68kTargetLowering::CanLowerReturn(
1062 CallingConv::ID CCID, MachineFunction &MF, bool IsVarArg,
1063 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
1064 const Type *RetTy) const {
1066 CCState CCInfo(CCID, IsVarArg, MF, RVLocs, Context);
1067 return CCInfo.CheckReturn(Outs, RetCC_M68k);
1068}
1069
1070SDValue
1071M68kTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CCID,
1072 bool IsVarArg,
1074 const SmallVectorImpl<SDValue> &OutVals,
1075 const SDLoc &DL, SelectionDAG &DAG) const {
1078
1080 CCState CCInfo(CCID, IsVarArg, MF, RVLocs, *DAG.getContext());
1081 CCInfo.AnalyzeReturn(Outs, RetCC_M68k);
1082
1083 SDValue Glue;
1085 // Operand #0 = Chain (updated below)
1086 RetOps.push_back(Chain);
1087 // Operand #1 = Bytes To Pop
1088 RetOps.push_back(
1089 DAG.getTargetConstant(MFI->getBytesToPopOnReturn(), DL, MVT::i32));
1090
1091 // Copy the result values into the output registers.
1092 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
1093 CCValAssign &VA = RVLocs[i];
1094 assert(VA.isRegLoc() && "Can only return in registers!");
1095 SDValue ValToCopy = OutVals[i];
1096 EVT ValVT = ValToCopy.getValueType();
1097
1098 // Promote values to the appropriate types.
1099 if (VA.getLocInfo() == CCValAssign::SExt)
1100 ValToCopy = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), ValToCopy);
1101 else if (VA.getLocInfo() == CCValAssign::ZExt)
1102 ValToCopy = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), ValToCopy);
1103 else if (VA.getLocInfo() == CCValAssign::AExt) {
1104 if (ValVT.isVector() && ValVT.getVectorElementType() == MVT::i1)
1105 ValToCopy = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), ValToCopy);
1106 else
1107 ValToCopy = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), ValToCopy);
1108 } else if (VA.getLocInfo() == CCValAssign::BCvt)
1109 ValToCopy = DAG.getBitcast(VA.getLocVT(), ValToCopy);
1110
1111 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), ValToCopy, Glue);
1112 Glue = Chain.getValue(1);
1113 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
1114 }
1115
1116 // Swift calling convention does not require we copy the sret argument
1117 // into %d0 for the return, and SRetReturnReg is not set for Swift.
1118
1119 // ABI require that for returning structs by value we copy the sret argument
1120 // into %D0 for the return. Save the argument into a virtual register so that
1121 // we can access it from the return points.
1122 //
1123 // Checking Function.hasStructRetAttr() here is insufficient because the IR
1124 // may not have an explicit sret argument. If MFI.CanLowerReturn is
1125 // false, then an sret argument may be implicitly inserted in the SelDAG. In
1126 // either case MFI->setSRetReturnReg() will have been called.
1127 if (unsigned SRetReg = MFI->getSRetReturnReg()) {
1128 // ??? Can i just move this to the top and escape this explanation?
1129 // When we have both sret and another return value, we should use the
1130 // original Chain stored in RetOps[0], instead of the current Chain updated
1131 // in the above loop. If we only have sret, RetOps[0] equals to Chain.
1132
1133 // For the case of sret and another return value, we have
1134 // Chain_0 at the function entry
1135 // Chain_1 = getCopyToReg(Chain_0) in the above loop
1136 // If we use Chain_1 in getCopyFromReg, we will have
1137 // Val = getCopyFromReg(Chain_1)
1138 // Chain_2 = getCopyToReg(Chain_1, Val) from below
1139
1140 // getCopyToReg(Chain_0) will be glued together with
1141 // getCopyToReg(Chain_1, Val) into Unit A, getCopyFromReg(Chain_1) will be
1142 // in Unit B, and we will have cyclic dependency between Unit A and Unit B:
1143 // Data dependency from Unit B to Unit A due to usage of Val in
1144 // getCopyToReg(Chain_1, Val)
1145 // Chain dependency from Unit A to Unit B
1146
1147 // So here, we use RetOps[0] (i.e Chain_0) for getCopyFromReg.
1148 SDValue Val = DAG.getCopyFromReg(RetOps[0], DL, SRetReg,
1150
1151 // ??? How will this work if CC does not use registers for args passing?
1152 // ??? What if I return multiple structs?
1153 unsigned RetValReg = M68k::D0;
1154 Chain = DAG.getCopyToReg(Chain, DL, RetValReg, Val, Glue);
1155 Glue = Chain.getValue(1);
1156
1157 RetOps.push_back(
1158 DAG.getRegister(RetValReg, getPointerTy(DAG.getDataLayout())));
1159 }
1160
1161 RetOps[0] = Chain; // Update chain.
1162
1163 // Add the glue if we have it.
1164 if (Glue.getNode())
1165 RetOps.push_back(Glue);
1166
1167 return DAG.getNode(M68kISD::RET, DL, MVT::Other, RetOps);
1168}
1169
1170//===----------------------------------------------------------------------===//
1171// Fast Calling Convention (tail call) implementation
1172//===----------------------------------------------------------------------===//
1173
1174// Like std call, callee cleans arguments, convention except that ECX is
1175// reserved for storing the tail called function address. Only 2 registers are
1176// free for argument passing (inreg). Tail call optimization is performed
1177// provided:
1178// * tailcallopt is enabled
1179// * caller/callee are fastcc
1180// On M68k_64 architecture with GOT-style position independent code only
1181// local (within module) calls are supported at the moment. To keep the stack
1182// aligned according to platform abi the function GetAlignedArgumentStackSize
1183// ensures that argument delta is always multiples of stack alignment. (Dynamic
1184// linkers need this - darwin's dyld for example) If a tail called function
1185// callee has more arguments than the caller the caller needs to make sure that
1186// there is room to move the RETADDR to. This is achieved by reserving an area
1187// the size of the argument delta right after the original RETADDR, but before
1188// the saved framepointer or the spilled registers e.g. caller(arg1, arg2)
1189// calls callee(arg1, arg2,arg3,arg4) stack layout:
1190// arg1
1191// arg2
1192// RETADDR
1193// [ new RETADDR
1194// move area ]
1195// (possible EBP)
1196// ESI
1197// EDI
1198// local1 ..
1199
1200/// Make the stack size align e.g 16n + 12 aligned for a 16-byte align
1201/// requirement.
1202unsigned
1203M68kTargetLowering::GetAlignedArgumentStackSize(unsigned StackSize,
1204 SelectionDAG &DAG) const {
1205 const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();
1206 unsigned StackAlignment = TFI.getStackAlignment();
1207 uint64_t AlignMask = StackAlignment - 1;
1208 int64_t Offset = StackSize;
1209 unsigned SlotSize = Subtarget.getSlotSize();
1210 if ((Offset & AlignMask) <= (StackAlignment - SlotSize)) {
1211 // Number smaller than 12 so just add the difference.
1212 Offset += ((StackAlignment - SlotSize) - (Offset & AlignMask));
1213 } else {
1214 // Mask out lower bits, add stackalignment once plus the 12 bytes.
1215 Offset =
1216 ((~AlignMask) & Offset) + StackAlignment + (StackAlignment - SlotSize);
1217 }
1218 return Offset;
1219}
1220
1221/// Check whether the call is eligible for tail call optimization. Targets
1222/// that want to do tail call optimization should implement this function.
1223bool M68kTargetLowering::IsEligibleForTailCallOptimization(
1224 SDValue Callee, CallingConv::ID CalleeCC, bool IsVarArg,
1225 bool IsCalleeStructRet, bool IsCallerStructRet, Type *RetTy,
1227 const SmallVectorImpl<SDValue> &OutVals,
1228 const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG &DAG) const {
1229 if (!mayTailCallThisCC(CalleeCC))
1230 return false;
1231
1232 // If -tailcallopt is specified, make fastcc functions tail-callable.
1234 const auto &CallerF = MF.getFunction();
1235
1236 CallingConv::ID CallerCC = CallerF.getCallingConv();
1237 bool CCMatch = CallerCC == CalleeCC;
1238
1240 if (canGuaranteeTCO(CalleeCC) && CCMatch)
1241 return true;
1242 return false;
1243 }
1244
1245 // Look for obvious safe cases to perform tail call optimization that do not
1246 // require ABI changes. This is what gcc calls sibcall.
1247
1248 // Can't do sibcall if stack needs to be dynamically re-aligned. PEI needs to
1249 // emit a special epilogue.
1250 const M68kRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1251 if (RegInfo->hasStackRealignment(MF))
1252 return false;
1253
1254 // Also avoid sibcall optimization if either caller or callee uses struct
1255 // return semantics.
1256 if (IsCalleeStructRet || IsCallerStructRet)
1257 return false;
1258
1259 // Do not sibcall optimize vararg calls unless all arguments are passed via
1260 // registers.
1261 LLVMContext &C = *DAG.getContext();
1262 if (IsVarArg && !Outs.empty()) {
1263
1265 CCState CCInfo(CalleeCC, IsVarArg, MF, ArgLocs, C);
1266
1267 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);
1268 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i)
1269 if (!ArgLocs[i].isRegLoc())
1270 return false;
1271 }
1272
1273 // Check that the call results are passed in the same way.
1274 if (!CCState::resultsCompatible(CalleeCC, CallerCC, MF, C, Ins, RetCC_M68k,
1275 RetCC_M68k))
1276 return false;
1277
1278 // The callee has to preserve all registers the caller needs to preserve.
1279 const M68kRegisterInfo *TRI = Subtarget.getRegisterInfo();
1280 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
1281 if (!CCMatch) {
1282 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);
1283 if (!TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
1284 return false;
1285 }
1286
1287 unsigned StackArgsSize = 0;
1288
1289 // If the callee takes no arguments then go on to check the results of the
1290 // call.
1291 if (!Outs.empty()) {
1292 // Check if stack adjustment is needed. For now, do not do this if any
1293 // argument is passed on the stack.
1295 CCState CCInfo(CalleeCC, IsVarArg, MF, ArgLocs, C);
1296
1297 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);
1298 StackArgsSize = CCInfo.getStackSize();
1299
1300 if (StackArgsSize) {
1301 // Check if the arguments are already laid out in the right way as
1302 // the caller's fixed stack objects.
1303 MachineFrameInfo &MFI = MF.getFrameInfo();
1304 const MachineRegisterInfo *MRI = &MF.getRegInfo();
1305 const M68kInstrInfo *TII = Subtarget.getInstrInfo();
1306 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1307 CCValAssign &VA = ArgLocs[i];
1308 SDValue Arg = OutVals[i];
1309 ISD::ArgFlagsTy Flags = Outs[i].Flags;
1311 return false;
1312 if (!VA.isRegLoc()) {
1313 if (!MatchingStackOffset(Arg, VA.getLocMemOffset(), Flags, MFI, MRI,
1314 TII, VA))
1315 return false;
1316 }
1317 }
1318 }
1319
1320 bool PositionIndependent = isPositionIndependent();
1321 // If the tailcall address may be in a register, then make sure it's
1322 // possible to register allocate for it. The call address can
1323 // only target %A0 or %A1 since the tail call must be scheduled after
1324 // callee-saved registers are restored. These happen to be the same
1325 // registers used to pass 'inreg' arguments so watch out for those.
1326 if ((!isa<GlobalAddressSDNode>(Callee) &&
1327 !isa<ExternalSymbolSDNode>(Callee)) ||
1328 PositionIndependent) {
1329 unsigned NumInRegs = 0;
1330 // In PIC we need an extra register to formulate the address computation
1331 // for the callee.
1332 unsigned MaxInRegs = PositionIndependent ? 1 : 2;
1333
1334 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
1335 CCValAssign &VA = ArgLocs[i];
1336 if (!VA.isRegLoc())
1337 continue;
1338 Register Reg = VA.getLocReg();
1339 switch (Reg) {
1340 default:
1341 break;
1342 case M68k::A0:
1343 case M68k::A1:
1344 if (++NumInRegs == MaxInRegs)
1345 return false;
1346 break;
1347 }
1348 }
1349 }
1350
1351 const MachineRegisterInfo &MRI = MF.getRegInfo();
1352 if (!parametersInCSRMatch(MRI, CallerPreserved, ArgLocs, OutVals))
1353 return false;
1354 }
1355
1356 bool CalleeWillPop = M68k::isCalleePop(
1357 CalleeCC, IsVarArg, MF.getTarget().Options.GuaranteedTailCallOpt);
1358
1359 if (unsigned BytesToPop =
1361 // If we have bytes to pop, the callee must pop them.
1362 bool CalleePopMatches = CalleeWillPop && BytesToPop == StackArgsSize;
1363 if (!CalleePopMatches)
1364 return false;
1365 } else if (CalleeWillPop && StackArgsSize > 0) {
1366 // If we don't have bytes to pop, make sure the callee doesn't pop any.
1367 return false;
1368 }
1369
1370 return true;
1371}
1372
1373//===----------------------------------------------------------------------===//
1374// Custom Lower
1375//===----------------------------------------------------------------------===//
1376
1378 SelectionDAG &DAG) const {
1379 switch (Op.getOpcode()) {
1380 default:
1381 llvm_unreachable("Should not custom lower this!");
1382 case ISD::SADDO:
1383 case ISD::UADDO:
1384 case ISD::SSUBO:
1385 case ISD::USUBO:
1386 case ISD::SMULO:
1387 case ISD::UMULO:
1388 return LowerXALUO(Op, DAG);
1389 case ISD::SETCC:
1390 return LowerSETCC(Op, DAG);
1391 case ISD::SETCCCARRY:
1392 return LowerSETCCCARRY(Op, DAG);
1393 case ISD::SELECT:
1394 return LowerSELECT(Op, DAG);
1395 case ISD::BRCOND:
1396 return LowerBRCOND(Op, DAG);
1397 case ISD::ADDC:
1398 case ISD::ADDE:
1399 case ISD::SUBC:
1400 case ISD::SUBE:
1401 return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
1402 case ISD::ConstantPool:
1403 return LowerConstantPool(Op, DAG);
1404 case ISD::GlobalAddress:
1405 return LowerGlobalAddress(Op, DAG);
1407 return LowerExternalSymbol(Op, DAG);
1408 case ISD::BlockAddress:
1409 return LowerBlockAddress(Op, DAG);
1410 case ISD::JumpTable:
1411 return LowerJumpTable(Op, DAG);
1412 case ISD::VASTART:
1413 return LowerVASTART(Op, DAG);
1415 return LowerDYNAMIC_STACKALLOC(Op, DAG);
1416 case ISD::SHL_PARTS:
1417 return LowerShiftLeftParts(Op, DAG);
1418 case ISD::SRA_PARTS:
1419 return LowerShiftRightParts(Op, DAG, true);
1420 case ISD::SRL_PARTS:
1421 return LowerShiftRightParts(Op, DAG, false);
1422 case ISD::ATOMIC_FENCE:
1423 return LowerATOMICFENCE(Op, DAG);
1425 return LowerGlobalTLSAddress(Op, DAG);
1426 }
1427}
1428
1429SDValue M68kTargetLowering::LowerExternalSymbolCall(SelectionDAG &DAG,
1430 SDLoc Loc,
1431 llvm::StringRef SymbolName,
1432 ArgListTy &&ArgList) const {
1433 PointerType *PtrTy = PointerType::get(*DAG.getContext(), 0);
1434 CallLoweringInfo CLI(DAG);
1435 CLI.setDebugLoc(Loc)
1436 .setChain(DAG.getEntryNode())
1438 DAG.getExternalSymbol(SymbolName.data(),
1440 std::move(ArgList));
1441 return LowerCallTo(CLI).first;
1442}
1443
1444SDValue M68kTargetLowering::getTLSGetAddr(GlobalAddressSDNode *GA,
1445 SelectionDAG &DAG,
1446 unsigned TargetFlags) const {
1447 SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32);
1449 GA->getGlobal(), GA, GA->getValueType(0), GA->getOffset(), TargetFlags);
1450 SDValue Arg = DAG.getNode(ISD::ADD, SDLoc(GA), MVT::i32, GOT, TGA);
1451
1452 PointerType *PtrTy = PointerType::get(*DAG.getContext(), 0);
1453
1454 ArgListTy Args;
1455 ArgListEntry Entry;
1456 Entry.Node = Arg;
1457 Entry.Ty = PtrTy;
1458 Args.push_back(Entry);
1459 return LowerExternalSymbolCall(DAG, SDLoc(GA), "__tls_get_addr",
1460 std::move(Args));
1461}
1462
1463SDValue M68kTargetLowering::getM68kReadTp(SDLoc Loc, SelectionDAG &DAG) const {
1464 return LowerExternalSymbolCall(DAG, Loc, "__m68k_read_tp", ArgListTy());
1465}
1466
1467SDValue M68kTargetLowering::LowerTLSGeneralDynamic(GlobalAddressSDNode *GA,
1468 SelectionDAG &DAG) const {
1469 return getTLSGetAddr(GA, DAG, M68kII::MO_TLSGD);
1470}
1471
1472SDValue M68kTargetLowering::LowerTLSLocalDynamic(GlobalAddressSDNode *GA,
1473 SelectionDAG &DAG) const {
1474 SDValue Addr = getTLSGetAddr(GA, DAG, M68kII::MO_TLSLDM);
1475 SDValue TGA =
1476 DAG.getTargetGlobalAddress(GA->getGlobal(), GA, GA->getValueType(0),
1478 return DAG.getNode(ISD::ADD, SDLoc(GA), MVT::i32, TGA, Addr);
1479}
1480
1481SDValue M68kTargetLowering::LowerTLSInitialExec(GlobalAddressSDNode *GA,
1482 SelectionDAG &DAG) const {
1483 SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32);
1484 SDValue Tp = getM68kReadTp(SDLoc(GA), DAG);
1485 SDValue TGA =
1486 DAG.getTargetGlobalAddress(GA->getGlobal(), GA, GA->getValueType(0),
1488 SDValue Addr = DAG.getNode(ISD::ADD, SDLoc(GA), MVT::i32, TGA, GOT);
1489 SDValue Offset =
1490 DAG.getLoad(MVT::i32, SDLoc(GA), DAG.getEntryNode(), Addr,
1492
1493 return DAG.getNode(ISD::ADD, SDLoc(GA), MVT::i32, Offset, Tp);
1494}
1495
1496SDValue M68kTargetLowering::LowerTLSLocalExec(GlobalAddressSDNode *GA,
1497 SelectionDAG &DAG) const {
1498 SDValue Tp = getM68kReadTp(SDLoc(GA), DAG);
1499 SDValue TGA =
1500 DAG.getTargetGlobalAddress(GA->getGlobal(), GA, GA->getValueType(0),
1502 return DAG.getNode(ISD::ADD, SDLoc(GA), MVT::i32, TGA, Tp);
1503}
1504
1505SDValue M68kTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1506 SelectionDAG &DAG) const {
1507 assert(Subtarget.isTargetELF());
1508
1509 auto *GA = cast<GlobalAddressSDNode>(Op);
1510 TLSModel::Model AccessModel = DAG.getTarget().getTLSModel(GA->getGlobal());
1511
1512 switch (AccessModel) {
1514 return LowerTLSGeneralDynamic(GA, DAG);
1516 return LowerTLSLocalDynamic(GA, DAG);
1518 return LowerTLSInitialExec(GA, DAG);
1520 return LowerTLSLocalExec(GA, DAG);
1521 }
1522
1523 llvm_unreachable("Unexpected TLS access model type");
1524}
1525
1526bool M68kTargetLowering::decomposeMulByConstant(LLVMContext &Context, EVT VT,
1527 SDValue C) const {
1528 // Shifts and add instructions in M68000 and M68010 support
1529 // up to 32 bits, but mul only has 16-bit variant. So it's almost
1530 // certainly beneficial to lower 8/16/32-bit mul to their
1531 // add / shifts counterparts. But for 64-bits mul, it might be
1532 // safer to just leave it to compiler runtime implementations.
1533 return VT.bitsLE(MVT::i32) || Subtarget.atLeastM68020();
1534}
1535
1536static bool isOverflowArithmetic(unsigned Opcode) {
1537 switch (Opcode) {
1538 case ISD::UADDO:
1539 case ISD::SADDO:
1540 case ISD::USUBO:
1541 case ISD::SSUBO:
1542 case ISD::UMULO:
1543 case ISD::SMULO:
1544 return true;
1545 default:
1546 return false;
1547 }
1548}
1549
1551 SDValue &Result, SDValue &CCR,
1552 unsigned &CC) {
1553 SDNode *N = Op.getNode();
1554 EVT VT = N->getValueType(0);
1555 SDValue LHS = N->getOperand(0);
1556 SDValue RHS = N->getOperand(1);
1557 SDLoc DL(Op);
1558
1559 unsigned TruncOp = 0;
1560 auto PromoteMULO = [&](unsigned ExtOp) {
1561 // We don't have 8-bit multiplications, so promote i8 version of U/SMULO
1562 // to i16.
1563 // Ideally this should be done by legalizer but sadly there is no promotion
1564 // rule for U/SMULO at this moment.
1565 if (VT == MVT::i8) {
1566 LHS = DAG.getNode(ExtOp, DL, MVT::i16, LHS);
1567 RHS = DAG.getNode(ExtOp, DL, MVT::i16, RHS);
1568 VT = MVT::i16;
1569 TruncOp = ISD::TRUNCATE;
1570 }
1571 };
1572
1573 bool NoOverflow = false;
1574 unsigned BaseOp = 0;
1575 switch (Op.getOpcode()) {
1576 default:
1577 llvm_unreachable("Unknown ovf instruction!");
1578 case ISD::SADDO:
1579 BaseOp = M68kISD::ADD;
1580 CC = M68k::COND_VS;
1581 break;
1582 case ISD::UADDO:
1583 BaseOp = M68kISD::ADD;
1584 CC = M68k::COND_CS;
1585 break;
1586 case ISD::SSUBO:
1587 BaseOp = M68kISD::SUB;
1588 CC = M68k::COND_VS;
1589 break;
1590 case ISD::USUBO:
1591 BaseOp = M68kISD::SUB;
1592 CC = M68k::COND_CS;
1593 break;
1594 case ISD::UMULO:
1595 PromoteMULO(ISD::ZERO_EXTEND);
1596 NoOverflow = VT != MVT::i32;
1597 BaseOp = NoOverflow ? ISD::MUL : M68kISD::UMUL;
1598 CC = M68k::COND_VS;
1599 break;
1600 case ISD::SMULO:
1601 PromoteMULO(ISD::SIGN_EXTEND);
1602 NoOverflow = VT != MVT::i32;
1603 BaseOp = NoOverflow ? ISD::MUL : M68kISD::SMUL;
1604 CC = M68k::COND_VS;
1605 break;
1606 }
1607
1608 SDVTList VTs;
1609 if (NoOverflow)
1610 VTs = DAG.getVTList(VT);
1611 else
1612 // Also sets CCR.
1613 VTs = DAG.getVTList(VT, MVT::i8);
1614
1615 SDValue Arith = DAG.getNode(BaseOp, DL, VTs, LHS, RHS);
1616 Result = Arith.getValue(0);
1617 if (TruncOp)
1618 // Right now the only place to truncate is from i16 to i8.
1619 Result = DAG.getNode(TruncOp, DL, MVT::i8, Arith);
1620
1621 if (NoOverflow)
1622 CCR = DAG.getConstant(0, DL, N->getValueType(1));
1623 else
1624 CCR = Arith.getValue(1);
1625}
1626
1627SDValue M68kTargetLowering::LowerXALUO(SDValue Op, SelectionDAG &DAG) const {
1628 SDNode *N = Op.getNode();
1629 SDLoc DL(Op);
1630
1631 // Lower the "add/sub/mul with overflow" instruction into a regular ins plus
1632 // a "setcc" instruction that checks the overflow flag.
1633 SDValue Result, CCR;
1634 unsigned CC;
1635 lowerOverflowArithmetic(Op, DAG, Result, CCR, CC);
1636
1637 SDValue Overflow;
1638 if (isa<ConstantSDNode>(CCR)) {
1639 // It's likely a result of operations that will not overflow
1640 // hence no setcc is needed.
1641 Overflow = CCR;
1642 } else {
1643 // Generate a M68kISD::SETCC.
1644 Overflow = DAG.getNode(M68kISD::SETCC, DL, N->getValueType(1),
1645 DAG.getConstant(CC, DL, MVT::i8), CCR);
1646 }
1647
1648 return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, Overflow);
1649}
1650
1651/// Create a BTST (Bit Test) node - Test bit \p BitNo in \p Src and set
1652/// condition according to equal/not-equal condition code \p CC.
1654 const SDLoc &DL, SelectionDAG &DAG) {
1655 // If Src is i8, promote it to i32 with any_extend. There is no i8 BTST
1656 // instruction. Since the shift amount is in-range-or-undefined, we know
1657 // that doing a bittest on the i32 value is ok.
1658 if (Src.getValueType() == MVT::i8 || Src.getValueType() == MVT::i16)
1659 Src = DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i32, Src);
1660
1661 // If the operand types disagree, extend the shift amount to match. Since
1662 // BTST ignores high bits (like shifts) we can use anyextend.
1663 if (Src.getValueType() != BitNo.getValueType())
1664 BitNo = DAG.getNode(ISD::ANY_EXTEND, DL, Src.getValueType(), BitNo);
1665
1666 SDValue BTST = DAG.getNode(M68kISD::BTST, DL, MVT::i32, Src, BitNo);
1667
1668 // NOTE BTST sets CCR.Z flag
1670 return DAG.getNode(M68kISD::SETCC, DL, MVT::i8,
1671 DAG.getConstant(Cond, DL, MVT::i8), BTST);
1672}
1673
1674/// Result of 'and' is compared against zero. Change to a BTST node if possible.
1676 SelectionDAG &DAG) {
1677 SDValue Op0 = And.getOperand(0);
1678 SDValue Op1 = And.getOperand(1);
1679 if (Op0.getOpcode() == ISD::TRUNCATE)
1680 Op0 = Op0.getOperand(0);
1681 if (Op1.getOpcode() == ISD::TRUNCATE)
1682 Op1 = Op1.getOperand(0);
1683
1684 SDValue LHS, RHS;
1685 if (Op1.getOpcode() == ISD::SHL)
1686 std::swap(Op0, Op1);
1687 if (Op0.getOpcode() == ISD::SHL) {
1688 if (isOneConstant(Op0.getOperand(0))) {
1689 // If we looked past a truncate, check that it's only truncating away
1690 // known zeros.
1691 unsigned BitWidth = Op0.getValueSizeInBits();
1692 unsigned AndBitWidth = And.getValueSizeInBits();
1693 if (BitWidth > AndBitWidth) {
1694 auto Known = DAG.computeKnownBits(Op0);
1695 if (Known.countMinLeadingZeros() < BitWidth - AndBitWidth)
1696 return SDValue();
1697 }
1698 LHS = Op1;
1699 RHS = Op0.getOperand(1);
1700 }
1701 } else if (auto *AndRHS = dyn_cast<ConstantSDNode>(Op1)) {
1702 uint64_t AndRHSVal = AndRHS->getZExtValue();
1703 SDValue AndLHS = Op0;
1704
1705 if (AndRHSVal == 1 && AndLHS.getOpcode() == ISD::SRL) {
1706 LHS = AndLHS.getOperand(0);
1707 RHS = AndLHS.getOperand(1);
1708 }
1709
1710 // Use BTST if the immediate can't be encoded in a TEST instruction.
1711 if (!isUInt<32>(AndRHSVal) && isPowerOf2_64(AndRHSVal)) {
1712 LHS = AndLHS;
1713 RHS = DAG.getConstant(Log2_64_Ceil(AndRHSVal), DL, LHS.getValueType());
1714 }
1715 }
1716
1717 if (LHS.getNode())
1718 return getBitTestCondition(LHS, RHS, CC, DL, DAG);
1719
1720 return SDValue();
1721}
1722
1724 switch (SetCCOpcode) {
1725 default:
1726 llvm_unreachable("Invalid integer condition!");
1727 case ISD::SETEQ:
1728 return M68k::COND_EQ;
1729 case ISD::SETGT:
1730 return M68k::COND_GT;
1731 case ISD::SETGE:
1732 return M68k::COND_GE;
1733 case ISD::SETLT:
1734 return M68k::COND_LT;
1735 case ISD::SETLE:
1736 return M68k::COND_LE;
1737 case ISD::SETNE:
1738 return M68k::COND_NE;
1739 case ISD::SETULT:
1740 return M68k::COND_CS;
1741 case ISD::SETUGE:
1742 return M68k::COND_CC;
1743 case ISD::SETUGT:
1744 return M68k::COND_HI;
1745 case ISD::SETULE:
1746 return M68k::COND_LS;
1747 }
1748}
1749
1750/// Do a one-to-one translation of a ISD::CondCode to the M68k-specific
1751/// condition code, returning the condition code and the LHS/RHS of the
1752/// comparison to make.
1753static unsigned TranslateM68kCC(ISD::CondCode SetCCOpcode, const SDLoc &DL,
1754 bool IsFP, SDValue &LHS, SDValue &RHS,
1755 SelectionDAG &DAG) {
1756 if (!IsFP) {
1757 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
1758 if (SetCCOpcode == ISD::SETGT && RHSC->isAllOnes()) {
1759 // X > -1 -> X == 0, jump !sign.
1760 RHS = DAG.getConstant(0, DL, RHS.getValueType());
1761 return M68k::COND_PL;
1762 }
1763 if (SetCCOpcode == ISD::SETLT && RHSC->isZero()) {
1764 // X < 0 -> X == 0, jump on sign.
1765 return M68k::COND_MI;
1766 }
1767 if (SetCCOpcode == ISD::SETLT && RHSC->getZExtValue() == 1) {
1768 // X < 1 -> X <= 0
1769 RHS = DAG.getConstant(0, DL, RHS.getValueType());
1770 return M68k::COND_LE;
1771 }
1772 }
1773
1774 return TranslateIntegerM68kCC(SetCCOpcode);
1775 }
1776
1777 // First determine if it is required or is profitable to flip the operands.
1778
1779 // If LHS is a foldable load, but RHS is not, flip the condition.
1780 if (ISD::isNON_EXTLoad(LHS.getNode()) && !ISD::isNON_EXTLoad(RHS.getNode())) {
1781 SetCCOpcode = getSetCCSwappedOperands(SetCCOpcode);
1782 std::swap(LHS, RHS);
1783 }
1784
1785 switch (SetCCOpcode) {
1786 default:
1787 break;
1788 case ISD::SETOLT:
1789 case ISD::SETOLE:
1790 case ISD::SETUGT:
1791 case ISD::SETUGE:
1792 std::swap(LHS, RHS);
1793 break;
1794 }
1795
1796 // On a floating point condition, the flags are set as follows:
1797 // ZF PF CF op
1798 // 0 | 0 | 0 | X > Y
1799 // 0 | 0 | 1 | X < Y
1800 // 1 | 0 | 0 | X == Y
1801 // 1 | 1 | 1 | unordered
1802 switch (SetCCOpcode) {
1803 default:
1804 llvm_unreachable("Condcode should be pre-legalized away");
1805 case ISD::SETUEQ:
1806 case ISD::SETEQ:
1807 return M68k::COND_EQ;
1808 case ISD::SETOLT: // flipped
1809 case ISD::SETOGT:
1810 case ISD::SETGT:
1811 return M68k::COND_HI;
1812 case ISD::SETOLE: // flipped
1813 case ISD::SETOGE:
1814 case ISD::SETGE:
1815 return M68k::COND_CC;
1816 case ISD::SETUGT: // flipped
1817 case ISD::SETULT:
1818 case ISD::SETLT:
1819 return M68k::COND_CS;
1820 case ISD::SETUGE: // flipped
1821 case ISD::SETULE:
1822 case ISD::SETLE:
1823 return M68k::COND_LS;
1824 case ISD::SETONE:
1825 case ISD::SETNE:
1826 return M68k::COND_NE;
1827 case ISD::SETOEQ:
1828 case ISD::SETUNE:
1829 return M68k::COND_INVALID;
1830 }
1831}
1832
1833// Convert (truncate (srl X, N) to i1) to (bt X, N)
1835 const SDLoc &DL, SelectionDAG &DAG) {
1836
1837 assert(Op.getOpcode() == ISD::TRUNCATE && Op.getValueType() == MVT::i1 &&
1838 "Expected TRUNCATE to i1 node");
1839
1840 if (Op.getOperand(0).getOpcode() != ISD::SRL)
1841 return SDValue();
1842
1843 SDValue ShiftRight = Op.getOperand(0);
1844 return getBitTestCondition(ShiftRight.getOperand(0), ShiftRight.getOperand(1),
1845 CC, DL, DAG);
1846}
1847
1848/// \brief return true if \c Op has a use that doesn't just read flags.
1850 for (SDNode::use_iterator UI = Op->use_begin(), UE = Op->use_end(); UI != UE;
1851 ++UI) {
1852 SDNode *User = UI->getUser();
1853 unsigned UOpNo = UI->getOperandNo();
1854 if (User->getOpcode() == ISD::TRUNCATE && User->hasOneUse()) {
1855 // Look past truncate.
1856 UOpNo = User->use_begin()->getOperandNo();
1857 User = User->use_begin()->getUser();
1858 }
1859
1860 if (User->getOpcode() != ISD::BRCOND && User->getOpcode() != ISD::SETCC &&
1861 !(User->getOpcode() == ISD::SELECT && UOpNo == 0))
1862 return true;
1863 }
1864 return false;
1865}
1866
1867SDValue M68kTargetLowering::EmitTest(SDValue Op, unsigned M68kCC,
1868 const SDLoc &DL, SelectionDAG &DAG) const {
1869
1870 // CF and OF aren't always set the way we want. Determine which
1871 // of these we need.
1872 bool NeedCF = false;
1873 bool NeedOF = false;
1874 switch (M68kCC) {
1875 default:
1876 break;
1877 case M68k::COND_HI:
1878 case M68k::COND_CC:
1879 case M68k::COND_CS:
1880 case M68k::COND_LS:
1881 NeedCF = true;
1882 break;
1883 case M68k::COND_GT:
1884 case M68k::COND_GE:
1885 case M68k::COND_LT:
1886 case M68k::COND_LE:
1887 case M68k::COND_VS:
1888 case M68k::COND_VC: {
1889 // Check if we really need to set the
1890 // Overflow flag. If NoSignedWrap is present
1891 // that is not actually needed.
1892 switch (Op->getOpcode()) {
1893 case ISD::ADD:
1894 case ISD::SUB:
1895 case ISD::MUL:
1896 case ISD::SHL: {
1897 if (Op.getNode()->getFlags().hasNoSignedWrap())
1898 break;
1899 [[fallthrough]];
1900 }
1901 default:
1902 NeedOF = true;
1903 break;
1904 }
1905 break;
1906 }
1907 }
1908 // See if we can use the CCR value from the operand instead of
1909 // doing a separate TEST. TEST always sets OF and CF to 0, so unless
1910 // we prove that the arithmetic won't overflow, we can't use OF or CF.
1911 if (Op.getResNo() != 0 || NeedOF || NeedCF) {
1912 // Emit a CMP with 0, which is the TEST pattern.
1913 return DAG.getNode(M68kISD::CMP, DL, MVT::i8,
1914 DAG.getConstant(0, DL, Op.getValueType()), Op);
1915 }
1916 unsigned Opcode = 0;
1917 unsigned NumOperands = 0;
1918
1919 // Truncate operations may prevent the merge of the SETCC instruction
1920 // and the arithmetic instruction before it. Attempt to truncate the operands
1921 // of the arithmetic instruction and use a reduced bit-width instruction.
1922 bool NeedTruncation = false;
1923 SDValue ArithOp = Op;
1924 if (Op->getOpcode() == ISD::TRUNCATE && Op->hasOneUse()) {
1925 SDValue Arith = Op->getOperand(0);
1926 // Both the trunc and the arithmetic op need to have one user each.
1927 if (Arith->hasOneUse())
1928 switch (Arith.getOpcode()) {
1929 default:
1930 break;
1931 case ISD::ADD:
1932 case ISD::SUB:
1933 case ISD::AND:
1934 case ISD::OR:
1935 case ISD::XOR: {
1936 NeedTruncation = true;
1937 ArithOp = Arith;
1938 }
1939 }
1940 }
1941
1942 // NOTICE: In the code below we use ArithOp to hold the arithmetic operation
1943 // which may be the result of a CAST. We use the variable 'Op', which is the
1944 // non-casted variable when we check for possible users.
1945 switch (ArithOp.getOpcode()) {
1946 case ISD::ADD:
1947 Opcode = M68kISD::ADD;
1948 NumOperands = 2;
1949 break;
1950 case ISD::SHL:
1951 case ISD::SRL:
1952 // If we have a constant logical shift that's only used in a comparison
1953 // against zero turn it into an equivalent AND. This allows turning it into
1954 // a TEST instruction later.
1955 if ((M68kCC == M68k::COND_EQ || M68kCC == M68k::COND_NE) &&
1956 Op->hasOneUse() && isa<ConstantSDNode>(Op->getOperand(1)) &&
1957 !hasNonFlagsUse(Op)) {
1958 EVT VT = Op.getValueType();
1959 unsigned BitWidth = VT.getSizeInBits();
1960 unsigned ShAmt = Op->getConstantOperandVal(1);
1961 if (ShAmt >= BitWidth) // Avoid undefined shifts.
1962 break;
1963 APInt Mask = ArithOp.getOpcode() == ISD::SRL
1965 : APInt::getLowBitsSet(BitWidth, BitWidth - ShAmt);
1966 if (!Mask.isSignedIntN(32)) // Avoid large immediates.
1967 break;
1968 Op = DAG.getNode(ISD::AND, DL, VT, Op->getOperand(0),
1969 DAG.getConstant(Mask, DL, VT));
1970 }
1971 break;
1972
1973 case ISD::AND:
1974 // If the primary 'and' result isn't used, don't bother using
1975 // M68kISD::AND, because a TEST instruction will be better.
1976 if (!hasNonFlagsUse(Op)) {
1977 SDValue Op0 = ArithOp->getOperand(0);
1978 SDValue Op1 = ArithOp->getOperand(1);
1979 EVT VT = ArithOp.getValueType();
1980 bool IsAndn = isBitwiseNot(Op0) || isBitwiseNot(Op1);
1981 bool IsLegalAndnType = VT == MVT::i32 || VT == MVT::i64;
1982
1983 // But if we can combine this into an ANDN operation, then create an AND
1984 // now and allow it to be pattern matched into an ANDN.
1985 if (/*!Subtarget.hasBMI() ||*/ !IsAndn || !IsLegalAndnType)
1986 break;
1987 }
1988 [[fallthrough]];
1989 case ISD::SUB:
1990 case ISD::OR:
1991 case ISD::XOR:
1992 // Due to the ISEL shortcoming noted above, be conservative if this op is
1993 // likely to be selected as part of a load-modify-store instruction.
1994 for (const auto *U : Op.getNode()->users())
1995 if (U->getOpcode() == ISD::STORE)
1996 goto default_case;
1997
1998 // Otherwise use a regular CCR-setting instruction.
1999 switch (ArithOp.getOpcode()) {
2000 default:
2001 llvm_unreachable("unexpected operator!");
2002 case ISD::SUB:
2003 Opcode = M68kISD::SUB;
2004 break;
2005 case ISD::XOR:
2006 Opcode = M68kISD::XOR;
2007 break;
2008 case ISD::AND:
2009 Opcode = M68kISD::AND;
2010 break;
2011 case ISD::OR:
2012 Opcode = M68kISD::OR;
2013 break;
2014 }
2015
2016 NumOperands = 2;
2017 break;
2018 case M68kISD::ADD:
2019 case M68kISD::SUB:
2020 case M68kISD::OR:
2021 case M68kISD::XOR:
2022 case M68kISD::AND:
2023 return SDValue(Op.getNode(), 1);
2024 default:
2025 default_case:
2026 break;
2027 }
2028
2029 // If we found that truncation is beneficial, perform the truncation and
2030 // update 'Op'.
2031 if (NeedTruncation) {
2032 EVT VT = Op.getValueType();
2033 SDValue WideVal = Op->getOperand(0);
2034 EVT WideVT = WideVal.getValueType();
2035 unsigned ConvertedOp = 0;
2036 // Use a target machine opcode to prevent further DAGCombine
2037 // optimizations that may separate the arithmetic operations
2038 // from the setcc node.
2039 switch (WideVal.getOpcode()) {
2040 default:
2041 break;
2042 case ISD::ADD:
2043 ConvertedOp = M68kISD::ADD;
2044 break;
2045 case ISD::SUB:
2046 ConvertedOp = M68kISD::SUB;
2047 break;
2048 case ISD::AND:
2049 ConvertedOp = M68kISD::AND;
2050 break;
2051 case ISD::OR:
2052 ConvertedOp = M68kISD::OR;
2053 break;
2054 case ISD::XOR:
2055 ConvertedOp = M68kISD::XOR;
2056 break;
2057 }
2058
2059 if (ConvertedOp) {
2060 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
2061 if (TLI.isOperationLegal(WideVal.getOpcode(), WideVT)) {
2062 SDValue V0 = DAG.getNode(ISD::TRUNCATE, DL, VT, WideVal.getOperand(0));
2063 SDValue V1 = DAG.getNode(ISD::TRUNCATE, DL, VT, WideVal.getOperand(1));
2064 Op = DAG.getNode(ConvertedOp, DL, VT, V0, V1);
2065 }
2066 }
2067 }
2068
2069 if (Opcode == 0) {
2070 // Emit a CMP with 0, which is the TEST pattern.
2071 return DAG.getNode(M68kISD::CMP, DL, MVT::i8,
2072 DAG.getConstant(0, DL, Op.getValueType()), Op);
2073 }
2074 SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i8);
2075 SmallVector<SDValue, 4> Ops(Op->op_begin(), Op->op_begin() + NumOperands);
2076
2077 SDValue New = DAG.getNode(Opcode, DL, VTs, Ops);
2078 DAG.ReplaceAllUsesWith(Op, New);
2079 return SDValue(New.getNode(), 1);
2080}
2081
2082/// \brief Return true if the condition is an unsigned comparison operation.
2083static bool isM68kCCUnsigned(unsigned M68kCC) {
2084 switch (M68kCC) {
2085 default:
2086 llvm_unreachable("Invalid integer condition!");
2087 case M68k::COND_EQ:
2088 case M68k::COND_NE:
2089 case M68k::COND_CS:
2090 case M68k::COND_HI:
2091 case M68k::COND_LS:
2092 case M68k::COND_CC:
2093 return true;
2094 case M68k::COND_GT:
2095 case M68k::COND_GE:
2096 case M68k::COND_LT:
2097 case M68k::COND_LE:
2098 return false;
2099 }
2100}
2101
2102SDValue M68kTargetLowering::EmitCmp(SDValue Op0, SDValue Op1, unsigned M68kCC,
2103 const SDLoc &DL, SelectionDAG &DAG) const {
2104 if (isNullConstant(Op1))
2105 return EmitTest(Op0, M68kCC, DL, DAG);
2106
2107 assert(!(isa<ConstantSDNode>(Op1) && Op0.getValueType() == MVT::i1) &&
2108 "Unexpected comparison operation for MVT::i1 operands");
2109
2110 if ((Op0.getValueType() == MVT::i8 || Op0.getValueType() == MVT::i16 ||
2111 Op0.getValueType() == MVT::i32 || Op0.getValueType() == MVT::i64)) {
2112 // Only promote the compare up to I32 if it is a 16 bit operation
2113 // with an immediate. 16 bit immediates are to be avoided.
2114 if ((Op0.getValueType() == MVT::i16 &&
2115 (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1))) &&
2117 unsigned ExtendOp =
2119 Op0 = DAG.getNode(ExtendOp, DL, MVT::i32, Op0);
2120 Op1 = DAG.getNode(ExtendOp, DL, MVT::i32, Op1);
2121 }
2122 // Use SUB instead of CMP to enable CSE between SUB and CMP.
2123 SDVTList VTs = DAG.getVTList(Op0.getValueType(), MVT::i8);
2124 SDValue Sub = DAG.getNode(M68kISD::SUB, DL, VTs, Op0, Op1);
2125 return SDValue(Sub.getNode(), 1);
2126 }
2127 return DAG.getNode(M68kISD::CMP, DL, MVT::i8, Op0, Op1);
2128}
2129
2130/// Result of 'and' or 'trunc to i1' is compared against zero.
2131/// Change to a BTST node if possible.
2132SDValue M68kTargetLowering::LowerToBTST(SDValue Op, ISD::CondCode CC,
2133 const SDLoc &DL,
2134 SelectionDAG &DAG) const {
2135 if (Op.getOpcode() == ISD::AND)
2136 return LowerAndToBTST(Op, CC, DL, DAG);
2137 if (Op.getOpcode() == ISD::TRUNCATE && Op.getValueType() == MVT::i1)
2138 return LowerTruncateToBTST(Op, CC, DL, DAG);
2139 return SDValue();
2140}
2141
2142SDValue M68kTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
2143 MVT VT = Op.getSimpleValueType();
2144 assert(VT == MVT::i8 && "SetCC type must be 8-bit integer");
2145
2146 SDValue Op0 = Op.getOperand(0);
2147 SDValue Op1 = Op.getOperand(1);
2148 SDLoc DL(Op);
2149 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
2150
2151 // Optimize to BTST if possible.
2152 // Lower (X & (1 << N)) == 0 to BTST(X, N).
2153 // Lower ((X >>u N) & 1) != 0 to BTST(X, N).
2154 // Lower ((X >>s N) & 1) != 0 to BTST(X, N).
2155 // Lower (trunc (X >> N) to i1) to BTST(X, N).
2156 if (Op0.hasOneUse() && isNullConstant(Op1) &&
2157 (CC == ISD::SETEQ || CC == ISD::SETNE)) {
2158 if (SDValue NewSetCC = LowerToBTST(Op0, CC, DL, DAG)) {
2159 if (VT == MVT::i1)
2160 return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, NewSetCC);
2161 return NewSetCC;
2162 }
2163 }
2164
2165 // Look for X == 0, X == 1, X != 0, or X != 1. We can simplify some forms of
2166 // these.
2167 if ((isOneConstant(Op1) || isNullConstant(Op1)) &&
2168 (CC == ISD::SETEQ || CC == ISD::SETNE)) {
2169
2170 // If the input is a setcc, then reuse the input setcc or use a new one with
2171 // the inverted condition.
2172 if (Op0.getOpcode() == M68kISD::SETCC) {
2174 bool Invert = (CC == ISD::SETNE) ^ isNullConstant(Op1);
2175 if (!Invert)
2176 return Op0;
2177
2178 CCode = M68k::GetOppositeBranchCondition(CCode);
2179 SDValue SetCC =
2180 DAG.getNode(M68kISD::SETCC, DL, MVT::i8,
2181 DAG.getConstant(CCode, DL, MVT::i8), Op0.getOperand(1));
2182 if (VT == MVT::i1)
2183 return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, SetCC);
2184 return SetCC;
2185 }
2186 }
2187 if (Op0.getValueType() == MVT::i1 && (CC == ISD::SETEQ || CC == ISD::SETNE)) {
2188 if (isOneConstant(Op1)) {
2190 return DAG.getSetCC(DL, VT, Op0, DAG.getConstant(0, DL, MVT::i1), NewCC);
2191 }
2192 if (!isNullConstant(Op1)) {
2193 SDValue Xor = DAG.getNode(ISD::XOR, DL, MVT::i1, Op0, Op1);
2194 return DAG.getSetCC(DL, VT, Xor, DAG.getConstant(0, DL, MVT::i1), CC);
2195 }
2196 }
2197
2198 bool IsFP = Op1.getSimpleValueType().isFloatingPoint();
2199 unsigned M68kCC = TranslateM68kCC(CC, DL, IsFP, Op0, Op1, DAG);
2200 if (M68kCC == M68k::COND_INVALID)
2201 return SDValue();
2202
2203 SDValue CCR = EmitCmp(Op0, Op1, M68kCC, DL, DAG);
2204 return DAG.getNode(M68kISD::SETCC, DL, MVT::i8,
2205 DAG.getConstant(M68kCC, DL, MVT::i8), CCR);
2206}
2207
2208SDValue M68kTargetLowering::LowerSETCCCARRY(SDValue Op,
2209 SelectionDAG &DAG) const {
2210 SDValue LHS = Op.getOperand(0);
2211 SDValue RHS = Op.getOperand(1);
2212 SDValue Carry = Op.getOperand(2);
2213 SDValue Cond = Op.getOperand(3);
2214 SDLoc DL(Op);
2215
2216 assert(LHS.getSimpleValueType().isInteger() && "SETCCCARRY is integer only.");
2217 M68k::CondCode CC = TranslateIntegerM68kCC(cast<CondCodeSDNode>(Cond)->get());
2218
2219 EVT CarryVT = Carry.getValueType();
2220 APInt NegOne = APInt::getAllOnes(CarryVT.getScalarSizeInBits());
2221 Carry = DAG.getNode(M68kISD::ADD, DL, DAG.getVTList(CarryVT, MVT::i32), Carry,
2222 DAG.getConstant(NegOne, DL, CarryVT));
2223
2224 SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
2225 SDValue Cmp =
2226 DAG.getNode(M68kISD::SUBX, DL, VTs, LHS, RHS, Carry.getValue(1));
2227
2228 return DAG.getNode(M68kISD::SETCC, DL, MVT::i8,
2229 DAG.getConstant(CC, DL, MVT::i8), Cmp.getValue(1));
2230}
2231
2232/// Return true if opcode is a M68k logical comparison.
2234 unsigned Opc = Op.getNode()->getOpcode();
2235 if (Opc == M68kISD::CMP)
2236 return true;
2237 if (Op.getResNo() == 1 &&
2238 (Opc == M68kISD::ADD || Opc == M68kISD::SUB || Opc == M68kISD::ADDX ||
2239 Opc == M68kISD::SUBX || Opc == M68kISD::SMUL || Opc == M68kISD::UMUL ||
2240 Opc == M68kISD::OR || Opc == M68kISD::XOR || Opc == M68kISD::AND))
2241 return true;
2242
2243 if (Op.getResNo() == 2 && Opc == M68kISD::UMUL)
2244 return true;
2245
2246 return false;
2247}
2248
2250 if (V.getOpcode() != ISD::TRUNCATE)
2251 return false;
2252
2253 SDValue VOp0 = V.getOperand(0);
2254 unsigned InBits = VOp0.getValueSizeInBits();
2255 unsigned Bits = V.getValueSizeInBits();
2256 return DAG.MaskedValueIsZero(VOp0,
2257 APInt::getHighBitsSet(InBits, InBits - Bits));
2258}
2259
2260SDValue M68kTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
2261 bool addTest = true;
2262 SDValue Cond = Op.getOperand(0);
2263 SDValue Op1 = Op.getOperand(1);
2264 SDValue Op2 = Op.getOperand(2);
2265 SDLoc DL(Op);
2266 SDValue CC;
2267
2268 if (Cond.getOpcode() == ISD::SETCC) {
2269 if (SDValue NewCond = LowerSETCC(Cond, DAG))
2270 Cond = NewCond;
2271 }
2272
2273 // (select (x == 0), -1, y) -> (sign_bit (x - 1)) | y
2274 // (select (x == 0), y, -1) -> ~(sign_bit (x - 1)) | y
2275 // (select (x != 0), y, -1) -> (sign_bit (x - 1)) | y
2276 // (select (x != 0), -1, y) -> ~(sign_bit (x - 1)) | y
2277 if (Cond.getOpcode() == M68kISD::SETCC &&
2278 Cond.getOperand(1).getOpcode() == M68kISD::CMP &&
2279 isNullConstant(Cond.getOperand(1).getOperand(0))) {
2280 SDValue Cmp = Cond.getOperand(1);
2281
2282 unsigned CondCode = Cond.getConstantOperandVal(0);
2283
2284 if ((isAllOnesConstant(Op1) || isAllOnesConstant(Op2)) &&
2285 (CondCode == M68k::COND_EQ || CondCode == M68k::COND_NE)) {
2286 SDValue Y = isAllOnesConstant(Op2) ? Op1 : Op2;
2287
2288 SDValue CmpOp0 = Cmp.getOperand(1);
2289 // Apply further optimizations for special cases
2290 // (select (x != 0), -1, 0) -> neg & sbb
2291 // (select (x == 0), 0, -1) -> neg & sbb
2292 if (isNullConstant(Y) &&
2293 (isAllOnesConstant(Op1) == (CondCode == M68k::COND_NE))) {
2294
2295 SDVTList VTs = DAG.getVTList(CmpOp0.getValueType(), MVT::i32);
2296
2297 SDValue Neg =
2298 DAG.getNode(M68kISD::SUB, DL, VTs,
2299 DAG.getConstant(0, DL, CmpOp0.getValueType()), CmpOp0);
2300
2301 SDValue Res = DAG.getNode(M68kISD::SETCC_CARRY, DL, Op.getValueType(),
2302 DAG.getConstant(M68k::COND_CS, DL, MVT::i8),
2303 SDValue(Neg.getNode(), 1));
2304 return Res;
2305 }
2306
2307 Cmp = DAG.getNode(M68kISD::CMP, DL, MVT::i8,
2308 DAG.getConstant(1, DL, CmpOp0.getValueType()), CmpOp0);
2309
2310 SDValue Res = // Res = 0 or -1.
2311 DAG.getNode(M68kISD::SETCC_CARRY, DL, Op.getValueType(),
2312 DAG.getConstant(M68k::COND_CS, DL, MVT::i8), Cmp);
2313
2314 if (isAllOnesConstant(Op1) != (CondCode == M68k::COND_EQ))
2315 Res = DAG.getNOT(DL, Res, Res.getValueType());
2316
2317 if (!isNullConstant(Op2))
2318 Res = DAG.getNode(ISD::OR, DL, Res.getValueType(), Res, Y);
2319 return Res;
2320 }
2321 }
2322
2323 // Look past (and (setcc_carry (cmp ...)), 1).
2324 if (Cond.getOpcode() == ISD::AND &&
2325 Cond.getOperand(0).getOpcode() == M68kISD::SETCC_CARRY &&
2326 isOneConstant(Cond.getOperand(1)))
2327 Cond = Cond.getOperand(0);
2328
2329 // If condition flag is set by a M68kISD::CMP, then use it as the condition
2330 // setting operand in place of the M68kISD::SETCC.
2331 unsigned CondOpcode = Cond.getOpcode();
2332 if (CondOpcode == M68kISD::SETCC || CondOpcode == M68kISD::SETCC_CARRY) {
2333 CC = Cond.getOperand(0);
2334
2335 SDValue Cmp = Cond.getOperand(1);
2336 unsigned Opc = Cmp.getOpcode();
2337
2338 bool IllegalFPCMov = false;
2339
2340 if ((isM68kLogicalCmp(Cmp) && !IllegalFPCMov) || Opc == M68kISD::BTST) {
2341 Cond = Cmp;
2342 addTest = false;
2343 }
2344 } else if (isOverflowArithmetic(CondOpcode)) {
2345 // Result is unused here.
2347 unsigned CCode;
2348 lowerOverflowArithmetic(Cond, DAG, Result, Cond, CCode);
2349 CC = DAG.getConstant(CCode, DL, MVT::i8);
2350 addTest = false;
2351 }
2352
2353 if (addTest) {
2354 // Look past the truncate if the high bits are known zero.
2356 Cond = Cond.getOperand(0);
2357
2358 // We know the result of AND is compared against zero. Try to match
2359 // it to BT.
2360 if (Cond.getOpcode() == ISD::AND && Cond.hasOneUse()) {
2361 if (SDValue NewSetCC = LowerToBTST(Cond, ISD::SETNE, DL, DAG)) {
2362 CC = NewSetCC.getOperand(0);
2363 Cond = NewSetCC.getOperand(1);
2364 addTest = false;
2365 }
2366 }
2367 }
2368
2369 if (addTest) {
2370 CC = DAG.getConstant(M68k::COND_NE, DL, MVT::i8);
2371 Cond = EmitTest(Cond, M68k::COND_NE, DL, DAG);
2372 }
2373
2374 // a < b ? -1 : 0 -> RES = ~setcc_carry
2375 // a < b ? 0 : -1 -> RES = setcc_carry
2376 // a >= b ? -1 : 0 -> RES = setcc_carry
2377 // a >= b ? 0 : -1 -> RES = ~setcc_carry
2378 if (Cond.getOpcode() == M68kISD::SUB) {
2379 unsigned CondCode = CC->getAsZExtVal();
2380
2381 if ((CondCode == M68k::COND_CC || CondCode == M68k::COND_CS) &&
2382 (isAllOnesConstant(Op1) || isAllOnesConstant(Op2)) &&
2383 (isNullConstant(Op1) || isNullConstant(Op2))) {
2384 SDValue Res =
2385 DAG.getNode(M68kISD::SETCC_CARRY, DL, Op.getValueType(),
2386 DAG.getConstant(M68k::COND_CS, DL, MVT::i8), Cond);
2387 if (isAllOnesConstant(Op1) != (CondCode == M68k::COND_CS))
2388 return DAG.getNOT(DL, Res, Res.getValueType());
2389 return Res;
2390 }
2391 }
2392
2393 // M68k doesn't have an i8 cmov. If both operands are the result of a
2394 // truncate widen the cmov and push the truncate through. This avoids
2395 // introducing a new branch during isel and doesn't add any extensions.
2396 if (Op.getValueType() == MVT::i8 && Op1.getOpcode() == ISD::TRUNCATE &&
2397 Op2.getOpcode() == ISD::TRUNCATE) {
2398 SDValue T1 = Op1.getOperand(0), T2 = Op2.getOperand(0);
2399 if (T1.getValueType() == T2.getValueType() &&
2400 // Block CopyFromReg so partial register stalls are avoided.
2401 T1.getOpcode() != ISD::CopyFromReg &&
2402 T2.getOpcode() != ISD::CopyFromReg) {
2403 SDValue Cmov =
2404 DAG.getNode(M68kISD::CMOV, DL, T1.getValueType(), T2, T1, CC, Cond);
2405 return DAG.getNode(ISD::TRUNCATE, DL, Op.getValueType(), Cmov);
2406 }
2407 }
2408
2409 // Simple optimization when Cond is a constant to avoid generating
2410 // M68kISD::CMOV if possible.
2411 // TODO: Generalize this to use SelectionDAG::computeKnownBits.
2412 if (auto *Const = dyn_cast<ConstantSDNode>(Cond.getNode())) {
2413 const APInt &C = Const->getAPIntValue();
2414 if (C.countr_zero() >= 5)
2415 return Op2;
2416 else if (C.countr_one() >= 5)
2417 return Op1;
2418 }
2419
2420 // M68kISD::CMOV means set the result (which is operand 1) to the RHS if
2421 // condition is true.
2422 SDValue Ops[] = {Op2, Op1, CC, Cond};
2423 return DAG.getNode(M68kISD::CMOV, DL, Op.getValueType(), Ops);
2424}
2425
2426/// Return true if node is an ISD::AND or ISD::OR of two M68k::SETcc nodes
2427/// each of which has no other use apart from the AND / OR.
2428static bool isAndOrOfSetCCs(SDValue Op, unsigned &Opc) {
2429 Opc = Op.getOpcode();
2430 if (Opc != ISD::OR && Opc != ISD::AND)
2431 return false;
2432 return (M68k::IsSETCC(Op.getOperand(0).getOpcode()) &&
2433 Op.getOperand(0).hasOneUse() &&
2434 M68k::IsSETCC(Op.getOperand(1).getOpcode()) &&
2435 Op.getOperand(1).hasOneUse());
2436}
2437
2438/// Return true if node is an ISD::XOR of a M68kISD::SETCC and 1 and that the
2439/// SETCC node has a single use.
2441 if (Op.getOpcode() != ISD::XOR)
2442 return false;
2443 if (isOneConstant(Op.getOperand(1)))
2444 return Op.getOperand(0).getOpcode() == M68kISD::SETCC &&
2445 Op.getOperand(0).hasOneUse();
2446 return false;
2447}
2448
2449SDValue M68kTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
2450 bool AddTest = true;
2451 SDValue Chain = Op.getOperand(0);
2452 SDValue Cond = Op.getOperand(1);
2453 SDValue Dest = Op.getOperand(2);
2454 SDLoc DL(Op);
2455 SDValue CC;
2456 bool Inverted = false;
2457
2458 if (Cond.getOpcode() == ISD::SETCC) {
2459 // Check for setcc([su]{add,sub}o == 0).
2460 if (cast<CondCodeSDNode>(Cond.getOperand(2))->get() == ISD::SETEQ &&
2461 isNullConstant(Cond.getOperand(1)) &&
2462 Cond.getOperand(0).getResNo() == 1 &&
2463 (Cond.getOperand(0).getOpcode() == ISD::SADDO ||
2464 Cond.getOperand(0).getOpcode() == ISD::UADDO ||
2465 Cond.getOperand(0).getOpcode() == ISD::SSUBO ||
2466 Cond.getOperand(0).getOpcode() == ISD::USUBO)) {
2467 Inverted = true;
2468 Cond = Cond.getOperand(0);
2469 } else {
2470 if (SDValue NewCond = LowerSETCC(Cond, DAG))
2471 Cond = NewCond;
2472 }
2473 }
2474
2475 // Look pass (and (setcc_carry (cmp ...)), 1).
2476 if (Cond.getOpcode() == ISD::AND &&
2477 Cond.getOperand(0).getOpcode() == M68kISD::SETCC_CARRY &&
2478 isOneConstant(Cond.getOperand(1)))
2479 Cond = Cond.getOperand(0);
2480
2481 // If condition flag is set by a M68kISD::CMP, then use it as the condition
2482 // setting operand in place of the M68kISD::SETCC.
2483 unsigned CondOpcode = Cond.getOpcode();
2484 if (CondOpcode == M68kISD::SETCC || CondOpcode == M68kISD::SETCC_CARRY) {
2485 CC = Cond.getOperand(0);
2486
2487 SDValue Cmp = Cond.getOperand(1);
2488 unsigned Opc = Cmp.getOpcode();
2489
2490 if (isM68kLogicalCmp(Cmp) || Opc == M68kISD::BTST) {
2491 Cond = Cmp;
2492 AddTest = false;
2493 } else {
2494 switch (CC->getAsZExtVal()) {
2495 default:
2496 break;
2497 case M68k::COND_VS:
2498 case M68k::COND_CS:
2499 // These can only come from an arithmetic instruction with overflow,
2500 // e.g. SADDO, UADDO.
2501 Cond = Cond.getNode()->getOperand(1);
2502 AddTest = false;
2503 break;
2504 }
2505 }
2506 }
2507 CondOpcode = Cond.getOpcode();
2508 if (isOverflowArithmetic(CondOpcode)) {
2510 unsigned CCode;
2511 lowerOverflowArithmetic(Cond, DAG, Result, Cond, CCode);
2512
2513 if (Inverted)
2515 CC = DAG.getConstant(CCode, DL, MVT::i8);
2516
2517 AddTest = false;
2518 } else {
2519 unsigned CondOpc;
2520 if (Cond.hasOneUse() && isAndOrOfSetCCs(Cond, CondOpc)) {
2521 SDValue Cmp = Cond.getOperand(0).getOperand(1);
2522 if (CondOpc == ISD::OR) {
2523 // Also, recognize the pattern generated by an FCMP_UNE. We can emit
2524 // two branches instead of an explicit OR instruction with a
2525 // separate test.
2526 if (Cmp == Cond.getOperand(1).getOperand(1) && isM68kLogicalCmp(Cmp)) {
2527 CC = Cond.getOperand(0).getOperand(0);
2528 Chain = DAG.getNode(M68kISD::BRCOND, DL, Op.getValueType(), Chain,
2529 Dest, CC, Cmp);
2530 CC = Cond.getOperand(1).getOperand(0);
2531 Cond = Cmp;
2532 AddTest = false;
2533 }
2534 } else { // ISD::AND
2535 // Also, recognize the pattern generated by an FCMP_OEQ. We can emit
2536 // two branches instead of an explicit AND instruction with a
2537 // separate test. However, we only do this if this block doesn't
2538 // have a fall-through edge, because this requires an explicit
2539 // jmp when the condition is false.
2540 if (Cmp == Cond.getOperand(1).getOperand(1) && isM68kLogicalCmp(Cmp) &&
2541 Op.getNode()->hasOneUse()) {
2542 M68k::CondCode CCode =
2543 (M68k::CondCode)Cond.getOperand(0).getConstantOperandVal(0);
2544 CCode = M68k::GetOppositeBranchCondition(CCode);
2545 CC = DAG.getConstant(CCode, DL, MVT::i8);
2546 SDNode *User = *Op.getNode()->user_begin();
2547 // Look for an unconditional branch following this conditional branch.
2548 // We need this because we need to reverse the successors in order
2549 // to implement FCMP_OEQ.
2550 if (User->getOpcode() == ISD::BR) {
2551 SDValue FalseBB = User->getOperand(1);
2552 SDNode *NewBR =
2553 DAG.UpdateNodeOperands(User, User->getOperand(0), Dest);
2554 assert(NewBR == User);
2555 (void)NewBR;
2556 Dest = FalseBB;
2557
2558 Chain = DAG.getNode(M68kISD::BRCOND, DL, Op.getValueType(), Chain,
2559 Dest, CC, Cmp);
2560 M68k::CondCode CCode =
2561 (M68k::CondCode)Cond.getOperand(1).getConstantOperandVal(0);
2562 CCode = M68k::GetOppositeBranchCondition(CCode);
2563 CC = DAG.getConstant(CCode, DL, MVT::i8);
2564 Cond = Cmp;
2565 AddTest = false;
2566 }
2567 }
2568 }
2569 } else if (Cond.hasOneUse() && isXor1OfSetCC(Cond)) {
2570 // Recognize for xorb (setcc), 1 patterns. The xor inverts the condition.
2571 // It should be transformed during dag combiner except when the condition
2572 // is set by a arithmetics with overflow node.
2573 M68k::CondCode CCode =
2574 (M68k::CondCode)Cond.getOperand(0).getConstantOperandVal(0);
2575 CCode = M68k::GetOppositeBranchCondition(CCode);
2576 CC = DAG.getConstant(CCode, DL, MVT::i8);
2577 Cond = Cond.getOperand(0).getOperand(1);
2578 AddTest = false;
2579 }
2580 }
2581
2582 if (AddTest) {
2583 // Look pass the truncate if the high bits are known zero.
2585 Cond = Cond.getOperand(0);
2586
2587 // We know the result is compared against zero. Try to match it to BT.
2588 if (Cond.hasOneUse()) {
2589 if (SDValue NewSetCC = LowerToBTST(Cond, ISD::SETNE, DL, DAG)) {
2590 CC = NewSetCC.getOperand(0);
2591 Cond = NewSetCC.getOperand(1);
2592 AddTest = false;
2593 }
2594 }
2595 }
2596
2597 if (AddTest) {
2598 M68k::CondCode MxCond = Inverted ? M68k::COND_EQ : M68k::COND_NE;
2599 CC = DAG.getConstant(MxCond, DL, MVT::i8);
2600 Cond = EmitTest(Cond, MxCond, DL, DAG);
2601 }
2602 return DAG.getNode(M68kISD::BRCOND, DL, Op.getValueType(), Chain, Dest, CC,
2603 Cond);
2604}
2605
2606SDValue M68kTargetLowering::LowerADDC_ADDE_SUBC_SUBE(SDValue Op,
2607 SelectionDAG &DAG) const {
2608 MVT VT = Op.getNode()->getSimpleValueType(0);
2609
2610 // Let legalize expand this if it isn't a legal type yet.
2611 if (!DAG.getTargetLoweringInfo().isTypeLegal(VT))
2612 return SDValue();
2613
2614 SDVTList VTs = DAG.getVTList(VT, MVT::i8);
2615
2616 unsigned Opc;
2617 bool ExtraOp = false;
2618 switch (Op.getOpcode()) {
2619 default:
2620 llvm_unreachable("Invalid code");
2621 case ISD::ADDC:
2622 Opc = M68kISD::ADD;
2623 break;
2624 case ISD::ADDE:
2625 Opc = M68kISD::ADDX;
2626 ExtraOp = true;
2627 break;
2628 case ISD::SUBC:
2629 Opc = M68kISD::SUB;
2630 break;
2631 case ISD::SUBE:
2632 Opc = M68kISD::SUBX;
2633 ExtraOp = true;
2634 break;
2635 }
2636
2637 if (!ExtraOp)
2638 return DAG.getNode(Opc, SDLoc(Op), VTs, Op.getOperand(0), Op.getOperand(1));
2639 return DAG.getNode(Opc, SDLoc(Op), VTs, Op.getOperand(0), Op.getOperand(1),
2640 Op.getOperand(2));
2641}
2642
2643// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as
2644// their target countpart wrapped in the M68kISD::Wrapper node. Suppose N is
2645// one of the above mentioned nodes. It has to be wrapped because otherwise
2646// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
2647// be used to form addressing mode. These wrapped nodes will be selected
2648// into MOV32ri.
2649SDValue M68kTargetLowering::LowerConstantPool(SDValue Op,
2650 SelectionDAG &DAG) const {
2651 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
2652
2653 // In PIC mode (unless we're in PCRel PIC mode) we add an offset to the
2654 // global base reg.
2655 unsigned char OpFlag = Subtarget.classifyLocalReference(nullptr);
2656
2657 unsigned WrapperKind = M68kISD::Wrapper;
2658 if (M68kII::isPCRelGlobalReference(OpFlag)) {
2659 WrapperKind = M68kISD::WrapperPC;
2660 }
2661
2662 MVT PtrVT = getPointerTy(DAG.getDataLayout());
2664 CP->getConstVal(), PtrVT, CP->getAlign(), CP->getOffset(), OpFlag);
2665
2666 SDLoc DL(CP);
2667 Result = DAG.getNode(WrapperKind, DL, PtrVT, Result);
2668
2669 // With PIC, the address is actually $g + Offset.
2671 Result = DAG.getNode(ISD::ADD, DL, PtrVT,
2672 DAG.getNode(M68kISD::GLOBAL_BASE_REG, SDLoc(), PtrVT),
2673 Result);
2674 }
2675
2676 return Result;
2677}
2678
2679SDValue M68kTargetLowering::LowerExternalSymbol(SDValue Op,
2680 SelectionDAG &DAG) const {
2681 const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
2682
2683 // In PIC mode (unless we're in PCRel PIC mode) we add an offset to the
2684 // global base reg.
2686 unsigned char OpFlag = Subtarget.classifyExternalReference(*Mod);
2687
2688 unsigned WrapperKind = M68kISD::Wrapper;
2689 if (M68kII::isPCRelGlobalReference(OpFlag)) {
2690 WrapperKind = M68kISD::WrapperPC;
2691 }
2692
2693 auto PtrVT = getPointerTy(DAG.getDataLayout());
2694 SDValue Result = DAG.getTargetExternalSymbol(Sym, PtrVT, OpFlag);
2695
2696 SDLoc DL(Op);
2697 Result = DAG.getNode(WrapperKind, DL, PtrVT, Result);
2698
2699 // With PIC, the address is actually $g + Offset.
2701 Result = DAG.getNode(ISD::ADD, DL, PtrVT,
2702 DAG.getNode(M68kISD::GLOBAL_BASE_REG, SDLoc(), PtrVT),
2703 Result);
2704 }
2705
2706 // For symbols that require a load from a stub to get the address, emit the
2707 // load.
2708 if (M68kII::isGlobalStubReference(OpFlag)) {
2709 Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result,
2711 }
2712
2713 return Result;
2714}
2715
2716SDValue M68kTargetLowering::LowerBlockAddress(SDValue Op,
2717 SelectionDAG &DAG) const {
2718 unsigned char OpFlags = Subtarget.classifyBlockAddressReference();
2719 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
2720 int64_t Offset = cast<BlockAddressSDNode>(Op)->getOffset();
2721 SDLoc DL(Op);
2722 auto PtrVT = getPointerTy(DAG.getDataLayout());
2723
2724 // Create the TargetBlockAddressAddress node.
2725 SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT, Offset, OpFlags);
2726
2727 if (M68kII::isPCRelBlockReference(OpFlags)) {
2728 Result = DAG.getNode(M68kISD::WrapperPC, DL, PtrVT, Result);
2729 } else {
2730 Result = DAG.getNode(M68kISD::Wrapper, DL, PtrVT, Result);
2731 }
2732
2733 // With PIC, the address is actually $g + Offset.
2734 if (M68kII::isGlobalRelativeToPICBase(OpFlags)) {
2735 Result =
2736 DAG.getNode(ISD::ADD, DL, PtrVT,
2737 DAG.getNode(M68kISD::GLOBAL_BASE_REG, DL, PtrVT), Result);
2738 }
2739
2740 return Result;
2741}
2742
2743SDValue M68kTargetLowering::LowerGlobalAddress(const GlobalValue *GV,
2744 const SDLoc &DL, int64_t Offset,
2745 SelectionDAG &DAG) const {
2746 unsigned char OpFlags = Subtarget.classifyGlobalReference(GV);
2747 auto PtrVT = getPointerTy(DAG.getDataLayout());
2748
2749 // Create the TargetGlobalAddress node, folding in the constant
2750 // offset if it is legal.
2752 if (M68kII::isDirectGlobalReference(OpFlags)) {
2753 Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, Offset);
2754 Offset = 0;
2755 } else {
2756 Result = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, OpFlags);
2757 }
2758
2759 if (M68kII::isPCRelGlobalReference(OpFlags))
2760 Result = DAG.getNode(M68kISD::WrapperPC, DL, PtrVT, Result);
2761 else
2762 Result = DAG.getNode(M68kISD::Wrapper, DL, PtrVT, Result);
2763
2764 // With PIC, the address is actually $g + Offset.
2765 if (M68kII::isGlobalRelativeToPICBase(OpFlags)) {
2766 Result =
2767 DAG.getNode(ISD::ADD, DL, PtrVT,
2768 DAG.getNode(M68kISD::GLOBAL_BASE_REG, DL, PtrVT), Result);
2769 }
2770
2771 // For globals that require a load from a stub to get the address, emit the
2772 // load.
2773 if (M68kII::isGlobalStubReference(OpFlags)) {
2774 Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Result,
2776 }
2777
2778 // If there was a non-zero offset that we didn't fold, create an explicit
2779 // addition for it.
2780 if (Offset != 0) {
2781 Result = DAG.getNode(ISD::ADD, DL, PtrVT, Result,
2782 DAG.getConstant(Offset, DL, PtrVT));
2783 }
2784
2785 return Result;
2786}
2787
2788SDValue M68kTargetLowering::LowerGlobalAddress(SDValue Op,
2789 SelectionDAG &DAG) const {
2790 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
2791 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
2792 return LowerGlobalAddress(GV, SDLoc(Op), Offset, DAG);
2793}
2794
2795//===----------------------------------------------------------------------===//
2796// Custom Lower Jump Table
2797//===----------------------------------------------------------------------===//
2798
2799SDValue M68kTargetLowering::LowerJumpTable(SDValue Op,
2800 SelectionDAG &DAG) const {
2801 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
2802
2803 // In PIC mode (unless we're in PCRel PIC mode) we add an offset to the
2804 // global base reg.
2805 unsigned char OpFlag = Subtarget.classifyLocalReference(nullptr);
2806
2807 unsigned WrapperKind = M68kISD::Wrapper;
2808 if (M68kII::isPCRelGlobalReference(OpFlag)) {
2809 WrapperKind = M68kISD::WrapperPC;
2810 }
2811
2812 auto PtrVT = getPointerTy(DAG.getDataLayout());
2813 SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, OpFlag);
2814 SDLoc DL(JT);
2815 Result = DAG.getNode(WrapperKind, DL, PtrVT, Result);
2816
2817 // With PIC, the address is actually $g + Offset.
2819 Result = DAG.getNode(ISD::ADD, DL, PtrVT,
2820 DAG.getNode(M68kISD::GLOBAL_BASE_REG, SDLoc(), PtrVT),
2821 Result);
2822 }
2823
2824 return Result;
2825}
2826
2828 return Subtarget.getJumpTableEncoding();
2829}
2830
2832 const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB,
2833 unsigned uid, MCContext &Ctx) const {
2835 Ctx);
2836}
2837
2839 SelectionDAG &DAG) const {
2843
2844 // MachineJumpTableInfo::EK_LabelDifference32 entry
2845 return Table;
2846}
2847
2848// NOTE This only used for MachineJumpTableInfo::EK_LabelDifference32 entries
2850 const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const {
2851 return MCSymbolRefExpr::create(MF->getJTISymbol(JTI, Ctx), Ctx);
2852}
2853
2856 if (Constraint.size() > 0) {
2857 switch (Constraint[0]) {
2858 case 'a':
2859 case 'd':
2860 return C_RegisterClass;
2861 case 'I':
2862 case 'J':
2863 case 'K':
2864 case 'L':
2865 case 'M':
2866 case 'N':
2867 case 'O':
2868 case 'P':
2869 return C_Immediate;
2870 case 'C':
2871 if (Constraint.size() == 2)
2872 switch (Constraint[1]) {
2873 case '0':
2874 case 'i':
2875 case 'j':
2876 return C_Immediate;
2877 default:
2878 break;
2879 }
2880 break;
2881 case 'Q':
2882 case 'U':
2883 return C_Memory;
2884 default:
2885 break;
2886 }
2887 }
2888
2889 return TargetLowering::getConstraintType(Constraint);
2890}
2891
2893 StringRef Constraint,
2894 std::vector<SDValue> &Ops,
2895 SelectionDAG &DAG) const {
2896 SDValue Result;
2897
2898 if (Constraint.size() == 1) {
2899 // Constant constraints
2900 switch (Constraint[0]) {
2901 case 'I':
2902 case 'J':
2903 case 'K':
2904 case 'L':
2905 case 'M':
2906 case 'N':
2907 case 'O':
2908 case 'P': {
2909 auto *C = dyn_cast<ConstantSDNode>(Op);
2910 if (!C)
2911 return;
2912
2913 int64_t Val = C->getSExtValue();
2914 switch (Constraint[0]) {
2915 case 'I': // constant integer in the range [1,8]
2916 if (Val > 0 && Val <= 8)
2917 break;
2918 return;
2919 case 'J': // constant signed 16-bit integer
2920 if (isInt<16>(Val))
2921 break;
2922 return;
2923 case 'K': // constant that is NOT in the range of [-0x80, 0x80)
2924 if (Val < -0x80 || Val >= 0x80)
2925 break;
2926 return;
2927 case 'L': // constant integer in the range [-8,-1]
2928 if (Val < 0 && Val >= -8)
2929 break;
2930 return;
2931 case 'M': // constant that is NOT in the range of [-0x100, 0x100]
2932 if (Val < -0x100 || Val >= 0x100)
2933 break;
2934 return;
2935 case 'N': // constant integer in the range [24,31]
2936 if (Val >= 24 && Val <= 31)
2937 break;
2938 return;
2939 case 'O': // constant integer 16
2940 if (Val == 16)
2941 break;
2942 return;
2943 case 'P': // constant integer in the range [8,15]
2944 if (Val >= 8 && Val <= 15)
2945 break;
2946 return;
2947 default:
2948 llvm_unreachable("Unhandled constant constraint");
2949 }
2950
2951 Result = DAG.getSignedTargetConstant(Val, SDLoc(Op), Op.getValueType());
2952 break;
2953 }
2954 default:
2955 break;
2956 }
2957 }
2958
2959 if (Constraint.size() == 2) {
2960 switch (Constraint[0]) {
2961 case 'C':
2962 // Constant constraints start with 'C'
2963 switch (Constraint[1]) {
2964 case '0':
2965 case 'i':
2966 case 'j': {
2967 auto *C = dyn_cast<ConstantSDNode>(Op);
2968 if (!C)
2969 break;
2970
2971 int64_t Val = C->getSExtValue();
2972 switch (Constraint[1]) {
2973 case '0': // constant integer 0
2974 if (!Val)
2975 break;
2976 return;
2977 case 'i': // constant integer
2978 break;
2979 case 'j': // integer constant that doesn't fit in 16 bits
2980 if (!isInt<16>(C->getSExtValue()))
2981 break;
2982 return;
2983 default:
2984 llvm_unreachable("Unhandled constant constraint");
2985 }
2986
2987 Result = DAG.getSignedTargetConstant(Val, SDLoc(Op), Op.getValueType());
2988 break;
2989 }
2990 default:
2991 break;
2992 }
2993 break;
2994 default:
2995 break;
2996 }
2997 }
2998
2999 if (Result.getNode()) {
3000 Ops.push_back(Result);
3001 return;
3002 }
3003
3004 TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
3005}
3006
3007std::pair<unsigned, const TargetRegisterClass *>
3009 StringRef Constraint,
3010 MVT VT) const {
3011 if (Constraint.size() == 1) {
3012 switch (Constraint[0]) {
3013 case 'r':
3014 case 'd':
3015 switch (VT.SimpleTy) {
3016 case MVT::i8:
3017 return std::make_pair(0U, &M68k::DR8RegClass);
3018 case MVT::i16:
3019 return std::make_pair(0U, &M68k::DR16RegClass);
3020 case MVT::i32:
3021 return std::make_pair(0U, &M68k::DR32RegClass);
3022 default:
3023 break;
3024 }
3025 break;
3026 case 'a':
3027 switch (VT.SimpleTy) {
3028 case MVT::i16:
3029 return std::make_pair(0U, &M68k::AR16RegClass);
3030 case MVT::i32:
3031 return std::make_pair(0U, &M68k::AR32RegClass);
3032 default:
3033 break;
3034 }
3035 break;
3036 default:
3037 break;
3038 }
3039 }
3040
3041 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
3042}
3043
3044/// Determines whether the callee is required to pop its own arguments.
3045/// Callee pop is necessary to support tail calls.
3046bool M68k::isCalleePop(CallingConv::ID CC, bool IsVarArg, bool GuaranteeTCO) {
3047 return CC == CallingConv::M68k_RTD && !IsVarArg;
3048}
3049
3050// Return true if it is OK for this CMOV pseudo-opcode to be cascaded
3051// together with other CMOV pseudo-opcodes into a single basic-block with
3052// conditional jump around it.
3054 switch (MI.getOpcode()) {
3055 case M68k::CMOV8d:
3056 case M68k::CMOV16d:
3057 case M68k::CMOV32r:
3058 return true;
3059
3060 default:
3061 return false;
3062 }
3063}
3064
3065// The CCR operand of SelectItr might be missing a kill marker
3066// because there were multiple uses of CCR, and ISel didn't know
3067// which to mark. Figure out whether SelectItr should have had a
3068// kill marker, and set it if it should. Returns the correct kill
3069// marker value.
3072 const TargetRegisterInfo *TRI) {
3073 // Scan forward through BB for a use/def of CCR.
3074 MachineBasicBlock::iterator miI(std::next(SelectItr));
3075 for (MachineBasicBlock::iterator miE = BB->end(); miI != miE; ++miI) {
3076 const MachineInstr &mi = *miI;
3077 if (mi.readsRegister(M68k::CCR, /*TRI=*/nullptr))
3078 return false;
3079 if (mi.definesRegister(M68k::CCR, /*TRI=*/nullptr))
3080 break; // Should have kill-flag - update below.
3081 }
3082
3083 // If we hit the end of the block, check whether CCR is live into a
3084 // successor.
3085 if (miI == BB->end())
3086 for (const auto *SBB : BB->successors())
3087 if (SBB->isLiveIn(M68k::CCR))
3088 return false;
3089
3090 // We found a def, or hit the end of the basic block and CCR wasn't live
3091 // out. SelectMI should have a kill flag on CCR.
3092 SelectItr->addRegisterKilled(M68k::CCR, TRI);
3093 return true;
3094}
3095
3097M68kTargetLowering::EmitLoweredSelect(MachineInstr &MI,
3098 MachineBasicBlock *MBB) const {
3099 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
3100 DebugLoc DL = MI.getDebugLoc();
3101
3102 // To "insert" a SELECT_CC instruction, we actually have to insert the
3103 // diamond control-flow pattern. The incoming instruction knows the
3104 // destination vreg to set, the condition code register to branch on, the
3105 // true/false values to select between, and a branch opcode to use.
3106 const BasicBlock *BB = MBB->getBasicBlock();
3108
3109 // ThisMBB:
3110 // ...
3111 // TrueVal = ...
3112 // cmp ccX, r1, r2
3113 // bcc Copy1MBB
3114 // fallthrough --> Copy0MBB
3115 MachineBasicBlock *ThisMBB = MBB;
3117
3118 // This code lowers all pseudo-CMOV instructions. Generally it lowers these
3119 // as described above, by inserting a MBB, and then making a PHI at the join
3120 // point to select the true and false operands of the CMOV in the PHI.
3121 //
3122 // The code also handles two different cases of multiple CMOV opcodes
3123 // in a row.
3124 //
3125 // Case 1:
3126 // In this case, there are multiple CMOVs in a row, all which are based on
3127 // the same condition setting (or the exact opposite condition setting).
3128 // In this case we can lower all the CMOVs using a single inserted MBB, and
3129 // then make a number of PHIs at the join point to model the CMOVs. The only
3130 // trickiness here, is that in a case like:
3131 //
3132 // t2 = CMOV cond1 t1, f1
3133 // t3 = CMOV cond1 t2, f2
3134 //
3135 // when rewriting this into PHIs, we have to perform some renaming on the
3136 // temps since you cannot have a PHI operand refer to a PHI result earlier
3137 // in the same block. The "simple" but wrong lowering would be:
3138 //
3139 // t2 = PHI t1(BB1), f1(BB2)
3140 // t3 = PHI t2(BB1), f2(BB2)
3141 //
3142 // but clearly t2 is not defined in BB1, so that is incorrect. The proper
3143 // renaming is to note that on the path through BB1, t2 is really just a
3144 // copy of t1, and do that renaming, properly generating:
3145 //
3146 // t2 = PHI t1(BB1), f1(BB2)
3147 // t3 = PHI t1(BB1), f2(BB2)
3148 //
3149 // Case 2, we lower cascaded CMOVs such as
3150 //
3151 // (CMOV (CMOV F, T, cc1), T, cc2)
3152 //
3153 // to two successives branches.
3154 MachineInstr *CascadedCMOV = nullptr;
3155 MachineInstr *LastCMOV = &MI;
3156 M68k::CondCode CC = M68k::CondCode(MI.getOperand(3).getImm());
3159 std::next(MachineBasicBlock::iterator(MI));
3160
3161 // Check for case 1, where there are multiple CMOVs with the same condition
3162 // first. Of the two cases of multiple CMOV lowerings, case 1 reduces the
3163 // number of jumps the most.
3164
3165 if (isCMOVPseudo(MI)) {
3166 // See if we have a string of CMOVS with the same condition.
3167 while (NextMIIt != MBB->end() && isCMOVPseudo(*NextMIIt) &&
3168 (NextMIIt->getOperand(3).getImm() == CC ||
3169 NextMIIt->getOperand(3).getImm() == OppCC)) {
3170 LastCMOV = &*NextMIIt;
3171 ++NextMIIt;
3172 }
3173 }
3174
3175 // This checks for case 2, but only do this if we didn't already find
3176 // case 1, as indicated by LastCMOV == MI.
3177 if (LastCMOV == &MI && NextMIIt != MBB->end() &&
3178 NextMIIt->getOpcode() == MI.getOpcode() &&
3179 NextMIIt->getOperand(2).getReg() == MI.getOperand(2).getReg() &&
3180 NextMIIt->getOperand(1).getReg() == MI.getOperand(0).getReg() &&
3181 NextMIIt->getOperand(1).isKill()) {
3182 CascadedCMOV = &*NextMIIt;
3183 }
3184
3185 MachineBasicBlock *Jcc1MBB = nullptr;
3186
3187 // If we have a cascaded CMOV, we lower it to two successive branches to
3188 // the same block. CCR is used by both, so mark it as live in the second.
3189 if (CascadedCMOV) {
3190 Jcc1MBB = F->CreateMachineBasicBlock(BB);
3191 F->insert(It, Jcc1MBB);
3192 Jcc1MBB->addLiveIn(M68k::CCR);
3193 }
3194
3195 MachineBasicBlock *Copy0MBB = F->CreateMachineBasicBlock(BB);
3196 MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(BB);
3197 F->insert(It, Copy0MBB);
3198 F->insert(It, SinkMBB);
3199
3200 // Set the call frame size on entry to the new basic blocks.
3201 unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
3202 Copy0MBB->setCallFrameSize(CallFrameSize);
3203 SinkMBB->setCallFrameSize(CallFrameSize);
3204
3205 // If the CCR register isn't dead in the terminator, then claim that it's
3206 // live into the sink and copy blocks.
3207 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
3208
3209 MachineInstr *LastCCRSUser = CascadedCMOV ? CascadedCMOV : LastCMOV;
3210 if (!LastCCRSUser->killsRegister(M68k::CCR, /*TRI=*/nullptr) &&
3211 !checkAndUpdateCCRKill(LastCCRSUser, MBB, TRI)) {
3212 Copy0MBB->addLiveIn(M68k::CCR);
3213 SinkMBB->addLiveIn(M68k::CCR);
3214 }
3215
3216 // Transfer the remainder of MBB and its successor edges to SinkMBB.
3217 SinkMBB->splice(SinkMBB->begin(), MBB,
3218 std::next(MachineBasicBlock::iterator(LastCMOV)), MBB->end());
3220
3221 // Add the true and fallthrough blocks as its successors.
3222 if (CascadedCMOV) {
3223 // The fallthrough block may be Jcc1MBB, if we have a cascaded CMOV.
3224 MBB->addSuccessor(Jcc1MBB);
3225
3226 // In that case, Jcc1MBB will itself fallthrough the Copy0MBB, and
3227 // jump to the SinkMBB.
3228 Jcc1MBB->addSuccessor(Copy0MBB);
3229 Jcc1MBB->addSuccessor(SinkMBB);
3230 } else {
3231 MBB->addSuccessor(Copy0MBB);
3232 }
3233
3234 // The true block target of the first (or only) branch is always SinkMBB.
3235 MBB->addSuccessor(SinkMBB);
3236
3237 // Create the conditional branch instruction.
3238 unsigned Opc = M68k::GetCondBranchFromCond(CC);
3239 BuildMI(MBB, DL, TII->get(Opc)).addMBB(SinkMBB);
3240
3241 if (CascadedCMOV) {
3242 unsigned Opc2 = M68k::GetCondBranchFromCond(
3243 (M68k::CondCode)CascadedCMOV->getOperand(3).getImm());
3244 BuildMI(Jcc1MBB, DL, TII->get(Opc2)).addMBB(SinkMBB);
3245 }
3246
3247 // Copy0MBB:
3248 // %FalseValue = ...
3249 // # fallthrough to SinkMBB
3250 Copy0MBB->addSuccessor(SinkMBB);
3251
3252 // SinkMBB:
3253 // %Result = phi [ %FalseValue, Copy0MBB ], [ %TrueValue, ThisMBB ]
3254 // ...
3257 std::next(MachineBasicBlock::iterator(LastCMOV));
3258 MachineBasicBlock::iterator SinkInsertionPoint = SinkMBB->begin();
3261
3262 // As we are creating the PHIs, we have to be careful if there is more than
3263 // one. Later CMOVs may reference the results of earlier CMOVs, but later
3264 // PHIs have to reference the individual true/false inputs from earlier PHIs.
3265 // That also means that PHI construction must work forward from earlier to
3266 // later, and that the code must maintain a mapping from earlier PHI's
3267 // destination registers, and the registers that went into the PHI.
3268
3269 for (MachineBasicBlock::iterator MIIt = MIItBegin; MIIt != MIItEnd; ++MIIt) {
3270 Register DestReg = MIIt->getOperand(0).getReg();
3271 Register Op1Reg = MIIt->getOperand(1).getReg();
3272 Register Op2Reg = MIIt->getOperand(2).getReg();
3273
3274 // If this CMOV we are generating is the opposite condition from
3275 // the jump we generated, then we have to swap the operands for the
3276 // PHI that is going to be generated.
3277 if (MIIt->getOperand(3).getImm() == OppCC)
3278 std::swap(Op1Reg, Op2Reg);
3279
3280 if (RegRewriteTable.find(Op1Reg) != RegRewriteTable.end())
3281 Op1Reg = RegRewriteTable[Op1Reg].first;
3282
3283 if (RegRewriteTable.find(Op2Reg) != RegRewriteTable.end())
3284 Op2Reg = RegRewriteTable[Op2Reg].second;
3285
3286 MIB =
3287 BuildMI(*SinkMBB, SinkInsertionPoint, DL, TII->get(M68k::PHI), DestReg)
3288 .addReg(Op1Reg)
3289 .addMBB(Copy0MBB)
3290 .addReg(Op2Reg)
3291 .addMBB(ThisMBB);
3292
3293 // Add this PHI to the rewrite table.
3294 RegRewriteTable[DestReg] = std::make_pair(Op1Reg, Op2Reg);
3295 }
3296
3297 // If we have a cascaded CMOV, the second Jcc provides the same incoming
3298 // value as the first Jcc (the True operand of the SELECT_CC/CMOV nodes).
3299 if (CascadedCMOV) {
3300 MIB.addReg(MI.getOperand(2).getReg()).addMBB(Jcc1MBB);
3301 // Copy the PHI result to the register defined by the second CMOV.
3302 BuildMI(*SinkMBB, std::next(MachineBasicBlock::iterator(MIB.getInstr())),
3303 DL, TII->get(TargetOpcode::COPY),
3304 CascadedCMOV->getOperand(0).getReg())
3305 .addReg(MI.getOperand(0).getReg());
3306 CascadedCMOV->eraseFromParent();
3307 }
3308
3309 // Now remove the CMOV(s).
3310 for (MachineBasicBlock::iterator MIIt = MIItBegin; MIIt != MIItEnd;)
3311 (MIIt++)->eraseFromParent();
3312
3313 return SinkMBB;
3314}
3315
3317M68kTargetLowering::EmitLoweredSegAlloca(MachineInstr &MI,
3318 MachineBasicBlock *BB) const {
3319 llvm_unreachable("Cannot lower Segmented Stack Alloca with stack-split on");
3320}
3321
3324 MachineBasicBlock *BB) const {
3325 switch (MI.getOpcode()) {
3326 default:
3327 llvm_unreachable("Unexpected instr type to insert");
3328 case M68k::CMOV8d:
3329 case M68k::CMOV16d:
3330 case M68k::CMOV32r:
3331 return EmitLoweredSelect(MI, BB);
3332 case M68k::SALLOCA:
3333 return EmitLoweredSegAlloca(MI, BB);
3334 }
3335}
3336
3337SDValue M68kTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
3339 auto PtrVT = getPointerTy(MF.getDataLayout());
3341
3342 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
3343 SDLoc DL(Op);
3344
3345 // vastart just stores the address of the VarArgsFrameIndex slot into the
3346 // memory location argument.
3347 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
3348 return DAG.getStore(Op.getOperand(0), DL, FR, Op.getOperand(1),
3349 MachinePointerInfo(SV));
3350}
3351
3352SDValue M68kTargetLowering::LowerATOMICFENCE(SDValue Op,
3353 SelectionDAG &DAG) const {
3354 // Lower to a memory barrier created from inline asm.
3355 const TargetLowering &TLI = DAG.getTargetLoweringInfo();
3356 LLVMContext &Ctx = *DAG.getContext();
3357
3358 const unsigned Flags = InlineAsm::Extra_MayLoad | InlineAsm::Extra_MayStore |
3360 const SDValue AsmOperands[4] = {
3361 Op.getOperand(0), // Input chain
3363 "", TLI.getProgramPointerTy(
3364 DAG.getDataLayout())), // Empty inline asm string
3365 DAG.getMDNode(MDNode::get(Ctx, {})), // (empty) srcloc
3366 DAG.getTargetConstant(Flags, SDLoc(Op),
3367 TLI.getPointerTy(DAG.getDataLayout())), // Flags
3368 };
3369
3370 return DAG.getNode(ISD::INLINEASM, SDLoc(Op),
3371 DAG.getVTList(MVT::Other, MVT::Glue), AsmOperands);
3372}
3373
3374// Lower dynamic stack allocation to _alloca call for Cygwin/Mingw targets.
3375// Calls to _alloca are needed to probe the stack when allocating more than 4k
3376// bytes in one go. Touching the stack at 4K increments is necessary to ensure
3377// that the guard pages used by the OS virtual memory manager are allocated in
3378// correct sequence.
3379SDValue M68kTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
3380 SelectionDAG &DAG) const {
3382 bool SplitStack = MF.shouldSplitStack();
3383
3384 SDLoc DL(Op);
3385
3386 // Get the inputs.
3387 SDNode *Node = Op.getNode();
3388 SDValue Chain = Op.getOperand(0);
3389 SDValue Size = Op.getOperand(1);
3390 unsigned Align = Op.getConstantOperandVal(2);
3391 EVT VT = Node->getValueType(0);
3392
3393 // Chain the dynamic stack allocation so that it doesn't modify the stack
3394 // pointer when other instructions are using the stack.
3395 Chain = DAG.getCALLSEQ_START(Chain, 0, 0, DL);
3396
3398 if (SplitStack) {
3399 auto &MRI = MF.getRegInfo();
3400 auto SPTy = getPointerTy(DAG.getDataLayout());
3401 auto *ARClass = getRegClassFor(SPTy);
3402 Register Vreg = MRI.createVirtualRegister(ARClass);
3403 Chain = DAG.getCopyToReg(Chain, DL, Vreg, Size);
3404 Result = DAG.getNode(M68kISD::SEG_ALLOCA, DL, SPTy, Chain,
3405 DAG.getRegister(Vreg, SPTy));
3406 } else {
3407 auto &TLI = DAG.getTargetLoweringInfo();
3409 assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and"
3410 " not tell us which reg is the stack pointer!");
3411
3412 SDValue SP = DAG.getCopyFromReg(Chain, DL, SPReg, VT);
3413 Chain = SP.getValue(1);
3414 const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();
3415 unsigned StackAlign = TFI.getStackAlignment();
3416 Result = DAG.getNode(ISD::SUB, DL, VT, SP, Size); // Value
3417 if (Align > StackAlign)
3418 Result = DAG.getNode(ISD::AND, DL, VT, Result,
3419 DAG.getSignedConstant(-(uint64_t)Align, DL, VT));
3420 Chain = DAG.getCopyToReg(Chain, DL, SPReg, Result); // Output chain
3421 }
3422
3423 Chain = DAG.getCALLSEQ_END(Chain, 0, 0, SDValue(), DL);
3424
3425 SDValue Ops[2] = {Result, Chain};
3426 return DAG.getMergeValues(Ops, DL);
3427}
3428
3429SDValue M68kTargetLowering::LowerShiftLeftParts(SDValue Op,
3430 SelectionDAG &DAG) const {
3431 SDLoc DL(Op);
3432 SDValue Lo = Op.getOperand(0);
3433 SDValue Hi = Op.getOperand(1);
3434 SDValue Shamt = Op.getOperand(2);
3435 EVT VT = Lo.getValueType();
3436
3437 // if Shamt - register size < 0: // Shamt < register size
3438 // Lo = Lo << Shamt
3439 // Hi = (Hi << Shamt) | ((Lo >>u 1) >>u (register size - 1 ^ Shamt))
3440 // else:
3441 // Lo = 0
3442 // Hi = Lo << (Shamt - register size)
3443
3444 SDValue Zero = DAG.getConstant(0, DL, VT);
3445 SDValue One = DAG.getConstant(1, DL, VT);
3446 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);
3447 SDValue RegisterSizeMinus1 = DAG.getConstant(32 - 1, DL, VT);
3448 SDValue ShamtMinusRegisterSize =
3449 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
3450 SDValue RegisterSizeMinus1Shamt =
3451 DAG.getNode(ISD::XOR, DL, VT, RegisterSizeMinus1, Shamt);
3452
3453 SDValue LoTrue = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);
3454 SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo, One);
3455 SDValue ShiftRightLo =
3456 DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, RegisterSizeMinus1Shamt);
3457 SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, Hi, Shamt);
3458 SDValue HiTrue = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);
3459 SDValue HiFalse = DAG.getNode(ISD::SHL, DL, VT, Lo, ShamtMinusRegisterSize);
3460
3461 SDValue CC =
3462 DAG.getSetCC(DL, MVT::i8, ShamtMinusRegisterSize, Zero, ISD::SETLT);
3463
3464 Lo = DAG.getNode(ISD::SELECT, DL, VT, CC, LoTrue, Zero);
3465 Hi = DAG.getNode(ISD::SELECT, DL, VT, CC, HiTrue, HiFalse);
3466
3467 return DAG.getMergeValues({Lo, Hi}, DL);
3468}
3469
3470SDValue M68kTargetLowering::LowerShiftRightParts(SDValue Op, SelectionDAG &DAG,
3471 bool IsSRA) const {
3472 SDLoc DL(Op);
3473 SDValue Lo = Op.getOperand(0);
3474 SDValue Hi = Op.getOperand(1);
3475 SDValue Shamt = Op.getOperand(2);
3476 EVT VT = Lo.getValueType();
3477
3478 // SRA expansion:
3479 // if Shamt - register size < 0: // Shamt < register size
3480 // Lo = (Lo >>u Shamt) | ((Hi << 1) << (register size - 1 ^ Shamt))
3481 // Hi = Hi >>s Shamt
3482 // else:
3483 // Lo = Hi >>s (Shamt - register size);
3484 // Hi = Hi >>s (register size - 1)
3485 //
3486 // SRL expansion:
3487 // if Shamt - register size < 0: // Shamt < register size
3488 // Lo = (Lo >>u Shamt) | ((Hi << 1) << (register size - 1 ^ Shamt))
3489 // Hi = Hi >>u Shamt
3490 // else:
3491 // Lo = Hi >>u (Shamt - register size);
3492 // Hi = 0;
3493
3494 unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL;
3495
3496 SDValue Zero = DAG.getConstant(0, DL, VT);
3497 SDValue One = DAG.getConstant(1, DL, VT);
3498 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);
3499 SDValue RegisterSizeMinus1 = DAG.getConstant(32 - 1, DL, VT);
3500 SDValue ShamtMinusRegisterSize =
3501 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
3502 SDValue RegisterSizeMinus1Shamt =
3503 DAG.getNode(ISD::XOR, DL, VT, RegisterSizeMinus1, Shamt);
3504
3505 SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, Lo, Shamt);
3506 SDValue ShiftLeftHi1 = DAG.getNode(ISD::SHL, DL, VT, Hi, One);
3507 SDValue ShiftLeftHi =
3508 DAG.getNode(ISD::SHL, DL, VT, ShiftLeftHi1, RegisterSizeMinus1Shamt);
3509 SDValue LoTrue = DAG.getNode(ISD::OR, DL, VT, ShiftRightLo, ShiftLeftHi);
3510 SDValue HiTrue = DAG.getNode(ShiftRightOp, DL, VT, Hi, Shamt);
3511 SDValue LoFalse =
3512 DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusRegisterSize);
3513 SDValue HiFalse =
3514 IsSRA ? DAG.getNode(ISD::SRA, DL, VT, Hi, RegisterSizeMinus1) : Zero;
3515
3516 SDValue CC =
3517 DAG.getSetCC(DL, MVT::i8, ShamtMinusRegisterSize, Zero, ISD::SETLT);
3518
3519 Lo = DAG.getNode(ISD::SELECT, DL, VT, CC, LoTrue, LoFalse);
3520 Hi = DAG.getNode(ISD::SELECT, DL, VT, CC, HiTrue, HiFalse);
3521
3522 return DAG.getMergeValues({Lo, Hi}, DL);
3523}
3524
3525//===----------------------------------------------------------------------===//
3526// DAG Combine
3527//===----------------------------------------------------------------------===//
3528
3530 SelectionDAG &DAG) {
3531 return DAG.getNode(M68kISD::SETCC, dl, MVT::i8,
3532 DAG.getConstant(Cond, dl, MVT::i8), CCR);
3533}
3534// When legalizing carry, we create carries via add X, -1
3535// If that comes from an actual carry, via setcc, we use the
3536// carry directly.
3538 if (CCR.getOpcode() == M68kISD::ADD) {
3539 if (isAllOnesConstant(CCR.getOperand(1))) {
3540 SDValue Carry = CCR.getOperand(0);
3541 while (Carry.getOpcode() == ISD::TRUNCATE ||
3542 Carry.getOpcode() == ISD::ZERO_EXTEND ||
3543 Carry.getOpcode() == ISD::SIGN_EXTEND ||
3544 Carry.getOpcode() == ISD::ANY_EXTEND ||
3545 (Carry.getOpcode() == ISD::AND &&
3546 isOneConstant(Carry.getOperand(1))))
3547 Carry = Carry.getOperand(0);
3548 if (Carry.getOpcode() == M68kISD::SETCC ||
3549 Carry.getOpcode() == M68kISD::SETCC_CARRY) {
3550 if (Carry.getConstantOperandVal(0) == M68k::COND_CS)
3551 return Carry.getOperand(1);
3552 }
3553 }
3554 }
3555
3556 return SDValue();
3557}
3558
3559/// Optimize a CCR definition used according to the condition code \p CC into
3560/// a simpler CCR value, potentially returning a new \p CC and replacing uses
3561/// of chain values.
3563 SelectionDAG &DAG,
3564 const M68kSubtarget &Subtarget) {
3565 if (CC == M68k::COND_CS)
3566 if (SDValue Flags = combineCarryThroughADD(CCR))
3567 return Flags;
3568
3569 return SDValue();
3570}
3571
3572// Optimize RES = M68kISD::SETCC CONDCODE, CCR_INPUT
3574 const M68kSubtarget &Subtarget) {
3575 SDLoc DL(N);
3576 M68k::CondCode CC = M68k::CondCode(N->getConstantOperandVal(0));
3577 SDValue CCR = N->getOperand(1);
3578
3579 // Try to simplify the CCR and condition code operands.
3580 if (SDValue Flags = combineSetCCCCR(CCR, CC, DAG, Subtarget))
3581 return getSETCC(CC, Flags, DL, DAG);
3582
3583 return SDValue();
3584}
3586 const M68kSubtarget &Subtarget) {
3587 SDLoc DL(N);
3588 M68k::CondCode CC = M68k::CondCode(N->getConstantOperandVal(2));
3589 SDValue CCR = N->getOperand(3);
3590
3591 // Try to simplify the CCR and condition code operands.
3592 // Make sure to not keep references to operands, as combineSetCCCCR can
3593 // RAUW them under us.
3594 if (SDValue Flags = combineSetCCCCR(CCR, CC, DAG, Subtarget)) {
3595 SDValue Cond = DAG.getConstant(CC, DL, MVT::i8);
3596 return DAG.getNode(M68kISD::BRCOND, DL, N->getVTList(), N->getOperand(0),
3597 N->getOperand(1), Cond, Flags);
3598 }
3599
3600 return SDValue();
3601}
3602
3604 if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) {
3605 MVT VT = N->getSimpleValueType(0);
3606 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
3607 return DAG.getNode(M68kISD::SUBX, SDLoc(N), VTs, N->getOperand(0),
3608 N->getOperand(1), Flags);
3609 }
3610
3611 return SDValue();
3612}
3613
3614// Optimize RES, CCR = M68kISD::ADDX LHS, RHS, CCR
3617 if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) {
3618 MVT VT = N->getSimpleValueType(0);
3619 SDVTList VTs = DAG.getVTList(VT, MVT::i32);
3620 return DAG.getNode(M68kISD::ADDX, SDLoc(N), VTs, N->getOperand(0),
3621 N->getOperand(1), Flags);
3622 }
3623
3624 return SDValue();
3625}
3626
3627SDValue M68kTargetLowering::PerformDAGCombine(SDNode *N,
3628 DAGCombinerInfo &DCI) const {
3629 SelectionDAG &DAG = DCI.DAG;
3630 switch (N->getOpcode()) {
3631 case M68kISD::SUBX:
3632 return combineSUBX(N, DAG);
3633 case M68kISD::ADDX:
3634 return combineADDX(N, DAG, DCI);
3635 case M68kISD::SETCC:
3636 return combineM68kSetCC(N, DAG, Subtarget);
3637 case M68kISD::BRCOND:
3638 return combineM68kBrCond(N, DAG, Subtarget);
3639 }
3640
3641 return SDValue();
3642}
3643
3644//===----------------------------------------------------------------------===//
3645// M68kISD Node Names
3646//===----------------------------------------------------------------------===//
3647const char *M68kTargetLowering::getTargetNodeName(unsigned Opcode) const {
3648 switch (Opcode) {
3649 case M68kISD::CALL:
3650 return "M68kISD::CALL";
3651 case M68kISD::TAIL_CALL:
3652 return "M68kISD::TAIL_CALL";
3653 case M68kISD::RET:
3654 return "M68kISD::RET";
3655 case M68kISD::TC_RETURN:
3656 return "M68kISD::TC_RETURN";
3657 case M68kISD::ADD:
3658 return "M68kISD::ADD";
3659 case M68kISD::SUB:
3660 return "M68kISD::SUB";
3661 case M68kISD::ADDX:
3662 return "M68kISD::ADDX";
3663 case M68kISD::SUBX:
3664 return "M68kISD::SUBX";
3665 case M68kISD::SMUL:
3666 return "M68kISD::SMUL";
3667 case M68kISD::UMUL:
3668 return "M68kISD::UMUL";
3669 case M68kISD::OR:
3670 return "M68kISD::OR";
3671 case M68kISD::XOR:
3672 return "M68kISD::XOR";
3673 case M68kISD::AND:
3674 return "M68kISD::AND";
3675 case M68kISD::CMP:
3676 return "M68kISD::CMP";
3677 case M68kISD::BTST:
3678 return "M68kISD::BTST";
3679 case M68kISD::SELECT:
3680 return "M68kISD::SELECT";
3681 case M68kISD::CMOV:
3682 return "M68kISD::CMOV";
3683 case M68kISD::BRCOND:
3684 return "M68kISD::BRCOND";
3685 case M68kISD::SETCC:
3686 return "M68kISD::SETCC";
3688 return "M68kISD::SETCC_CARRY";
3690 return "M68kISD::GLOBAL_BASE_REG";
3691 case M68kISD::Wrapper:
3692 return "M68kISD::Wrapper";
3693 case M68kISD::WrapperPC:
3694 return "M68kISD::WrapperPC";
3696 return "M68kISD::SEG_ALLOCA";
3697 default:
3698 return NULL;
3699 }
3700}
3701
3703 bool IsVarArg) const {
3704 if (Return)
3705 return RetCC_M68k_C;
3706 else
3707 return CC_M68k_C;
3708}
unsigned const MachineRegisterInfo * MRI
static SDValue getSETCC(AArch64CC::CondCode CC, SDValue NZCV, const SDLoc &DL, SelectionDAG &DAG)
Helper function to create 'CSET', which is equivalent to 'CSINC <Wd>, WZR, WZR, invert(<cond>)'.
static bool canGuaranteeTCO(CallingConv::ID CC, bool GuaranteeTailCalls)
Return true if the calling convention is one that we can guarantee TCO for.
static bool mayTailCallThisCC(CallingConv::ID CC)
Return true if we might ever do TCO for calls with this calling convention.
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
return RetTy
uint64_t Addr
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
IRTranslator LLVM IR MI
static LVOptions Options
Definition: LVOptions.cpp:25
This file contains the custom routines for the M68k Calling Convention that aren't done by tablegen.
static SDValue LowerTruncateToBTST(SDValue Op, ISD::CondCode CC, const SDLoc &DL, SelectionDAG &DAG)
static void lowerOverflowArithmetic(SDValue Op, SelectionDAG &DAG, SDValue &Result, SDValue &CCR, unsigned &CC)
static SDValue combineADDX(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI)
static bool isAndOrOfSetCCs(SDValue Op, unsigned &Opc)
Return true if node is an ISD::AND or ISD::OR of two M68k::SETcc nodes each of which has no other use...
static bool hasNonFlagsUse(SDValue Op)
return true if Op has a use that doesn't just read flags.
static bool isM68kCCUnsigned(unsigned M68kCC)
Return true if the condition is an unsigned comparison operation.
static StructReturnType callIsStructReturn(const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isXor1OfSetCC(SDValue Op)
Return true if node is an ISD::XOR of a M68kISD::SETCC and 1 and that the SETCC node has a single use...
static SDValue LowerAndToBTST(SDValue And, ISD::CondCode CC, const SDLoc &DL, SelectionDAG &DAG)
Result of 'and' is compared against zero. Change to a BTST node if possible.
static SDValue combineM68kBrCond(SDNode *N, SelectionDAG &DAG, const M68kSubtarget &Subtarget)
static M68k::CondCode TranslateIntegerM68kCC(ISD::CondCode SetCCOpcode)
static StructReturnType argsAreStructReturn(const SmallVectorImpl< ISD::InputArg > &Ins)
Determines whether a function uses struct return semantics.
static bool isCMOVPseudo(MachineInstr &MI)
static bool shouldGuaranteeTCO(CallingConv::ID CC, bool GuaranteedTailCallOpt)
Return true if the function is being made into a tailcall target by changing its ABI.
static bool isM68kLogicalCmp(SDValue Op)
Return true if opcode is a M68k logical comparison.
static SDValue combineM68kSetCC(SDNode *N, SelectionDAG &DAG, const M68kSubtarget &Subtarget)
static SDValue combineSetCCCCR(SDValue CCR, M68k::CondCode &CC, SelectionDAG &DAG, const M68kSubtarget &Subtarget)
Optimize a CCR definition used according to the condition code CC into a simpler CCR value,...
static SDValue combineCarryThroughADD(SDValue CCR)
static bool isOverflowArithmetic(unsigned Opcode)
static bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags, MachineFrameInfo &MFI, const MachineRegisterInfo *MRI, const M68kInstrInfo *TII, const CCValAssign &VA)
Return true if the given stack call argument is already available in the same position (relatively) o...
static SDValue getBitTestCondition(SDValue Src, SDValue BitNo, ISD::CondCode CC, const SDLoc &DL, SelectionDAG &DAG)
Create a BTST (Bit Test) node - Test bit BitNo in Src and set condition according to equal/not-equal ...
StructReturnType
@ NotStructReturn
@ RegStructReturn
@ StackStructReturn
static bool isTruncWithZeroHighBitsInput(SDValue V, SelectionDAG &DAG)
static bool checkAndUpdateCCRKill(MachineBasicBlock::iterator SelectItr, MachineBasicBlock *BB, const TargetRegisterInfo *TRI)
static SDValue combineSUBX(SDNode *N, SelectionDAG &DAG)
static unsigned TranslateM68kCC(ISD::CondCode SetCCOpcode, const SDLoc &DL, bool IsFP, SDValue &LHS, SDValue &RHS, SelectionDAG &DAG)
Do a one-to-one translation of a ISD::CondCode to the M68k-specific condition code,...
This file defines the interfaces that M68k uses to lower LLVM code into a selection DAG.
This file declares the M68k specific subclass of MachineFunctionInfo.
This file declares the M68k specific subclass of TargetSubtargetInfo.
This file declares the M68k specific subclass of TargetMachine.
This file contains declarations for M68k ELF object file lowering.
#define F(x, y, z)
Definition: MD5.cpp:55
#define G(x, y, z)
Definition: MD5.cpp:56
unsigned const TargetRegisterInfo * TRI
#define T1
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static constexpr Register SPReg
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
#define OP(OPC)
Definition: Instruction.h:45
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:166
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:78
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
Definition: APInt.h:234
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition: APInt.h:296
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:704
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
The address of a basic block.
Definition: Constants.h:893
CCState - This class holds information needed while lowering arguments and return values.
static bool resultsCompatible(CallingConv::ID CalleeCC, CallingConv::ID CallerCC, MachineFunction &MF, LLVMContext &C, const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn CalleeFn, CCAssignFn CallerFn)
Returns true if the results of the two calling conventions are compatible.
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
bool isMemLoc() const
bool isExtInLoc() const
int64_t getLocMemOffset() const
unsigned getValNo() const
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
This is an important base class in LLVM.
Definition: Constant.h:42
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
A debug info location.
Definition: DebugLoc.h:33
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:156
iterator end()
Definition: DenseMap.h:84
iterator_range< arg_iterator > args()
Definition: Function.h:892
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.cpp:766
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Definition: Function.h:704
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:277
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition: Function.h:688
const GlobalValue * getGlobal() const
bool hasDLLImportStorageClass() const
Definition: GlobalValue.h:279
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:657
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
SmallVectorImpl< ForwardedRegister > & getForwardedMustTailRegParms()
void setBytesToPopOnReturn(unsigned bytes)
void setArgumentStackSize(unsigned size)
unsigned char classifyExternalReference(const Module &M) const
Classify a external variable reference for the current subtarget according to how we should reference...
unsigned char classifyBlockAddressReference() const
Classify a blockaddress reference for the current subtarget according to how we should reference it i...
unsigned getSlotSize() const
getSlotSize - Stack slot size in bytes.
const M68kInstrInfo * getInstrInfo() const override
unsigned char classifyGlobalReference(const GlobalValue *GV, const Module &M) const
Classify a global variable reference for the current subtarget according to how we should reference i...
unsigned getJumpTableEncoding() const
unsigned char classifyLocalReference(const GlobalValue *GV) const
Classify a global variable reference for the current subtarget according to how we should reference i...
const M68kRegisterInfo * getRegisterInfo() const override
bool atLeastM68020() const
Definition: M68kSubtarget.h:89
unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, const Module &M) const
Classify a global function reference for the current subtarget.
bool isTargetELF() const
const M68kFrameLowering * getFrameLowering() const override
ConstraintType getConstraintType(StringRef ConstraintStr) const override
Given a constraint, return the type of constraint it is for this target.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
virtual MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override
EVT is not used in-tree, but is used by out-of-tree target.
const MCExpr * LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned uid, MCContext &Ctx) const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
CCAssignFn * getCCAssignFn(CallingConv::ID CC, bool Return, bool IsVarArg) const
M68kTargetLowering(const M68kTargetMachine &TM, const M68kSubtarget &STI)
InlineAsm::ConstraintCode getInlineAsmMemConstraint(StringRef ConstraintCode) const override
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
Provide custom lowering hooks for some operations.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
Return the value type to use for ISD::SETCC.
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
Context object for machine code objects.
Definition: MCContext.h:83
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:398
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1549
Machine Value Type.
SimpleValueType SimpleTy
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
void setCallFrameSize(unsigned N)
Set the call frame size on entry to 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 addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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 setObjectZExt(int ObjectIdx, bool IsZExt)
void setObjectSExt(int ObjectIdx, bool IsSExt)
void setHasTailCall(bool V=true)
bool isObjectZExt(int ObjectIdx) const
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool isObjectSExt(int ObjectIdx) const
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCSymbol * getJTISymbol(unsigned JTI, MCContext &Ctx, bool isLinkerPrivate=false) const
getJTISymbol - Return the MCSymbol for the specified non-empty jump table.
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.
bool shouldSplitStack() const
Should we be emitting segmented stack stuff for the function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
Definition: MachineInstr.h:69
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr fully defines the specified register.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:585
@ EK_Custom32
EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the TargetLowering::LowerCustomJ...
int64_t getImm() const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
Class to represent pointers.
Definition: DerivedTypes.h:670
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Definition: Register.h:71
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
bool hasOneUse() const
Return true if there is exactly one use of this node.
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
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
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:228
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:750
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
Definition: SelectionDAG.h:801
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.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getRegister(Register Reg, EVT VT)
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 getGLOBAL_OFFSET_TABLE(EVT VT)
Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:503
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:760
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.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
Definition: SelectionDAG.h:827
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:497
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
Definition: SelectionDAG.h:712
SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
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 getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
Definition: SelectionDAG.h:498
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:700
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:796
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:492
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
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.
SDValue getRegisterMask(const uint32_t *RegMask)
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
LLVMContext * getContext() const
Definition: SelectionDAG.h:510
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:767
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:580
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:937
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
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.
unsigned getStackAlignment() 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 setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
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.
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.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
MVT getProgramPointerTy(const DataLayout &DL) const
Return the type for code pointers, which is determined by the program address space specified through...
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...
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
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
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual InlineAsm::ConstraintCode getInlineAsmMemConstraint(StringRef ConstraintCode) const
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
bool parametersInCSRMatch(const MachineRegisterInfo &MRI, const uint32_t *CallerPreservedMask, const SmallVectorImpl< CCValAssign > &ArgLocs, const SmallVectorImpl< SDValue > &OutVals) const
Check whether parameters to a call that are passed in callee saved registers are the same as from the...
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
TargetOptions Options
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
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:45
Value * getOperand(unsigned i) const
Definition: User.h:228
LLVM Value Representation.
Definition: Value.h:74
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition: Value.h:434
use_iterator use_begin()
Definition: Value.h:360
self_iterator getIterator()
Definition: ilist_node.h:132
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:125
@ M68k_INTR
Used for M68k interrupt routines.
Definition: CallingConv.h:235
@ Swift
Calling convention for Swift.
Definition: CallingConv.h:69
@ M68k_RTD
Used for M68k rtd-based CC (similar to X86's stdcall).
Definition: CallingConv.h:252
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
CondCode getSetCCInverse(CondCode Operation, bool isIntegerLike)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:780
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
Definition: ISDOpcodes.h:243
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1197
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1193
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:257
@ ATOMIC_LOAD_NAND
Definition: ISDOpcodes.h:1340
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:744
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1226
@ ATOMIC_LOAD_MAX
Definition: ISDOpcodes.h:1342
@ ATOMIC_LOAD_UMIN
Definition: ISDOpcodes.h:1343
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:276
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:246
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:814
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
Definition: ISDOpcodes.h:1304
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:262
@ ATOMIC_LOAD_OR
Definition: ISDOpcodes.h:1338
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:954
@ ATOMIC_LOAD_XOR
Definition: ISDOpcodes.h:1339
@ GlobalTLSAddress
Definition: ISDOpcodes.h:79
@ FrameIndex
Definition: ISDOpcodes.h:80
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:805
@ BR
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:1118
@ SETCCCARRY
Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but op #2 is a boolean indicating ...
Definition: ISDOpcodes.h:788
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1148
@ SSUBO
Same for subtraction.
Definition: ISDOpcodes.h:334
@ ATOMIC_LOAD_MIN
Definition: ISDOpcodes.h:1341
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1127
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:757
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1222
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
Definition: ISDOpcodes.h:215
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition: ISDOpcodes.h:330
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:674
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:735
@ ATOMIC_LOAD_AND
Definition: ISDOpcodes.h:1336
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:811
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:772
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
Definition: ISDOpcodes.h:1319
@ ATOMIC_LOAD_UMAX
Definition: ISDOpcodes.h:1344
@ SMULO
Same for multiplication.
Definition: ISDOpcodes.h:338
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1112
@ ConstantPool
Definition: ISDOpcodes.h:82
@ ATOMIC_LOAD_ADD
Definition: ISDOpcodes.h:1334
@ ATOMIC_LOAD_SUB
Definition: ISDOpcodes.h:1335
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:709
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:286
@ 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:1333
@ ExternalSymbol
Definition: ISDOpcodes.h:83
@ INLINEASM
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:1165
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:817
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1217
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1141
@ 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:794
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:61
@ AssertZext
Definition: ISDOpcodes.h:62
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1610
static bool isPCRelBlockReference(unsigned char Flag)
Return True if the Block is referenced using PC.
Definition: M68kBaseInfo.h:243
static bool isGlobalRelativeToPICBase(unsigned char TargetFlag)
Return true if the specified global value reference is relative to a 32-bit PIC base (M68kISD::GLOBAL...
Definition: M68kBaseInfo.h:221
static bool isGlobalStubReference(unsigned char TargetFlag)
Return true if the specified TargetFlag operand is a reference to a stub for a global,...
Definition: M68kBaseInfo.h:195
static bool isPCRelGlobalReference(unsigned char Flag)
Return True if the specified GlobalValue requires PC addressing mode.
Definition: M68kBaseInfo.h:232
@ MO_TLSLDM
On a symbol operand, this indicates that the immediate is the offset to the slot in GOT which stores ...
Definition: M68kBaseInfo.h:177
@ MO_TLSLE
On a symbol operand, this indicates that the immediate is the offset to the variable within in the th...
Definition: M68kBaseInfo.h:189
@ MO_TLSGD
On a symbol operand, this indicates that the immediate is the offset to the slot in GOT which stores ...
Definition: M68kBaseInfo.h:165
@ MO_GOTPCREL
On a symbol operand this indicates that the immediate is offset to the GOT entry for the symbol name ...
Definition: M68kBaseInfo.h:153
@ MO_TLSIE
On a symbol operand, this indicates that the immediate is the offset to the variable within the threa...
Definition: M68kBaseInfo.h:183
@ MO_TLSLD
On a symbol operand, this indicates that the immediate is the offset to variable within the thread lo...
Definition: M68kBaseInfo.h:171
static bool isDirectGlobalReference(unsigned char Flag)
Return True if the specified GlobalValue is a direct reference for a symbol.
Definition: M68kBaseInfo.h:207
@ SETCC
M68k SetCC.
@ BRCOND
M68k conditional branches.
@ CMOV
M68k conditional moves.
@ BTST
M68k bit-test instructions.
@ CMP
M68k compare and logical compare instructions.
@ SELECT
M68k Select.
@ WrapperPC
Special wrapper used under M68k PIC mode for PC relative displacements.
@ Wrapper
A wrapper node for TargetConstantPool, TargetExternalSymbol, and TargetGlobalAddress.
static bool IsSETCC(unsigned SETCC)
static unsigned GetCondBranchFromCond(M68k::CondCode CC)
Definition: M68kInstrInfo.h:97
bool isCalleePop(CallingConv::ID CallingConv, bool IsVarArg, bool GuaranteeTCO)
Determines whether the callee is required to pop its own arguments.
static M68k::CondCode GetOppositeBranchCondition(M68k::CondCode CC)
Definition: M68kInstrInfo.h:58
@ GeneralDynamic
Definition: CodeGen.h:46
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
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.
unsigned Log2_64_Ceil(uint64_t Value)
Return the ceil log base 2 of the specified value, 64 if the value is zero.
Definition: MathExtras.h:361
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:298
bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
@ Mod
The access may modify the value stored in memory.
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.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:217
bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
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: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:35
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
Definition: ValueTypes.h:137
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:368
uint64_t getScalarSizeInBits() const
Definition: ValueTypes.h:380
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
bool isVector() const
Return true if this is a vector value type.
Definition: ValueTypes.h:168
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition: ValueTypes.h:323
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
Definition: ValueTypes.h:303
Describes a register that needs to be forwarded from the prologue to a musttail call.
Custom state to propagate llvm type info to register CC assigner.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
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 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.
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)