LLVM: lib/Target/Mips/MipsISelLowering.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

69#include

70#include

71#include

72#include

73#include

74#include

75#include

76#include

77

78using namespace llvm;

79

80#define DEBUG_TYPE "mips-lower"

81

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

83

86 cl::desc("MIPS: Don't trap on integer division by zero."),

88

90

92 Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,

93 Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64

94};

95

96

97

100 EVT VT) const {

103

106 : MVT::i64;

108}

109

112 EVT VT) const {

118 }

120}

121

124 unsigned &NumIntermediates, MVT &RegisterVT) const {

127 RegisterVT = IntermediateVT.getSimpleVT();

129 return NumIntermediates;

130 }

134 return NumIntermediates * getNumRegisters(Context, IntermediateVT);

135}

136

142

145 unsigned Flag) const {

147}

148

151 unsigned Flag) const {

153}

154

157 unsigned Flag) const {

159}

160

163 unsigned Flag) const {

165}

166

169 unsigned Flag) const {

171 N->getOffset(), Flag);

172}

173

177

178

181

182

186

187

192 }

193

194

195

199 }

200

201

206 }

207

210

212

213

214

215

216

218

219

239

244

248

249

263 } else {

266 }

267

278 } else {

281 }

288 }

289

294 }

295

299

308

309

323

327 } else {

330 }

337

340

343

360

361

366

368

373

374

377

381 }

382

386 }

387

388

393

398

404 } else if (Subtarget.isGP64bit()) {

409 }

410

412

416

419 else

421

423

424

425

428

430

432

433 isMicroMips = Subtarget.inMicroMipsMode();

434}

435

444

445

451

452

456

457

458

459 if (!TM.isPositionIndependent() || !TM.getABI().IsO32() ||

461 UseFastISel = false;

462

464}

465

467 EVT VT) const {

469 return MVT::i32;

471}

472

478

479 EVT Ty = N->getValueType(0);

480 unsigned LO = (Ty == MVT::i32) ? Mips::LO0 : Mips::LO0_64;

481 unsigned HI = (Ty == MVT::i32) ? Mips::HI0 : Mips::HI0_64;

482 unsigned Opc = N->getOpcode() == ISD::SDIVREM ? MipsISD::DivRem16 :

483 MipsISD::DivRemU16;

485

487 N->getOperand(0), N->getOperand(1));

490

491

492 if (N->hasAnyUseOfValue(0)) {

494 InGlue);

496 InChain = CopyFromLo.getValue(1);

497 InGlue = CopyFromLo.getValue(2);

498 }

499

500

501 if (N->hasAnyUseOfValue(1)) {

503 HI, Ty, InGlue);

505 }

506

508}

509

511 switch (CC) {

533 }

534}

535

536

537

540 return false;

541

543 "Illegal Condition Code");

544

545 return true;

546}

547

548

549

551

554 return Op;

555

557

558 if (LHS.getValueType().isFloatingPoint())

559 return Op;

560

563

564

565

567

568 return DAG.getNode(MipsISD::FPCmp, DL, MVT::Glue, LHS, RHS,

570}

571

572

578

579 return DAG.getNode((invert ? MipsISD::CMovFP_F : MipsISD::CMovFP_T), DL,

581}

582

588

589 SDValue SetCC = N->getOperand(0);

590

594

595 SDValue False = N->getOperand(2);

597

600

602

603

604

605

606

607

608

609

610 if (!FalseC)

612

614

617 SDValue True = N->getOperand(1);

618

622

624 }

625

626

627

628 SDValue True = N->getOperand(1);

630

633

634

635

636

639

641

642

643

644

645 if (Diff == 1)

647

648

649

650

651

652 if (Diff == -1) {

658 }

659

660

662}

663

669

670 SDValue ValueIfTrue = N->getOperand(0), ValueIfFalse = N->getOperand(2);

671

675

676

677

678

679

680

681

682

683 unsigned Opc = (N->getOpcode() == MipsISD::CMovFP_T) ? MipsISD::CMovFP_F :

684 MipsISD::CMovFP_T;

685

686 SDValue FCC = N->getOperand(1), Glue = N->getOperand(3);

687 return DAG.getNode(Opc, SDLoc(N), ValueIfFalse.getValueType(),

688 ValueIfFalse, FCC, ValueIfTrue, Glue);

689}

690

696

697 SDValue FirstOperand = N->getOperand(0);

698 unsigned FirstOperandOpc = FirstOperand.getOpcode();

699 SDValue Mask = N->getOperand(1);

700 EVT ValTy = N->getValueType(0);

702

704 unsigned SMPos, SMSize;

707 unsigned Opc;

708

709

713

714 if (FirstOperandOpc == ISD::SRA || FirstOperandOpc == ISD::SRL) {

715

716

717

718

719

722

724

725

726

727 if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits())

729

730 Opc = MipsISD::Ext;

731 NewOperand = FirstOperand.getOperand(0);

732 } else if (FirstOperandOpc == ISD::SHL && Subtarget.hasCnMips()) {

733

734

735

736

737

738

739

742

744

745 if (SMPos != Pos || Pos >= ValTy.getSizeInBits() || SMSize >= 32 ||

746 Pos + SMSize > ValTy.getSizeInBits())

748

749 NewOperand = FirstOperand.getOperand(0);

750

751 SMSize--;

752 Opc = MipsISD::CIns;

753 } else {

754

755

756

757

758

761

762

763 if (SMPos)

765

766 Opc = MipsISD::Ext;

767 NewOperand = FirstOperand;

768 }

769 return DAG.getNode(Opc, DL, ValTy, NewOperand,

772}

773

779

780 SDValue FirstOperand = N->getOperand(0), SecondOperand = N->getOperand(1);

781 unsigned SMPos0, SMSize0, SMPos1, SMSize1;

783

785 SecondOperand.getOpcode() == ISD::SHL) ||

787 SecondOperand.getOpcode() == ISD::AND)) {

788

789

790

791

792

793

798 ? SecondOperand.getOperand(0)

806

808 ? SecondOperand.getOperand(1)

813

814 if (SMPos0 != 0 || SMSize0 != ShlShiftValue)

816

818 EVT ValTy = N->getValueType(0);

819 SMPos1 = ShlShiftValue;

820 assert(SMPos1 < ValTy.getSizeInBits());

821 SMSize1 = (ValTy == MVT::i64 ? 64 : 32) - SMPos1;

822 return DAG.getNode(MipsISD::Ins, DL, ValTy, ShlOperand0,

824 DAG.getConstant(SMSize1, DL, MVT::i32), AndOperand0);

825 }

826

827

830

831

832

833

834

838

839

840 if (SecondOperand.getOpcode() == ISD::AND &&

841 SecondOperand.getOperand(0).getOpcode() == ISD::SHL) {

842

846

847

848 if (SMPos0 != SMPos1 || SMSize0 != SMSize1)

850

852

855

857

858

859

860 EVT ValTy = N->getValueType(0);

861 if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits()))

863

869 } else {

870

871

872

873

874 if (~CN->getSExtValue() == ((((int64_t)1 << SMSize0) - 1) << SMPos0) &&

875 ((SMSize0 + SMPos0 <= 64 && Subtarget.hasMips64r2()) ||

876 (SMSize0 + SMPos0 <= 32))) {

877

878 bool isConstCase = SecondOperand.getOpcode() != ISD::AND;

879 if (SecondOperand.getOpcode() == ISD::AND) {

882 } else {

885 }

886

887

890

892 EVT ValTy = N->getOperand(0)->getValueType(0);

895 if (!isConstCase) {

898 SecondOperand, Const1);

899 }

901 MipsISD::Ins, DL, N->getValueType(0),

902 isConstCase

904 : SrlX,

906 DAG.getConstant(ValTy.getSizeInBits() / 8 < 8 ? SMSize0 & 31

907 : SMSize0,

908 DL, MVT::i32),

910 }

912 }

913}

914

917

918

922

923

924

925

926

930

931

934

935

936

937

938

939

940

941

942

943

944

945

946

947

948

949

950

951

952

953

956

960

964

965

966

969

970

971

972

973

974

977

982

983 if (!IsSigned && !IsUnsigned)

985

986

988 SDValue BottomHalf, TopHalf;

989 std::tie(BottomHalf, TopHalf) =

990 CurDAG.SplitScalar(AddOperand, DL, MVT::i32, MVT::i32);

992 CurDAG.getNode(MipsISD::MTLOHI, DL, MVT::Untyped, BottomHalf, TopHalf);

993

994

996 unsigned Opcode = IsAdd ? (IsUnsigned ? MipsISD::MAddu : MipsISD::MAdd)

997 : (IsUnsigned ? MipsISD::MSubu : MipsISD::MSub);

1001 SDValue MAdd = CurDAG.getNode(Opcode, DL, MVT::Untyped, MAddOps);

1002

1003 SDValue ResLo = CurDAG.getNode(MipsISD::MFLO, DL, MVT::i32, MAdd);

1004 SDValue ResHi = CurDAG.getNode(MipsISD::MFHI, DL, MVT::i32, MAdd);

1007 return Combined;

1008}

1009

1013

1016 !Subtarget.inMips16Mode() && N->getValueType(0) == MVT::i64)

1018

1020 }

1021

1023}

1024

1028

1031 !Subtarget.inMips16Mode() && N->getValueType(0) == MVT::i64)

1033

1035 }

1036

1037

1038

1039

1040

1041 SDValue InnerAdd = N->getOperand(1);

1042 SDValue Index = N->getOperand(0);

1047

1050 if (Lo.getOpcode() != MipsISD::Lo)

1052

1053 if ((Lo.getOpcode() != MipsISD::Lo) ||

1056

1057 EVT ValTy = N->getValueType(0);

1059

1062}

1063

1067

1068

1069

1070

1073

1074 SDValue FirstOperand = N->getOperand(0);

1075 unsigned FirstOperandOpc = FirstOperand.getOpcode();

1076 SDValue SecondOperand = N->getOperand(1);

1077 EVT ValTy = N->getValueType(0);

1079

1081 unsigned SMPos, SMSize;

1084

1085

1088

1090

1091 if (Pos >= ValTy.getSizeInBits())

1093

1094 if (FirstOperandOpc != ISD::AND)

1096

1097

1101

1102

1103

1104 if (SMPos != 0 || SMSize > 32 || Pos + SMSize > ValTy.getSizeInBits())

1106

1107 NewOperand = FirstOperand.getOperand(0);

1108

1109 SMSize--;

1110

1111 return DAG.getNode(MipsISD::CIns, DL, ValTy, NewOperand,

1114}

1115

1121 }

1122

1123 SDValue N0 = N->getOperand(0);

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

1125

1126

1127

1128

1134

1138

1139 int64_t ConstImm = ConstantOperand->getSExtValue();

1142 }

1143

1145}

1146

1148 const {

1150 unsigned Opc = N->getOpcode();

1151

1152 switch (Opc) {

1153 default: break;

1159 case MipsISD::CMovFP_F:

1160 case MipsISD::CMovFP_T:

1174 }

1175

1177}

1178

1182

1186

1188

1189

1190

1192 return C->getAPIntValue().ule(15);

1193

1194 return false;

1195}

1196

1198 const SDNode *N) const {

1200 N->getOperand(0).getOpcode() == ISD::SRL) ||

1202 N->getOperand(0).getOpcode() == ISD::SHL)) &&

1203 "Expected shift-shift mask");

1204

1205 if (N->getOperand(0).getValueType().isVector())

1206 return false;

1207 return true;

1208}

1209

1210void

1216

1219{

1220 switch (Op.getOpcode())

1221 {

1222 case ISD::BRCOND: return lowerBRCOND(Op, DAG);

1229 case ISD::SETCC: return lowerSETCC(Op, DAG);

1232 return lowerFSETCC(Op, DAG);

1233 case ISD::VASTART: return lowerVASTART(Op, DAG);

1234 case ISD::VAARG: return lowerVAARG(Op, DAG);

1236 case ISD::FABS: return lowerFABS(Op, DAG);

1238 return lowerFCANONICALIZE(Op, DAG);

1242 case ISD::ATOMIC_FENCE: return lowerATOMIC_FENCE(Op, DAG);

1244 case ISD::SRA_PARTS: return lowerShiftRightParts(Op, DAG, true);

1245 case ISD::SRL_PARTS: return lowerShiftRightParts(Op, DAG, false);

1246 case ISD::LOAD: return lowerLOAD(Op, DAG);

1247 case ISD::STORE: return lowerSTORE(Op, DAG);

1251 return lowerSTRICT_FP_TO_INT(Op, DAG);

1253 case ISD::READCYCLECOUNTER:

1254 return lowerREADCYCLECOUNTER(Op, DAG);

1255 }

1257}

1258

1259

1260

1261

1262

1263

1264

1265

1266static unsigned

1268{

1271 return VReg;

1272}

1273

1277 bool Is64Bit, bool IsMicroMips) {

1279 return &MBB;

1280

1281

1285 MIB = BuildMI(MBB, std::next(I), MI.getDebugLoc(),

1286 TII.get(IsMicroMips ? Mips::TEQ_MM : Mips::TEQ))

1290

1291

1292 if (Is64Bit)

1294

1295

1297

1298

1299

1300

1301 return &MBB;

1302}

1303

