LLVM: lib/Target/M68k/M68kISelLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

23

41

42using namespace llvm;

43

44#define DEBUG_TYPE "M68k-isel"

45

46STATISTIC(NumTailCalls, "Number of tail calls");

47

51

52 MVT PtrVT = MVT::i32;

53

54

55

57

58 auto *RegInfo = Subtarget.getRegisterInfo();

60

61

65

70 }

71

72

79

82 if (Subtarget.atLeastM68020())

84 else

87

88 for (auto OP :

94 }

95

99 }

100

105 }

106

109

110

111 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {

116 }

117

118

119 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {

124 }

125

128

129 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {

135 }

136

137 for (auto VT : {MVT::i8, MVT::i16, MVT::i32}) {

142 }

143

150

155

158

160

162

163

164

166 setOperationAction(ISD::ATOMIC_CMP_SWAP, {MVT::i8, MVT::i16, MVT::i32},

167 Subtarget.atLeastM68020() ? Legal : LibCall);

168

170

171

172

173

175 {

176 ISD::ATOMIC_LOAD_ADD,

177 ISD::ATOMIC_LOAD_SUB,

178 ISD::ATOMIC_LOAD_AND,

179 ISD::ATOMIC_LOAD_OR,

180 ISD::ATOMIC_LOAD_XOR,

181 ISD::ATOMIC_LOAD_NAND,

182 ISD::ATOMIC_LOAD_MIN,

183 ISD::ATOMIC_LOAD_MAX,

184 ISD::ATOMIC_LOAD_UMIN,

185 ISD::ATOMIC_LOAD_UMAX,

186 ISD::ATOMIC_SWAP,

187 },

188 {MVT::i8, MVT::i16, MVT::i32}, LibCall);

189

191}

192

195 return Subtarget.atLeastM68020()

198}

199

202 return M68k::D0;

203}

204

207 return M68k::D1;

208}

209

218

221

222 return MVT::i8;

223}

224

226 EVT Ty) const {

227 if (Ty.isSimple()) {

228 return Ty.getSimpleVT();

229 }

231}

232

233#include "M68kGenCallingConv.inc"

234

236

239 if (Outs.empty())

241

243 if (!Flags.isSRet())

245 if (Flags.isInReg())

248}

249

250

255

257 if (!Flags.isSRet())

259 if (Flags.isInReg())

262}

263

264

265

266

271

273 Chain, DL, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),

274 false, true,

276}

277

278

280

281

283 switch (CC) {

284

286 return true;

287 default:

289 }

290}

291

292

293

297

298

299

306

307 for (;;) {

308

312 continue;

313 }

320 continue;

321 }

322 }

323 break;

324 }

325

326 int FI = INT_MAX;

330 return false;

332 if (!Def)

333 return false;

334 if (!Flags.isByVal()) {

335 if (TII->isLoadFromStackSlot(*Def, FI))

336 return false;

337 } else {

338 unsigned Opcode = Def->getOpcode();

339 if ((Opcode == M68k::LEA32p || Opcode == M68k::LEA32f) &&

340 Def->getOperand(1).isFI()) {

341 FI = Def->getOperand(1).getIndex();

342 Bytes = Flags.getByValSize();

343 } else

344 return false;

345 }

347 if (Flags.isByVal())

348

349

350

351

352

353 return false;

354 SDValue Ptr = Ld->getBasePtr();

356 if (!FINode)

357 return false;

362 Bytes = Flags.getByValSize();

363 } else

364 return false;

365

366 assert(FI != INT_MAX);

368 return false;

369

371 return false;

372

374

375

376 if (Flags.isZExt() != MFI.isObjectZExt(FI) ||

378 return false;

379 }

380 }

381

383}

384

386M68kTargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {

388 M68kMachineFunctionInfo *FuncInfo = MF.getInfo();

389 int ReturnAddrIndex = FuncInfo->getRAIndex();

390

391 if (ReturnAddrIndex == 0) {

392

393 unsigned SlotSize = Subtarget.getSlotSize();

395 SlotSize, -(int64_t)SlotSize, false);

396 FuncInfo->setRAIndex(ReturnAddrIndex);

397 }

398

400}

401

405 bool IsTailCall, int FPDiff,

408 OutRetAddr = getReturnAddressFrameIndex(DAG);

409

410

411 OutRetAddr = DAG.getLoad(VT, DL, Chain, OutRetAddr, MachinePointerInfo());

413}

414

415SDValue M68kTargetLowering::EmitTailCallStoreRetAddr(

417 EVT PtrVT, unsigned SlotSize, int FPDiff, const SDLoc &DL) const {

418 if (!FPDiff)

419 return Chain;

420

421

423 SlotSize, (int64_t)FPDiff - SlotSize, false);

424

426

428 Chain, DL, RetFI, NewFI,

430 return Chain;

431}

432

439 unsigned ArgIdx) const {

440

441 ISD::ArgFlagsTy Flags = Ins[ArgIdx].Flags;

442 EVT ValVT;

443

444

445

448 else

450

451

452

454 if (VA.getValVT() == MVT::i8) {

456 } else if (VA.getValVT() == MVT::i16) {

458 }

459

460

461

462

463

464

465

466

467

470 bool IsImmutable = !AlwaysUseMutable && Flags.isByVal();

471

472 if (Flags.isByVal()) {

473 unsigned Bytes = Flags.getByValSize();

474 if (Bytes == 0)

475 Bytes = 1;

477

478

480 } else {

481 int FI =

483

484

489 }

490

491

492

493

496 ValVT, DL, Chain, FIN,

499 : Val;

500 }

501}

502

511 StackPtr, PtrOff);

512 if (Flags.isByVal())

514

516 Chain, DL, Arg, PtrOff,

518}

519

520

521

522

523

526 SelectionDAG &DAG = CLI.DAG;

527 SDLoc &DL = CLI.DL;

528 SmallVectorImplISD::OutputArg &Outs = CLI.Outs;

529 SmallVectorImpl &OutVals = CLI.OutVals;

530 SmallVectorImplISD::InputArg &Ins = CLI.Ins;

535 bool IsVarArg = CLI.IsVarArg;

536

539 bool IsSibcall = false;

540 M68kMachineFunctionInfo *MFI = MF.getInfo();

541

542

545

547 if (Attr.getValueAsBool())

548 IsTailCall = false;

549

550

551

553 if (IsMustTail) {

554

555

556

557 IsTailCall = true;

558 } else if (IsTailCall) {

559

560 IsTailCall = IsEligibleForTailCallOptimization(

563 DAG);

564

565

566

568 IsSibcall = true;

569

570 if (IsTailCall)

571 ++NumTailCalls;

572 }

573

575 "Var args not supported with calling convention fastcc");

576

577

580 for (const auto &Arg : CLI.getArgs())

582 M68kCCState CCInfo(ArgTypes, CallConv, IsVarArg, MF, ArgLocs,

584 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);

585

586

587 unsigned NumBytes = CCInfo.getAlignedCallFrameSize();

588 if (IsSibcall) {

589

590

591 NumBytes = 0;

594 NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);

595 }

596

597 int FPDiff = 0;

598 if (IsTailCall && !IsSibcall && !IsMustTail) {

599

601

602 FPDiff = NumBytesCallerPushed - NumBytes;

603

604

605

606 if (FPDiff < MFI->getTCReturnAddrDelta())

608 }

609

610 unsigned NumBytesToPush = NumBytes;

611 unsigned NumBytesToPop = NumBytes;

612

613

614

615

616 if (!Outs.empty() && Outs.back().Flags.isInAlloca()) {

617 NumBytesToPush = 0;

618 if (!ArgLocs.back().isMemLoc())

620 "parameter");

621 if (ArgLocs.back().getLocMemOffset() != 0)

622 report_fatal_error("any parameter with the inalloca attribute must be "

623 "the only memory argument");

624 }

625

626 if (!IsSibcall)

628 NumBytes - NumBytesToPush, DL);

629

631

632 if (IsTailCall && FPDiff)

633 Chain = EmitTailCallLoadRetAddr(DAG, RetFI, Chain, IsTailCall, FPDiff, DL);

634

638

639

640

641 const M68kRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

