44#define DEBUG_TYPE "M68k-isel"
58 auto *RegInfo = Subtarget.getRegisterInfo();
87 if (Subtarget.atLeastM68020()) {
123 for (
auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
129 for (
auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
139 for (
auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
151 for (
auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
201 {MVT::i8, MVT::i16, MVT::i32},
LibCall);
208 return Subtarget.atLeastM68020()
243 return Ty.getSimpleVT();
248#define GET_CALLING_CONV_IMPL
249#include "M68kGenCallingConv.inc"
287 Align Alignment = Flags.getNonZeroByValAlign();
289 return DAG.
getMemcpy(Chain,
DL, Dst, Src, SizeNode, Alignment, Alignment,
351 if (!Flags.isByVal()) {
352 if (!
TII->isLoadFromStackSlot(*Def, FI))
355 unsigned Opcode = Def->getOpcode();
356 if ((Opcode == M68k::LEA32p || Opcode == M68k::LEA32f) &&
357 Def->getOperand(1).isFI()) {
358 FI = Def->getOperand(1).getIndex();
359 Bytes = Flags.getByValSize();
371 SDValue Ptr = Ld->getBasePtr();
379 Bytes = Flags.getByValSize();
403M68kTargetLowering::getReturnAddressFrameIndex(
SelectionDAG &DAG)
const {
405 M68kMachineFunctionInfo *FuncInfo = MF.
getInfo<M68kMachineFunctionInfo>();
408 if (ReturnAddrIndex == 0) {
410 unsigned SlotSize = Subtarget.getSlotSize();
412 SlotSize, -(int64_t)SlotSize,
false);
422 bool IsTailCall,
int FPDiff,
425 OutRetAddr = getReturnAddressFrameIndex(DAG);
428 OutRetAddr = DAG.
getLoad(VT,
DL, Chain, OutRetAddr, MachinePointerInfo());
429 return SDValue(OutRetAddr.
getNode(), 1);
432SDValue M68kTargetLowering::EmitTailCallStoreRetAddr(
434 EVT PtrVT,
unsigned SlotSize,
int FPDiff,
const SDLoc &
DL)
const {
440 SlotSize, (int64_t)FPDiff - SlotSize,
false);
445 Chain,
DL, RetFI, NewFI,
456 unsigned ArgIdx)
const {
458 ISD::ArgFlagsTy
Flags = Ins[ArgIdx].Flags;
473 }
else if (VA.
getValVT() == MVT::i16) {
487 bool IsImmutable = !AlwaysUseMutable && !
Flags.isByVal();
489 if (
Flags.isByVal()) {
490 unsigned Bytes =
Flags.getByValSize();
513 ValVT,
DL, Chain, FIN,
533 Chain,
DL, Arg, PtrOff,
543 SelectionDAG &DAG = CLI.
DAG;
545 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.
Outs;
546 SmallVectorImpl<SDValue> &OutVals = CLI.
OutVals;
547 SmallVectorImpl<ISD::InputArg> &Ins = CLI.
Ins;
548 SDValue Chain = CLI.
Chain;
556 bool IsSibcall =
false;
557 M68kMachineFunctionInfo *MFI = MF.
getInfo<M68kMachineFunctionInfo>();
564 if (Attr.getValueAsBool())
575 }
else if (IsTailCall) {
577 IsTailCall = IsEligibleForTailCallOptimization(
592 "Var args not supported with calling convention fastcc");
597 for (
const auto &Arg : CLI.
getArgs())
599 M68kCCState CCInfo(ArgTypes, CallConv, IsVarArg, MF, ArgLocs,
601 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);
604 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
611 NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);
615 if (IsTailCall && !IsSibcall && !IsMustTail) {
619 FPDiff = NumBytesCallerPushed - NumBytes;
623 if (FPDiff < MFI->getTCReturnAddrDelta())
627 unsigned NumBytesToPush = NumBytes;
628 unsigned NumBytesToPop = NumBytes;
633 if (!Outs.
empty() && Outs.
back().Flags.isInAlloca()) {
635 if (!ArgLocs.
back().isMemLoc())
638 if (ArgLocs.
back().getLocMemOffset() != 0)
640 "the only memory argument");
645 NumBytes - NumBytesToPush,
DL);
649 if (IsTailCall && FPDiff)
650 Chain = EmitTailCallLoadRetAddr(DAG, RetFI, Chain, IsTailCall, FPDiff,
DL);
658 const M68kRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
659 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
660 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
663 if (
Flags.isInAlloca())
666 CCValAssign &VA = ArgLocs[i];
668 SDValue Arg = OutVals[i];
669 bool IsByVal =
Flags.isByVal();
694 Chain,
DL, Arg, SpillSlot,
703 }
else if (!IsSibcall && (!IsTailCall || IsByVal)) {
710 LowerMemOpCallTo(Chain, StackPtr, Arg,
DL, DAG, VA, Flags));
714 if (!MemOpChains.
empty())
721 if (IsVarArg && IsMustTail) {
723 for (
const auto &
F : Forwards) {
725 RegsToPass.
push_back(std::make_pair(
unsigned(
F.PReg), Val));
732 if (!IsSibcall && IsTailCall) {
744 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
745 CCValAssign &VA = ArgLocs[i];
749 SDValue Arg = OutVals[i];
750 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
752 if (
Flags.isInAlloca())
756 uint32_t OpSize = (VA.
getLocVT().getSizeInBits() + 7) / 8;
760 if (
Flags.isByVal()) {
775 ArgChain,
DL, Arg, FIN,
780 if (!MemOpChains2.
empty())
784 Chain = EmitTailCallStoreRetAddr(DAG, MF, Chain, RetFI,
786 Subtarget.getSlotSize(), FPDiff,
DL);
792 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
794 RegsToPass[i].second, InGlue);
806 const GlobalValue *GV =
G->getGlobal();
808 unsigned char OpFlags = Subtarget.classifyGlobalFunctionReference(GV);
827 unsigned char OpFlags =
828 Subtarget.classifyGlobalFunctionReference(
nullptr, *
Mod);
836 if (!IsSibcall && IsTailCall) {
841 Ops.push_back(Chain);
842 Ops.push_back(Callee);
849 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i)
851 RegsToPass[i].second.getValueType()));
855 assert(Mask &&
"Missing call preserved mask for calling convention");
860 Ops.push_back(InGlue);
864 return DAG.
getNode(M68kISD::TC_RETURN,
DL, MVT::Other,
Ops);
868 Chain = DAG.
getNode(M68kISD::CALL,
DL, {MVT::Other, MVT::Glue},
Ops);
872 unsigned NumBytesForCalleeToPop;
875 NumBytesForCalleeToPop = NumBytes;
879 NumBytesForCalleeToPop = 4;
881 NumBytesForCalleeToPop = 0;
887 NumBytesForCalleeToPop = NumBytes;
892 Chain = DAG.
getCALLSEQ_END(Chain, NumBytesToPop, NumBytesForCalleeToPop,
899 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins,
DL, DAG,
903SDValue M68kTargetLowering::LowerCallResult(
912 CCInfo.AnalyzeCallResult(Ins, RetCC_M68k);
915 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
916 CCValAssign &VA = RVLocs[i];
938SDValue M68kTargetLowering::LowerFormalArguments(
943 M68kMachineFunctionInfo *MMFI = MF.
getInfo<M68kMachineFunctionInfo>();
953 M68kCCState CCInfo(ArgTypes, CCID, IsVarArg, MF, ArgLocs, *DAG.
getContext());
955 CCInfo.AnalyzeFormalArguments(Ins, CC_M68k);
957 unsigned LastVal = ~0
U;
959 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
960 CCValAssign &VA = ArgLocs[i];
961 assert(VA.
getValNo() != LastVal &&
"Same value in different locations");
969 if (RegVT == MVT::i32)
970 RC = &M68k::XR32RegClass;
995 ArgValue = LowerMemArgument(Chain, CCID, Ins,
DL, DAG, VA, MFI, i);
1007 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1016 if (Ins[i].
Flags.isSRet()) {
1029 unsigned StackSize = CCInfo.getStackSize();
1032 StackSize = GetAlignedArgumentStackSize(StackSize, DAG);
1037 if (MFI.hasVAStart()) {
1041 if (IsVarArg && MFI.hasMustTailInVarArgFunc()) {
1044 MVT IntVT = MVT::i32;
1049 SmallVectorImpl<ForwardedRegister> &Forwards =
1051 CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, CC_M68k);
1054 for (ForwardedRegister &
F : Forwards) {
1082bool M68kTargetLowering::CanLowerReturn(
1085 const Type *RetTy)
const {
1087 CCState CCInfo(CCID, IsVarArg, MF, RVLocs,
Context);
1088 return CCInfo.CheckReturn(Outs, RetCC_M68k);
1098 M68kMachineFunctionInfo *MFI = MF.
getInfo<M68kMachineFunctionInfo>();
1101 CCState CCInfo(CCID, IsVarArg, MF, RVLocs, *DAG.
getContext());
1102 CCInfo.AnalyzeReturn(Outs, RetCC_M68k);
1113 for (
unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
1114 CCValAssign &VA = RVLocs[i];
1116 SDValue ValToCopy = OutVals[i];
1174 unsigned RetValReg = M68k::D0;
1188 return DAG.
getNode(M68kISD::RET,
DL, MVT::Other, RetOps);
1224M68kTargetLowering::GetAlignedArgumentStackSize(
unsigned StackSize,
1226 const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();
1228 uint64_t AlignMask = StackAlignment - 1;
1229 int64_t
Offset = StackSize;
1230 unsigned SlotSize = Subtarget.getSlotSize();
1231 if ((
Offset & AlignMask) <= (StackAlignment - SlotSize)) {
1233 Offset += ((StackAlignment - SlotSize) - (
Offset & AlignMask));
1237 ((~AlignMask) &
Offset) + StackAlignment + (StackAlignment - SlotSize);
1244bool M68kTargetLowering::IsEligibleForTailCallOptimization(
1246 bool IsCalleeStructRet,
bool IsCallerStructRet,
Type *RetTy,
1258 bool CCMatch = CallerCC == CalleeCC;
1271 const M68kRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
1272 if (RegInfo->hasStackRealignment(MF))
1277 if (IsCalleeStructRet || IsCallerStructRet)
1283 if (IsVarArg && !Outs.
empty()) {
1286 CCState CCInfo(CalleeCC, IsVarArg, MF, ArgLocs,
C);
1288 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);
1289 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i)
1290 if (!ArgLocs[i].isRegLoc())
1300 const M68kRegisterInfo *
TRI = Subtarget.getRegisterInfo();
1301 const uint32_t *CallerPreserved =
TRI->getCallPreservedMask(MF, CallerCC);
1303 const uint32_t *CalleePreserved =
TRI->getCallPreservedMask(MF, CalleeCC);
1304 if (!
TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
1308 unsigned StackArgsSize = 0;
1312 if (!Outs.
empty()) {
1316 CCState CCInfo(CalleeCC, IsVarArg, MF, ArgLocs,
C);
1318 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);
1319 StackArgsSize = CCInfo.getStackSize();
1321 if (StackArgsSize) {
1326 const M68kInstrInfo *
TII = Subtarget.getInstrInfo();
1327 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1328 CCValAssign &VA = ArgLocs[i];
1329 SDValue Arg = OutVals[i];
1330 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
1349 PositionIndependent) {
1350 unsigned NumInRegs = 0;
1353 unsigned MaxInRegs = PositionIndependent ? 1 : 2;
1355 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1356 CCValAssign &VA = ArgLocs[i];
1365 if (++NumInRegs == MaxInRegs)
1380 if (
unsigned BytesToPop =
1381 MF.
getInfo<M68kMachineFunctionInfo>()->getBytesToPopOnReturn()) {
1383 bool CalleePopMatches = CalleeWillPop && BytesToPop == StackArgsSize;
1384 if (!CalleePopMatches)
1386 }
else if (CalleeWillPop && StackArgsSize > 0) {
1400 switch (
Op.getOpcode()) {
1409 return LowerXALUO(
Op, DAG);
1411 return LowerSETCC(
Op, DAG);
1413 return LowerSETCCCARRY(
Op, DAG);
1415 return LowerSELECT(
Op, DAG);
1417 return LowerBRCOND(
Op, DAG);
1420 return LowerUADDO_USUBO_CARRY(
Op, DAG);
1422 return LowerConstantPool(
Op, DAG);
1424 return LowerGlobalAddress(
Op, DAG);
1426 return LowerExternalSymbol(
Op, DAG);
1428 return LowerBlockAddress(
Op, DAG);
1430 return LowerJumpTable(
Op, DAG);
1432 return LowerVASTART(
Op, DAG);
1434 return LowerDYNAMIC_STACKALLOC(
Op, DAG);
1436 return LowerShiftLeftParts(
Op, DAG);
1438 return LowerShiftRightParts(
Op, DAG,
true);
1440 return LowerShiftRightParts(
Op, DAG,
false);
1442 return LowerATOMICFENCE(
Op, DAG);
1444 return LowerGlobalTLSAddress(
Op, DAG);
1451 ArgListTy &&ArgList)
const {
1453 CallLoweringInfo CLI(DAG);
1459 std::move(ArgList));
1465 unsigned TargetFlags)
const {
1474 Args.emplace_back(Arg, PtrTy);
1475 return LowerExternalSymbolCall(DAG,
SDLoc(GA),
"__tls_get_addr",
1480 return LowerExternalSymbolCall(DAG, Loc,
"__m68k_read_tp",
ArgListTy());
1500 SDValue Tp = getM68kReadTp(SDLoc(GA), DAG);
1514 SDValue Tp = getM68kReadTp(SDLoc(GA), DAG);
1523 assert(Subtarget.isTargetELF());
1528 switch (AccessModel) {
1530 return LowerTLSGeneralDynamic(GA, DAG);
1532 return LowerTLSLocalDynamic(GA, DAG);
1534 return LowerTLSInitialExec(GA, DAG);
1536 return LowerTLSLocalExec(GA, DAG);
1549 return VT.
bitsLE(MVT::i32) || Subtarget.atLeastM68020();
1554 return DAG.
getNode(M68kISD::SETCC, dl, MVT::i8,
1576 EVT VT =
N->getValueType(0);
1581 unsigned TruncOp = 0;
1582 auto PromoteMULO = [&](
unsigned ExtOp) {
1587 if (VT == MVT::i8) {
1595 bool NoOverflow =
false;
1596 unsigned BaseOp = 0;
1597 switch (
Op.getOpcode()) {
1601 BaseOp = M68kISD::ADD;
1605 BaseOp = M68kISD::ADD;
1609 BaseOp = M68kISD::SUB;
1613 BaseOp = M68kISD::SUB;
1618 NoOverflow = VT != MVT::i32;
1624 NoOverflow = VT != MVT::i32;
1641 Result = DAG.
getNode(TruncOp,
DL, MVT::i8, Arith);
1650 SDNode *
N =
Op.getNode();
1666 Overflow = DAG.
getNode(M68kISD::SETCC,
DL,
N->getValueType(1),
1680 if (Src.getValueType() == MVT::i8 || Src.getValueType() == MVT::i16)
1692 return DAG.
getNode(M68kISD::SETCC,
DL, MVT::i8,
1714 unsigned AndBitWidth =
And.getValueSizeInBits();
1724 uint64_t AndRHSVal = AndRHS->getZExtValue();
1746 switch (SetCCOpcode) {
1780 if (SetCCOpcode ==
ISD::SETGT && RHSC->isAllOnes()) {
1785 if (SetCCOpcode ==
ISD::SETLT && RHSC->isZero()) {
1789 if (SetCCOpcode ==
ISD::SETLT && RHSC->getZExtValue() == 1) {
1803 SetCCOpcode = getSetCCSwappedOperands(SetCCOpcode);
1807 switch (SetCCOpcode) {
1824 switch (SetCCOpcode) {
1860 "Expected TRUNCATE to i1 node");
1862 if (
Op.getOperand(0).getOpcode() !=
ISD::SRL)
1875 unsigned UOpNo = UI->getOperandNo();
1894 bool NeedCF =
false;
1895 bool NeedOF =
false;
1914 switch (
Op->getOpcode()) {
1919 if (
Op.getNode()->getFlags().hasNoSignedWrap())
1933 if (
Op.getResNo() != 0 || NeedOF || NeedCF) {
1935 return DAG.
getNode(M68kISD::CMP,
DL, MVT::i8,
1938 unsigned Opcode = 0;
1939 unsigned NumOperands = 0;
1944 bool NeedTruncation =
false;
1945 SDValue ArithOp =
Op;
1947 SDValue Arith =
Op->getOperand(0);
1958 NeedTruncation =
true;
1969 Opcode = M68kISD::ADD;
1980 EVT VT =
Op.getValueType();
1982 unsigned ShAmt =
Op->getConstantOperandVal(1);
1988 if (!
Mask.isSignedIntN(32))
2003 bool IsLegalAndnType = VT == MVT::i32 || VT == MVT::i64;
2007 if ( !IsAndn || !IsLegalAndnType)
2016 for (
const auto *U :
Op.getNode()->users())
2025 Opcode = M68kISD::SUB;
2028 Opcode = M68kISD::XOR;
2031 Opcode = M68kISD::AND;
2034 Opcode = M68kISD::OR;
2045 return SDValue(
Op.getNode(), 1);
2053 if (NeedTruncation) {
2054 EVT VT =
Op.getValueType();
2055 SDValue WideVal =
Op->getOperand(0);
2057 unsigned ConvertedOp = 0;
2065 ConvertedOp = M68kISD::ADD;
2068 ConvertedOp = M68kISD::SUB;
2071 ConvertedOp = M68kISD::AND;
2074 ConvertedOp = M68kISD::OR;
2077 ConvertedOp = M68kISD::XOR;
2093 return DAG.
getNode(M68kISD::CMP,
DL, MVT::i8,
2096 SDVTList VTs = DAG.
getVTList(
Op.getValueType(), MVT::i8);
2101 return SDValue(
New.getNode(), 1);
2107 return EmitTest(Op0, M68kCC,
DL, DAG);
2110 "Unexpected comparison operation for MVT::i1 operands");
2112 return DAG.
getNode(M68kISD::CMP,
DL, MVT::i8, Op1, Op0);
2128 MVT VT =
Op.getSimpleValueType();
2129 assert(VT == MVT::i8 &&
"SetCC type must be 8-bit integer");
2131 SDValue Op0 =
Op.getOperand(0);
2132 SDValue Op1 =
Op.getOperand(1);
2143 if (SDValue NewSetCC = LowerToBTST(Op0,
CC,
DL, DAG)) {
2157 if (Op0.
getOpcode() == M68kISD::SETCC) {
2165 DAG.
getNode(M68kISD::SETCC,
DL, MVT::i8,
2188 SDValue CCR = EmitCmp(Op0, Op1, M68kCC,
DL, DAG);
2189 return DAG.
getNode(M68kISD::SETCC,
DL, MVT::i8,
2195 SDValue
LHS =
Op.getOperand(0);
2196 SDValue
RHS =
Op.getOperand(1);
2197 SDValue Carry =
Op.getOperand(2);
2198 SDValue
Cond =
Op.getOperand(3);
2201 assert(
LHS.getSimpleValueType().isInteger() &&
"SETCCCARRY is integer only.");
2209 SDVTList VTs = DAG.
getVTList(
LHS.getValueType(), MVT::i8);
2213 return DAG.
getNode(M68kISD::SETCC,
DL, MVT::i8,
2219 unsigned Opc =
Op.getNode()->getOpcode();
2220 if (
Opc == M68kISD::CMP)
2222 if (
Op.getResNo() == 1 &&
2223 (
Opc == M68kISD::ADD ||
Opc == M68kISD::SUB ||
Opc == M68kISD::ADDX ||
2224 Opc == M68kISD::SUBX ||
Opc == M68kISD::SMUL ||
Opc == M68kISD::UMUL ||
2225 Opc == M68kISD::OR ||
Opc == M68kISD::XOR ||
Opc == M68kISD::AND))
2228 if (
Op.getResNo() == 2 &&
Opc == M68kISD::UMUL)
2240 unsigned Bits = V.getValueSizeInBits();
2246 bool addTest =
true;
2247 SDValue
Cond =
Op.getOperand(0);
2248 SDValue Op1 =
Op.getOperand(1);
2249 SDValue Op2 =
Op.getOperand(2);
2254 if (SDValue NewCond = LowerSETCC(
Cond, DAG))
2260 unsigned CondOpcode =
Cond.getOpcode();
2261 if (CondOpcode == M68kISD::SETCC) {
2264 SDValue
Cmp =
Cond.getOperand(1);
2265 unsigned Opc =
Cmp.getOpcode();
2267 bool IllegalFPCMov =
false;
2291 CC = NewSetCC.getOperand(0);
2292 Cond = NewSetCC.getOperand(1);
2309 if (
T1.getValueType() == T2.getValueType() &&
2323 const APInt &
C =
Const->getAPIntValue();
2324 if (
C.countr_zero() >= 5)
2326 else if (
C.countr_one() >= 5)
2339 Opc =
Op.getOpcode();
2343 Op.getOperand(0).hasOneUse() &&
2345 Op.getOperand(1).hasOneUse());
2354 return Op.getOperand(0).getOpcode() == M68kISD::SETCC &&
2355 Op.getOperand(0).hasOneUse();
2360 bool AddTest =
true;
2361 SDValue Chain =
Op.getOperand(0);
2362 SDValue
Cond =
Op.getOperand(1);
2363 SDValue Dest =
Op.getOperand(2);
2366 bool Inverted =
false;
2372 Cond.getOperand(0).getResNo() == 1 &&
2380 if (SDValue NewCond = LowerSETCC(
Cond, DAG))
2387 unsigned CondOpcode =
Cond.getOpcode();
2388 if (CondOpcode == M68kISD::SETCC) {
2391 SDValue
Cmp =
Cond.getOperand(1);
2392 unsigned Opc =
Cmp.getOpcode();
2398 switch (
CC->getAsZExtVal()) {
2405 Cond =
Cond.getNode()->getOperand(1);
2411 CondOpcode =
Cond.getOpcode();
2425 SDValue
Cmp =
Cond.getOperand(0).getOperand(1);
2431 CC =
Cond.getOperand(0).getOperand(0);
2432 Chain = DAG.
getNode(M68kISD::BRCOND,
DL,
Op.getValueType(), Chain,
2434 CC =
Cond.getOperand(1).getOperand(0);
2445 Op.getNode()->hasOneUse()) {
2450 SDNode *
User = *
Op.getNode()->user_begin();
2455 SDValue FalseBB =
User->getOperand(1);
2462 Chain = DAG.
getNode(M68kISD::BRCOND,
DL,
Op.getValueType(), Chain,
2481 Cond =
Cond.getOperand(0).getOperand(1);
2492 if (
Cond.hasOneUse()) {
2494 CC = NewSetCC.getOperand(0);
2495 Cond = NewSetCC.getOperand(1);
2506 return DAG.
getNode(M68kISD::BRCOND,
DL,
Op.getValueType(), Chain, Dest,
CC,
2512 SDNode *
N =
Op.getNode();
2513 MVT VT =
N->getSimpleValueType(0);
2517 SDValue Carry =
Op.getOperand(2);
2524 SDValue Sum = DAG.
getNode(IsAdd ? M68kISD::ADDX : M68kISD::SUBX,
DL,
2526 Op.getOperand(1), Flags);
2545 unsigned char OpFlag = Subtarget.classifyLocalReference(
nullptr);
2547 unsigned WrapperKind = M68kISD::Wrapper;
2549 WrapperKind = M68kISD::WrapperPC;
2562 DAG.
getNode(M68kISD::GLOBAL_BASE_REG, SDLoc(), PtrVT),
2576 unsigned char OpFlag = Subtarget.classifyExternalReference(*
Mod);
2578 unsigned WrapperKind = M68kISD::Wrapper;
2580 WrapperKind = M68kISD::WrapperPC;
2592 DAG.
getNode(M68kISD::GLOBAL_BASE_REG, SDLoc(), PtrVT),
2608 unsigned char OpFlags = Subtarget.classifyBlockAddressReference();
2627 DAG.
getNode(M68kISD::GLOBAL_BASE_REG,
DL, PtrVT), Result);
2636 unsigned char OpFlags = Subtarget.classifyGlobalReference(GV);
2658 DAG.
getNode(M68kISD::GLOBAL_BASE_REG,
DL, PtrVT), Result);
2682 return LowerGlobalAddress(GV, SDLoc(
Op),
Offset, DAG);
2695 unsigned char OpFlag = Subtarget.classifyLocalReference(
nullptr);
2697 unsigned WrapperKind = M68kISD::Wrapper;
2699 WrapperKind = M68kISD::WrapperPC;
2710 DAG.
getNode(M68kISD::GLOBAL_BASE_REG, SDLoc(), PtrVT),
2718 return Subtarget.getJumpTableEncoding();
2745 if (Constraint.
size() > 0) {
2746 switch (Constraint[0]) {
2760 if (Constraint.
size() == 2)
2761 switch (Constraint[1]) {
2783 std::vector<SDValue> &
Ops,
2787 if (Constraint.
size() == 1) {
2789 switch (Constraint[0]) {
2802 int64_t Val =
C->getSExtValue();
2803 switch (Constraint[0]) {
2805 if (Val > 0 && Val <= 8)
2813 if (Val < -0x80 || Val >= 0x80)
2817 if (Val < 0 && Val >= -8)
2821 if (Val < -0x100 || Val >= 0x100)
2825 if (Val >= 24 && Val <= 31)
2833 if (Val >= 8 && Val <= 15)
2848 if (Constraint.
size() == 2) {
2849 switch (Constraint[0]) {
2852 switch (Constraint[1]) {
2860 int64_t Val =
C->getSExtValue();
2861 switch (Constraint[1]) {
2888 if (Result.getNode()) {
2889 Ops.push_back(Result);
2896std::pair<unsigned, const TargetRegisterClass *>
2900 if (Constraint.
size() == 1) {
2901 switch (Constraint[0]) {
2906 return std::make_pair(0U, &M68k::DR8RegClass);
2908 return std::make_pair(0U, &M68k::DR16RegClass);
2910 return std::make_pair(0U, &M68k::DR32RegClass);
2918 return std::make_pair(0U, &M68k::AR16RegClass);
2920 return std::make_pair(0U, &M68k::AR32RegClass);
2943 switch (
MI.getOpcode()) {
2974 if (miI == BB->
end())
2976 if (SBB->isLiveIn(M68k::CCR))
2981 SelectItr->addRegisterKilled(M68k::CCR,
TRI);
2988 const TargetInstrInfo *
TII = Subtarget.getInstrInfo();
3004 MachineBasicBlock *ThisMBB =
MBB;
3043 MachineInstr *CascadedCMOV =
nullptr;
3044 MachineInstr *LastCMOV = &
MI;
3057 (NextMIIt->getOperand(3).getImm() ==
CC ||
3058 NextMIIt->getOperand(3).getImm() == OppCC)) {
3059 LastCMOV = &*NextMIIt;
3066 if (LastCMOV == &
MI && NextMIIt !=
MBB->
end() &&
3067 NextMIIt->getOpcode() ==
MI.getOpcode() &&
3068 NextMIIt->getOperand(2).getReg() ==
MI.getOperand(2).getReg() &&
3069 NextMIIt->getOperand(1).getReg() ==
MI.getOperand(0).getReg() &&
3070 NextMIIt->getOperand(1).isKill()) {
3071 CascadedCMOV = &*NextMIIt;
3074 MachineBasicBlock *Jcc1MBB =
nullptr;
3079 Jcc1MBB =
F->CreateMachineBasicBlock(BB);
3084 MachineBasicBlock *Copy0MBB =
F->CreateMachineBasicBlock(BB);
3085 MachineBasicBlock *SinkMBB =
F->CreateMachineBasicBlock(BB);
3086 F->insert(It, Copy0MBB);
3087 F->insert(It, SinkMBB);
3090 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
3096 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
3098 MachineInstr *LastCCRSUser = CascadedCMOV ? CascadedCMOV : LastCMOV;
3148 DenseMap<unsigned, std::pair<unsigned, unsigned>> RegRewriteTable;
3149 MachineInstrBuilder MIB;
3159 Register DestReg = MIIt->getOperand(0).getReg();
3160 Register Op1Reg = MIIt->getOperand(1).getReg();
3161 Register Op2Reg = MIIt->getOperand(2).getReg();
3166 if (MIIt->getOperand(3).getImm() == OppCC)
3169 if (RegRewriteTable.
find(Op1Reg) != RegRewriteTable.
end())
3170 Op1Reg = RegRewriteTable[Op1Reg].first;
3172 if (RegRewriteTable.
find(Op2Reg) != RegRewriteTable.
end())
3173 Op2Reg = RegRewriteTable[Op2Reg].second;
3176 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(M68k::PHI), DestReg)
3183 RegRewriteTable[DestReg] = std::make_pair(Op1Reg, Op2Reg);
3192 DL,
TII->get(TargetOpcode::COPY),
3194 .
addReg(
MI.getOperand(0).getReg());
3200 (MIIt++)->eraseFromParent();
3208 llvm_unreachable(
"Cannot lower Segmented Stack Alloca with stack-split on");
3214 switch (
MI.getOpcode()) {
3220 return EmitLoweredSelect(
MI, BB);
3222 return EmitLoweredSegAlloca(
MI, BB);
3249 const SDValue AsmOperands[4] = {
3260 DAG.
getVTList(MVT::Other, MVT::Glue), AsmOperands);
3276 SDNode *
Node =
Op.getNode();
3277 SDValue Chain =
Op.getOperand(0);
3278 SDValue
Size =
Op.getOperand(1);
3279 unsigned Align =
Op.getConstantOperandVal(2);
3280 EVT VT =
Node->getValueType(0);
3298 assert(
SPReg &&
"Target cannot require DYNAMIC_STACKALLOC expansion and"
3299 " not tell us which reg is the stack pointer!");
3302 Chain =
SP.getValue(1);
3303 const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();
3306 if (Align > StackAlign)
3321 SDValue
Lo =
Op.getOperand(0);
3322 SDValue
Hi =
Op.getOperand(1);
3323 SDValue Shamt =
Op.getOperand(2);
3324 EVT VT =
Lo.getValueType();
3336 SDValue RegisterSizeMinus1 = DAG.
getConstant(32 - 1,
DL, VT);
3337 SDValue ShamtMinusRegisterSize =
3339 SDValue RegisterSizeMinus1Shamt =
3344 SDValue ShiftRightLo =
3362 SDValue
Lo =
Op.getOperand(0);
3363 SDValue
Hi =
Op.getOperand(1);
3364 SDValue Shamt =
Op.getOperand(2);
3365 EVT VT =
Lo.getValueType();
3388 SDValue RegisterSizeMinus1 = DAG.
getConstant(32 - 1,
DL, VT);
3389 SDValue ShamtMinusRegisterSize =
3391 SDValue RegisterSizeMinus1Shamt =
3396 SDValue ShiftLeftHi =
3399 SDValue HiTrue = DAG.
getNode(ShiftRightOp,
DL, VT,
Hi, Shamt);
3401 DAG.
getNode(ShiftRightOp,
DL, VT,
Hi, ShamtMinusRegisterSize);
3433 if (Carry.
getOpcode() == M68kISD::SETCC) {
3436 if (NeedX && Flags.getOpcode() != M68kISD::ADD &&
3437 Flags.getOpcode() != M68kISD::SUB &&
3438 Flags.getOpcode() != M68kISD::ADDX &&
3439 Flags.getOpcode() != M68kISD::SUBX)
3487 return DAG.
getNode(M68kISD::BRCOND,
DL,
N->getVTList(),
N->getOperand(0),
3488 N->getOperand(1),
Cond, Flags);
3497 MVT VT =
N->getSimpleValueType(0);
3499 return DAG.
getNode(M68kISD::SUBX,
SDLoc(
N), VTs,
N->getOperand(0),
3500 N->getOperand(1), Flags);
3511 MVT VT =
N->getSimpleValueType(0);
3513 return DAG.
getNode(M68kISD::ADDX,
SDLoc(
N), VTs,
N->getOperand(0),
3514 N->getOperand(1), Flags);
3521 DAGCombinerInfo &DCI)
const {
3522 SelectionDAG &DAG = DCI.DAG;
3523 switch (
N->getOpcode()) {
3528 case M68kISD::SETCC:
3530 case M68kISD::BRCOND:
3538 bool IsVarArg)
const {
3540 return RetCC_M68k_C;
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.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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...
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
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 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 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 M68k::CondCode 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,...
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 void lowerOverflowArithmetic(SDValue Op, SelectionDAG &DAG, SDValue &Result, SDValue &CCR, M68k::CondCode &CC)
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 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 ...
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 SDValue combineCarryThroughADD(SDValue CCR, bool NeedX)
This file defines the interfaces that M68k uses to lower LLVM code into a selection DAG.
This file contains the declarations of the M68k MCAsmInfo properties.
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.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static constexpr MCPhysReg SPReg
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
an instruction that atomically reads a memory location, combines it with another value,...
static LLVM_ABI 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.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
unsigned getValNo() const
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
const Constant * getConstVal() const
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
iterator_range< arg_iterator > args()
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
int64_t getOffset() const
const GlobalValue * getGlobal() const
bool hasDLLImportStorageClass() const
Module * getParent()
Get the module that this global value is contained inside of...
This is an important class for using LLVM in a threaded context.
void setVarArgsFrameIndex(int Index)
void setSRetReturnReg(unsigned Reg)
SmallVectorImpl< ForwardedRegister > & getForwardedMustTailRegParms()
void setBytesToPopOnReturn(unsigned bytes)
unsigned getBytesToPopOnReturn() const
unsigned getSRetReturnReg() const
void setRAIndex(int Index)
int getVarArgsFrameIndex() const
void setArgumentStackSize(unsigned size)
void setTCReturnAddrDelta(int delta)
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
unsigned getStackRegister() const
const M68kRegisterInfo * getRegisterInfo() 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...
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
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,...
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.
Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
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.
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
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.
LLVM_ABI 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.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void 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.
BasicBlockListType::iterator iterator
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, RegState Flags={}, 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.
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.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
@ EK_Custom32
EK_Custom32 - Each entry is a 32-bit value that is custom lowered by the TargetLowering::LowerCustomJ...
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Class to represent pointers.
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
Wrapper class representing virtual and physical registers.
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
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, in exactly one operand.
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...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI 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)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
SDValue getGLOBAL_OFFSET_TABLE(EVT VT)
Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
LLVM_ABI 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)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
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.
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 ...
@ ZeroOrNegativeOneBooleanContent
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.
TargetLowering(const TargetLowering &)=delete
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
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.
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
User * getUser() const
Returns the User that contains this Use.
LLVM Value Representation.
bool hasOneUse() const
Return true if there is exactly one use of this value.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ M68k_INTR
Used for M68k interrupt routines.
@ Swift
Calling convention for Swift.
@ M68k_RTD
Used for M68k rtd-based CC (similar to X86's stdcall).
@ C
The default llvm calling convention, compatible with C.
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.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ BR
Control flow instructions. These all have token chains.
@ SETCCCARRY
Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but op #2 is a boolean indicating ...
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ BasicBlock
Various leaf nodes.
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ SMULO
Same for multiplication.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
static bool isPCRelBlockReference(unsigned char Flag)
Return True if the Block is referenced using PC.
static bool isGlobalRelativeToPICBase(unsigned char TargetFlag)
Return true if the specified global value reference is relative to a 32-bit PIC base (M68kISD::GLOBAL...
static bool isGlobalStubReference(unsigned char TargetFlag)
Return true if the specified TargetFlag operand is a reference to a stub for a global,...
static bool isPCRelGlobalReference(unsigned char Flag)
Return True if the specified GlobalValue requires PC addressing mode.
@ MO_TLSLDM
On a symbol operand, this indicates that the immediate is the offset to the slot in GOT which stores ...
@ MO_TLSLE
On a symbol operand, this indicates that the immediate is the offset to the variable within in the th...
@ MO_TLSGD
On a symbol operand, this indicates that the immediate is the offset to the slot in GOT which stores ...
@ MO_GOTPCREL
On a symbol operand this indicates that the immediate is offset to the GOT entry for the symbol name ...
@ MO_TLSIE
On a symbol operand, this indicates that the immediate is the offset to the variable within the threa...
@ MO_TLSLD
On a symbol operand, this indicates that the immediate is the offset to variable within the thread lo...
static bool isDirectGlobalReference(unsigned char Flag)
Return True if the specified GlobalValue is a direct reference for a symbol.
static bool IsSETCC(unsigned SETCC)
static unsigned GetCondBranchFromCond(M68k::CondCode CC)
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)
@ User
could "use" a pointer
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
unsigned Log2_64_Ceil(uint64_t Value)
Return the ceil log base 2 of the specified value, 64 if the value is zero.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
LLVM_ABI 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)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Mod
The access may modify the value stored in memory.
@ Xor
Bitwise or logical XOR of integers.
DWARFExpression::Operation Op
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
bool isVectorOf(EVT EltVT) const
Return true if this is a vector with matching element type.
bool bitsLE(EVT VT) const
Return true if this has no more bits than VT.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This 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
Type * RetTy
Same as OrigRetTy, or partially legalized for soft float libcalls.
CallLoweringInfo & setChain(SDValue InChain)