1307 switch (MI.getOpcode()) {

1308 default:

1310 case Mips::ATOMIC_LOAD_ADD_I8:

1311 return emitAtomicBinaryPartword(MI, BB, 1);

1312 case Mips::ATOMIC_LOAD_ADD_I16:

1313 return emitAtomicBinaryPartword(MI, BB, 2);

1314 case Mips::ATOMIC_LOAD_ADD_I32:

1315 return emitAtomicBinary(MI, BB);

1316 case Mips::ATOMIC_LOAD_ADD_I64:

1317 return emitAtomicBinary(MI, BB);

1318

1319 case Mips::ATOMIC_LOAD_AND_I8:

1320 return emitAtomicBinaryPartword(MI, BB, 1);

1321 case Mips::ATOMIC_LOAD_AND_I16:

1322 return emitAtomicBinaryPartword(MI, BB, 2);

1323 case Mips::ATOMIC_LOAD_AND_I32:

1324 return emitAtomicBinary(MI, BB);

1325 case Mips::ATOMIC_LOAD_AND_I64:

1326 return emitAtomicBinary(MI, BB);

1327

1328 case Mips::ATOMIC_LOAD_OR_I8:

1329 return emitAtomicBinaryPartword(MI, BB, 1);

1330 case Mips::ATOMIC_LOAD_OR_I16:

1331 return emitAtomicBinaryPartword(MI, BB, 2);

1332 case Mips::ATOMIC_LOAD_OR_I32:

1333 return emitAtomicBinary(MI, BB);

1334 case Mips::ATOMIC_LOAD_OR_I64:

1335 return emitAtomicBinary(MI, BB);

1336

1337 case Mips::ATOMIC_LOAD_XOR_I8:

1338 return emitAtomicBinaryPartword(MI, BB, 1);

1339 case Mips::ATOMIC_LOAD_XOR_I16:

1340 return emitAtomicBinaryPartword(MI, BB, 2);

1341 case Mips::ATOMIC_LOAD_XOR_I32:

1342 return emitAtomicBinary(MI, BB);

1343 case Mips::ATOMIC_LOAD_XOR_I64:

1344 return emitAtomicBinary(MI, BB);

1345

1346 case Mips::ATOMIC_LOAD_NAND_I8:

1347 return emitAtomicBinaryPartword(MI, BB, 1);

1348 case Mips::ATOMIC_LOAD_NAND_I16:

1349 return emitAtomicBinaryPartword(MI, BB, 2);

1350 case Mips::ATOMIC_LOAD_NAND_I32:

1351 return emitAtomicBinary(MI, BB);

1352 case Mips::ATOMIC_LOAD_NAND_I64:

1353 return emitAtomicBinary(MI, BB);

1354

1355 case Mips::ATOMIC_LOAD_SUB_I8:

1356 return emitAtomicBinaryPartword(MI, BB, 1);

1357 case Mips::ATOMIC_LOAD_SUB_I16:

1358 return emitAtomicBinaryPartword(MI, BB, 2);

1359 case Mips::ATOMIC_LOAD_SUB_I32:

1360 return emitAtomicBinary(MI, BB);

1361 case Mips::ATOMIC_LOAD_SUB_I64:

1362 return emitAtomicBinary(MI, BB);

1363

1364 case Mips::ATOMIC_SWAP_I8:

1365 return emitAtomicBinaryPartword(MI, BB, 1);

1366 case Mips::ATOMIC_SWAP_I16:

1367 return emitAtomicBinaryPartword(MI, BB, 2);

1368 case Mips::ATOMIC_SWAP_I32:

1369 return emitAtomicBinary(MI, BB);

1370 case Mips::ATOMIC_SWAP_I64:

1371 return emitAtomicBinary(MI, BB);

1372

1373 case Mips::ATOMIC_CMP_SWAP_I8:

1374 return emitAtomicCmpSwapPartword(MI, BB, 1);

1375 case Mips::ATOMIC_CMP_SWAP_I16:

1376 return emitAtomicCmpSwapPartword(MI, BB, 2);

1377 case Mips::ATOMIC_CMP_SWAP_I32:

1378 return emitAtomicCmpSwap(MI, BB);

1379 case Mips::ATOMIC_CMP_SWAP_I64:

1380 return emitAtomicCmpSwap(MI, BB);

1381

1382 case Mips::ATOMIC_LOAD_MIN_I8:

1383 return emitAtomicBinaryPartword(MI, BB, 1);

1384 case Mips::ATOMIC_LOAD_MIN_I16:

1385 return emitAtomicBinaryPartword(MI, BB, 2);

1386 case Mips::ATOMIC_LOAD_MIN_I32:

1387 return emitAtomicBinary(MI, BB);

1388 case Mips::ATOMIC_LOAD_MIN_I64:

1389 return emitAtomicBinary(MI, BB);

1390

1391 case Mips::ATOMIC_LOAD_MAX_I8:

1392 return emitAtomicBinaryPartword(MI, BB, 1);

1393 case Mips::ATOMIC_LOAD_MAX_I16:

1394 return emitAtomicBinaryPartword(MI, BB, 2);

1395 case Mips::ATOMIC_LOAD_MAX_I32:

1396 return emitAtomicBinary(MI, BB);

1397 case Mips::ATOMIC_LOAD_MAX_I64:

1398 return emitAtomicBinary(MI, BB);

1399

1400 case Mips::ATOMIC_LOAD_UMIN_I8:

1401 return emitAtomicBinaryPartword(MI, BB, 1);

1402 case Mips::ATOMIC_LOAD_UMIN_I16:

1403 return emitAtomicBinaryPartword(MI, BB, 2);

1404 case Mips::ATOMIC_LOAD_UMIN_I32:

1405 return emitAtomicBinary(MI, BB);

1406 case Mips::ATOMIC_LOAD_UMIN_I64:

1407 return emitAtomicBinary(MI, BB);

1408

1409 case Mips::ATOMIC_LOAD_UMAX_I8:

1410 return emitAtomicBinaryPartword(MI, BB, 1);

1411 case Mips::ATOMIC_LOAD_UMAX_I16:

1412 return emitAtomicBinaryPartword(MI, BB, 2);

1413 case Mips::ATOMIC_LOAD_UMAX_I32:

1414 return emitAtomicBinary(MI, BB);

1415 case Mips::ATOMIC_LOAD_UMAX_I64:

1416 return emitAtomicBinary(MI, BB);

1417

1418 case Mips::PseudoSDIV:

1419 case Mips::PseudoUDIV:

1420 case Mips::DIV:

1421 case Mips::DIVU:

1422 case Mips::MOD:

1423 case Mips::MODU:

1425 false);

1426 case Mips::SDIV_MM_Pseudo:

1427 case Mips::UDIV_MM_Pseudo:

1428 case Mips::SDIV_MM:

1429 case Mips::UDIV_MM:

1430 case Mips::DIV_MMR6:

1431 case Mips::DIVU_MMR6:

1432 case Mips::MOD_MMR6:

1433 case Mips::MODU_MMR6:

1435 case Mips::PseudoDSDIV:

1436 case Mips::PseudoDUDIV:

1437 case Mips::DDIV:

1438 case Mips::DDIVU:

1439 case Mips::DMOD:

1440 case Mips::DMODU:

1442

1443 case Mips::PseudoSELECT_I:

1444 case Mips::PseudoSELECT_I64:

1445 case Mips::PseudoSELECT_S:

1446 case Mips::PseudoSELECT_D32:

1447 case Mips::PseudoSELECT_D64:

1448 return emitPseudoSELECT(MI, BB, false, Mips::BNE);

1449 case Mips::PseudoSELECTFP_F_I:

1450 case Mips::PseudoSELECTFP_F_I64:

1451 case Mips::PseudoSELECTFP_F_S:

1452 case Mips::PseudoSELECTFP_F_D32:

1453 case Mips::PseudoSELECTFP_F_D64:

1454 return emitPseudoSELECT(MI, BB, true, Mips::BC1F);

1455 case Mips::PseudoSELECTFP_T_I:

1456 case Mips::PseudoSELECTFP_T_I64:

1457 case Mips::PseudoSELECTFP_T_S:

1458 case Mips::PseudoSELECTFP_T_D32:

1459 case Mips::PseudoSELECTFP_T_D64:

1460 return emitPseudoSELECT(MI, BB, true, Mips::BC1T);

1461 case Mips::PseudoD_SELECT_I:

1462 case Mips::PseudoD_SELECT_I64:

1463 return emitPseudoD_SELECT(MI, BB);

1464 case Mips::LDR_W:

1465 return emitLDR_W(MI, BB);

1466 case Mips::LDR_D:

1467 return emitLDR_D(MI, BB);

1468 case Mips::STR_W:

1469 return emitSTR_W(MI, BB);

1470 case Mips::STR_D:

1471 return emitSTR_D(MI, BB);

1472 }

1473}

1474

1475

1476

1478MipsTargetLowering::emitAtomicBinary(MachineInstr &MI,

1480

1485

1486 unsigned AtomicOp;

1487 bool NeedsAdditionalReg = false;

1488 switch (MI.getOpcode()) {

1489 case Mips::ATOMIC_LOAD_ADD_I32:

1490 AtomicOp = Mips::ATOMIC_LOAD_ADD_I32_POSTRA;

1491 break;

1492 case Mips::ATOMIC_LOAD_SUB_I32:

1493 AtomicOp = Mips::ATOMIC_LOAD_SUB_I32_POSTRA;

1494 break;

1495 case Mips::ATOMIC_LOAD_AND_I32:

1496 AtomicOp = Mips::ATOMIC_LOAD_AND_I32_POSTRA;

1497 break;

1498 case Mips::ATOMIC_LOAD_OR_I32:

1499 AtomicOp = Mips::ATOMIC_LOAD_OR_I32_POSTRA;

1500 break;

1501 case Mips::ATOMIC_LOAD_XOR_I32:

1502 AtomicOp = Mips::ATOMIC_LOAD_XOR_I32_POSTRA;

1503 break;

1504 case Mips::ATOMIC_LOAD_NAND_I32:

1505 AtomicOp = Mips::ATOMIC_LOAD_NAND_I32_POSTRA;

1506 break;

1507 case Mips::ATOMIC_SWAP_I32:

1508 AtomicOp = Mips::ATOMIC_SWAP_I32_POSTRA;

1509 break;

1510 case Mips::ATOMIC_LOAD_ADD_I64:

1511 AtomicOp = Mips::ATOMIC_LOAD_ADD_I64_POSTRA;

1512 break;

1513 case Mips::ATOMIC_LOAD_SUB_I64:

1514 AtomicOp = Mips::ATOMIC_LOAD_SUB_I64_POSTRA;

1515 break;

1516 case Mips::ATOMIC_LOAD_AND_I64:

1517 AtomicOp = Mips::ATOMIC_LOAD_AND_I64_POSTRA;

1518 break;

1519 case Mips::ATOMIC_LOAD_OR_I64:

1520 AtomicOp = Mips::ATOMIC_LOAD_OR_I64_POSTRA;

1521 break;

1522 case Mips::ATOMIC_LOAD_XOR_I64:

1523 AtomicOp = Mips::ATOMIC_LOAD_XOR_I64_POSTRA;

1524 break;

1525 case Mips::ATOMIC_LOAD_NAND_I64:

1526 AtomicOp = Mips::ATOMIC_LOAD_NAND_I64_POSTRA;

1527 break;

1528 case Mips::ATOMIC_SWAP_I64:

1529 AtomicOp = Mips::ATOMIC_SWAP_I64_POSTRA;

1530 break;

1531 case Mips::ATOMIC_LOAD_MIN_I32:

1532 AtomicOp = Mips::ATOMIC_LOAD_MIN_I32_POSTRA;

1533 NeedsAdditionalReg = true;

1534 break;

1535 case Mips::ATOMIC_LOAD_MAX_I32:

1536 AtomicOp = Mips::ATOMIC_LOAD_MAX_I32_POSTRA;

1537 NeedsAdditionalReg = true;

1538 break;

1539 case Mips::ATOMIC_LOAD_UMIN_I32:

1540 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I32_POSTRA;

1541 NeedsAdditionalReg = true;

1542 break;

1543 case Mips::ATOMIC_LOAD_UMAX_I32:

1544 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I32_POSTRA;

1545 NeedsAdditionalReg = true;

1546 break;

1547 case Mips::ATOMIC_LOAD_MIN_I64:

1548 AtomicOp = Mips::ATOMIC_LOAD_MIN_I64_POSTRA;

1549 NeedsAdditionalReg = true;

1550 break;

1551 case Mips::ATOMIC_LOAD_MAX_I64:

1552 AtomicOp = Mips::ATOMIC_LOAD_MAX_I64_POSTRA;

1553 NeedsAdditionalReg = true;

1554 break;

1555 case Mips::ATOMIC_LOAD_UMIN_I64:

1556 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I64_POSTRA;

1557 NeedsAdditionalReg = true;

1558 break;

1559 case Mips::ATOMIC_LOAD_UMAX_I64:

1560 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I64_POSTRA;

1561 NeedsAdditionalReg = true;

1562 break;

1563 default:

1565 }

1566

1567 Register OldVal = MI.getOperand(0).getReg();

1568 Register Ptr = MI.getOperand(1).getReg();

1569 Register Incr = MI.getOperand(2).getReg();

1571

1573

1574

1575

1576

1577

1578

1579

1580

1581

1582

1583

1584

1585

1586

1587

1588

1589

1590

1591

1592

1593

1594

1595

1596

1597

1598

1599

1600

1601

1602

1603

1604

1605

1606

1607

1608

1611

1614

1622 if (NeedsAdditionalReg) {

1624 RegInfo.createVirtualRegister(RegInfo.getRegClass(OldVal));

1627 }

1628

1629 MI.eraseFromParent();

1630

1631 return BB;

1632}

1633

1636 unsigned SrcReg) const {

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

1639

1642 return BB;

1643 }

1644

1647 return BB;

1648 }

1649

1650 MachineFunction *MF = BB->getParent();

1651 MachineRegisterInfo &RegInfo = MF->getRegInfo();

1652 const TargetRegisterClass *RC = getRegClassFor(MVT::i32);

1654

1656 int64_t ShiftImm = 32 - (Size * 8);

1657

1660

1661 return BB;

1662}

1663

1667 "Unsupported size for EmitAtomicBinaryPartial.");

1668

1669 MachineFunction *MF = BB->getParent();

1670 MachineRegisterInfo &RegInfo = MF->getRegInfo();

1671 const TargetRegisterClass *RC = getRegClassFor(MVT::i32);

1672 const bool ArePtrs64bit = ABI.ArePtrs64bit();

1673 const TargetRegisterClass *RCp =

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

1677

1678 Register Dest = MI.getOperand(0).getReg();

1679 Register Ptr = MI.getOperand(1).getReg();

1680 Register Incr = MI.getOperand(2).getReg();

1681

1693

1694 unsigned AtomicOp = 0;

1695 bool NeedsAdditionalReg = false;