642 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {

643 ISD::ArgFlagsTy Flags = Outs[i].Flags;

644

645

646 if (Flags.isInAlloca())

647 continue;

648

649 CCValAssign &VA = ArgLocs[i];

651 SDValue Arg = OutVals[i];

652 bool IsByVal = Flags.isByVal();

653

654

656 default:

659 break;

662 break;

665 break;

668 break;

671 break;

673

677 Chain, DL, Arg, SpillSlot,

679 Arg = SpillSlot;

680 break;

681 }

682 }

683

686 } else if (!IsSibcall && (!IsTailCall || IsByVal)) {

691 }

693 LowerMemOpCallTo(Chain, StackPtr, Arg, DL, DAG, VA, Flags));

694 }

695 }

696

697 if (!MemOpChains.empty())

699

700

701

702

703

704 if (IsVarArg && IsMustTail) {

706 for (const auto &F : Forwards) {

708 RegsToPass.push_back(std::make_pair(unsigned(F.PReg), Val));

709 }

710 }

711

712

713

714

715 if (!IsSibcall && IsTailCall) {

716

717

718

719

720

721

723

726 int FI = 0;

727 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {

728 CCValAssign &VA = ArgLocs[i];

730 continue;

732 SDValue Arg = OutVals[i];

733 ISD::ArgFlagsTy Flags = Outs[i].Flags;

734

735 if (Flags.isInAlloca())

736 continue;

737

739 uint32_t OpSize = (VA.getLocVT().getSizeInBits() + 7) / 8;

742

743 if (Flags.isByVal()) {

744

749 }

751 StackPtr, Source);

752

755 } else {

756

758 ArgChain, DL, Arg, FIN,

760 }

761 }

762

763 if (!MemOpChains2.empty())

765

766

767 Chain = EmitTailCallStoreRetAddr(DAG, MF, Chain, RetFI,

769 Subtarget.getSlotSize(), FPDiff, DL);

770 }

771

772

773

775 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {

776 Chain = DAG.getCopyToReg(Chain, DL, RegsToPass[i].first,

777 RegsToPass[i].second, InGlue);

779 }

780

782

783

784

786

787

788

789 const GlobalValue *GV = G->getGlobal();

791 unsigned char OpFlags = Subtarget.classifyGlobalFunctionReference(GV);

792

795

797

798

801

802

806 }

807 }

810 unsigned char OpFlags =

811 Subtarget.classifyGlobalFunctionReference(nullptr, *Mod);

812

815 }

816

818

819 if (!IsSibcall && IsTailCall) {

820 Chain = DAG.getCALLSEQ_END(Chain, NumBytesToPop, 0, InGlue, DL);

822 }

823

824 Ops.push_back(Chain);

825 Ops.push_back(Callee);

826

827 if (IsTailCall)

829

830

831

832 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)

834 RegsToPass[i].second.getValueType()));

835

836

838 assert(Mask && "Missing call preserved mask for calling convention");

839

841

843 Ops.push_back(InGlue);

844

845 if (IsTailCall) {

847 return DAG.getNode(M68kISD::TC_RETURN, DL, MVT::Other, Ops);

848 }

849

850

851 Chain = DAG.getNode(M68kISD::CALL, DL, {MVT::Other, MVT::Glue}, Ops);

853

854

855 unsigned NumBytesForCalleeToPop;

858 NumBytesForCalleeToPop = NumBytes;

860

861

862 NumBytesForCalleeToPop = 4;

863 } else {

864 NumBytesForCalleeToPop = 0;

865 }

866

868

869

870 NumBytesForCalleeToPop = NumBytes;

871 }

872

873

874 if (!IsSibcall) {

875 Chain = DAG.getCALLSEQ_END(Chain, NumBytesToPop, NumBytesForCalleeToPop,

876 InGlue, DL);

878 }

879

880

881

882 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, DL, DAG,

883 InVals);

884}

885

886SDValue M68kTargetLowering::LowerCallResult(

890

891

895 CCInfo.AnalyzeCallResult(Ins, RetCC_M68k);

896

897

898 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {

899 CCValAssign &VA = RVLocs[i];

901

902

906

909

912 }

913

914 return Chain;

915}

916

917

918

919

920

921SDValue M68kTargetLowering::LowerFormalArguments(

926 M68kMachineFunctionInfo *MMFI = MF.getInfo();

927

928

930

931

936 M68kCCState CCInfo(ArgTypes, CCID, IsVarArg, MF, ArgLocs, *DAG.getContext());

937

938 CCInfo.AnalyzeFormalArguments(Ins, CC_M68k);

939

940 unsigned LastVal = ~0U;

942 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {

943 CCValAssign &VA = ArgLocs[i];

944 assert(VA.getValNo() != LastVal && "Same value in different locations");

945 (void)LastVal;

946

948

951 const TargetRegisterClass *RC;

952 if (RegVT == MVT::i32)

953 RC = &M68k::XR32RegClass;

954 else

956

959

960

961

962

971 }

972

975 }

976 } else {

978 ArgValue = LowerMemArgument(Chain, CCID, Ins, DL, DAG, VA, MFI, i);

979 }

980

981

982

984 ArgValue =

985 DAG.getLoad(VA.getValVT(), DL, Chain, ArgValue, MachinePointerInfo());

986

988 }

989

990 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {

991

992

994 continue;

995

996

997

998

999 if (Ins[i].Flags.isSRet()) {

1001 if (Reg) {

1005 }

1008 break;

1009 }

1010 }

1011

1012 unsigned StackSize = CCInfo.getStackSize();

1013

1015 StackSize = GetAlignedArgumentStackSize(StackSize, DAG);

1016

1017

1018

1019

1020 if (MFI.hasVAStart()) {

1022 }

1023

1024 if (IsVarArg && MFI.hasMustTailInVarArgFunc()) {

1025

1027 MVT IntVT = MVT::i32;

1029

1030

1031

1032 SmallVectorImpl &Forwards =

1034 CCInfo.analyzeMustTailForwardedRegisters(Forwards, RegParmTypes, CC_M68k);

1035

1036

1037 for (ForwardedRegister &F : Forwards) {

1038

1042 }

1043 }

1044

1045

1049 } else {

1051

1054 }

1055

1057

1058 return Chain;

1059}

1060

1061

1062

1063

1064

1065bool M68kTargetLowering::CanLowerReturn(

1068 const Type *RetTy) const {

1070 CCState CCInfo(CCID, IsVarArg, MF, RVLocs, Context);

1071 return CCInfo.CheckReturn(Outs, RetCC_M68k);

1072}

1073

1076 bool IsVarArg,

1081 M68kMachineFunctionInfo *MFI = MF.getInfo();

1082

1084 CCState CCInfo(CCID, IsVarArg, MF, RVLocs, *DAG.getContext());

1085 CCInfo.AnalyzeReturn(Outs, RetCC_M68k);

1086

1089

1091

1094

1095

1096 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {

1097 CCValAssign &VA = RVLocs[i];

1098 assert(VA.isRegLoc() && "Can only return in registers!");

1099 SDValue ValToCopy = OutVals[i];

1101

1102

1110 else

1114

1118 }

1119

1120

1121

1122

1123

1124

1125

1126

1127

1128

1129

1130

1132

1133

1134

1135

1136

1137

1138

1139

1140

1141

1142

1143

1144

1145

1146

1147

1148

1149

1150

1151

1154

1155

1156

1157 unsigned RetValReg = M68k::D0;

1158 Chain = DAG.getCopyToReg(Chain, DL, RetValReg, Val, Glue);

1160

1163 }

1164

1165 RetOps[0] = Chain;

1166

1167

1170

1171 return DAG.getNode(M68kISD::RET, DL, MVT::Other, RetOps);

1172}

1173

1174

1175

1176

1177

1178

1179

1180

1181

1182

1183

1184

1185

1186

1187

1188

1189

1190

1191

1192

1193

1194

1195

1196

1197

1198

1199

1200

1201

1202

1203

1204

1205

1206unsigned

1207M68kTargetLowering::GetAlignedArgumentStackSize(unsigned StackSize,

1209 const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();

1211 uint64_t AlignMask = StackAlignment - 1;

1212 int64_t Offset = StackSize;

1213 unsigned SlotSize = Subtarget.getSlotSize();

1214 if ((Offset & AlignMask) <= (StackAlignment - SlotSize)) {

1215

1216 Offset += ((StackAlignment - SlotSize) - (Offset & AlignMask));

1217 } else {

1218

1220 ((~AlignMask) & Offset) + StackAlignment + (StackAlignment - SlotSize);

1221 }

1223}

