42#define DEBUG_TYPE "M68k-isel"
108 for (
auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
116 for (
auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
126 for (
auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
134 for (
auto VT : {MVT::i8, MVT::i16, MVT::i32}) {
185 {MVT::i8, MVT::i16, MVT::i32},
LibCall);
230#include "M68kGenCallingConv.inc"
270 Chain,
DL, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
314 cast<VTSDNode>(TruncInput.
getOperand(1))->getVT() ==
331 if (!Flags.isByVal()) {
335 unsigned Opcode = Def->getOpcode();
336 if ((Opcode == M68k::LEA32p || Opcode == M68k::LEA32f) &&
337 Def->getOperand(1).isFI()) {
338 FI = Def->getOperand(1).getIndex();
339 Bytes = Flags.getByValSize();
343 }
else if (
auto *Ld = dyn_cast<LoadSDNode>(Arg)) {
359 Bytes = Flags.getByValSize();
383M68kTargetLowering::getReturnAddressFrameIndex(
SelectionDAG &DAG)
const {
388 if (ReturnAddrIndex == 0) {
392 SlotSize, -(int64_t)SlotSize,
false);
402 bool IsTailCall,
int FPDiff,
405 OutRetAddr = getReturnAddressFrameIndex(DAG);
412SDValue M68kTargetLowering::EmitTailCallStoreRetAddr(
414 EVT PtrVT,
unsigned SlotSize,
int FPDiff,
const SDLoc &
DL)
const {
420 SlotSize, (int64_t)FPDiff - SlotSize,
false);
425 Chain,
DL, RetFI, NewFI,
436 unsigned ArgIdx)
const {
453 }
else if (VA.
getValVT() == MVT::i16) {
467 bool IsImmutable = !AlwaysUseMutable && !
Flags.isByVal();
469 if (
Flags.isByVal()) {
470 unsigned Bytes =
Flags.getByValSize();
493 ValVT,
DL, Chain, FIN,
513 Chain,
DL, Arg, PtrOff,
536 bool IsSibcall =
false;
544 if (Attr.getValueAsBool())
555 }
else if (IsTailCall) {
557 IsTailCall = IsEligibleForTailCallOptimization(
572 "Var args not supported with calling convention fastcc");
577 for (
const auto &Arg : CLI.
getArgs())
579 M68kCCState CCInfo(ArgTypes, CallConv, IsVarArg, MF, ArgLocs,
581 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);
584 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();
591 NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);
595 if (IsTailCall && !IsSibcall && !IsMustTail) {
599 FPDiff = NumBytesCallerPushed - NumBytes;
603 if (FPDiff < MFI->getTCReturnAddrDelta())
607 unsigned NumBytesToPush = NumBytes;
608 unsigned NumBytesToPop = NumBytes;
613 if (!Outs.
empty() && Outs.
back().Flags.isInAlloca()) {
615 if (!ArgLocs.
back().isMemLoc())
618 if (ArgLocs.
back().getLocMemOffset() != 0)
620 "the only memory argument");
625 NumBytes - NumBytesToPush,
DL);
629 if (IsTailCall && FPDiff)
630 Chain = EmitTailCallLoadRetAddr(DAG, RetFI, Chain, IsTailCall, FPDiff,
DL);
639 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
643 if (
Flags.isInAlloca())
649 bool IsByVal =
Flags.isByVal();
672 int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
674 Chain,
DL, Arg, SpillSlot,
683 }
else if (!IsSibcall && (!IsTailCall || IsByVal)) {
690 LowerMemOpCallTo(Chain, StackPtr, Arg,
DL, DAG, VA, Flags));
694 if (!MemOpChains.
empty())
701 if (IsVarArg && IsMustTail) {
703 for (
const auto &
F : Forwards) {
705 RegsToPass.
push_back(std::make_pair(
unsigned(
F.PReg), Val));
712 if (!IsSibcall && IsTailCall) {
724 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
732 if (
Flags.isInAlloca())
740 if (
Flags.isByVal()) {
755 ArgChain,
DL, Arg, FIN,
760 if (!MemOpChains2.
empty())
764 Chain = EmitTailCallStoreRetAddr(DAG, MF, Chain, RetFI,
772 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
774 RegsToPass[i].second, InGlue);
807 unsigned char OpFlags =
818 if (!IsSibcall && IsTailCall) {
831 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i)
833 RegsToPass[i].second.getValueType()));
837 assert(Mask &&
"Missing call preserved mask for calling convention");
853 unsigned NumBytesForCalleeToPop;
856 NumBytesForCalleeToPop = NumBytes;
860 NumBytesForCalleeToPop = 4;
862 NumBytesForCalleeToPop = 0;
868 NumBytesForCalleeToPop = NumBytes;
873 Chain = DAG.
getCALLSEQ_END(Chain, NumBytesToPop, NumBytesForCalleeToPop,
880 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins,
DL, DAG,
884SDValue M68kTargetLowering::LowerCallResult(
893 CCInfo.AnalyzeCallResult(Ins, RetCC_M68k);
896 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
919SDValue M68kTargetLowering::LowerFormalArguments(
936 CCInfo.AnalyzeFormalArguments(Ins, CC_M68k);
938 unsigned LastVal = ~0
U;
940 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
942 assert(VA.
getValNo() != LastVal &&
"Same value in different locations");
949 if (RegVT == MVT::i32)
950 RC = &M68k::XR32RegClass;
975 ArgValue = LowerMemArgument(Chain, CCID, Ins,
DL, DAG, VA, MFI, i);
987 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
996 if (Ins[i].
Flags.isSRet()) {
1009 unsigned StackSize = CCInfo.getStackSize();
1012 StackSize = GetAlignedArgumentStackSize(StackSize, DAG);
1017 if (MFI.hasVAStart()) {
1021 if (IsVarArg && MFI.hasMustTailInVarArgFunc()) {
1024 MVT IntVT = MVT::i32;
1031 CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, CC_M68k);
1062bool M68kTargetLowering::CanLowerReturn(
1066 CCState CCInfo(CCID, IsVarArg, MF, RVLocs, Context);
1067 return CCInfo.CheckReturn(Outs, RetCC_M68k);
1081 CCInfo.AnalyzeReturn(Outs, RetCC_M68k);
1092 for (
unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
1095 SDValue ValToCopy = OutVals[i];
1153 unsigned RetValReg = M68k::D0;
1203M68kTargetLowering::GetAlignedArgumentStackSize(
unsigned StackSize,
1207 uint64_t AlignMask = StackAlignment - 1;
1208 int64_t
Offset = StackSize;
1210 if ((
Offset & AlignMask) <= (StackAlignment - SlotSize)) {
1212 Offset += ((StackAlignment - SlotSize) - (
Offset & AlignMask));
1216 ((~AlignMask) &
Offset) + StackAlignment + (StackAlignment - SlotSize);
1223bool M68kTargetLowering::IsEligibleForTailCallOptimization(
1225 bool IsCalleeStructRet,
bool IsCallerStructRet,
Type *
RetTy,
1237 bool CCMatch = CallerCC == CalleeCC;
1251 if (
RegInfo->hasStackRealignment(MF))
1256 if (IsCalleeStructRet || IsCallerStructRet)
1262 if (IsVarArg && !Outs.
empty()) {
1265 CCState CCInfo(CalleeCC, IsVarArg, MF, ArgLocs,
C);
1267 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);
1268 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i)
1269 if (!ArgLocs[i].isRegLoc())
1280 const uint32_t *CallerPreserved =
TRI->getCallPreservedMask(MF, CallerCC);
1282 const uint32_t *CalleePreserved =
TRI->getCallPreservedMask(MF, CalleeCC);
1283 if (!
TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))
1287 unsigned StackArgsSize = 0;
1291 if (!Outs.
empty()) {
1295 CCState CCInfo(CalleeCC, IsVarArg, MF, ArgLocs,
C);
1297 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);
1298 StackArgsSize = CCInfo.getStackSize();
1300 if (StackArgsSize) {
1306 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1326 if ((!isa<GlobalAddressSDNode>(Callee) &&
1327 !isa<ExternalSymbolSDNode>(Callee)) ||
1328 PositionIndependent) {
1329 unsigned NumInRegs = 0;
1332 unsigned MaxInRegs = PositionIndependent ? 1 : 2;
1334 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
1344 if (++NumInRegs == MaxInRegs)
1359 if (
unsigned BytesToPop =
1362 bool CalleePopMatches = CalleeWillPop && BytesToPop == StackArgsSize;
1363 if (!CalleePopMatches)
1365 }
else if (CalleeWillPop && StackArgsSize > 0) {
1379 switch (
Op.getOpcode()) {
1388 return LowerXALUO(
Op, DAG);
1390 return LowerSETCC(
Op, DAG);
1392 return LowerSETCCCARRY(
Op, DAG);
1394 return LowerSELECT(
Op, DAG);
1396 return LowerBRCOND(
Op, DAG);
1401 return LowerADDC_ADDE_SUBC_SUBE(
Op, DAG);
1403 return LowerConstantPool(
Op, DAG);
1405 return LowerGlobalAddress(
Op, DAG);
1407 return LowerExternalSymbol(
Op, DAG);
1409 return LowerBlockAddress(
Op, DAG);
1411 return LowerJumpTable(
Op, DAG);
1413 return LowerVASTART(
Op, DAG);
1415 return LowerDYNAMIC_STACKALLOC(
Op, DAG);
1417 return LowerShiftLeftParts(
Op, DAG);
1419 return LowerShiftRightParts(
Op, DAG,
true);
1421 return LowerShiftRightParts(
Op, DAG,
false);
1423 return LowerATOMICFENCE(
Op, DAG);
1425 return LowerGlobalTLSAddress(
Op, DAG);
1432 ArgListTy &&ArgList)
const {
1434 CallLoweringInfo CLI(DAG);
1440 std::move(ArgList));
1446 unsigned TargetFlags)
const {
1458 Args.push_back(Entry);
1459 return LowerExternalSymbolCall(DAG,
SDLoc(GA),
"__tls_get_addr",
1464 return LowerExternalSymbolCall(DAG, Loc,
"__m68k_read_tp",
ArgListTy());
1509 auto *GA = cast<GlobalAddressSDNode>(
Op);
1512 switch (AccessModel) {
1514 return LowerTLSGeneralDynamic(GA, DAG);
1516 return LowerTLSLocalDynamic(GA, DAG);
1518 return LowerTLSInitialExec(GA, DAG);
1520 return LowerTLSLocalExec(GA, DAG);
1526bool M68kTargetLowering::decomposeMulByConstant(
LLVMContext &Context,
EVT VT,
1544 unsigned BaseOp = 0;
1547 switch (
Op.getOpcode()) {
1585 if (Src.getValueType() == MVT::i8 || Src.getValueType() == MVT::i16)
1619 unsigned AndBitWidth =
And.getValueSizeInBits();
1622 if (Known.countMinLeadingZeros() <
BitWidth - AndBitWidth)
1628 }
else if (
auto *AndRHS = dyn_cast<ConstantSDNode>(Op1)) {
1629 uint64_t AndRHSVal = AndRHS->getZExtValue();
1651 switch (SetCCOpcode) {
1685 if (SetCCOpcode ==
ISD::SETGT && RHSC->isAllOnes()) {
1690 if (SetCCOpcode ==
ISD::SETLT && RHSC->isZero()) {
1694 if (SetCCOpcode ==
ISD::SETLT && RHSC->getZExtValue() == 1) {
1708 SetCCOpcode = getSetCCSwappedOperands(SetCCOpcode);
1712 switch (SetCCOpcode) {
1729 switch (SetCCOpcode) {
1765 "Expected TRUNCATE to i1 node");
1767 if (
Op.getOperand(0).getOpcode() !=
ISD::SRL)
1780 unsigned UOpNo = UI.getOperandNo();
1799 bool NeedCF =
false;
1800 bool NeedOF =
false;
1819 switch (
Op->getOpcode()) {
1824 if (
Op.getNode()->getFlags().hasNoSignedWrap())
1838 if (
Op.getResNo() != 0 || NeedOF || NeedCF) {
1843 unsigned Opcode = 0;
1844 unsigned NumOperands = 0;
1849 bool NeedTruncation =
false;
1863 NeedTruncation =
true;
1883 Op->hasOneUse() && isa<ConstantSDNode>(
Op->getOperand(1)) &&
1885 EVT VT =
Op.getValueType();
1887 unsigned ShAmt =
Op->getConstantOperandVal(1);
1893 if (!
Mask.isSignedIntN(32))
1908 bool IsLegalAndnType = VT == MVT::i32 || VT == MVT::i64;
1912 if ( !IsAndn || !IsLegalAndnType)
1921 for (
const auto *U :
Op.getNode()->uses())
1958 if (NeedTruncation) {
1959 EVT VT =
Op.getValueType();
1962 unsigned ConvertedOp = 0;
2032 return EmitTest(Op0, M68kCC,
DL, DAG);
2035 "Unexpected comparison operation for MVT::i1 operands");
2042 (isa<ConstantSDNode>(Op0) || isa<ConstantSDNode>(Op1))) &&
2046 Op0 = DAG.
getNode(ExtendOp,
DL, MVT::i32, Op0);
2047 Op1 = DAG.
getNode(ExtendOp,
DL, MVT::i32, Op1);
2070 MVT VT =
Op.getSimpleValueType();
2071 assert(VT == MVT::i8 &&
"SetCC type must be 8-bit integer");
2085 if (
SDValue NewSetCC = LowerToBTST(Op0,
CC,
DL, DAG)) {
2130 SDValue CCR = EmitCmp(Op0, Op1, M68kCC,
DL, DAG);
2143 assert(
LHS.getSimpleValueType().isInteger() &&
"SETCCCARRY is integer only.");
2161 unsigned Opc =
Op.getNode()->getOpcode();
2164 if (
Op.getResNo() == 1 &&
2180 SDValue VOp0 = V.getOperand(0);
2182 unsigned Bits = V.getValueSizeInBits();
2188 bool addTest =
true;
2210 cast<ConstantSDNode>(
Cond.getOperand(0))->getZExtValue();
2259 unsigned CondOpcode =
Cond.getOpcode();
2264 unsigned Opc =
Cmp.getOpcode();
2266 bool IllegalFPCMov =
false;
2280 switch (CondOpcode) {
2309 VTs = DAG.
getVTList(
LHS.getValueType(),
LHS.getValueType(), MVT::i32);
2333 CC = NewSetCC.getOperand(0);
2334 Cond = NewSetCC.getOperand(1);
2350 unsigned CondCode = cast<ConstantSDNode>(
CC)->getZExtValue();
2370 if (
T1.getValueType() == T2.getValueType() &&
2390 Opc =
Op.getOpcode();
2394 Op.getOperand(0).hasOneUse() &&
2396 Op.getOperand(1).hasOneUse());
2406 Op.getOperand(0).hasOneUse();
2411 bool AddTest =
true;
2417 bool Inverted =
false;
2421 if (cast<CondCodeSDNode>(
Cond.getOperand(2))->get() ==
ISD::SETEQ &&
2423 Cond.getOperand(0).getResNo() == 1 &&
2444 unsigned CondOpcode =
Cond.getOpcode();
2449 unsigned Opc =
Cmp.getOpcode();
2455 switch (cast<ConstantSDNode>(
CC)->getZExtValue()) {
2462 Cond =
Cond.getNode()->getOperand(1);
2468 CondOpcode =
Cond.getOpcode();
2479 switch (CondOpcode) {
2534 CC =
Cond.getOperand(0).getOperand(0);
2537 CC =
Cond.getOperand(1).getOperand(0);
2548 Op.getNode()->hasOneUse()) {
2584 Cond =
Cond.getOperand(0).getOperand(1);
2595 if (
Cond.hasOneUse()) {
2597 CC = NewSetCC.getOperand(0);
2598 Cond = NewSetCC.getOperand(1);
2615 MVT VT =
Op.getNode()->getSimpleValueType(0);
2624 bool ExtraOp =
false;
2625 switch (
Op.getOpcode()) {
2671 CP->getConstVal(), PtrVT,
CP->getAlign(),
CP->getOffset(), OpFlag);
2688 const char *
Sym = cast<ExternalSymbolSDNode>(
Op)->getSymbol();
2726 const BlockAddress *BA = cast<BlockAddressSDNode>(
Op)->getBlockAddress();
2727 int64_t
Offset = cast<BlockAddressSDNode>(
Op)->getOffset();
2797 const GlobalValue *GV = cast<GlobalAddressSDNode>(
Op)->getGlobal();
2798 int64_t
Offset = cast<GlobalAddressSDNode>(
Op)->getOffset();
2863 if (Constraint.
size() > 0) {
2864 switch (Constraint[0]) {
2878 if (Constraint.
size() == 2)
2879 switch (Constraint[1]) {
2900 std::string &Constraint,
2901 std::vector<SDValue> &Ops,
2905 if (Constraint.size() == 1) {
2907 switch (Constraint[0]) {
2916 auto *
C = dyn_cast<ConstantSDNode>(
Op);
2920 int64_t Val =
C->getSExtValue();
2921 switch (Constraint[0]) {
2923 if (Val > 0 && Val <= 8)
2931 if (Val < -0x80 || Val >= 0x80)
2935 if (Val < 0 && Val >= -8)
2939 if (Val < -0x100 || Val >= 0x100)
2943 if (Val >= 24 && Val <= 31)
2951 if (Val >= 8 && Val <= 15)
2966 if (Constraint.size() == 2) {
2967 switch (Constraint[0]) {
2970 switch (Constraint[1]) {
2974 auto *
C = dyn_cast<ConstantSDNode>(
Op);
2978 int64_t Val =
C->getSExtValue();
2979 switch (Constraint[1]) {
2987 if (!isInt<16>(
C->getSExtValue()))
3006 if (Result.getNode()) {
3007 Ops.push_back(Result);
3014std::pair<unsigned, const TargetRegisterClass *>
3018 if (Constraint.
size() == 1) {
3019 switch (Constraint[0]) {
3024 return std::make_pair(0U, &M68k::DR8RegClass);
3026 return std::make_pair(0U, &M68k::DR16RegClass);
3028 return std::make_pair(0U, &M68k::DR32RegClass);
3036 return std::make_pair(0U, &M68k::AR16RegClass);
3038 return std::make_pair(0U, &M68k::AR32RegClass);
3054 bool GuaranteeTCO) {
3062 switch (
MI.getOpcode()) {
3093 if (miI == BB->
end())
3095 if (SBB->isLiveIn(M68k::CCR))
3100 SelectItr->addRegisterKilled(M68k::CCR,
TRI);
3176 (NextMIIt->getOperand(3).getImm() ==
CC ||
3177 NextMIIt->getOperand(3).getImm() == OppCC)) {
3178 LastCMOV = &*NextMIIt;
3185 if (LastCMOV == &
MI && NextMIIt !=
MBB->
end() &&
3186 NextMIIt->getOpcode() ==
MI.getOpcode() &&
3187 NextMIIt->getOperand(2).getReg() ==
MI.getOperand(2).getReg() &&
3188 NextMIIt->getOperand(1).getReg() ==
MI.getOperand(0).getReg() &&
3189 NextMIIt->getOperand(1).isKill()) {
3190 CascadedCMOV = &*NextMIIt;
3198 Jcc1MBB =
F->CreateMachineBasicBlock(BB);
3199 F->insert(It, Jcc1MBB);
3205 F->insert(It, Copy0MBB);
3206 F->insert(It, SinkMBB);
3209 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
3217 MachineInstr *LastCCRSUser = CascadedCMOV ? CascadedCMOV : LastCMOV;
3278 Register DestReg = MIIt->getOperand(0).getReg();
3279 Register Op1Reg = MIIt->getOperand(1).getReg();
3280 Register Op2Reg = MIIt->getOperand(2).getReg();
3285 if (MIIt->getOperand(3).getImm() == OppCC)
3288 if (RegRewriteTable.
find(Op1Reg) != RegRewriteTable.
end())
3289 Op1Reg = RegRewriteTable[Op1Reg].first;
3291 if (RegRewriteTable.
find(Op2Reg) != RegRewriteTable.
end())
3292 Op2Reg = RegRewriteTable[Op2Reg].second;
3295 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(M68k::PHI), DestReg)
3302 RegRewriteTable[DestReg] = std::make_pair(Op1Reg, Op2Reg);
3311 DL,
TII->get(TargetOpcode::COPY),
3313 .
addReg(
MI.getOperand(0).getReg());
3319 (MIIt++)->eraseFromParent();
3327 llvm_unreachable(
"Cannot lower Segmented Stack Alloca with stack-split on");
3333 switch (
MI.getOpcode()) {
3339 return EmitLoweredSelect(
MI, BB);
3341 return EmitLoweredSegAlloca(
MI, BB);
3350 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3368 const SDValue AsmOperands[4] = {
3379 DAG.
getVTList(MVT::Other, MVT::Glue), AsmOperands);
3398 unsigned Align = cast<ConstantSDNode>(
Op.getOperand(2))->getZExtValue();
3399 EVT VT =
Node->getValueType(0);
3410 Register Vreg =
MRI.createVirtualRegister(ARClass);
3417 assert(SPReg &&
"Target cannot require DYNAMIC_STACKALLOC expansion and"
3418 " not tell us which reg is the stack pointer!");
3425 if (
Align > StackAlign)
3443 EVT VT =
Lo.getValueType();
3456 SDValue ShamtMinusRegisterSize =
3458 SDValue RegisterSizeMinus1Shamt =
3484 EVT VT =
Lo.getValueType();
3508 SDValue ShamtMinusRegisterSize =
3510 SDValue RegisterSizeMinus1Shamt =
3520 DAG.
getNode(ShiftRightOp,
DL, VT,
Hi, ShamtMinusRegisterSize);
3605 N->getOperand(1),
Cond, Flags);
3613 MVT VT =
N->getSimpleValueType(0);
3616 N->getOperand(1), Flags);
3626 MVT VT =
N->getSimpleValueType(0);
3629 N->getOperand(1), Flags);
3636 DAGCombinerInfo &DCI)
const {
3638 switch (
N->getOpcode()) {
3658 return "M68kISD::CALL";
3660 return "M68kISD::TAIL_CALL";
3662 return "M68kISD::RET";
3664 return "M68kISD::TC_RETURN";
3666 return "M68kISD::ADD";
3668 return "M68kISD::SUB";
3670 return "M68kISD::ADDX";
3672 return "M68kISD::SUBX";
3674 return "M68kISD::SMUL";
3676 return "M68kISD::UMUL";
3678 return "M68kISD::OR";
3680 return "M68kISD::XOR";
3682 return "M68kISD::AND";
3684 return "M68kISD::CMP";
3686 return "M68kISD::BTST";
3688 return "M68kISD::SELECT";
3690 return "M68kISD::CMOV";
3692 return "M68kISD::BRCOND";
3694 return "M68kISD::SETCC";
3696 return "M68kISD::SETCC_CARRY";
3698 return "M68kISD::GLOBAL_BASE_REG";
3700 return "M68kISD::Wrapper";
3702 return "M68kISD::WrapperPC";
3704 return "M68kISD::SEG_ALLOCA";
3711 bool IsVarArg)
const {
3713 return RetCC_M68k_C;
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 MachineBasicBlock::iterator DebugLoc DL
static bool MatchingStackOffset(SDValue Arg, unsigned Offset, ISD::ArgFlagsTy Flags, MachineFrameInfo &MFI, const MachineRegisterInfo *MRI, const TargetInstrInfo *TII)
MatchingStackOffset - Return true if the given stack call argument is already available in the same p...
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...
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 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 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 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.
unsigned const TargetRegisterInfo * TRI
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const char LLVMTargetMachineRef TM
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
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.
This class represents an incoming formal argument to a Function.
an instruction that atomically reads a memory location, combines it with another value,...
LLVM Basic Block Representation.
The address of a basic block.
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.
Register getLocReg() const
LocInfo getLocInfo() 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.
This class represents an Operation in the Expression.
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 hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
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...
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
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)
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
unsigned char classifyGlobalFunctionReference(const GlobalValue *GV, const Module &M) const
Classify a global function reference for the current subtarget.
const M68kFrameLowering * getFrameLowering() const override
ConstraintType getConstraintType(StringRef ConstraintStr) const override
Given a constraint, return the type of constraint it is for this target.
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
void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
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.
Base class for the full range of assembler expressions which are needed for parsing.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
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.
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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 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.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr kills the specified register.
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
@ 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,...
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.
Class to represent pointers.
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.
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.
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)
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
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 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 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
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
const DataLayout & getDataLayout() const
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
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 getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
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)
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
MachineFunction & getMachineFunction() const
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
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
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)
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)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
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.