1696 switch (MI.getOpcode()) {

1697 case Mips::ATOMIC_LOAD_NAND_I8:

1698 AtomicOp = Mips::ATOMIC_LOAD_NAND_I8_POSTRA;

1699 break;

1700 case Mips::ATOMIC_LOAD_NAND_I16:

1701 AtomicOp = Mips::ATOMIC_LOAD_NAND_I16_POSTRA;

1702 break;

1703 case Mips::ATOMIC_SWAP_I8:

1704 AtomicOp = Mips::ATOMIC_SWAP_I8_POSTRA;

1705 break;

1706 case Mips::ATOMIC_SWAP_I16:

1707 AtomicOp = Mips::ATOMIC_SWAP_I16_POSTRA;

1708 break;

1709 case Mips::ATOMIC_LOAD_ADD_I8:

1710 AtomicOp = Mips::ATOMIC_LOAD_ADD_I8_POSTRA;

1711 break;

1712 case Mips::ATOMIC_LOAD_ADD_I16:

1713 AtomicOp = Mips::ATOMIC_LOAD_ADD_I16_POSTRA;

1714 break;

1715 case Mips::ATOMIC_LOAD_SUB_I8:

1716 AtomicOp = Mips::ATOMIC_LOAD_SUB_I8_POSTRA;

1717 break;

1718 case Mips::ATOMIC_LOAD_SUB_I16:

1719 AtomicOp = Mips::ATOMIC_LOAD_SUB_I16_POSTRA;

1720 break;

1721 case Mips::ATOMIC_LOAD_AND_I8:

1722 AtomicOp = Mips::ATOMIC_LOAD_AND_I8_POSTRA;

1723 break;

1724 case Mips::ATOMIC_LOAD_AND_I16:

1725 AtomicOp = Mips::ATOMIC_LOAD_AND_I16_POSTRA;

1726 break;

1727 case Mips::ATOMIC_LOAD_OR_I8:

1728 AtomicOp = Mips::ATOMIC_LOAD_OR_I8_POSTRA;

1729 break;

1730 case Mips::ATOMIC_LOAD_OR_I16:

1731 AtomicOp = Mips::ATOMIC_LOAD_OR_I16_POSTRA;

1732 break;

1733 case Mips::ATOMIC_LOAD_XOR_I8:

1734 AtomicOp = Mips::ATOMIC_LOAD_XOR_I8_POSTRA;

1735 break;

1736 case Mips::ATOMIC_LOAD_XOR_I16:

1737 AtomicOp = Mips::ATOMIC_LOAD_XOR_I16_POSTRA;

1738 break;

1739 case Mips::ATOMIC_LOAD_MIN_I8:

1740 AtomicOp = Mips::ATOMIC_LOAD_MIN_I8_POSTRA;

1741 NeedsAdditionalReg = true;

1742 break;

1743 case Mips::ATOMIC_LOAD_MIN_I16:

1744 AtomicOp = Mips::ATOMIC_LOAD_MIN_I16_POSTRA;

1745 NeedsAdditionalReg = true;

1746 break;

1747 case Mips::ATOMIC_LOAD_MAX_I8:

1748 AtomicOp = Mips::ATOMIC_LOAD_MAX_I8_POSTRA;

1749 NeedsAdditionalReg = true;

1750 break;

1751 case Mips::ATOMIC_LOAD_MAX_I16:

1752 AtomicOp = Mips::ATOMIC_LOAD_MAX_I16_POSTRA;

1753 NeedsAdditionalReg = true;

1754 break;

1755 case Mips::ATOMIC_LOAD_UMIN_I8:

1756 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I8_POSTRA;

1757 NeedsAdditionalReg = true;

1758 break;

1759 case Mips::ATOMIC_LOAD_UMIN_I16:

1760 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I16_POSTRA;

1761 NeedsAdditionalReg = true;

1762 break;

1763 case Mips::ATOMIC_LOAD_UMAX_I8:

1764 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I8_POSTRA;

1765 NeedsAdditionalReg = true;

1766 break;

1767 case Mips::ATOMIC_LOAD_UMAX_I16:

1768 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I16_POSTRA;

1769 NeedsAdditionalReg = true;

1770 break;

1771 default:

1772 llvm_unreachable("Unknown subword atomic pseudo for expansion!");

1773 }

1774

1775

1779 MF->insert(It, exitMBB);

1780

1781

1785

1787

1788

1789

1790

1791

1792

1793

1794

1795

1796

1797

1798 int64_t MaskImm = (Size == 1) ? 255 : 65535;

1804 .addReg(Ptr, 0, ArePtrs64bit ? Mips::sub_32 : 0).addImm(3);

1807 } else {

1812 }

1819

1820

1821

1822

1823

1824

1825 MachineInstrBuilder MIB =

1828 .addReg(AlignedAddr)

1839 if (NeedsAdditionalReg) {

1843 }

1844

1845 MI.eraseFromParent();

1846

1847 return exitMBB;

1848}

1849

1850

1851

1852

1853

1854

1856MipsTargetLowering::emitAtomicCmpSwap(MachineInstr &MI,

1858

1859 assert((MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32 ||

1860 MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I64) &&

1861 "Unsupported atomic pseudo for EmitAtomicCmpSwap.");

1862

1863 const unsigned Size = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32 ? 4 : 8;

1864

1865 MachineFunction *MF = BB->getParent();

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

1870

1871 unsigned AtomicOp = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32

1872 ? Mips::ATOMIC_CMP_SWAP_I32_POSTRA

1873 : Mips::ATOMIC_CMP_SWAP_I64_POSTRA;

1874 Register Dest = MI.getOperand(0).getReg();

1875 Register Ptr = MI.getOperand(1).getReg();

1876 Register OldVal = MI.getOperand(2).getReg();

1877 Register NewVal = MI.getOperand(3).getReg();

1878

1879 Register Scratch = MRI.createVirtualRegister(RC);

1881

1882

1883

1884

1885

1886

1887 Register PtrCopy = MRI.createVirtualRegister(MRI.getRegClass(Ptr));

1888 Register OldValCopy = MRI.createVirtualRegister(MRI.getRegClass(OldVal));

1889 Register NewValCopy = MRI.createVirtualRegister(MRI.getRegClass(NewVal));

1890

1894

1895

1896

1897

1898

1906

1907 MI.eraseFromParent();

1908

1909 return BB;

1910}

1911

1912MachineBasicBlock *MipsTargetLowering::emitAtomicCmpSwapPartword(

1915 "Unsupported size for EmitAtomicCmpSwapPartial.");

1916

1917 MachineFunction *MF = BB->getParent();

1918 MachineRegisterInfo &RegInfo = MF->getRegInfo();

1919 const TargetRegisterClass *RC = getRegClassFor(MVT::i32);

1920 const bool ArePtrs64bit = ABI.ArePtrs64bit();

1921 const TargetRegisterClass *RCp =

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

1925

1926 Register Dest = MI.getOperand(0).getReg();

1927 Register Ptr = MI.getOperand(1).getReg();

1928 Register CmpVal = MI.getOperand(2).getReg();

1929 Register NewVal = MI.getOperand(3).getReg();

1930

1942 unsigned AtomicOp = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I8

1943 ? Mips::ATOMIC_CMP_SWAP_I8_POSTRA

1944 : Mips::ATOMIC_CMP_SWAP_I16_POSTRA;

1945

1946

1947

1948

1949

1950

1951

1952

1953

1954

1955

1958

1959

1963 MF->insert(It, exitMBB);

1964

1965

1969

1971

1972

1973

1974

1975

1976

1977

1978

1979

1980

1981

1982

1983

1984

1985 int64_t MaskImm = (Size == 1) ? 255 : 65535;

1986 BuildMI(BB, DL, TII->get(ArePtrs64bit ? Mips::DADDiu : Mips::ADDiu), MaskLSB2)

1988 BuildMI(BB, DL, TII->get(ArePtrs64bit ? Mips::AND64 : Mips::AND), AlignedAddr)

1991 .addReg(Ptr, 0, ArePtrs64bit ? Mips::sub_32 : 0).addImm(3);

1994 } else {

1999 }

2013

2014

2015

2016

2017

2020 .addReg(AlignedAddr)

2022 .addReg(ShiftedCmpVal)

2024 .addReg(ShiftedNewVal)

2030

2031 MI.eraseFromParent();

2032

2033 return exitMBB;

2034}

2035

2036SDValue MipsTargetLowering::lowerREADCYCLECOUNTER(SDValue Op,

2039 SDLoc DL(Op);

2041 unsigned RdhwrOpc, DestReg;

2043

2044 if (PtrVT == MVT::i64) {

2045 RdhwrOpc = Mips::RDHWR64;

2047 SDNode *Rdhwr = DAG.getMachineNode(RdhwrOpc, DL, MVT::i64, MVT::Glue,

2054 Results.push_back(ResNode);

2056 } else {

2057 RdhwrOpc = Mips::RDHWR;

2059 SDNode *Rdhwr = DAG.getMachineNode(RdhwrOpc, DL, MVT::i32, MVT::Glue,

2069 }

2070

2072}

2073

2075

2076

2077 SDValue Chain = Op.getOperand(0);

2078 SDValue Dest = Op.getOperand(2);

2079 SDLoc DL(Op);

2080

2083

2084

2085 if (CondRes.getOpcode() != MipsISD::FPCmp)

2086 return Op;

2087

2093 return DAG.getNode(MipsISD::FPBrcond, DL, Op.getValueType(), Chain, BrCode,

2094 FCC0, Dest, CondRes);

2095}

2096

2097SDValue MipsTargetLowering::

2099{

2102

2103

2104 if (Cond.getOpcode() != MipsISD::FPCmp)

2105 return Op;

2106

2108 SDLoc(Op));

2109}

2110

2114

2115 assert(Cond.getOpcode() == MipsISD::FPCmp &&

2116 "Floating point operand expected.");

2117

2118 SDLoc DL(Op);

2121

2123}

2124

2127

2128 SDLoc DL(Op);

2129 SDValue Chain = Op.getOperand(0);

2133

2139

2141}

2142

2145 EVT Ty = Op.getValueType();

2147 const GlobalValue *GV = N->getGlobal();

2148

2151 "Windows is the only supported COFF target");

2155 }

2156

2158 const MipsTargetObjectFile *TLOF =

2159 static_cast<const MipsTargetObjectFile *>(

2162 if (GO && TLOF->IsGlobalInSmallSection(GO, getTargetMachine()))

2163

2165

2166

2168

2170 }

2171

2172

2173

2174

2175

2176

2177

2178

2179

2180

2181

2182

2185

2191

2193 N, SDLoc(N), Ty, DAG,

2196}

2197

2201 EVT Ty = Op.getValueType();

2202

2206

2208}

2209

2210SDValue MipsTargetLowering::

2212{

2213

2214

2215

2216

2220

2221 SDLoc DL(GA);

2222 const GlobalValue *GV = GA->getGlobal();

2224

2226

2228

2231

2237

2239

2241 Args.emplace_back(Argument, PtrTy);

2242

2243 TargetLowering::CallLoweringInfo CLI(DAG);

2244 CLI.setDebugLoc(DL)

2246 .setLibCallee(CallingConv::C, PtrTy, TlsGetAddr, std::move(Args));

2247 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);

2248

2249 SDValue Ret = CallResult.first;

2250

2252 return Ret;

2253

2262 }

2263

2266

2270 TGA);

2273 } else {

2274

2283 }

2284

2285 SDValue ThreadPointer = DAG.getNode(MipsISD::ThreadPointer, DL, PtrVT);

2287}

2288

2289SDValue MipsTargetLowering::

2291{

2293 EVT Ty = Op.getValueType();

2294

2298

2300}

2301

2302SDValue MipsTargetLowering::

2304{

2306 EVT Ty = Op.getValueType();

2307

2309 const MipsTargetObjectFile *TLOF =

2310 static_cast<const MipsTargetObjectFile *>(

2312

2315

2317

2320 }

2321

2323}

2324

2327 MipsFunctionInfo *FuncInfo = MF.getInfo();

2328

2329 SDLoc DL(Op);

2332

2333

2334

2336 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),

2337 MachinePointerInfo(SV));

2338}

2339

2341 SDNode *Node = Op.getNode();

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

2344 SDValue VAListPtr = Node->getOperand(1);

2346 llvm::MaybeAlign(Node->getConstantOperandVal(3)).valueOrOne();

2348 SDLoc DL(Node);

2349 unsigned ArgSlotSizeInBytes = (ABI.IsN32() || ABI.IsN64()) ? 8 : 4;

2350

2352 VAListPtr, MachinePointerInfo(SV));

2353 SDValue VAList = VAListLoad;

2354

2355

2356

2357

2358

2359

2360

2361

2366

2370 }

2371

2372

2374 unsigned ArgSizeInBytes =

2380

2382 MachinePointerInfo(SV));

2383

2384

2385

2386

2387

2388

2389 if (Subtarget.isLittle() && ArgSizeInBytes < ArgSlotSizeInBytes) {

2390 unsigned Adjustment = ArgSlotSizeInBytes - ArgSizeInBytes;

2393 }

2394

2395 return DAG.getLoad(VT, DL, Chain, VAList, MachinePointerInfo());

2396}

2397

2399 bool HasExtractInsert) {

2400 EVT TyX = Op.getOperand(0).getValueType();

2401 EVT TyY = Op.getOperand(1).getValueType();

2406

2407

2408

2409 SDValue X = (TyX == MVT::f32) ?

2410 DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(0)) :

2411 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),

2412 Const1);

2413 SDValue Y = (TyY == MVT::f32) ?

2414 DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(1)) :

2415 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(1),

2416 Const1);

2417

2418 if (HasExtractInsert) {

2419

2420

2421 SDValue E = DAG.getNode(MipsISD::Ext, DL, MVT::i32, Y, Const31, Const1);

2422 Res = DAG.getNode(MipsISD::Ins, DL, MVT::i32, E, Const31, Const1, X);

2423 } else {

2424

2425

2426

2427

2428

2434 }

2435

2436 if (TyX == MVT::f32)

2437 return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), Res);

2438

2439 SDValue LowX = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,

2440 Op.getOperand(0),

2442 return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, LowX, Res);

2443}

2444

2446 bool HasExtractInsert) {

2447 unsigned WidthX = Op.getOperand(0).getValueSizeInBits();

2448 unsigned WidthY = Op.getOperand(1).getValueSizeInBits();

2452

2453

2456

2457 if (HasExtractInsert) {

2458

2459

2461 DAG.getConstant(WidthY - 1, DL, MVT::i32), Const1);

2462

2463 if (WidthX > WidthY)

2465 else if (WidthY > WidthX)

2467

2469 DAG.getConstant(WidthX - 1, DL, MVT::i32), Const1,

2470 X);

2471 return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), I);

2472 }

2473

2474

2475

2476

2477

2478

2483

2484 if (WidthX > WidthY)