1224

1225

1226

1227bool M68kTargetLowering::IsEligibleForTailCallOptimization(

1229 bool IsCalleeStructRet, bool IsCallerStructRet, Type *RetTy,

1234 return false;

1235

1236

1239

1241 bool CCMatch = CallerCC == CalleeCC;

1242

1245 return true;

1246 return false;

1247 }

1248

1249

1250

1251

1252

1253

1254 const M68kRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

1255 if (RegInfo->hasStackRealignment(MF))

1256 return false;

1257

1258

1259

1260 if (IsCalleeStructRet || IsCallerStructRet)

1261 return false;

1262

1263

1264

1266 if (IsVarArg && !Outs.empty()) {

1267

1269 CCState CCInfo(CalleeCC, IsVarArg, MF, ArgLocs, C);

1270

1271 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);

1272 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i)

1273 if (!ArgLocs[i].isRegLoc())

1274 return false;

1275 }

1276

1277

1279 RetCC_M68k))

1280 return false;

1281

1282

1283 const M68kRegisterInfo *TRI = Subtarget.getRegisterInfo();

1284 const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);

1285 if (!CCMatch) {

1286 const uint32_t *CalleePreserved = TRI->getCallPreservedMask(MF, CalleeCC);

1287 if (TRI->regmaskSubsetEqual(CallerPreserved, CalleePreserved))

1288 return false;

1289 }

1290

1291 unsigned StackArgsSize = 0;

1292

1293

1294

1295 if (!Outs.empty()) {

1296

1297

1299 CCState CCInfo(CalleeCC, IsVarArg, MF, ArgLocs, C);

1300

1301 CCInfo.AnalyzeCallOperands(Outs, CC_M68k);

1302 StackArgsSize = CCInfo.getStackSize();

1303

1304 if (StackArgsSize) {

1305

1306

1308 const MachineRegisterInfo *MRI = &MF.getRegInfo();

1309 const M68kInstrInfo *TII = Subtarget.getInstrInfo();

1310 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {

1311 CCValAssign &VA = ArgLocs[i];

1312 SDValue Arg = OutVals[i];

1313 ISD::ArgFlagsTy Flags = Outs[i].Flags;

1315 return false;

1318 TII, VA))

1319 return false;

1320 }

1321 }

1322 }

1323

1325

1326

1327

1328

1329

1332 PositionIndependent) {

1333 unsigned NumInRegs = 0;

1334

1335

1336 unsigned MaxInRegs = PositionIndependent ? 1 : 2;

1337

1338 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {

1339 CCValAssign &VA = ArgLocs[i];

1341 continue;

1343 switch (Reg) {

1344 default:

1345 break;

1346 case M68k::A0:

1347 case M68k::A1:

1348 if (++NumInRegs == MaxInRegs)

1349 return false;

1350 break;

1351 }

1352 }

1353 }

1354

1355 const MachineRegisterInfo &MRI = MF.getRegInfo();

1357 return false;

1358 }

1359

1362

1363 if (unsigned BytesToPop =

1364 MF.getInfo()->getBytesToPopOnReturn()) {

1365

1366 bool CalleePopMatches = CalleeWillPop && BytesToPop == StackArgsSize;

1367 if (!CalleePopMatches)

1368 return false;

1369 } else if (CalleeWillPop && StackArgsSize > 0) {

1370

1371 return false;

1372 }

1373

1374 return true;

1375}

1376

1377

1378

1379

1380

1383 switch (Op.getOpcode()) {

1384 default:

1392 return LowerXALUO(Op, DAG);

1394 return LowerSETCC(Op, DAG);

1396 return LowerSETCCCARRY(Op, DAG);

1398 return LowerSELECT(Op, DAG);

1399 case ISD::BRCOND:

1400 return LowerBRCOND(Op, DAG);

1405 return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);

1407 return LowerConstantPool(Op, DAG);

1409 return LowerGlobalAddress(Op, DAG);

1411 return LowerExternalSymbol(Op, DAG);

1413 return LowerBlockAddress(Op, DAG);

1415 return LowerJumpTable(Op, DAG);

1416 case ISD::VASTART:

1417 return LowerVASTART(Op, DAG);

1418 case ISD::DYNAMIC_STACKALLOC:

1419 return LowerDYNAMIC_STACKALLOC(Op, DAG);

1421 return LowerShiftLeftParts(Op, DAG);

1423 return LowerShiftRightParts(Op, DAG, true);

1425 return LowerShiftRightParts(Op, DAG, false);

1426 case ISD::ATOMIC_FENCE:

1427 return LowerATOMICFENCE(Op, DAG);

1429 return LowerGlobalTLSAddress(Op, DAG);

1430 }

1431}

1432

1436 ArgListTy &&ArgList) const {

1438 CallLoweringInfo CLI(DAG);

1444 std::move(ArgList));

1446}

1447

1450 unsigned TargetFlags) const {

1455

1457

1458 ArgListTy Args;

1459 Args.emplace_back(Arg, PtrTy);

1460 return LowerExternalSymbolCall(DAG, SDLoc(GA), "__tls_get_addr",

1461 std::move(Args));

1462}

1463

1465 return LowerExternalSymbolCall(DAG, Loc, "__m68k_read_tp", ArgListTy());

1466}

1467

1471}

1472

1479 return DAG.getNode(ISD::ADD, SDLoc(GA), MVT::i32, TGA, Addr);

1480}

1481

1485 SDValue Tp = getM68kReadTp(SDLoc(GA), DAG);

1493

1495}

1496

1499 SDValue Tp = getM68kReadTp(SDLoc(GA), DAG);

1503 return DAG.getNode(ISD::ADD, SDLoc(GA), MVT::i32, TGA, Tp);

1504}

1505

1506SDValue M68kTargetLowering::LowerGlobalTLSAddress(SDValue Op,

1508 assert(Subtarget.isTargetELF());

1509

1512

1513 switch (AccessModel) {

1515 return LowerTLSGeneralDynamic(GA, DAG);

1517 return LowerTLSLocalDynamic(GA, DAG);

1519 return LowerTLSInitialExec(GA, DAG);

1521 return LowerTLSLocalExec(GA, DAG);

1522 }

1523

1525}

1526

1529

1530

1531

1532

1533

1534 return VT.bitsLE(MVT::i32) || Subtarget.atLeastM68020();

1535}

1536

1538 switch (Opcode) {

1545 return true;

1546 default:

1547 return false;

1548 }

1549}

1550

1553 unsigned &CC) {

1555 EVT VT = N->getValueType(0);

1559

1560 unsigned TruncOp = 0;

1561 auto PromoteMULO = [&](unsigned ExtOp) {

1562

1563

1564

1565

1566 if (VT == MVT::i8) {

1569 VT = MVT::i16;

1571 }

1572 };

1573

1574 bool NoOverflow = false;

1575 unsigned BaseOp = 0;

1576 switch (Op.getOpcode()) {

1577 default:

1580 BaseOp = M68kISD::ADD;

1582 break;

1584 BaseOp = M68kISD::ADD;

1586 break;

1588 BaseOp = M68kISD::SUB;

1590 break;

1592 BaseOp = M68kISD::SUB;

1594 break;

1597 NoOverflow = VT != MVT::i32;

1600 break;

1603 NoOverflow = VT != MVT::i32;

1606 break;

1607 }

1608

1610 if (NoOverflow)

1612 else

1613

1614 VTs = DAG.getVTList(VT, MVT::i8);

1615

1618 if (TruncOp)

1619

1620 Result = DAG.getNode(TruncOp, DL, MVT::i8, Arith);

1621

1622 if (NoOverflow)

1624 else

1626}

1627

1629 SDNode *N = Op.getNode();

1630 SDLoc DL(Op);

1631

1632

1633

1635 unsigned CC;

1637

1640

1641

1642 Overflow = CCR;

1643 } else {

1644

1645 Overflow = DAG.getNode(M68kISD::SETCC, DL, N->getValueType(1),

1647 }

1648

1650}

1651

1652

1653

1656

1657

1658

1659 if (Src.getValueType() == MVT::i8 || Src.getValueType() == MVT::i16)

1661

1662

1663

1664 if (Src.getValueType() != BitNo.getValueType())

1666

1667 SDValue BTST = DAG.getNode(M68kISD::BTST, DL, MVT::i8, Src, BitNo);