2486 else if (WidthY > WidthX)

2488

2492 return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), Or);

2493}

2494

2499

2501}

2502

2504 bool HasExtractInsert) const {

2505 SDLoc DL(Op);

2507

2510

2511

2512

2513 SDValue X = (Op.getValueType() == MVT::f32)

2514 ? DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(0))

2515 : DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,

2516 Op.getOperand(0), Const1);

2517

2518

2519 if (HasExtractInsert)

2520 Res = DAG.getNode(MipsISD::Ins, DL, MVT::i32,

2523 else {

2524

2525

2528 }

2529

2530 if (Op.getValueType() == MVT::f32)

2531 return DAG.getNode(ISD::BITCAST, DL, MVT::f32, Res);

2532

2533

2534

2535

2536

2538 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),

2540 return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, LowX, Res);

2541}

2542

2544 bool HasExtractInsert) const {

2545 SDLoc DL(Op);

2547

2550

2551

2553

2554

2555 if (HasExtractInsert)

2556 Res = DAG.getNode(MipsISD::Ins, DL, MVT::i64,

2557 DAG.getRegister(Mips::ZERO_64, MVT::i64),

2559 else {

2562 }

2563

2564 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, Res);

2565}

2566

2568 if ((ABI.IsN32() || ABI.IsN64()) && (Op.getValueType() == MVT::f64))

2569 return lowerFABS64(Op, DAG, Subtarget.hasExtractInsert());

2570

2571 return lowerFABS32(Op, DAG, Subtarget.hasExtractInsert());

2572}

2573

2576 SDLoc DL(Op);

2577 EVT VT = Op.getValueType();

2578 SDValue Operand = Op.getOperand(0);

2579 SDNodeFlags Flags = Op->getFlags();

2580

2582 return Operand;

2583

2586}

2587

2588SDValue MipsTargetLowering::

2590

2591 if (Op.getConstantOperandVal(0) != 0) {

2593 "return address can be determined only for current frame");

2595 }

2596

2599 EVT VT = Op.getValueType();

2600 SDLoc DL(Op);

2602 DAG.getEntryNode(), DL, ABI.IsN64() ? Mips::FP_64 : Mips::FP, VT);

2603 return FrameAddr;

2604}

2605

2608

2609 if (Op.getConstantOperandVal(0) != 0) {

2611 "return address can be determined only for current frame");

2613 }

2614

2617 MVT VT = Op.getSimpleValueType();

2618 unsigned RA = ABI.IsN64() ? Mips::RA_64 : Mips::RA;

2620

2621

2624}

2625

2626

2627

2628

2629

2631 const {

2633 MipsFunctionInfo *MipsFI = MF.getInfo();

2634

2636 SDValue Chain = Op.getOperand(0);

2638 SDValue Handler = Op.getOperand(2);

2639 SDLoc DL(Op);

2640 EVT Ty = ABI.IsN64() ? MVT::i64 : MVT::i32;

2641

2642

2643

2644 unsigned OffsetReg = ABI.IsN64() ? Mips::V1_64 : Mips::V1;

2645 unsigned AddrReg = ABI.IsN64() ? Mips::V0_64 : Mips::V0;

2648 return DAG.getNode(MipsISD::EH_RETURN, DL, MVT::Other, Chain,

2652}

2653

2656

2657

2658 unsigned SType = 0;

2659 SDLoc DL(Op);

2660 return DAG.getNode(MipsISD::Sync, DL, MVT::Other, Op.getOperand(0),

2662}

2663

2666 SDLoc DL(Op);

2667 MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;

2668

2670 SDValue Shamt = Op.getOperand(2);

2671

2672

2673

2674

2675

2676

2691

2694}

2695

2697 bool IsSRA) const {

2698 SDLoc DL(Op);

2700 SDValue Shamt = Op.getOperand(2);

2701 MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;

2702

2703

2704

2705

2706

2707

2708

2709

2710

2711

2712

2713

2714

2715

2725 DL, VT, Hi, Shamt);

2730

2732 SDVTList VTList = DAG.getVTList(VT, VT);

2735 DL, VTList, Cond, ShiftRightHi,

2737 ShiftRightHi);

2738 }

2739

2742 IsSRA ? Ext : DAG.getConstant(0, DL, VT), ShiftRightHi);

2743

2746}

2747

2750 SDValue Ptr = LD->getBasePtr();

2751 EVT VT = LD->getValueType(0), MemVT = LD->getMemoryVT();

2755

2759

2760 SDValue Ops[] = { Chain, Ptr, Src };

2762 LD->getMemOperand());

2763}

2764

2765

2768 EVT MemVT = LD->getMemoryVT();

2769

2770 if (Subtarget.systemSupportsUnalignedAccess())

2771 return Op;

2772

2773

2774 if ((LD->getAlign().value() >= (MemVT.getSizeInBits() / 8)) ||

2775 ((MemVT != MVT::i32) && (MemVT != MVT::i64)))

2777

2778 bool IsLittle = Subtarget.isLittle();

2779 EVT VT = Op.getValueType();

2781 SDValue Chain = LD->getChain(), Undef = DAG.getUNDEF(VT);

2782

2783 assert((VT == MVT::i32) || (VT == MVT::i64));

2784

2785

2786

2787

2788

2789

2792 IsLittle ? 7 : 0);

2794 IsLittle ? 0 : 7);

2795 }

2796

2798 IsLittle ? 3 : 0);

2800 IsLittle ? 0 : 3);

2801

2802

2803

2804

2805

2806

2807

2808

2809 if ((VT == MVT::i32) || (ExtType == ISD::SEXTLOAD) ||

2811 return LWR;

2812

2814

2815

2816

2817

2818

2819

2820

2821

2828}

2829

2845

2846

2848 bool IsLittle) {

2850 EVT VT = Value.getValueType();

2851

2852

2853

2854

2855

2856

2857

2860 IsLittle ? 3 : 0);

2861 return createStoreLR(MipsISD::SWR, DAG, SD, SWL, IsLittle ? 0 : 3);

2862 }

2863

2864 assert(VT == MVT::i64);

2865

2866

2867

2868

2869

2870

2871 SDValue SDL = createStoreLR(MipsISD::SDL, DAG, SD, Chain, IsLittle ? 7 : 0);

2872 return createStoreLR(MipsISD::SDR, DAG, SD, SDL, IsLittle ? 0 : 7);

2873}

2874

2875

2877 bool SingleFloat) {

2879

2883

2890}

2891

2895

2896

2897 if (Subtarget.systemSupportsUnalignedAccess() &&

2899 ((MemVT == MVT::i32) || (MemVT == MVT::i64)))

2901

2903}

2904

2907

2908

2909

2911 EVT ValTy = Op->getValueType(0);

2914}

2915

2920

2923 Op.getOperand(0));

2924 return DAG.getNode(ISD::BITCAST, SDLoc(Op), Op.getValueType(), Trunc);

2925}

2926

2927SDValue MipsTargetLowering::lowerSTRICT_FP_TO_INT(SDValue Op,

2929 assert(Op->isStrictFPOpcode());

2930 SDValue SrcVal = Op.getOperand(1);

2931 SDLoc Loc(Op);

2932

2936 Loc, Op.getValueType(), SrcVal);

2937

2939}

2940

2941

2942

2943

2944

2945

2946

2947

2948

2949

2950

2951

2952

2953

2954

2955

2956

2957

2958

2959

2960

2961

2962

2963

2964

2970 State.getMachineFunction().getSubtarget());

2971

2972 static const MCPhysReg IntRegs[] = { Mips::A0, Mips::A1, Mips::A2, Mips::A3 };

2973

2974 static const MCPhysReg F32Regs[] = { Mips::F12, Mips::F14 };

2975

2976 static const MCPhysReg FloatVectorIntRegs[] = { Mips::A0, Mips::A2 };

2977

2978

2980 return true;

2981

2982

2984 if (LocVT == MVT::i8 || LocVT == MVT::i16 || LocVT == MVT::i32) {

2985 LocVT = MVT::i32;

2986 if (ArgFlags.isSExt())

2988 else if (ArgFlags.isZExt())

2990 else

2992 }

2993 }

2994

2995

2996 if (LocVT == MVT::i8 || LocVT == MVT::i16) {

2997 LocVT = MVT::i32;

2998 if (ArgFlags.isSExt())

3000 else if (ArgFlags.isZExt())

3002 else

3004 }

3005

3006 unsigned Reg;

3007

3008

3009

3010

3011 bool AllocateFloatsInIntReg = State.isVarArg() || ValNo > 1 ||

3012 State.getFirstUnallocated(F32Regs) != ValNo;

3014 bool isI64 = (ValVT == MVT::i32 && OrigAlign == Align(8));

3016

3017

3018 if (ValVT == MVT::i32 && isVectorFloat) {

3019

3020

3021

3022

3023 if (ArgFlags.isSplit()) {

3024 Reg = State.AllocateReg(FloatVectorIntRegs);

3025 if (Reg == Mips::A2)

3026 State.AllocateReg(Mips::A1);

3027 else if (Reg == 0)

3028 State.AllocateReg(Mips::A3);

3029 } else {

3030

3031

3033 }

3034 } else if (ValVT == MVT::i32 ||

3035 (ValVT == MVT::f32 && AllocateFloatsInIntReg)) {

3037

3038

3039 if (isI64 && (Reg == Mips::A1 || Reg == Mips::A3))

3041 LocVT = MVT::i32;

3042 } else if (ValVT == MVT::f64 && AllocateFloatsInIntReg) {

3043

3044

3046 if (Reg == Mips::A1 || Reg == Mips::A3)

3048

3049 if (Reg) {

3050 LocVT = MVT::i32;

3051

3052 State.addLoc(

3056 State.addLoc(

3058 return false;

3059 }

3060 } else if (ValVT.isFloatingPoint() && !AllocateFloatsInIntReg) {

3061

3062 if (ValVT == MVT::f32) {

3064

3065 State.AllocateReg(IntRegs);

3066 } else {

3067 Reg = State.AllocateReg(F64Regs);

3068

3070 if (Reg2 == Mips::A1 || Reg2 == Mips::A3)

3071 State.AllocateReg(IntRegs);

3072 State.AllocateReg(IntRegs);

3073 }

3074 } else

3076

3077 if (Reg) {

3078 unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);

3080 } else

3082

3083 return false;

3084}

3085

3090 static const MCPhysReg F64Regs[] = { Mips::D6, Mips::D7 };

3091

3092 return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State,

3093 F64Regs);

3094}

3095

3100 static const MCPhysReg F64Regs[] = { Mips::D12_64, Mips::D14_64 };

3101

3102 return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State,

3103 F64Regs);

3104}

3105

3106[[maybe_unused]] static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT,

3110

3111#include "MipsGenCallingConv.inc"

3112

3114 return CC_Mips_FixedArg;

3115 }

3116

3118 return RetCC_Mips;

3119 }

3120

3121

3122

3123

3124SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset,

3126 const SDLoc &DL, bool IsTailCall,

3128 if (!IsTailCall) {

3133 }

3134

3140}

3141

3144 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,

3145 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,

3148

3149

3150

3151

3152

3153

3154

3155

3156

3157

3158 if (IsPICCall && !InternalLinkage && IsCallReloc) {

3159 unsigned GPReg = ABI.IsN64() ? Mips::GP_64 : Mips::GP;

3160 EVT Ty = ABI.IsN64() ? MVT::i64 : MVT::i32;

3161 RegsToPass.push_back(std::make_pair(GPReg, getGlobalReg(CLI.DAG, Ty)));

3162 }

3163

3164

3165

3166

3167

3169

3170 for (auto &R : RegsToPass) {

3171 Chain = CLI.DAG.getCopyToReg(Chain, CLI.DL, R.first, R.second, InGlue);

3173 }

3174

3175

3176

3177 for (auto &R : RegsToPass)

3178 Ops.push_back(CLI.DAG.getRegister(R.first, R.second.getValueType()));

3179

3180

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

3185 if (Subtarget.inMips16HardFloat()) {

3187 StringRef Sym = G->getGlobal()->getName();

3188 Function *F = G->getGlobal()->getParent()->getFunction(Sym);

3189 if (F && F->hasFnAttribute("__Mips16RetHelper")) {

3191 }

3192 }

3193 }

3195

3197 Ops.push_back(InGlue);

3198}

3199

3202 switch (MI.getOpcode()) {

3203 default:

3204 return;

3205 case Mips::JALR:

3206 case Mips::JALRPseudo:

3207 case Mips::JALR64:

3208 case Mips::JALR64Pseudo:

3209 case Mips::JALR16_MM:

3210 case Mips::JALRC16_MMR6:

3211 case Mips::TAILCALLREG:

3212 case Mips::TAILCALLREG64:

3213 case Mips::TAILCALLR6REG:

3214 case Mips::TAILCALL64R6REG:

3215 case Mips::TAILCALLREG_MM:

3216 case Mips::TAILCALLREG_MMR6: {

3220 Node->getNumOperands() < 1 ||

3221 Node->getOperand(0).getNumOperands() < 2) {

3222 return;

3223 }

3224

3225

3226

3227 const SDValue TargetAddr = Node->getOperand(0).getOperand(1);

3231

3232

3233

3235 LLVM_DEBUG(dbgs() << "Not adding R_MIPS_JALR against data symbol "

3236 << G->getGlobal()->getName() << "\n");

3237 return;

3238 }

3239 Sym = G->getGlobal()->getName();

3240 }

3243 Sym = ES->getSymbol();

3244 }

3245

3246 if (Sym.empty())

3247 return;

3248

3251 LLVM_DEBUG(dbgs() << "Adding R_MIPS_JALR against " << Sym << "\n");

3253 }

3254 }

3255}

3256

3257

3258

3271 bool IsVarArg = CLI.IsVarArg;

3273

3279

3280

3285

3288

3289

3290

3291

3292

3293

3294

3295

3296

3297

3298

3299

3300

3301

3302

3303

3304

3305

3306

3307

3308

3309

3310

3311

3312

3313 bool MemcpyInByVal = ES && StringRef(ES->getSymbol()) == "memcpy" &&

3315 Chain.getOpcode() == ISD::CALLSEQ_START;

3316

3317

3318

3319 unsigned ReservedArgArea =

3320 MemcpyInByVal ? 0 : ABI.GetCalleeAllocdArgSizeInBytes(CallConv);

3321 CCInfo.AllocateStack(ReservedArgArea, Align(1));

3322

3323 CCInfo.AnalyzeCallOperands(Outs, CC_Mips);

3324

3325

3326 unsigned StackSize = CCInfo.getStackSize();

3327

3328

3330

3333

3334

3335

3336 bool InternalLinkage = false;

3337 if (IsTailCall) {

3338 IsTailCall = isEligibleForTailCallOptimization(

3341 InternalLinkage = G->getGlobal()->hasInternalLinkage();

3342 IsTailCall &= (InternalLinkage || G->getGlobal()->hasLocalLinkage() ||

3343 G->getGlobal()->hasPrivateLinkage() ||

3344 G->getGlobal()->hasHiddenVisibility() ||

3345 G->getGlobal()->hasProtectedVisibility());

3346 }

3347 }

3349 report_fatal_error("failed to perform tail call elimination on a call "

3350 "site marked musttail");

3351

3352 if (IsTailCall)

3353 ++NumTailCalls;

3354

3355

3356

3357

3359 StackSize = alignTo(StackSize, StackAlignment);

3360

3361 if (!(IsTailCall || MemcpyInByVal))

3363

3367 std::deque<std::pair<unsigned, SDValue>> RegsToPass;

3369

3370 CCInfo.rewindByValRegsInfo();

3371

3372

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

3374 SDValue Arg = OutVals[OutIdx];

3375 CCValAssign &VA = ArgLocs[i];

3377 ISD::ArgFlagsTy Flags = Outs[OutIdx].Flags;

3378 bool UseUpperBits = false;

3379

3380

3381 if (Flags.isByVal()) {

3382 unsigned FirstByValReg, LastByValReg;

3383 unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();

3384 CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg);

3385

3387 "ByVal args of size 0 should have been ignored by front-end.");

3388 assert(ByValIdx < CCInfo.getInRegsParamsCount());

3389 assert(!IsTailCall &&

3390 "Do not tail-call optimize if there is a byval argument.");

3391 passByValArg(Chain, DL, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg,

3392 FirstByValReg, LastByValReg, Flags, Subtarget.isLittle(),

3393 VA);

3394 CCInfo.nextInRegsParam();

3395 continue;

3396 }

3397

3398

3400 default:

3404 if ((ValVT == MVT::f32 && LocVT == MVT::i32) ||

3405 (ValVT == MVT::f64 && LocVT == MVT::i64) ||

3406 (ValVT == MVT::i64 && LocVT == MVT::f64))

3407 Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg);

3408 else if (ValVT == MVT::f64 && LocVT == MVT::i32) {

3415

3417

3419 Register LocRegHigh = ArgLocs[++i].getLocReg();

3420 RegsToPass.push_back(std::make_pair(LocRegLo, Lo));

3421 RegsToPass.push_back(std::make_pair(LocRegHigh, Hi));

3422 continue;

3423 }

3424 }

3425 break;

3427 Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg);

3428 break;

3430 UseUpperBits = true;

3431 [[fallthrough]];

3434 break;

3436 UseUpperBits = true;

3437 [[fallthrough]];

3440 break;

3442 UseUpperBits = true;

3443 [[fallthrough]];

3446 break;

3447 }

3448

3449 if (UseUpperBits) {

3450 unsigned ValSizeInBits = Outs[OutIdx].ArgVT.getSizeInBits();

3455 }

3456

3457

3458

3460 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));

3461

3462

3463

3465 continue;

3466

3467

3469 if (Options.EmitCallSiteInfo)

3471

3472 continue;

3473 }

3474

3475

3477

3478

3479

3481 Chain, Arg, DL, IsTailCall, DAG));

3482 }

3483

3484

3485

3486 if (!MemOpChains.empty())

3488

3489

3490

3491

3492

3493 EVT Ty = Callee.getValueType();

3494 bool GlobalOrExternal = false, IsCallReloc = false;

3495

3496

3497

3498

3499 if (Subtarget.isABICalls() && !IsPIC) {

3500

3501

3502

3509 bool UseLongCalls = Subtarget.useLongCalls();

3510

3511

3513 if (F->hasFnAttribute("long-call"))

3514 UseLongCalls = true;

3515 else if (F->hasFnAttribute("short-call"))

3516 UseLongCalls = false;

3517 }

3518 if (UseLongCalls)

3522 }

3523 }

3524

3527 G->getGlobal()->hasDLLImportStorageClass()) {

3529 "Windows is the only supported COFF target");

3530 auto PtrInfo = MachinePointerInfo();

3533 } else if (IsPIC) {

3534 const GlobalValue *Val = G->getGlobal();

3536

3537 if (InternalLinkage)

3543 IsCallReloc = true;

3544 } else {

3547 IsCallReloc = true;

3548 }

3549 } else

3553 GlobalOrExternal = true;

3554 }

3556 const char *Sym = S->getSymbol();

3557

3558 if (!IsPIC)

3565 IsCallReloc = true;

3566 } else {

3569 IsCallReloc = true;

3570 }

3571

3572 GlobalOrExternal = true;

3573 }

3574

3576 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);

3577

3578 getOpndList(Ops, RegsToPass, IsPIC, GlobalOrExternal, InternalLinkage,

3579 IsCallReloc, CLI, Callee, Chain);

3580

3581 if (IsTailCall) {

3585 return Ret;

3586 }

3587

3588 Chain = DAG.getNode(MipsISD::JmpLink, DL, NodeTys, Ops);

3590

3592

3593

3594

3595 if (!(MemcpyInByVal)) {

3596 Chain = DAG.getCALLSEQ_END(Chain, StackSize, 0, InGlue, DL);

3598 }

3599

3600

3601

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

3603 InVals, CLI);

3604}

3605

3606

3607

3608SDValue MipsTargetLowering::LowerCallResult(

3613

3615 MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,

3617

3618 CCInfo.AnalyzeCallResult(Ins, RetCC_Mips);

3619

3620

3621 for (unsigned i = 0; i != RVLocs.size(); ++i) {

3622 CCValAssign &VA = RVLocs[i];

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

3624

3626 RVLocs[i].getLocVT(), InGlue);

3629

3631 unsigned ValSizeInBits = Ins[i].ArgVT.getSizeInBits();

3633 unsigned Shift =

3638 }

3639

3641 default:

3644 break;

3647 break;

3651 break;

3657 break;

3663 break;

3664 }

3665

3667 }

3668

3669 return Chain;

3670}

3671

3677

3678

3680 default:

3681 break;

3687 unsigned Opcode =

3692 break;

3693 }

3694 }

3695

3696

3697

3698

3699

3701 default:

3704 break;

3708 break;

3713 break;

3718 break;

3720 Val = DAG.getNode(ISD::BITCAST, DL, ValVT, Val);

3721 break;

3722 }

3723

3724 return Val;

3725}

3726

3727

3728

3729

3730

3731

3732SDValue MipsTargetLowering::LowerFormalArguments(

3738 MipsFunctionInfo *MipsFI = MF.getInfo();

3739

3741

3742

3743 std::vector OutChains;

3744

3745

3747 MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,

3749 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv), Align(1));

3752

3753 if (Func.hasFnAttribute("interrupt") && Func.arg_empty())

3755 "Functions with the interrupt attribute cannot have arguments!");

3756

3757 CCInfo.AnalyzeFormalArguments(Ins, CC_Mips_FixedArg);

3759 CCInfo.getInRegsParamsCount() > 0);

3760

3761 unsigned CurArgIdx = 0;

3762 CCInfo.rewindByValRegsInfo();

3763

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

3765 CCValAssign &VA = ArgLocs[i];

3766 if (Ins[InsIdx].isOrigArg()) {

3767 std::advance(FuncArg, Ins[InsIdx].getOrigArgIndex() - CurArgIdx);

3768 CurArgIdx = Ins[InsIdx].getOrigArgIndex();

3769 }

3771 ISD::ArgFlagsTy Flags = Ins[InsIdx].Flags;

3772 bool IsRegLoc = VA.isRegLoc();

3773

3774 if (Flags.isByVal()) {

3775 assert(Ins[InsIdx].isOrigArg() && "Byval arguments cannot be implicit");

3776 unsigned FirstByValReg, LastByValReg;

3777 unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();

3778 CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg);

3779

3781 "ByVal args of size 0 should have been ignored by front-end.");

3782 assert(ByValIdx < CCInfo.getInRegsParamsCount());

3783 copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, &*FuncArg,

3784 FirstByValReg, LastByValReg, VA, CCInfo);

3785 CCInfo.nextInRegsParam();

3786 continue;

3787 }

3788

3789

3790 if (IsRegLoc) {

3793 const TargetRegisterClass *RC = getRegClassFor(RegVT);

3794

3795

3796

3799

3800 ArgValue =

3802

3803

3804

3805 if ((RegVT == MVT::i32 && ValVT == MVT::f32) ||

3806 (RegVT == MVT::i64 && ValVT == MVT::f64) ||

3807 (RegVT == MVT::f64 && ValVT == MVT::i64))

3808 ArgValue = DAG.getNode(ISD::BITCAST, DL, ValVT, ArgValue);

3809 else if (ABI.IsO32() && RegVT == MVT::i32 &&

3810 ValVT == MVT::f64) {

3811 assert(VA.needsCustom() && "Expected custom argument for f64 split");

3812 CCValAssign &NextVA = ArgLocs[++i];

3813 unsigned Reg2 =

3818 ArgValue = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64,

3819 ArgValue, ArgValue2);

3820 }

3821

3823 } else {

3825

3826 assert(!VA.needsCustom() && "unexpected custom memory argument");

3827

3828

3830

3831

3834

3835

3838 LocVT, DL, Chain, FIN,

3840 OutChains.push_back(ArgValue.getValue(1));

3841

3842 ArgValue =

3844

3846 }

3847 }

3848

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

3850

3851 if (ArgLocs[i].needsCustom()) {

3852 ++i;

3853 continue;

3854 }

3855

3856

3857

3858

3859 if (Ins[InsIdx].Flags.isSRet()) {

3861 if (Reg) {

3865 }

3868 break;

3869 }

3870 }

3871

3872 if (IsVarArg)

3873 writeVarArgRegs(OutChains, Chain, DL, DAG, CCInfo);

3874

3875

3876

3877 if (!OutChains.empty()) {

3878 OutChains.push_back(Chain);

3880 }

3881

3882 return Chain;

3883}

3884

3885

3886

3887

3888

3889bool

3890MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,

3895 MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);

3896 return CCInfo.CheckReturn(Outs, RetCC_Mips);

3897}

3898

3899bool MipsTargetLowering::shouldSignExtendTypeInLibCall(Type *Ty,

3900 bool IsSigned) const {

3902 return true;

3903

3904 return IsSigned;

3905}

3906

3912 MipsFunctionInfo *MipsFI = MF.getInfo();

3913

3915

3916 return DAG.getNode(MipsISD::ERet, DL, MVT::Other, RetOps);

3917}

3918

3921 bool IsVarArg,

3925

3926

3929

3930

3931 MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());

3932

3933

3934 CCInfo.AnalyzeReturn(Outs, RetCC_Mips);

3935

3938

3939

3940 for (unsigned i = 0; i != RVLocs.size(); ++i) {

3941 SDValue Val = OutVals[i];

3942 CCValAssign &VA = RVLocs[i];

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

3944 bool UseUpperBits = false;

3945

3947 default:

3950 break;

3953 break;

3955 UseUpperBits = true;

3956 [[fallthrough]];

3959 break;

3961 UseUpperBits = true;

3962 [[fallthrough]];

3965 break;

3967 UseUpperBits = true;

3968 [[fallthrough]];

3971 break;

3972 }

3973

3974 if (UseUpperBits) {

3975 unsigned ValSizeInBits = Outs[i].ArgVT.getSizeInBits();

3980 }

3981

3983

3984

3987 }

3988

3989

3990

3991

3992

3994 MipsFunctionInfo *MipsFI = MF.getInfo();

3996

3997 if (Reg)

3998 llvm_unreachable("sret virtual register not created in the entry block");

4001 unsigned V0 = ABI.IsN64() ? Mips::V0_64 : Mips::V0;

4002

4006 }

4007

4008 RetOps[0] = Chain;

4009

4010

4013

4014

4016 return LowerInterruptReturn(RetOps, DL, DAG);

4017

4018

4019 return DAG.getNode(MipsISD::Ret, DL, MVT::Other, RetOps);

4020}

4021

4022

4023

4024

4025

4026

4027

4029MipsTargetLowering::getConstraintType(StringRef Constraint) const {

4030

4031

4032

4033

4034

4035

4036

4037

4038

4039

4040

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

4042 switch (Constraint[0]) {

4043 default : break;

4044 case 'd':

4045 case 'y':

4046 case 'f':

4047 case 'c':

4048 case 'l':

4049 case 'x':

4051 case 'R':

4053 }

4054 }

4055

4056 if (Constraint == "ZC")

4058

4060}

4061

4062

4063

4064

4066MipsTargetLowering::getSingleConstraintMatchWeight(

4067 AsmOperandInfo &info, const char *constraint) const {

4069 Value *CallOperandVal = info.CallOperandVal;

4070

4071

4072 if (!CallOperandVal)

4075

4076 switch (*constraint) {

4077 default:

4079 break;

4080 case 'd':

4081 case 'y':

4084 break;

4085 case 'f':

4091 break;

4092 case 'c':

4093 case 'l':

4094 case 'x':

4097 break;

4098 case 'I':

4099 case 'J':

4100 case 'K':

4101 case 'L':

4102 case 'N':

4103 case 'O':

4104 case 'P':

4107 break;

4108 case 'R':

4110 break;

4111 }

4112 return weight;

4113}

4114

4115

4116

4117

4118

4120 unsigned long long &Reg) {

4121 if (C.front() != '{' || C.back() != '}')

4122 return std::make_pair(false, false);

4123

4124

4126 I = std::find_if(B, E, isdigit);

4127

4129

4130

4131 if (I == E)

4132 return std::make_pair(true, false);

4133

4134

4136 true);

4137}

4138

4143 return VT.bitsLT(MinVT) ? MinVT : VT;

4144}

4145

4146std::pair<unsigned, const TargetRegisterClass *> MipsTargetLowering::