1668

1669

1671 return DAG.getNode(M68kISD::SETCC, DL, MVT::i8,

1673}

1674

1675

1684

1690

1691

1693 unsigned AndBitWidth = And.getValueSizeInBits();

1694 if (BitWidth > AndBitWidth) {

1696 if (Known.countMinLeadingZeros() < BitWidth - AndBitWidth)

1698 }

1699 LHS = Op1;

1701 }

1703 uint64_t AndRHSVal = AndRHS->getZExtValue();

1705

1709 }

1710

1711

1713 LHS = AndLHS;

1715 }

1716 }

1717

1718 if (LHS.getNode())

1720

1722}

1723

1725 switch (SetCCOpcode) {

1726 default:

1748 }

1749}

1750

1751

1752

1753

1757 if (!IsFP) {

1759 if (SetCCOpcode == ISD::SETGT && RHSC->isAllOnes()) {

1760

1763 }

1764 if (SetCCOpcode == ISD::SETLT && RHSC->isZero()) {

1765

1767 }

1768 if (SetCCOpcode == ISD::SETLT && RHSC->getZExtValue() == 1) {

1769

1772 }

1773 }

1774

1776 }

1777

1778

1779

1780

1782 SetCCOpcode = getSetCCSwappedOperands(SetCCOpcode);

1784 }

1785

1786 switch (SetCCOpcode) {

1787 default:

1788 break;

1794 break;

1795 }

1796

1797

1798

1799

1800

1801

1802

1803 switch (SetCCOpcode) {

1804 default:

1831 }

1832}

1833

1834

1837

1839 "Expected TRUNCATE to i1 node");

1840

1841 if (Op.getOperand(0).getOpcode() != ISD::SRL)

1843

1844 SDValue ShiftRight = Op.getOperand(0);

1846 CC, DL, DAG);

1847}

1848

1849

1852 ++UI) {

1854 unsigned UOpNo = UI->getOperandNo();

1856

1859 }

1860

1861 if (User->getOpcode() != ISD::BRCOND && User->getOpcode() != ISD::SETCC &&

1863 return true;

1864 }

1865 return false;

1866}

1867

1868SDValue M68kTargetLowering::EmitTest(SDValue Op, unsigned M68kCC,

1870

1871

1872

1873 bool NeedCF = false;

1874 bool NeedOF = false;

1875 switch (M68kCC) {

1876 default:

1877 break;

1882 NeedCF = true;

1883 break;

1890

1891

1892

1893 switch (Op->getOpcode()) {

1898 if (Op.getNode()->getFlags().hasNoSignedWrap())

1899 break;

1900 [[fallthrough]];

1901 }

1902 default:

1903 NeedOF = true;

1904 break;

1905 }

1906 break;

1907 }

1908 }

1909

1910

1911

1912 if (Op.getResNo() != 0 || NeedOF || NeedCF) {

1913

1914 return DAG.getNode(M68kISD::CMP, DL, MVT::i8,

1916 }

1917 unsigned Opcode = 0;

1918 unsigned NumOperands = 0;

1919

1920

1921

1922

1923 bool NeedTruncation = false;

1926 SDValue Arith = Op->getOperand(0);

1927

1930 default:

1931 break;

1937 NeedTruncation = true;

1938 ArithOp = Arith;

1939 }

1940 }

1941 }

1942

1943

1944

1945

1948 Opcode = M68kISD::ADD;

1949 NumOperands = 2;

1950 break;

1953

1954

1955

1959 EVT VT = Op.getValueType();

1961 unsigned ShAmt = Op->getConstantOperandVal(1);

1962 if (ShAmt >= BitWidth)

1963 break;

1967 if (Mask.isSignedIntN(32))

1968 break;

1971 }

1972 break;

1973

1975

1976

1982 bool IsLegalAndnType = VT == MVT::i32 || VT == MVT::i64;

1983

1984

1985

1986 if ( !IsAndn || !IsLegalAndnType)

1987 break;

1988 }

1989 [[fallthrough]];

1993

1994

1995 for (const auto *U : Op.getNode()->users())

1996 if (U->getOpcode() == ISD::STORE)

1997 goto default_case;

1998

1999

2001 default:

2004 Opcode = M68kISD::SUB;

2005 break;

2007 Opcode = M68kISD::XOR;

2008 break;

2010 Opcode = M68kISD::AND;

2011 break;

2013 Opcode = M68kISD::OR;

2014 break;

2015 }

2016

2017 NumOperands = 2;

2018 break;

2019 case M68kISD::ADD:

2020 case M68kISD::SUB:

2021 case M68kISD::OR:

2022 case M68kISD::XOR:

2023 case M68kISD::AND:

2024 return SDValue(Op.getNode(), 1);

2025 default:

2026 default_case:

2027 break;

2028 }

2029

2030

2031

2032 if (NeedTruncation) {

2033 EVT VT = Op.getValueType();

2034 SDValue WideVal = Op->getOperand(0);

2036 unsigned ConvertedOp = 0;

2037

2038

2039

2041 default:

2042 break;

2044 ConvertedOp = M68kISD::ADD;

2045 break;

2047 ConvertedOp = M68kISD::SUB;

2048 break;

2050 ConvertedOp = M68kISD::AND;

2051 break;

2053 ConvertedOp = M68kISD::OR;

2054 break;

2056 ConvertedOp = M68kISD::XOR;

2057 break;

2058 }

2059

2060 if (ConvertedOp) {

2065 Op = DAG.getNode(ConvertedOp, DL, VT, V0, V1);

2066 }

2067 }

2068 }

2069

2070 if (Opcode == 0) {

2071

2072 return DAG.getNode(M68kISD::CMP, DL, MVT::i8,

2074 }

2075 SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i8);

2077

2081}

2082

2083

2085 switch (M68kCC) {

2086 default:

2094 return true;

2099 return false;

2100 }

2101}

2102

2106 return EmitTest(Op0, M68kCC, DL, DAG);

2107

2109 "Unexpected comparison operation for MVT::i1 operands");

2110

2113

2114

2118 unsigned ExtendOp =

2120 Op0 = DAG.getNode(ExtendOp, DL, MVT::i32, Op0);

2121 Op1 = DAG.getNode(ExtendOp, DL, MVT::i32, Op1);

2122 }

2123

2127 }

2128 return DAG.getNode(M68kISD::CMP, DL, MVT::i8, Op0, Op1);

2129}

2130

2131

2132

2138 if (Op.getOpcode() == ISD::TRUNCATE && Op.getValueType() == MVT::i1)

2141}

2142

2144 MVT VT = Op.getSimpleValueType();

2145 assert(VT == MVT::i8 && "SetCC type must be 8-bit integer");

2146

2149 SDLoc DL(Op);

2151

2152

2153

2154

2155

2156

2159 if (SDValue NewSetCC = LowerToBTST(Op0, CC, DL, DAG)) {

2160 if (VT == MVT::i1)

2162 return NewSetCC;

2163 }

2164 }

2165

2166

2167

2170

2171

2172

2173 if (Op0.getOpcode() == M68kISD::SETCC) {

2176 if (!Invert)

2177 return Op0;

2178

2181 DAG.getNode(M68kISD::SETCC, DL, MVT::i8,

2183 if (VT == MVT::i1)

2185 return SetCC;

2186 }

2187 }

2192 }

2196 }

2197 }

2198

2203

2204 SDValue CCR = EmitCmp(Op0, Op1, M68kCC, DL, DAG);

2205 return DAG.getNode(M68kISD::SETCC, DL, MVT::i8,

2207}

2208

2213 SDValue Carry = Op.getOperand(2);

2215 SDLoc DL(Op);

2216

2217 assert(LHS.getSimpleValueType().isInteger() && "SETCCCARRY is integer only.");

2219

2222 Carry = DAG.getNode(M68kISD::ADD, DL, DAG.getVTList(CarryVT, MVT::i32), Carry,

2224

2225 SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);

2228

2229 return DAG.getNode(M68kISD::SETCC, DL, MVT::i8,

2231}

2232

2233

2235 unsigned Opc = Op.getNode()->getOpcode();

2236 if (Opc == M68kISD::CMP)

2237 return true;