4147parseRegForInlineAsmConstraint(StringRef C, MVT VT) const {

4152 unsigned long long Reg;

4153

4155

4156 if (!R.first)

4157 return std::make_pair(0U, nullptr);

4158

4159 if ((Prefix == "hi" || Prefix == "lo")) {

4160

4161 if (R.second)

4162 return std::make_pair(0U, nullptr);

4163

4164 RC = TRI->getRegClass(Prefix == "hi" ?

4165 Mips::HI32RegClassID : Mips::LO32RegClassID);

4166 return std::make_pair(*(RC->begin()), RC);

4167 } else if (Prefix.starts_with("$msa")) {

4168

4169

4170

4171 if (R.second)

4172 return std::make_pair(0U, nullptr);

4173

4175 .Case("$msair", Mips::MSAIR)

4176 .Case("$msacsr", Mips::MSACSR)

4177 .Case("$msaaccess", Mips::MSAAccess)

4178 .Case("$msasave", Mips::MSASave)

4179 .Case("$msamodify", Mips::MSAModify)

4180 .Case("$msarequest", Mips::MSARequest)

4181 .Case("$msamap", Mips::MSAMap)

4182 .Case("$msaunmap", Mips::MSAUnmap)

4184

4185 if (Reg)

4186 return std::make_pair(0U, nullptr);

4187

4188 RC = TRI->getRegClass(Mips::MSACtrlRegClassID);

4189 return std::make_pair(Reg, RC);

4190 }

4191

4192 if (R.second)

4193 return std::make_pair(0U, nullptr);

4194

4195 if (Prefix == "$f") {

4196

4197

4198

4199

4200 if (VT == MVT::Other) {

4202 VT = MVT::f32;

4203 else

4204 VT = (Subtarget.isFP64bit() || !(Reg % 2)) ? MVT::f64 : MVT::f32;

4205 }

4206

4208

4209 if (RC == &Mips::AFGR64RegClass) {

4211 Reg >>= 1;

4212 }

4213 } else if (Prefix == "$fcc")

4214 RC = TRI->getRegClass(Mips::FCCRegClassID);

4215 else if (Prefix == "$w") {

4216 RC = getRegClassFor((VT == MVT::Other) ? MVT::v16i8 : VT);

4217 } else {

4218 assert(Prefix == "$");

4219 RC = getRegClassFor((VT == MVT::Other) ? MVT::i32 : VT);

4220 }

4221

4223 return std::make_pair(*(RC->begin() + Reg), RC);

4224}

4225

4226

4227

4228

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

4232 MVT VT) const {

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

4234 switch (Constraint[0]) {

4235 case 'd':

4236 case 'y':

4237 case 'r':

4238 if ((VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 ||

4239 VT == MVT::i1) ||

4240 (VT == MVT::f32 && Subtarget.useSoftFloat())) {

4242 return std::make_pair(0U, &Mips::CPU16RegsRegClass);

4243 return std::make_pair(0U, &Mips::GPR32RegClass);

4244 }

4245 if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat()) ||

4246 (VT == MVT::f64 && Subtarget.isSingleFloat())) &&

4248 return std::make_pair(0U, &Mips::GPR32RegClass);

4249 if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat()) ||

4250 (VT == MVT::f64 && Subtarget.isSingleFloat())) &&

4252 return std::make_pair(0U, &Mips::GPR64RegClass);

4253

4254 return std::make_pair(0U, nullptr);

4255 case 'f':

4256 if (VT == MVT::v16i8)

4257 return std::make_pair(0U, &Mips::MSA128BRegClass);

4258 else if (VT == MVT::v8i16 || VT == MVT::v8f16)

4259 return std::make_pair(0U, &Mips::MSA128HRegClass);

4260 else if (VT == MVT::v4i32 || VT == MVT::v4f32)

4261 return std::make_pair(0U, &Mips::MSA128WRegClass);

4262 else if (VT == MVT::v2i64 || VT == MVT::v2f64)

4263 return std::make_pair(0U, &Mips::MSA128DRegClass);

4264 else if (VT == MVT::f32)

4265 return std::make_pair(0U, &Mips::FGR32RegClass);

4266 else if ((VT == MVT::f64) && (Subtarget.isSingleFloat())) {

4268 return std::make_pair(0U, &Mips::FGR64RegClass);

4269 return std::make_pair(0U, &Mips::AFGR64RegClass);

4270 }

4271 break;

4272 case 'c':

4273 if (VT == MVT::i32)

4274 return std::make_pair((unsigned)Mips::T9, &Mips::GPR32RegClass);

4275 if (VT == MVT::i64)

4276 return std::make_pair((unsigned)Mips::T9_64, &Mips::GPR64RegClass);

4277

4278 return std::make_pair(0U, nullptr);

4279 case 'l':

4280

4281 if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8)

4282 return std::make_pair((unsigned)Mips::LO0, &Mips::LO32RegClass);

4283 return std::make_pair((unsigned)Mips::LO0_64, &Mips::LO64RegClass);

4284 case 'x':

4285

4286

4287

4288 return std::make_pair(0U, nullptr);

4289 }

4290 }

4291

4292 if (!Constraint.empty()) {

4293 std::pair<unsigned, const TargetRegisterClass *> R;

4294 R = parseRegForInlineAsmConstraint(Constraint, VT);

4295

4296 if (R.second)

4297 return R;

4298 }

4299

4301}

4302

4303

4304

4305void MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op,

4307 std::vector &Ops,

4309 SDLoc DL(Op);

4311

4312

4313 if (Constraint.size() > 1)

4314 return;

4315

4316 char ConstraintLetter = Constraint[0];

4317 switch (ConstraintLetter) {

4318 default: break;

4319 case 'I':

4320

4322 EVT Type = Op.getValueType();

4323 int64_t Val = C->getSExtValue();

4326 break;

4327 }

4328 }

4329 return;

4330 case 'J':

4332 EVT Type = Op.getValueType();

4333 int64_t Val = C->getZExtValue();

4334 if (Val == 0) {

4336 break;

4337 }

4338 }

4339 return;

4340 case 'K':

4342 EVT Type = Op.getValueType();

4343 uint64_t Val = C->getZExtValue();

4346 break;

4347 }

4348 }

4349 return;

4350 case 'L':

4352 EVT Type = Op.getValueType();

4353 int64_t Val = C->getSExtValue();

4354 if ((isInt<32>(Val)) && ((Val & 0xffff) == 0)){

4356 break;

4357 }

4358 }

4359 return;

4360 case 'N':

4362 EVT Type = Op.getValueType();

4363 int64_t Val = C->getSExtValue();

4364 if ((Val >= -65535) && (Val <= -1)) {

4366 break;

4367 }

4368 }

4369 return;

4370 case 'O':

4372 EVT Type = Op.getValueType();

4373 int64_t Val = C->getSExtValue();

4376 break;

4377 }

4378 }

4379 return;

4380 case 'P':

4382 EVT Type = Op.getValueType();

4383 int64_t Val = C->getSExtValue();

4384 if ((Val <= 65535) && (Val >= 1)) {

4386 break;

4387 }

4388 }

4389 return;

4390 }

4391

4392 if (Result.getNode()) {

4393 Ops.push_back(Result);

4394 return;

4395 }

4396

4398}

4399

4400bool MipsTargetLowering::isLegalAddressingMode(const DataLayout &DL,

4402 unsigned AS,

4404

4405 if (AM.BaseGV)

4406 return false;

4407

4408 switch (AM.Scale) {

4409 case 0:

4410 break;

4411 case 1:

4412 if (!AM.HasBaseReg)

4413 break;

4414 return false;

4415 default:

4416 return false;

4417 }

4418

4419 return true;

4420}

4421

4422bool

4423MipsTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {

4424

4425 return false;

4426}

4427

4428EVT MipsTargetLowering::getOptimalMemOpType(

4430 const AttributeList &FuncAttributes) const {

4432 return MVT::i64;

4433

4434 return MVT::i32;

4435}

4436

4437bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,

4438 bool ForCodeSize) const {

4439 if (VT != MVT::f32 && VT != MVT::f64)

4440 return false;

4441 if (Imm.isNegZero())

4442 return false;

4443 return Imm.isZero();

4444}

4445

4446bool MipsTargetLowering::isLegalICmpImmediate(int64_t Imm) const {

4448}

4449

4450bool MipsTargetLowering::isLegalAddImmediate(int64_t Imm) const {

4452}

4453

4457 if (ABI.IsN64())

4460}

4461

4462SDValue MipsTargetLowering::getPICJumpTableRelocBase(SDValue Table,

4465 return Table;

4467}

4468

4470 return Subtarget.useSoftFloat();

4471}

4472

4473void MipsTargetLowering::copyByValRegs(

4474 SDValue Chain, const SDLoc &DL, std::vector &OutChains,

4477 unsigned FirstReg, unsigned LastReg, const CCValAssign &VA,

4481 unsigned GPRSizeInBytes = Subtarget.getGPRSizeInBytes();

4482 unsigned NumRegs = LastReg - FirstReg;

4483 unsigned RegAreaSize = NumRegs * GPRSizeInBytes;

4484 unsigned FrameObjSize = std::max(Flags.getByValSize(), RegAreaSize);

4485 int FrameObjOffset;

4487

4488 if (RegAreaSize)

4489 FrameObjOffset =

4490 (int)ABI.GetCalleeAllocdArgSizeInBytes(State.getCallingConv()) -

4491 (int)((ByValArgRegs.size() - FirstReg) * GPRSizeInBytes);

4492 else

4494

4495

4497

4498

4499

4500

4501

4502 int FI = MFI.CreateFixedObject(FrameObjSize, FrameObjOffset, false, true);

4505

4506 if (!NumRegs)

4507 return;

4508

4509

4511 const TargetRegisterClass *RC = getRegClassFor(RegTy);

4512

4513 for (unsigned I = 0; I < NumRegs; ++I) {

4514 unsigned ArgReg = ByValArgRegs[FirstReg + I];

4515 unsigned VReg = addLiveIn(MF, ArgReg, RC);

4516 unsigned Offset = I * GPRSizeInBytes;

4520 StorePtr, MachinePointerInfo(FuncArg, Offset));

4521 OutChains.push_back(Store);

4522 }

4523}

4524

4525

4526void MipsTargetLowering::passByValArg(

4528 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,

4531 unsigned LastReg, const ISD::ArgFlagsTy &Flags, bool isLittle,

4533 unsigned ByValSizeInBytes = Flags.getByValSize();

4534 unsigned OffsetInBytes = 0;

4535 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();

4536 Align Alignment =

4537 std::min(Flags.getNonZeroByValAlign(), Align(RegSizeInBytes));

4540 unsigned NumRegs = LastReg - FirstReg;

4541

4542 if (NumRegs) {

4544 bool LeftoverBytes = (NumRegs * RegSizeInBytes > ByValSizeInBytes);

4545 unsigned I = 0;

4546

4547

4548 for (; I < NumRegs - LeftoverBytes; ++I, OffsetInBytes += RegSizeInBytes) {

4552 MachinePointerInfo(), Alignment);

4554 unsigned ArgReg = ArgRegs[FirstReg + I];

4555 RegsToPass.push_back(std::make_pair(ArgReg, LoadVal));

4556 }

4557

4558

4559 if (ByValSizeInBytes == OffsetInBytes)

4560 return;

4561

4562

4563 if (LeftoverBytes) {

4565

4566 for (unsigned LoadSizeInBytes = RegSizeInBytes / 2, TotalBytesLoaded = 0;

4567 OffsetInBytes < ByValSizeInBytes; LoadSizeInBytes /= 2) {

4568 unsigned RemainingSizeInBytes = ByValSizeInBytes - OffsetInBytes;

4569

4570 if (RemainingSizeInBytes < LoadSizeInBytes)

4571 continue;

4572

4573

4576 PtrTy));

4578 ISD::ZEXTLOAD, DL, RegTy, Chain, LoadPtr, MachinePointerInfo(),

4581

4582

4583 unsigned Shamt;

4584

4585 if (isLittle)

4586 Shamt = TotalBytesLoaded * 8;

4587 else

4588 Shamt = (RegSizeInBytes - (TotalBytesLoaded + LoadSizeInBytes)) * 8;

4589

4592

4595 else

4596 Val = Shift;

4597

4598 OffsetInBytes += LoadSizeInBytes;

4599 TotalBytesLoaded += LoadSizeInBytes;

4600 Alignment = std::min(Alignment, Align(LoadSizeInBytes));

4601 }

4602

4603 unsigned ArgReg = ArgRegs[FirstReg + I];

4604 RegsToPass.push_back(std::make_pair(ArgReg, Val));

4605 return;

4606 }

4607 }

4608

4609

4610 unsigned MemCpySize = ByValSizeInBytes - OffsetInBytes;

4616 Chain, DL, Dst, Src, DAG.getConstant(MemCpySize, DL, PtrTy),

4617 Align(Alignment), false, false,

4618 nullptr, std::nullopt, MachinePointerInfo(), MachinePointerInfo());

4620}

4621

4622void MipsTargetLowering::writeVarArgRegs(std::vector &OutChains,

4628 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();

4630 const TargetRegisterClass *RC = getRegClassFor(RegTy);

4633 MipsFunctionInfo *MipsFI = MF.getInfo();

4634

4635

4636 int VaArgOffset;

4637

4638 if (ArgRegs.size() == Idx)

4640 else {

4641 VaArgOffset =

4642 (int)ABI.GetCalleeAllocdArgSizeInBytes(State.getCallingConv()) -

4643 (int)(RegSizeInBytes * (ArgRegs.size() - Idx));

4644 }

4645

4646

4647

4648 int FI = MFI.CreateFixedObject(RegSizeInBytes, VaArgOffset, true);

4650

4651

4652

4653

4654

4655 for (unsigned I = Idx; I < ArgRegs.size();

4656 ++I, VaArgOffset += RegSizeInBytes) {

4662 DAG.getStore(Chain, DL, ArgValue, PtrOff, MachinePointerInfo());

4664 (Value *)nullptr);

4665 OutChains.push_back(Store);

4666 }

4667}

4668

4670 Align Alignment) const {

4672

4673 assert(Size && "Byval argument's size shouldn't be 0.");

4674

4675 Alignment = std::min(Alignment, TFL->getStackAlign());

4676

4677 unsigned FirstReg = 0;

4678 unsigned NumRegs = 0;

4679

4681 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();

4683

4686

4687

4688

4690 Alignment >= Align(RegSizeInBytes) &&

4691 "Byval argument's alignment should be a multiple of RegSizeInBytes.");

4692

4693 FirstReg = State->getFirstUnallocated(IntArgRegs);

4694

4695

4696

4697

4698

4699 if ((Alignment > RegSizeInBytes) && (FirstReg % 2)) {

4700 State->AllocateReg(IntArgRegs[FirstReg], ShadowRegs[FirstReg]);

4701 ++FirstReg;

4702 }

4703

4704

4706 for (unsigned I = FirstReg; Size > 0 && (I < IntArgRegs.size());

4707 Size -= RegSizeInBytes, ++I, ++NumRegs)

4708 State->AllocateReg(IntArgRegs[I], ShadowRegs[I]);

4709 }

4710

4711 State->addInRegsParamInfo(FirstReg, FirstReg + NumRegs);

4712}

4713

4716 bool isFPCmp,

4717 unsigned Opc) const {

4719 "Subtarget already supports SELECT nodes with the use of"

4720 "conditional-move instructions.");

4721

4725

4726

4727

4728

4729

4732

4733

4734

4735

4736

4737

4738

4743 F->insert(It, copy0MBB);

4744 F->insert(It, sinkMBB);

4745

4746

4750

4751

4754

4755 if (isFPCmp) {

4756

4758 .addReg(MI.getOperand(1).getReg())

4760 } else {

4761

4763 .addReg(MI.getOperand(1).getReg())

4766 }

4767

4768

4769

4770

4771 BB = copy0MBB;

4772

4773

4775

4776

4777

4778

4779 BB = sinkMBB;

4780

4782 .addReg(MI.getOperand(2).getReg())

4784 .addReg(MI.getOperand(3).getReg())

4786

4787 MI.eraseFromParent();

4788

4789 return BB;

4790}

4791

4793MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,

4796 "Subtarget already supports SELECT nodes with the use of"

4797 "conditional-move instructions.");

4798

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

4801

4802

4803

4804

4805

4806

4809

4810

4811

4812

4813

4814

4815

4816 MachineBasicBlock *thisMBB = BB;

4817 MachineFunction *F = BB->getParent();

4818 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);

4819 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);

4820 F->insert(It, copy0MBB);

4821 F->insert(It, sinkMBB);

4822

4823

4827

4828

4831

4832

4834 .addReg(MI.getOperand(2).getReg())

4837

4838

4839

4840

4841 BB = copy0MBB;

4842

4843

4845

4846

4847

4848

4849 BB = sinkMBB;

4850

4851

4853 .addReg(MI.getOperand(3).getReg())

4855 .addReg(MI.getOperand(5).getReg())

4858 .addReg(MI.getOperand(4).getReg())

4860 .addReg(MI.getOperand(6).getReg())

4862

4863 MI.eraseFromParent();

4864

4865 return BB;

4866}

4867

4868

4869

4873

4876 .Case("$28", Mips::GP_64)

4877 .Case("sp", Mips::SP_64)

4879 return Reg;

4880 }

4881

4883 .Case("$28", Mips::GP)

4884 .Case("sp", Mips::SP)

4886 return Reg;

4887}

4888

4896

4897 Register Dest = MI.getOperand(0).getReg();

4899 unsigned Imm = MI.getOperand(2).getImm();

4900

4902

4904

4905 Register Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4911 } else {

4912

4913

4914 Register LoadHalf = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4915 Register LoadFull = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4916 Register Undef = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4921 .addImm(Imm + (IsLittle ? 0 : 3))

4926 .addImm(Imm + (IsLittle ? 3 : 0))

4929 }

4930

4931 MI.eraseFromParent();

4932 return BB;

4933}

4934

4937 MachineFunction *MF = BB->getParent();

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

4940 const bool IsLittle = Subtarget.isLittle();

4942

4943 Register Dest = MI.getOperand(0).getReg();

4945 unsigned Imm = MI.getOperand(2).getImm();

4946

4948

4950

4952 Register Temp = MRI.createVirtualRegister(&Mips::GPR64RegClass);

4958 } else {

4959 Register Wtemp = MRI.createVirtualRegister(&Mips::MSA128WRegClass);

4960 Register Lo = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4961 Register Hi = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4965 .addImm(Imm + (IsLittle ? 0 : 4));

4969 .addImm(Imm + (IsLittle ? 4 : 0));

4975 }

4976 } else {

4977

4978

4979 Register LoHalf = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4980 Register LoFull = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4981 Register LoUndef = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4982 Register HiHalf = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4983 Register HiFull = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4984 Register HiUndef = MRI.createVirtualRegister(&Mips::GPR32RegClass);

4985 Register Wtemp = MRI.createVirtualRegister(&Mips::MSA128WRegClass);

4990 .addImm(Imm + (IsLittle ? 0 : 7))

4995 .addImm(Imm + (IsLittle ? 3 : 4))

5001 .addImm(Imm + (IsLittle ? 4 : 3))

5006 .addImm(Imm + (IsLittle ? 7 : 0))

5013 }

5014

5015 MI.eraseFromParent();

5016 return BB;

5017}

5018

5021 MachineFunction *MF = BB->getParent();

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

5024 const bool IsLittle = Subtarget.isLittle();

5026

5027 Register StoreVal = MI.getOperand(0).getReg();

5029 unsigned Imm = MI.getOperand(2).getImm();

5030

5032

5034

5035 Register BitcastW = MRI.createVirtualRegister(&Mips::MSA128WRegClass);

5036 Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);

5046 } else {

5047

5048

5049 Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);

5057 .addImm(Imm + (IsLittle ? 0 : 3));

5061 .addImm(Imm + (IsLittle ? 3 : 0));

5062 }

5063

5064 MI.eraseFromParent();

5065

5066 return BB;

5067}

5068

5071 MachineFunction *MF = BB->getParent();

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

5074 const bool IsLittle = Subtarget.isLittle();

5076

5077 Register StoreVal = MI.getOperand(0).getReg();

5079 unsigned Imm = MI.getOperand(2).getImm();

5080

5082

5084

5086 Register BitcastD = MRI.createVirtualRegister(&Mips::MSA128DRegClass);

5087 Register Lo = MRI.createVirtualRegister(&Mips::GPR64RegClass);

5099 } else {

5100 Register BitcastW = MRI.createVirtualRegister(&Mips::MSA128WRegClass);

5101 Register Lo = MRI.createVirtualRegister(&Mips::GPR32RegClass);

5102 Register Hi = MRI.createVirtualRegister(&Mips::GPR32RegClass);

5117 .addImm(Imm + (IsLittle ? 0 : 4));

5121 .addImm(Imm + (IsLittle ? 4 : 0));

5122 }

5123 } else {

5124

5125

5126 Register Bitcast = MRI.createVirtualRegister(&Mips::MSA128WRegClass);

5127 Register Lo = MRI.createVirtualRegister(&Mips::GPR32RegClass);

5128 Register Hi = MRI.createVirtualRegister(&Mips::GPR32RegClass);

5141 .addImm(Imm + (IsLittle ? 0 : 3));

5145 .addImm(Imm + (IsLittle ? 3 : 0));

5149 .addImm(Imm + (IsLittle ? 4 : 7));

5153 .addImm(Imm + (IsLittle ? 7 : 4));

5154 }

5155

5156 MI.eraseFromParent();

5157 return BB;

5158}

unsigned const MachineRegisterInfo * MRI

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

If the operand is a bitwise AND with a constant RHS, and the shift has a constant RHS and is the only...

static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const AArch64Subtarget *Subtarget, const AArch64TargetLowering &TLI)

static SDValue performANDCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI)

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const TargetInstrInfo & TII

This file declares a class to represent arbitrary precision floating point values and provide a varie...

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Function Alias Analysis Results

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

This file contains the declarations for the subclasses of Constant, which represent the different fla...

Module.h This file contains the declarations for the Module class.

const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]

static MachineBasicBlock * insertDivByZeroTrap(MachineInstr &MI, MachineBasicBlock *MBB)

Register const TargetRegisterInfo * TRI

Promote Memory to Register

cl::opt< bool > EmitJalrReloc

static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)

static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)

static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)

static SDValue performMADD_MSUBCombine(SDNode *ROOTNode, SelectionDAG &CurDAG, const MipsSubtarget &Subtarget)

Definition MipsISelLowering.cpp:915

static bool invertFPCondCodeUser(Mips::CondCode CC)

This function returns true if the floating point conditional branches and conditional moves which use...

Definition MipsISelLowering.cpp:538

static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State, ArrayRef< MCPhysReg > F64Regs)

Definition MipsISelLowering.cpp:2965

static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG, bool SingleFloat)

Definition MipsISelLowering.cpp:2876

static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)

Definition MipsISelLowering.cpp:473

static const MCPhysReg Mips64DPRegs[8]

Definition MipsISelLowering.cpp:91

static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG, bool IsLittle)

Definition MipsISelLowering.cpp:2847

static SDValue createStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD, SDValue Chain, unsigned Offset)

Definition MipsISelLowering.cpp:2830

static unsigned addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC)

Definition MipsISelLowering.cpp:1267

static std::pair< bool, bool > parsePhysicalReg(StringRef C, StringRef &Prefix, unsigned long long &Reg)

This is a helper function to parse a physical register string and split it into non-numeric and numer...

Definition MipsISelLowering.cpp:4119

static SDValue createLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD, SDValue Chain, SDValue Src, unsigned Offset)

Definition MipsISelLowering.cpp:2748

static SDValue lowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG, bool HasExtractInsert)

Definition MipsISelLowering.cpp:2445

static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)

Definition MipsISelLowering.cpp:1025

static SDValue performSUBCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)

Definition MipsISelLowering.cpp:1010

static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op)

Definition MipsISelLowering.cpp:550

static SDValue lowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG, bool HasExtractInsert)

Definition MipsISelLowering.cpp:2398

static cl::opt< bool > NoZeroDivCheck("mno-check-zero-division", cl::Hidden, cl::desc("MIPS: Don't trap on integer division by zero."), cl::init(false))

static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)

Definition MipsISelLowering.cpp:583

static SDValue performSignExtendCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)

Definition MipsISelLowering.cpp:1116

static SDValue performCMovFPCombine(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, const MipsSubtarget &Subtarget)

Definition MipsISelLowering.cpp:664

static SDValue UnpackFromArgumentSlot(SDValue Val, const CCValAssign &VA, EVT ArgVT, const SDLoc &DL, SelectionDAG &DAG)

Definition MipsISelLowering.cpp:3672

static Mips::CondCode condCodeToFCC(ISD::CondCode CC)

Definition MipsISelLowering.cpp:510

static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True, SDValue False, const SDLoc &DL)

Definition MipsISelLowering.cpp:573

uint64_t IntrinsicInst * II

const SmallVectorImpl< MachineOperand > & Cond

SI optimize exec mask operations pre RA

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

This file defines the SmallVector class.

static const MCPhysReg IntRegs[32]

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

#define STATISTIC(VARNAME, DESC)

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

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

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

static const MCPhysReg F32Regs[64]

This class represents an incoming formal argument to a Function.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

LLVM Basic Block Representation.

static BranchProbability getOne()

CCState - This class holds information needed while lowering arguments and return values.

unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const

getFirstUnallocated - Return the index of the first unallocated register in the set,...

CallingConv::ID getCallingConv() const

uint64_t getStackSize() const

Returns the size of the currently allocated portion of the stack.

CCValAssign - Represent assignment of one arg/retval to a location.

Register getLocReg() const

LocInfo getLocInfo() const

static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)

static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)

bool isUpperBitsInLoc() const

static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)

int64_t getLocMemOffset() const

Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...

LLVM_ABI bool isMustTailCall() const

Tests if this call site must be tail call optimized.

LLVM_ABI bool isIndirectCall() const

Return true if the callsite is an indirect call.

uint64_t getZExtValue() const

int64_t getSExtValue() const

A parsed version of the target data layout string in and methods for querying it.

LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const

Returns the offset in bytes between successive objects of the specified type, including alignment pad...

const char * getSymbol() const

This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...

FunctionLoweringInfo - This contains information that is global to a function that is used when lower...

bool hasStructRetAttr() const

Determine if the function returns a structure through first or second pointer argument.

const Argument * const_arg_iterator

bool hasFnAttribute(Attribute::AttrKind Kind) const

Return true if the function has the attribute.

const GlobalValue * getGlobal() const

bool hasLocalLinkage() const

bool hasDLLImportStorageClass() const

LLVM_ABI const GlobalObject * getAliaseeObject() const

bool hasInternalLinkage() const

This is an important class for using LLVM in a threaded context.

LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)

emitError - Emit an error message to the currently installed error handler with optional location inf...

This class is used to represent ISD::LOAD nodes.

LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)

Lookup the symbol inside with the specified Name.

const MCInstrDesc & get(unsigned Opcode) const

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

Wrapper class representing physical registers. Should be passed by value.

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

static auto integer_valuetypes()

TypeSize getSizeInBits() const

Returns the size of the specified MVT in bits.

TypeSize getStoreSize() const

Return the number of bytes overwritten by a store of the specified value type.

static MVT getVectorVT(MVT VT, unsigned NumElements)

bool isFloatingPoint() const

Return true if this is a FP or a vector FP type.

bool isValid() const

Return true if this is a valid simple valuetype.

static MVT getIntegerVT(unsigned BitWidth)

static auto fp_valuetypes()

static auto fp_fixedlen_vector_valuetypes()

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.

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.

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

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 setFrameAddressIsTaken(bool T)

void setHasTailCall(bool V=true)

void setReturnAddressIsTaken(bool s)

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

MCContext & getContext() const

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

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

MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)

CreateMachineInstr - Allocate a new MachineInstr.

void insert(iterator MBBI, MachineBasicBlock *MBB)

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

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

const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register use operand.

const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register definition operand.

Representation of each machine instruction.

const MachineOperand & getOperand(unsigned i) const

@ EK_GPRel32BlockAddress

EK_GPRel32BlockAddress - Each entry is an address of block, encoded with a relocation as gp-relative,...

@ EK_BlockAddress

EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.

@ EK_GPRel64BlockAddress

EK_GPRel64BlockAddress - Each entry is an address of block, encoded with a relocation as gp-relative,...

@ MOVolatile

The memory access is volatile.

Flags getFlags() const

Return the raw flags of the source value,.

MachineOperand class - Representation of each machine instruction operand.

void setSubReg(unsigned subReg)

static MachineOperand CreateMCSymbol(MCSymbol *Sym, unsigned TargetFlags=0)