2238 if (Op.getResNo() == 1 &&

2239 (Opc == M68kISD::ADD || Opc == M68kISD::SUB || Opc == M68kISD::ADDX ||

2240 Opc == M68kISD::SUBX || Opc == M68kISD::SMUL || Opc == M68kISD::UMUL ||

2241 Opc == M68kISD::OR || Opc == M68kISD::XOR || Opc == M68kISD::AND))

2242 return true;

2243

2244 if (Op.getResNo() == 2 && Opc == M68kISD::UMUL)

2245 return true;

2246

2247 return false;

2248}

2249

2252 return false;

2253

2256 unsigned Bits = V.getValueSizeInBits();

2259}

2260

2262 bool addTest = true;

2266 SDLoc DL(Op);

2268

2270 if (SDValue NewCond = LowerSETCC(Cond, DAG))

2271 Cond = NewCond;

2272 }

2273

2274

2275

2276

2277

2278 if (Cond.getOpcode() == M68kISD::SETCC &&

2279 Cond.getOperand(1).getOpcode() == M68kISD::CMP &&

2282

2283 unsigned CondCode = Cond.getConstantOperandVal(0);

2284

2288

2290

2291

2292

2295

2297

2299 DAG.getNode(M68kISD::SUB, DL, VTs,

2301

2302 SDValue Res = DAG.getNode(M68kISD::SETCC_CARRY, DL, Op.getValueType(),

2305 return Res;

2306 }

2307

2308 Cmp = DAG.getNode(M68kISD::CMP, DL, MVT::i8,

2310

2311 SDValue Res =

2312 DAG.getNode(M68kISD::SETCC_CARRY, DL, Op.getValueType(),

2314

2317

2320 return Res;

2321 }

2322 }

2323

2324

2326 Cond.getOperand(0).getOpcode() == M68kISD::SETCC_CARRY &&

2329

2330

2331

2332 unsigned CondOpcode = Cond.getOpcode();

2333 if (CondOpcode == M68kISD::SETCC || CondOpcode == M68kISD::SETCC_CARRY) {

2335

2337 unsigned Opc = Cmp.getOpcode();

2338

2339 bool IllegalFPCMov = false;

2340

2341 if ((isM68kLogicalCmp(Cmp) && !IllegalFPCMov) || Opc == M68kISD::BTST) {

2343 addTest = false;

2344 }

2346

2348 unsigned CCode;

2351 addTest = false;

2352 }

2353

2354 if (addTest) {

2355

2358

2359

2360

2365 addTest = false;

2366 }

2367 }

2368 }

2369

2370 if (addTest) {

2373 }

2374

2375

2376

2377

2378

2379 if (Cond.getOpcode() == M68kISD::SUB) {

2381

2386 DAG.getNode(M68kISD::SETCC_CARRY, DL, Op.getValueType(),

2390 return Res;

2391 }

2392 }

2393

2394

2395

2396

2400 if (T1.getValueType() == T2.getValueType() &&

2401

2405 DAG.getNode(M68kISD::CMOV, DL, T1.getValueType(), T2, T1, CC, Cond);

2407 }

2408 }

2409

2410

2411

2412

2414 const APInt &C = Const->getAPIntValue();

2415 if (C.countr_zero() >= 5)

2416 return Op2;

2417 else if (C.countr_one() >= 5)

2418 return Op1;

2419 }

2420

2421

2422

2424 return DAG.getNode(M68kISD::CMOV, DL, Op.getValueType(), Ops);

2425}

2426

2427

2428

2430 Opc = Op.getOpcode();

2432 return false;

2434 Op.getOperand(0).hasOneUse() &&

2436 Op.getOperand(1).hasOneUse());

2437}

2438

2439

2440

2443 return false;

2445 return Op.getOperand(0).getOpcode() == M68kISD::SETCC &&

2446 Op.getOperand(0).hasOneUse();

2447 return false;

2448}

2449

2451 bool AddTest = true;

2452 SDValue Chain = Op.getOperand(0);

2454 SDValue Dest = Op.getOperand(2);

2455 SDLoc DL(Op);

2457 bool Inverted = false;

2458

2460

2463 Cond.getOperand(0).getResNo() == 1 &&

2468 Inverted = true;

2470 } else {

2471 if (SDValue NewCond = LowerSETCC(Cond, DAG))

2472 Cond = NewCond;

2473 }

2474 }

2475

2476

2478 Cond.getOperand(0).getOpcode() == M68kISD::SETCC_CARRY &&

2481

2482

2483

2484 unsigned CondOpcode = Cond.getOpcode();

2485 if (CondOpcode == M68kISD::SETCC || CondOpcode == M68kISD::SETCC_CARRY) {

2487

2489 unsigned Opc = Cmp.getOpcode();

2490

2493 AddTest = false;

2494 } else {

2496 default:

2497 break;

2500

2501

2502 Cond = Cond.getNode()->getOperand(1);

2503 AddTest = false;

2504 break;

2505 }

2506 }

2507 }

2508 CondOpcode = Cond.getOpcode();

2511 unsigned CCode;

2513

2514 if (Inverted)

2517

2518 AddTest = false;

2519 } else {

2520 unsigned CondOpc;

2523 if (CondOpc == ISD::OR) {

2524

2525

2526

2529 Chain = DAG.getNode(M68kISD::BRCOND, DL, Op.getValueType(), Chain,

2530 Dest, CC, Cmp);

2533 AddTest = false;

2534 }

2535 } else {

2536

2537

2538

2539

2540

2542 Op.getNode()->hasOneUse()) {

2547 SDNode *User = *Op.getNode()->user_begin();

2548

2549

2550

2551 if (User->getOpcode() == ISD::BR) {

2553 SDNode *NewBR =

2555 assert(NewBR == User);

2556 (void)NewBR;

2557 Dest = FalseBB;

2558

2559 Chain = DAG.getNode(M68kISD::BRCOND, DL, Op.getValueType(), Chain,

2560 Dest, CC, Cmp);

2566 AddTest = false;

2567 }

2568 }

2569 }

2571

2572

2573

2579 AddTest = false;

2580 }

2581 }

2582

2583 if (AddTest) {

2584

2587

2588

2589 if (Cond.hasOneUse()) {

2593 AddTest = false;

2594 }

2595 }

2596 }

2597

2598 if (AddTest) {

2601 Cond = EmitTest(Cond, MxCond, DL, DAG);

2602 }

2603 return DAG.getNode(M68kISD::BRCOND, DL, Op.getValueType(), Chain, Dest, CC,

2605}

2606

2607SDValue M68kTargetLowering::LowerADDC_ADDE_SUBC_SUBE(SDValue Op,

2609 MVT VT = Op.getNode()->getSimpleValueType(0);

2610

2611

2614

2615 SDVTList VTs = DAG.getVTList(VT, MVT::i8);

2616

2617 unsigned Opc;

2618 bool ExtraOp = false;

2619 switch (Op.getOpcode()) {

2620 default:

2623 Opc = M68kISD::ADD;

2624 break;

2626 Opc = M68kISD::ADDX;

2627 ExtraOp = true;

2628 break;

2630 Opc = M68kISD::SUB;

2631 break;

2633 Opc = M68kISD::SUBX;

2634 ExtraOp = true;

2635 break;

2636 }

2637

2638 if (!ExtraOp)

2639 return DAG.getNode(Opc, SDLoc(Op), VTs, Op.getOperand(0), Op.getOperand(1));

2640 return DAG.getNode(Opc, SDLoc(Op), VTs, Op.getOperand(0), Op.getOperand(1),

2641 Op.getOperand(2));

2642}

2643

2644

2645

2646

2647

2648

2649

2653

2654

2655

2656 unsigned char OpFlag = Subtarget.classifyLocalReference(nullptr);

2657

2658 unsigned WrapperKind = M68kISD::Wrapper;

2660 WrapperKind = M68kISD::WrapperPC;

2661 }

2662

2665 CP->getConstVal(), PtrVT, CP->getAlign(), CP->getOffset(), OpFlag);

2666

2667 SDLoc DL(CP);

2669

2670

2673 DAG.getNode(M68kISD::GLOBAL_BASE_REG, SDLoc(), PtrVT),

2674 Result);

2675 }

2676

2678}

2679

2683

2684

2685

2687 unsigned char OpFlag = Subtarget.classifyExternalReference(*Mod);

2688

2689 unsigned WrapperKind = M68kISD::Wrapper;

2691 WrapperKind = M68kISD::WrapperPC;

2692 }

2693

2696

2697 SDLoc DL(Op);

2699

2700

2703 DAG.getNode(M68kISD::GLOBAL_BASE_REG, SDLoc(), PtrVT),

2704 Result);

2705 }

2706

2707

2708

2712 }

2713

2715}

2716

2719 unsigned char OpFlags = Subtarget.classifyBlockAddressReference();

2722 SDLoc DL(Op);

2724

2725

2727

2729 Result = DAG.getNode(M68kISD::WrapperPC, DL, PtrVT, Result);

2730 } else {

2731 Result = DAG.getNode(M68kISD::Wrapper, DL, PtrVT, Result);

2732 }

2733

2734

2738 DAG.getNode(M68kISD::GLOBAL_BASE_REG, DL, PtrVT), Result);

2739 }

2740

2742}

2743

2744SDValue M68kTargetLowering::LowerGlobalAddress(const GlobalValue *GV,

2747 unsigned char OpFlags = Subtarget.classifyGlobalReference(GV);

2749

2750

2751

2756 } else {

2758 }

2759

2761 Result = DAG.getNode(M68kISD::WrapperPC, DL, PtrVT, Result);

2762 else

2763 Result = DAG.getNode(M68kISD::Wrapper, DL, PtrVT, Result);

2764

2765

2769 DAG.getNode(M68kISD::GLOBAL_BASE_REG, DL, PtrVT), Result);

2770 }

2771

2772

2773

2777 }

2778

2779

2780

2784 }

2785

2787}

2788

2793 return LowerGlobalAddress(GV, SDLoc(Op), Offset, DAG);

2794}

2795

2796

2797

2798

2799

2803

2804

2805

2806 unsigned char OpFlag = Subtarget.classifyLocalReference(nullptr);

2807

2808 unsigned WrapperKind = M68kISD::Wrapper;

2810 WrapperKind = M68kISD::WrapperPC;

2811 }

2812

2815 SDLoc DL(JT);

2817

2818

2821 DAG.getNode(M68kISD::GLOBAL_BASE_REG, SDLoc(), PtrVT),

2822 Result);

2823 }

2824

2826}

2827

2829 return Subtarget.getJumpTableEncoding();

2830}

2831

2834 unsigned uid, MCContext &Ctx) const {

2836}

2837

2841 return DAG.getNode(M68kISD::GLOBAL_BASE_REG, SDLoc(),

2843

2844

2845 return Table;

2846}

2847

2848

2853

2856 if (Constraint.size() > 0) {

2857 switch (Constraint[0]) {

2858 case 'a':

2859 case 'd':

2861 case 'I':

2862 case 'J':

2863 case 'K':

2864 case 'L':

2865 case 'M':

2866 case 'N':

2867 case 'O':

2868 case 'P':

2870 case 'C':

2871 if (Constraint.size() == 2)

2872 switch (Constraint[1]) {

2873 case '0':

2874 case 'i':

2875 case 'j':

2877 default:

2878 break;

2879 }

2880 break;

2881 case 'Q':

2882 case 'U':

2884 default:

2885 break;

2886 }

2887 }

2888

2890}

2891

2894 std::vector &Ops,

2897

2898 if (Constraint.size() == 1) {

2899

2900 switch (Constraint[0]) {

2901 case 'I':

2902 case 'J':

2903 case 'K':

2904 case 'L':

2905 case 'M':

2906 case 'N':

2907 case 'O':

2908 case 'P': {

2910 if (C)

2911 return;

2912

2913 int64_t Val = C->getSExtValue();

2914 switch (Constraint[0]) {

2915 case 'I':

2916 if (Val > 0 && Val <= 8)

2917 break;

2918 return;

2919 case 'J':

2921 break;

2922 return;

2923 case 'K':

2924 if (Val < -0x80 || Val >= 0x80)

2925 break;

2926 return;

2927 case 'L':

2928 if (Val < 0 && Val >= -8)

2929 break;

2930 return;

2931 case 'M':

2932 if (Val < -0x100 || Val >= 0x100)

2933 break;

2934 return;

2935 case 'N':

2936 if (Val >= 24 && Val <= 31)

2937 break;

2938 return;

2939 case 'O':

2940 if (Val == 16)

2941 break;

2942 return;

2943 case 'P':

2944 if (Val >= 8 && Val <= 15)

2945 break;

2946 return;

2947 default:

2949 }

2950

2952 break;

2953 }

2954 default:

2955 break;

2956 }

2957 }

2958

2959 if (Constraint.size() == 2) {

2960 switch (Constraint[0]) {

2961 case 'C':

2962

2963 switch (Constraint[1]) {

2964 case '0':

2965 case 'i':

2966 case 'j': {

2968 if (C)

2969 break;

2970

2971 int64_t Val = C->getSExtValue();

2972 switch (Constraint[1]) {

2973 case '0':

2974 if (!Val)

2975 break;

2976 return;

2977 case 'i':

2978 break;

2979 case 'j':

2981 break;

2982 return;

2983 default:

2985 }

2986

2988 break;

2989 }

2990 default:

2991 break;

2992 }

2993 break;

2994 default:

2995 break;

2996 }

2997 }

2998

2999 if (Result.getNode()) {

3000 Ops.push_back(Result);

3001 return;

3002 }

3003

3005}

3006

3007std::pair<unsigned, const TargetRegisterClass *>

3010 MVT VT) const {

3011 if (Constraint.size() == 1) {

3012 switch (Constraint[0]) {

3013 case 'r':

3014 case 'd':

3016 case MVT::i8:

3017 return std::make_pair(0U, &M68k::DR8RegClass);

3018 case MVT::i16:

3019 return std::make_pair(0U, &M68k::DR16RegClass);

3020 case MVT::i32:

3021 return std::make_pair(0U, &M68k::DR32RegClass);

3022 default:

3023 break;

3024 }

3025 break;

3026 case 'a':

3028 case MVT::i16:

3029 return std::make_pair(0U, &M68k::AR16RegClass);

3030 case MVT::i32:

3031 return std::make_pair(0U, &M68k::AR32RegClass);

3032 default:

3033 break;

3034 }

3035 break;

3036 default:

3037 break;

3038 }

3039 }

3040

3042}

3043

3044

3045

3049

3050

3051

3052

3054 switch (MI.getOpcode()) {

3055 case M68k::CMOV8d:

3056 case M68k::CMOV16d:

3057 case M68k::CMOV32r:

3058 return true;

3059

3060 default:

3061 return false;

3062 }

3063}

3064

3065

3066

3067

3068

3069

3073

3077 if (mi.readsRegister(M68k::CCR, nullptr))

3078 return false;

3080 break;

3081 }

3082

3083

3084

3085 if (miI == BB->end())

3086 for (const auto *SBB : BB->successors())

3087 if (SBB->isLiveIn(M68k::CCR))

3088 return false;

3089

3090

3091

3092 SelectItr->addRegisterKilled(M68k::CCR, TRI);

3093 return true;

3094}

3095

3097M68kTargetLowering::EmitLoweredSelect(MachineInstr &MI,

3099 const TargetInstrInfo *TII = Subtarget.getInstrInfo();

3101

3102

3103

3104

3105

3108

3109

3110

3111

3112

3113

3114

3115 MachineBasicBlock *ThisMBB = MBB;

3117

3118

3119

3120

3121

3122

3123

3124

3125

3126

3127

3128

3129

3130

3131

3132

3133

3134

3135

3136

3137

3138

3139

3140

3141

3142

3143

3144

3145

3146

3147

3148

3149

3150

3151

3152

3153

3154 MachineInstr *CascadedCMOV = nullptr;

3155 MachineInstr *LastCMOV = &MI;

3160

3161

3162

3163

3164

3166

3168 (NextMIIt->getOperand(3).getImm() == CC ||

3169 NextMIIt->getOperand(3).getImm() == OppCC)) {

3170 LastCMOV = &*NextMIIt;

3171 ++NextMIIt;

3172 }

3173 }

3174

3175

3176

3177 if (LastCMOV == &MI && NextMIIt != MBB->end() &&

3178 NextMIIt->getOpcode() == MI.getOpcode() &&

3179 NextMIIt->getOperand(2).getReg() == MI.getOperand(2).getReg() &&

3180 NextMIIt->getOperand(1).getReg() == MI.getOperand(0).getReg() &&

3181 NextMIIt->getOperand(1).isKill()) {

3182 CascadedCMOV = &*NextMIIt;

3183 }