void setIsKill(bool Val=true)

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

void addLiveIn(MCRegister Reg, Register vreg=Register())

addLiveIn - Add the specified register as a live-in.

MachineMemOperand * getMemOperand() const

Return a MachineMemOperand object describing the memory reference performed by operation.

const MachinePointerInfo & getPointerInfo() const

const SDValue & getChain() const

EVT getMemoryVT() const

Return the type of the in-memory value.

static SpecialCallingConvType getSpecialCallingConvForCallee(const SDNode *Callee, const MipsSubtarget &Subtarget)

Determine the SpecialCallingConvType for the given callee.

MipsFunctionInfo - This class is derived from MachineFunction private Mips target-specific informatio...

void setVarArgsFrameIndex(int Index)

unsigned getSRetReturnReg() const

int getVarArgsFrameIndex() const

MachinePointerInfo callPtrInfo(MachineFunction &MF, const char *ES)

Create a MachinePointerInfo that has an ExternalSymbolPseudoSourceValue object representing a GOT ent...

Register getGlobalBaseReg(MachineFunction &MF)

void setSRetReturnReg(unsigned Reg)

void setFormalArgInfo(unsigned Size, bool HasByval)

static const uint32_t * getMips16RetHelperMask()

const MipsInstrInfo * getInstrInfo() const override

bool inMips16Mode() const

const MipsRegisterInfo * getRegisterInfo() const override

bool hasExtractInsert() const

Features related to the presence of specific instructions.

bool isSingleFloat() const

const TargetFrameLowering * getFrameLowering() const override

MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override

Return the register type for a given MVT, ensuring vectors are treated as a series of gpr sized integ...

Definition MipsISelLowering.cpp:98

bool hasBitTest(SDValue X, SDValue Y) const override

Return true if the target has a bit-test instruction: (X & (1 << Y)) ==/!= 0 This knowledge can be us...

Definition MipsISelLowering.cpp:1187

static const MipsTargetLowering * create(const MipsTargetMachine &TM, const MipsSubtarget &STI)

Definition MipsISelLowering.cpp:437

SDValue getAddrGPRel(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, bool IsN64) const

unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const override

Break down vectors to the correct number of gpr sized integers.

Definition MipsISelLowering.cpp:122

Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override

Return the register ID of the name passed in.

Definition MipsISelLowering.cpp:4871

SDValue getAddrNonPICSym64(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const

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

getSetCCResultType - get the ISD::SETCC result ValueType

Definition MipsISelLowering.cpp:466

SDValue getAddrGlobal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned Flag, SDValue Chain, const MachinePointerInfo &PtrInfo) const

FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo) const override

createFastISel - This method returns a target specific FastISel object, or null if the target does no...

Definition MipsISelLowering.cpp:447

MipsTargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)

Definition MipsISelLowering.cpp:174

SDValue getAddrGlobalLargeGOT(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, unsigned HiFlag, unsigned LoFlag, SDValue Chain, const MachinePointerInfo &PtrInfo) const

SDValue getDllimportVariable(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, SDValue Chain, const MachinePointerInfo &PtrInfo) const

bool shouldFoldConstantShiftPairToMask(const SDNode *N) const override

Return true if it is profitable to fold a pair of shifts into a mask.

Definition MipsISelLowering.cpp:1197

SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override

This method will be invoked for all target nodes and for any target-independent nodes that the target...

Definition MipsISelLowering.cpp:1147

CCAssignFn * CCAssignFnForReturn() const

Definition MipsISelLowering.cpp:3117

void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override

ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...

Definition MipsISelLowering.cpp:1211

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

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

Definition MipsISelLowering.cpp:1305

SDValue getDllimportSymbol(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const

CCAssignFn * CCAssignFnForCall() const

Definition MipsISelLowering.cpp:3113

unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override

Return the number of registers for a given MVT, ensuring vectors are treated as a series of gpr sized...

Definition MipsISelLowering.cpp:110

SDValue getAddrNonPIC(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG) const

SDValue lowerSTORE(SDValue Op, SelectionDAG &DAG) const

Definition MipsISelLowering.cpp:2892

void AdjustInstrPostInstrSelection(MachineInstr &MI, SDNode *Node) const override

This method should be implemented by targets that mark instructions with the 'hasPostISelHook' flag.

Definition MipsISelLowering.cpp:3200

virtual void getOpndList(SmallVectorImpl< SDValue > &Ops, std::deque< std::pair< unsigned, SDValue > > &RegsToPass, bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const

This function fills Ops, which is the list of operands that will later be used when a function call n...

Definition MipsISelLowering.cpp:3143

EVT getTypeForExtReturn(LLVMContext &Context, EVT VT, ISD::NodeType) const override

Return the type that should be used to zero or sign extend a zeroext/signext integer return value.

Definition MipsISelLowering.cpp:4139

bool isCheapToSpeculateCtlz(Type *Ty) const override

Return true if it is cheap to speculate a call to intrinsic ctlz.

Definition MipsISelLowering.cpp:1183

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

LowerOperation - Provide custom lowering hooks for some operations.

Definition MipsISelLowering.cpp:1218

bool isCheapToSpeculateCttz(Type *Ty) const override

Return true if it is cheap to speculate a call to intrinsic cttz.

Definition MipsISelLowering.cpp:1179

SDValue getAddrLocal(NodeTy *N, const SDLoc &DL, EVT Ty, SelectionDAG &DAG, bool IsN32OrN64) const

SDValue getGlobalReg(SelectionDAG &DAG, EVT Ty) const

Definition MipsISelLowering.cpp:137

const MipsSubtarget & Subtarget

void HandleByVal(CCState *, unsigned &, Align) const override

Target-specific cleanup for formal ByVal parameters.

Definition MipsISelLowering.cpp:4669

SDValue lowerLOAD(SDValue Op, SelectionDAG &DAG) const

Definition MipsISelLowering.cpp:2766

bool IsConstantInSmallSection(const DataLayout &DL, const Constant *CN, const TargetMachine &TM) const

Return true if this constant should be placed into small data section.

Wrapper class representing virtual and physical registers.

Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...

Represents one node in the SelectionDAG.

unsigned getOpcode() const

Return the SelectionDAG opcode value for 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

unsigned getOpcode() const

This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...

LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())

SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)

SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)

LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)

Create a MERGE_VALUES node from the given operands.

LLVM_ABI SDVTList getVTList(EVT VT)

Return an SDVTList that represents the list of values specified.

LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)

These are used for target selectors to create a new node with specified return type(s),...

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 getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())

Creates a MemIntrinsicNode that may produce a result and takes a list of operands.

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)

SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)

SDValue getUNDEF(EVT VT)

Return an UNDEF node. UNDEF does not have a useful SDLoc.

SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)

Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).

SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)

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

SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())

Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...

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.

LLVM_ABI bool isKnownNeverNaN(SDValue Op, const APInt &DemandedElts, bool SNaN=false, unsigned Depth=0) const

Test whether the given SDValue (or all elements of it, if it is a vector) is known to never be NaN in...

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)

LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)

Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.

MachineFunction & getMachineFunction() const

LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)

LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)

void addCallSiteInfo(const SDNode *Node, CallSiteInfo &&CallInfo)

Set CallSiteInfo to be associated with Node.

LLVMContext * getContext() const

LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)

SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)

SDValue getEntryNode() const

Return the token chain corresponding to the entry of the function.

LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)

Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

This class is used to represent ISD::STORE nodes.

const SDValue & getBasePtr() const

const SDValue & getValue() const

bool isTruncatingStore() const

Return true if the op does a truncation before store.

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

const char * const_iterator

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

Align getStackAlign() 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.

Provides information about what library functions are available for the current target.

void setBooleanVectorContents(BooleanContent Ty)

Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...

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.

void setMinStackArgumentAlignment(Align Alignment)

Set the minimum stack alignment of an argument.

const TargetMachine & getTargetMachine() const

virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, std::optional< MVT > RegisterVT=std::nullopt) const

Return the number of registers that this ValueType will eventually require.

void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)

Set the maximum atomic operation size supported by the backend.

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

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

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

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

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

@ ZeroOrOneBooleanContent

@ ZeroOrNegativeOneBooleanContent

void setStackPointerRegisterToSaveRestore(Register R)

If set to a physical register, this specifies the register that llvm.savestack/llvm....

void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)

If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...

void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)

Targets should invoke this method for each target independent node that they want to provide a custom...

virtual bool useSoftFloat() const

Align getMinStackArgumentAlignment() const

Return the minimum stack alignment of an argument.

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

unsigned MaxStoresPerMemcpy

Specify maximum number of store instructions per memcpy call.

MVT getRegisterType(MVT VT) const

Return the type of registers that this ValueType will eventually require.

virtual ConstraintType getConstraintType(StringRef Constraint) const

Given a constraint, return the type of constraint it is for this target.

virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const

Lower TLS global address SDNode for target independent emulated TLS model.

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 ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const

Examine constraint string and operand type and determine a weight value.

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

Given a physical register constraint (e.g.

TargetLowering(const TargetLowering &)=delete

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

Lower the specified operand into the Ops vector.

virtual unsigned getJumpTableEncoding() const

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

virtual void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const

This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...

TLSModel::Model getTLSModel(const GlobalValue *GV) const

Returns the TLS model which should be used for the given global variable.

bool useEmulatedTLS() const

Returns true if this target uses emulated TLS.

virtual TargetLoweringObjectFile * getObjFileLowering() const

unsigned NoNaNsFPMath

NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...

unsigned EnableFastISel

EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...

unsigned EmitCallGraphSection

Emit section containing call graph metadata.

iterator begin() const

begin/end - Return all of the registers in this class.

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.

bool isVectorTy() const

True if this is an instance of VectorType.

bool isFloatTy() const

Return true if this is 'float', a 32-bit IEEE fp type.

LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY

Return the basic size of this type if it is a primitive type.

bool isIntegerTy() const

True if this is an instance of IntegerType.

static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)

bool isFPOrFPVectorTy() const

Return true if this is a FP type or a vector of FP.

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

constexpr ScalarTy getFixedValue() const

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 char Args[]

Key for Kernel::Metadata::mArgs.

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.

@ Fast

Attempts to make calls as fast as possible (e.g.

@ C

The default llvm calling convention, compatible with C.

NodeType

ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.

@ SETCC

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

@ STRICT_FSETCC

STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.

@ BSWAP

Byte Swap and Counting operators.

@ ADD

Simple integer binary arithmetic operators.

@ ANY_EXTEND

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

@ FMA

FMA - Perform a * b + c with no intermediate rounding step.

@ FADD

Simple binary floating point operators.

@ SDIVREM

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

@ BUILD_PAIR

BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.

@ EH_RETURN

OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents 'eh_return' gcc dwarf builtin,...

@ SIGN_EXTEND

Conversion operators.

@ FCANONICALIZE

Returns platform specific canonical encoding of a floating point number.

@ IS_FPCLASS

Performs a check of floating point class property, defined by IEEE-754.

@ SELECT

Select(COND, TRUEVAL, FALSEVAL).

@ BasicBlock

Various leaf nodes.

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

@ SIGN_EXTEND_INREG

SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...

@ EH_DWARF_CFA

EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...

@ FRAMEADDR

FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.

@ STRICT_FP_TO_SINT

STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.

@ FP_TO_SINT

FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.

@ AND

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

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

@ FCOPYSIGN

FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.

LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)

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

CondCode

ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...

LoadExtType

LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).

@ Bitcast

Perform the operation on a different, but equivalently sized type.

@ MO_TLSGD

On a symbol operand, this indicates that the immediate is the offset to the slot in GOT which stores ...

Flag

These should be considered private to the implementation of the MCInstrDesc class.

FastISel * createFastISel(FunctionLoweringInfo &funcInfo, const TargetLibraryInfo *libInfo)

@ Implicit

Not emitted register (e.g. carry, or temporary result).

@ Define

Register definition.

@ Kill

The last use of a register.

@ EarlyClobber

Register definition happens before uses.

Not(const Pred &P) -> Not< Pred >

initializer< Ty > init(const Ty &Val)

NodeAddr< NodeBase * > Node

NodeAddr< FuncNode * > Func

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

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.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

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 isShiftedMask_64(uint64_t Value)

Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...

auto dyn_cast_or_null(const Y &Val)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

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

constexpr T divideCeil(U Numerator, V Denominator)

Returns the integer ceil(Numerator / Denominator).

const MipsTargetLowering * createMips16TargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)

Create MipsTargetLowering objects.

@ Or

Bitwise or logical OR of integers.

unsigned getKillRegState(bool B)

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

DWARFExpression::Operation Op

ArrayRef(const T &OneElt) -> ArrayRef< T >

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

const MipsTargetLowering * createMipsSETargetLowering(const MipsTargetMachine &TM, const MipsSubtarget &STI)

LLVM_ABI bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)

Helper functions for StringRef::getAsInteger.

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.

constexpr uint64_t value() const

This is a hole in the type system and should not be abused.

EVT changeVectorElementTypeToInteger() const

Return a vector with the same number of elements as this vector, but with the element type converted ...

bool bitsLT(EVT VT) const

Return true if this has less bits than VT.

TypeSize getSizeInBits() const

Return the size of the specified value type in bits.

bool isPow2VectorType() const

Returns true if the given vector is a power of 2.

MVT getSimpleVT() const

Return the SimpleValueType held in the specified simple EVT.

static EVT getFloatingPointVT(unsigned BitWidth)

Returns the EVT that represents a floating-point type with the given number of bits.

bool isVector() const

Return true if this is a vector value type.

LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const

This method returns an LLVM type corresponding to the specified EVT.

bool isRound() const

Return true if the size is a power-of-two number of bytes.

EVT getVectorElementType() const

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

unsigned getVectorNumElements() const

Given a vector type, return the number of elements it contains.

bool isInteger() const

Return true if this is an integer or a vector integer type.

Align getNonZeroOrigAlign() const

SmallVector< ArgRegPair, 1 > ArgRegPairs

Vector of call argument and its forwarding register.

This class contains a discriminated union of information about pointers in memory operands,...

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 struct is a compact representation of a valid (power of two) or undefined (0) alignment.

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.

SmallVector< ISD::InputArg, 32 > Ins

SmallVector< ISD::OutputArg, 32 > Outs

SmallVector< SDValue, 32 > OutVals

bool isBeforeLegalizeOps() const