3184

3185 MachineBasicBlock *Jcc1MBB = nullptr;

3186

3187

3188

3189 if (CascadedCMOV) {

3190 Jcc1MBB = F->CreateMachineBasicBlock(BB);

3193 }

3194

3195 MachineBasicBlock *Copy0MBB = F->CreateMachineBasicBlock(BB);

3196 MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(BB);

3197 F->insert(It, Copy0MBB);

3198 F->insert(It, SinkMBB);

3199

3200

3204

3205

3206

3207 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();

3208

3209 MachineInstr *LastCCRSUser = CascadedCMOV ? CascadedCMOV : LastCMOV;

3210 if (!LastCCRSUser->killsRegister(M68k::CCR, nullptr) &&

3214 }

3215

3216

3220

3221

3222 if (CascadedCMOV) {

3223

3225

3226

3227

3230 } else {

3232 }

3233

3234

3236

3237

3240

3241 if (CascadedCMOV) {

3245 }

3246

3247

3248

3249

3251

3252

3253

3254

3259 DenseMap<unsigned, std::pair<unsigned, unsigned>> RegRewriteTable;

3260 MachineInstrBuilder MIB;

3261

3262

3263

3264

3265

3266

3267

3268

3270 Register DestReg = MIIt->getOperand(0).getReg();

3271 Register Op1Reg = MIIt->getOperand(1).getReg();

3272 Register Op2Reg = MIIt->getOperand(2).getReg();

3273

3274

3275

3276

3277 if (MIIt->getOperand(3).getImm() == OppCC)

3279

3280 if (RegRewriteTable.find(Op1Reg) != RegRewriteTable.end())

3281 Op1Reg = RegRewriteTable[Op1Reg].first;

3282

3283 if (RegRewriteTable.find(Op2Reg) != RegRewriteTable.end())

3284 Op2Reg = RegRewriteTable[Op2Reg].second;

3285

3286 MIB =

3287 BuildMI(*SinkMBB, SinkInsertionPoint, DL, TII->get(M68k::PHI), DestReg)

3292

3293

3294 RegRewriteTable[DestReg] = std::make_pair(Op1Reg, Op2Reg);

3295 }

3296

3297

3298

3299 if (CascadedCMOV) {

3300 MIB.addReg(MI.getOperand(2).getReg()).addMBB(Jcc1MBB);

3301

3303 DL, TII->get(TargetOpcode::COPY),

3305 .addReg(MI.getOperand(0).getReg());

3307 }

3308

3309

3311 (MIIt++)->eraseFromParent();

3312

3313 return SinkMBB;

3314}

3315

3317M68kTargetLowering::EmitLoweredSegAlloca(MachineInstr &MI,

3319 llvm_unreachable("Cannot lower Segmented Stack Alloca with stack-split on");

3320}

3321

3325 switch (MI.getOpcode()) {

3326 default:

3328 case M68k::CMOV8d:

3329 case M68k::CMOV16d:

3330 case M68k::CMOV32r:

3331 return EmitLoweredSelect(MI, BB);

3332 case M68k::SALLOCA:

3333 return EmitLoweredSegAlloca(MI, BB);

3334 }

3335}

3336

3341

3344

3345

3346

3348 return DAG.getStore(Op.getOperand(0), DL, FR, Op.getOperand(1),

3350}

3351

3354

3357

3360 const SDValue AsmOperands[4] = {

3361 Op.getOperand(0),

3364 DAG.getDataLayout())),

3368 };

3369

3370 return DAG.getNode(ISD::INLINEASM, SDLoc(Op),

3371 DAG.getVTList(MVT::Other, MVT::Glue), AsmOperands);

3372}

3373

3374

3375

3376

3377

3378

3379SDValue M68kTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,

3383

3384 SDLoc DL(Op);

3385

3386

3387 SDNode *Node = Op.getNode();

3388 SDValue Chain = Op.getOperand(0);

3390 unsigned Align = Op.getConstantOperandVal(2);

3391 EVT VT = Node->getValueType(0);

3392

3393

3394

3396

3398 if (SplitStack) {

3402 Register Vreg = MRI.createVirtualRegister(ARClass);

3404 Result = DAG.getNode(M68kISD::SEG_ALLOCA, DL, SPTy, Chain,

3406 } else {

3409 assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and"

3410 " not tell us which reg is the stack pointer!");

3411

3413 Chain = SP.getValue(1);

3414 const TargetFrameLowering &TFI = *Subtarget.getFrameLowering();

3417 if (Align > StackAlign)

3421 }

3422

3424

3427}

3428

3431 SDLoc DL(Op);

3434 SDValue Shamt = Op.getOperand(2);

3435 EVT VT = Lo.getValueType();

3436

3437

3438

3439

3440

3441

3442

3443

3448 SDValue ShamtMinusRegisterSize =

3450 SDValue RegisterSizeMinus1Shamt =

3452

3456 DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, RegisterSizeMinus1Shamt);

3460

3463

3466

3468}

3469

3471 bool IsSRA) const {

3472 SDLoc DL(Op);

3475 SDValue Shamt = Op.getOperand(2);

3476 EVT VT = Lo.getValueType();

3477

3478

3479

3480

3481

3482

3483

3484

3485

3486

3487

3488

3489

3490

3491

3492

3493

3495

3500 SDValue ShamtMinusRegisterSize =

3502 SDValue RegisterSizeMinus1Shamt =

3504

3508 DAG.getNode(ISD::SHL, DL, VT, ShiftLeftHi1, RegisterSizeMinus1Shamt);

3512 DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusRegisterSize);

3515

3518

3521

3523}

3524

3525

3526

3527

3528

3531 return DAG.getNode(M68kISD::SETCC, dl, MVT::i8,

3533}

3534

3535

3536

3538 if (CCR.getOpcode() == M68kISD::ADD) {

3548 if (Carry.getOpcode() == M68kISD::SETCC ||

3549 Carry.getOpcode() == M68kISD::SETCC_CARRY) {

3552 }

3553 }

3554 }

3555

3557}

3558

3559

3560

3561

3567 return Flags;

3568

3570}

3571

3572

3577 SDValue CCR = N->getOperand(1);

3578

3579

3581 return getSETCC(CC, Flags, DL, DAG);

3582

3584}

3589 SDValue CCR = N->getOperand(3);

3590

3591

3592

3593

3596 return DAG.getNode(M68kISD::BRCOND, DL, N->getVTList(), N->getOperand(0),

3597 N->getOperand(1), Cond, Flags);

3598 }

3599

3601}

3602

3605 MVT VT = N->getSimpleValueType(0);

3607 return DAG.getNode(M68kISD::SUBX, SDLoc(N), VTs, N->getOperand(0),

3608 N->getOperand(1), Flags);

3609 }

3610

3612}

3613

3614

3618 MVT VT = N->getSimpleValueType(0);

3620 return DAG.getNode(M68kISD::ADDX, SDLoc(N), VTs, N->getOperand(0),

3621 N->getOperand(1), Flags);

3622 }

3623

3625}

3626

3627SDValue M68kTargetLowering::PerformDAGCombine(SDNode *N,

3628 DAGCombinerInfo &DCI) const {

3629 SelectionDAG &DAG = DCI.DAG;

3630 switch (N->getOpcode()) {

3631 case M68kISD::SUBX:

3633 case M68kISD::ADDX:

3635 case M68kISD::SETCC:

3637 case M68kISD::BRCOND:

3639 }

3640

3642}

3643

3645 bool IsVarArg) const {

3646 if (Return)

3647 return RetCC_M68k_C;

3648 else

3649 return CC_M68k_C;

3650}

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 , WZR, WZR, invert()'.

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!")

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

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)

Definition M68kISelLowering.cpp:1835

static void lowerOverflowArithmetic(SDValue Op, SelectionDAG &DAG, SDValue &Result, SDValue &CCR, unsigned &CC)

Definition M68kISelLowering.cpp:1551

static SDValue combineADDX(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI)

Definition M68kISelLowering.cpp:3615

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...

Definition M68kISelLowering.cpp:2429

static bool hasNonFlagsUse(SDValue Op)

return true if Op has a use that doesn't just read flags.

Definition M68kISelLowering.cpp:1850

static bool isM68kCCUnsigned(unsigned M68kCC)

Return true if the condition is an unsigned comparison operation.

Definition M68kISelLowering.cpp:2084

static StructReturnType callIsStructReturn(const SmallVectorImpl< ISD::OutputArg > &Outs)

Definition M68kISelLowering.cpp:238

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...

Definition M68kISelLowering.cpp:2441

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.

Definition M68kISelLowering.cpp:1676

static SDValue combineM68kBrCond(SDNode *N, SelectionDAG &DAG, const M68kSubtarget &Subtarget)

Definition M68kISelLowering.cpp:3585

static M68k::CondCode TranslateIntegerM68kCC(ISD::CondCode SetCCOpcode)

Definition M68kISelLowering.cpp:1724

static StructReturnType argsAreStructReturn(const SmallVectorImpl< ISD::InputArg > &Ins)

Determines whether a function uses struct return semantics.

Definition M68kISelLowering.cpp:252

static bool isCMOVPseudo(MachineInstr &MI)

Definition M68kISelLowering.cpp:3053

static bool shouldGuaranteeTCO(CallingConv::ID CC, bool GuaranteedTailCallOpt)

Return true if the function is being made into a tailcall target by changing its ABI.

Definition M68kISelLowering.cpp:294

static bool isM68kLogicalCmp(SDValue Op)

Return true if opcode is a M68k logical comparison.

Definition M68kISelLowering.cpp:2234

static SDValue combineM68kSetCC(SDNode *N, SelectionDAG &DAG, const M68kSubtarget &Subtarget)

Definition M68kISelLowering.cpp:3573

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,...

Definition M68kISelLowering.cpp:3562

static SDValue combineCarryThroughADD(SDValue CCR)

Definition M68kISelLowering.cpp:3537

static bool isOverflowArithmetic(unsigned Opcode)

Definition M68kISelLowering.cpp:1537

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...

Definition M68kISelLowering.cpp:300

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 ...

Definition M68kISelLowering.cpp:1654

StructReturnType

Definition M68kISelLowering.cpp:235

@ NotStructReturn

Definition M68kISelLowering.cpp:235

@ RegStructReturn

Definition M68kISelLowering.cpp:235

@ StackStructReturn

Definition M68kISelLowering.cpp:235

static bool isTruncWithZeroHighBitsInput(SDValue V, SelectionDAG &DAG)

Definition M68kISelLowering.cpp:2250

static bool checkAndUpdateCCRKill(MachineBasicBlock::iterator SelectItr, MachineBasicBlock *BB, const TargetRegisterInfo *TRI)

Definition M68kISelLowering.cpp:3070

static SDValue combineSUBX(SDNode *N, SelectionDAG &DAG)

Definition M68kISelLowering.cpp:3603

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,...

Definition M68kISelLowering.cpp:1754

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.

Machine Check Debug Module

Register const TargetRegisterInfo * TRI

Promote Memory to Register

static constexpr MCPhysReg SPReg

const SmallVectorImpl< MachineOperand > & Cond

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")

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.

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 hasMinSize() const

Optimize this function for minimum size (-Oz).

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.

Definition M68kISelLowering.cpp:2855

void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override

Lower the specified operand into the Ops vector.

Definition M68kISelLowering.cpp:2892

MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override

This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...

Definition M68kISelLowering.cpp:3323

virtual MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override

EVT is not used in-tree, but is used by out-of-tree target.

Definition M68kISelLowering.cpp:225

const MCExpr * LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, const MachineBasicBlock *MBB, unsigned uid, MCContext &Ctx) const override

Definition M68kISelLowering.cpp:2832

SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override

Returns relocation base for the given PIC jumptable.

Definition M68kISelLowering.cpp:2838

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,...

Definition M68kISelLowering.cpp:2849

AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const override

Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.

Definition M68kISelLowering.cpp:194

Register getExceptionPointerRegister(const Constant *PersonalityFn) const override

If a physical register, this returns the register that receives the exception address on entry to an ...

Definition M68kISelLowering.cpp:201

CCAssignFn * getCCAssignFn(CallingConv::ID CC, bool Return, bool IsVarArg) const

Definition M68kISelLowering.cpp:3644

M68kTargetLowering(const M68kTargetMachine &TM, const M68kSubtarget &STI)

Definition M68kISelLowering.cpp:48

InlineAsm::ConstraintCode getInlineAsmMemConstraint(StringRef ConstraintCode) const override

Definition M68kISelLowering.cpp:211

SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override

Provide custom lowering hooks for some operations.

Definition M68kISelLowering.cpp:1381

EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override

Return the value type to use for ISD::SETCC.

Definition M68kISelLowering.cpp:219

unsigned getJumpTableEncoding() const override

Return the entry encoding for a jump table in the current function.

Definition M68kISelLowering.cpp:2828

std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override

Given a physical register constraint (e.g.

Definition M68kISelLowering.cpp:3008

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...

Definition M68kISelLowering.cpp:206

Context object for machine code objects.

Base class for the full range of assembler expressions which are needed for parsing.

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

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, 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 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.

LLVM_ABI 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,...

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(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.

uint64_t getAsZExtVal() const

Helper method returns the zero-extended integer value of a ConstantSDNode.

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)

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.

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...

LLVM_ABI SDValue getRegister(Register Reg, EVT VT)

LLVM_ABI 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.

LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)

LLVM_ABI 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).

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 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 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.

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 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)

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)

unsigned getStackAlignment() const

getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...

unsigned getCallFrameSizeAt(MachineInstr &MI) const

void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)

Indicate that the specified operation does not work with the specified type and indicate what to do a...

virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const

Return the register class that should be used for the specified value type.

const TargetMachine & getTargetMachine() const

void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)

Set the maximum atomic operation size supported by the backend.

Register getStackPointerRegisterToSaveRestore() const

If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...

void setMinFunctionAlignment(Align Alignment)

Set the target's minimum function alignment.

void setBooleanContents(BooleanContent Ty)

Specify how the target extends the result of integer and floating point boolean values from i1 to a w...

void computeRegisterProperties(const TargetRegisterInfo *TRI)

Once all of the register classes are added, this allows us to compute derived properties we expose.

void addRegisterClass(MVT VT, const TargetRegisterClass *RC)

Add the specified register class as an available regclass for the specified value type.

bool isTypeLegal(EVT VT) const

Return true if the target has native support for the specified value type.

MVT getProgramPointerTy(const DataLayout &DL) const

Return the type for code pointers, which is determined by the program address space specified through...

virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const

Return the pointer type for the given address space, defaults to the pointer type from the data layou...

bool isOperationLegal(unsigned Op, EVT VT) const

Return true if the specified operation is legal on this target.

void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)

Indicate that the specified truncating store does not work with the specified type and indicate what ...

@ 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.

LLVM_ABI CondCode getSetCCInverse(CondCode Operation, bool isIntegerLike)

Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.

bool isNON_EXTLoad(const SDNode *N)

Returns true if the specified node is a non-extending load.

@ SETCC

SetCC operator - This evaluates to a true value iff the condition is true.

@ MERGE_VALUES

MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...

@ 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.

@ ADDC

Carry-setting nodes for multiple precision addition and subtraction.

@ ADD

Simple integer binary arithmetic operators.

@ ANY_EXTEND

ANY_EXTEND - Used for integer types. The high bits are undefined.

@ SDIVREM

SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.

@ SIGN_EXTEND

Conversion operators.

@ SETCCCARRY

Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but op #2 is a boolean indicating ...

@ SSUBO

Same for subtraction.

@ SELECT

Select(COND, TRUEVAL, FALSEVAL).

@ 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) ...

@ SMULO

Same for multiplication.

@ AND

Bitwise operators - logical and, logical or, logical xor.

@ ADDE

Carry-using nodes for multiple precision addition and subtraction.

@ TokenFactor

TokenFactor - This node takes multiple tokens as input and produces a single token result.

@ TRUNCATE

TRUNCATE - Completely drop the high bits.

@ 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...

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.

Definition M68kISelLowering.cpp:3046

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.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - 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 - 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.

@ Sub

Subtraction of integers.

DWARFExpression::Operation Op

constexpr unsigned BitWidth

decltype(auto) cast(const From &Val)

cast - 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.

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 isVector() const

Return true if this is a vector value type.

EVT getVectorElementType() const

Given a vector type, return the type of each element.

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)