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

1

2

3

4

5

6

7

8

9

10

11

12

27#include "llvm/IR/IntrinsicsMips.h"

31using namespace llvm;

32

33#define DEBUG_TYPE "mips-isel"

34

35bool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {

38 return false;

40}

41

46

47void MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI,

50 unsigned Mask = MI.getOperand(1).getImm();

51 unsigned Flag =

53

54 if (Mask & 1)

55 MIB.addReg(Mips::DSPPos, Flag);

56

57 if (Mask & 2)

58 MIB.addReg(Mips::DSPSCount, Flag);

59

60 if (Mask & 4)

61 MIB.addReg(Mips::DSPCarry, Flag);

62

63 if (Mask & 8)

64 MIB.addReg(Mips::DSPOutFlag, Flag);

65

66 if (Mask & 16)

67 MIB.addReg(Mips::DSPCCond, Flag);

68

69 if (Mask & 32)

70 MIB.addReg(Mips::DSPEFI, Flag);

71}

72

73MCRegister MipsSEDAGToDAGISel::getMSACtrlReg(const SDValue RegIdx) const {

75 return Mips::MSACtrlRegClass.getRegister(RegNum);

76}

77

80 unsigned DstReg = 0, ZeroReg = 0;

81

82

83 if ((MI.getOpcode() == Mips::ADDiu) &&

84 (MI.getOperand(1).getReg() == Mips::ZERO) &&

85 (MI.getOperand(2).isImm()) &&

86 (MI.getOperand(2).getImm() == 0)) {

87 DstReg = MI.getOperand(0).getReg();

88 ZeroReg = Mips::ZERO;

89 } else if ((MI.getOpcode() == Mips::DADDiu) &&

90 (MI.getOperand(1).getReg() == Mips::ZERO_64) &&

91 (MI.getOperand(2).isImm()) &&

92 (MI.getOperand(2).getImm() == 0)) {

93 DstReg = MI.getOperand(0).getReg();

94 ZeroReg = Mips::ZERO_64;

95 }

96

97 if (!DstReg)

98 return false;

99

100

102 E = MRI->use_end(); U != E;) {

103 MachineOperand &MO = *U;

104 unsigned OpNo = U.getOperandNo();

106 ++U;

107

108

109 if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) || MI->isPseudo())

110 continue;

111

112

113

114 if (MRI->getRegClass(MO.getReg())->contains(ZeroReg))

115 continue;

116

118 }

119

120 return true;

121}

122

125 MachineInstrBuilder MIB(MF, &MI);

126 if (Subtarget->isABI_O32()) {

127

131 .addUse(Mips::ZERO_64);

132

134 } else {

135

140

145

147 }

148}

149

150void MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) {

151 MF.getInfo()->initGlobalBaseReg(MF);

152

153 MachineRegisterInfo *MRI = &MF.getRegInfo();

154

155 for (auto &MBB: MF) {

156 for (auto &MI: MBB) {

157 switch (MI.getOpcode()) {

158 case Mips::RDDSP:

159 addDSPCtrlRegOperands(false, MI, MF);

160 break;

161 case Mips::WRDSP:

162 addDSPCtrlRegOperands(true, MI, MF);

163 break;

164 case Mips::BuildPairF64_64:

165 case Mips::ExtractElementF64_64:

168 break;

169 }

170 [[fallthrough]];

171 case Mips::BuildPairF64:

172 case Mips::ExtractElementF64:

175 break;

176 case Mips::JAL:

177 case Mips::JAL_MM:

178 if (MI.getOperand(0).isGlobal() &&

179 MI.getOperand(0).getGlobal()->hasExternalLinkage() &&

180 MI.getOperand(0).getGlobal()->getName() == "_mcount")

181 emitMCountABI(MI, MBB, MF);

182 break;

183 case Mips::JALRPseudo:

184 case Mips::JALR64Pseudo:

185 case Mips::JALR16_MM:

186 if (MI.getOperand(2).isMCSymbol() &&

187 MI.getOperand(2).getMCSymbol()->getName() == "_mcount")

188 emitMCountABI(MI, MBB, MF);

189 break;

190 case Mips::JALR:

191 if (MI.getOperand(3).isMCSymbol() &&

192 MI.getOperand(3).getMCSymbol()->getName() == "_mcount")

193 emitMCountABI(MI, MBB, MF);

194 break;

195 default:

196 replaceUsesWithZeroReg(MRI, MI);

197 }

198 }

199 }

200}

201

202void MipsSEDAGToDAGISel::selectAddE(SDNode *Node, const SDLoc &DL) const {

206 EVT VT = LHS.getValueType();

207

208

209

212 CurDAG->SelectNodeTo(Node, Mips::ADDWC, VT, MVT::Glue, Ops);

213 return;

214 }

215

216 assert(Opc == ISD::ADDE && "ISD::ADDE not in a chain of ADDE nodes!");

217

218

219

220

221

222

223

224

225

226

227

228

229

230 SDValue CstOne = CurDAG->getTargetConstant(1, DL, MVT::i32);

231

232 SDValue OuFlag = CurDAG->getTargetConstant(20, DL, MVT::i32);

233

234 SDNode *DSPCtrlField = CurDAG->getMachineNode(Mips::RDDSP, DL, MVT::i32,

235 MVT::Glue, CstOne, InGlue);

236

237 SDNode *Carry = CurDAG->getMachineNode(

238 Mips::EXT, DL, MVT::i32, SDValue(DSPCtrlField, 0), OuFlag, CstOne);

239

241 CurDAG->getTargetConstant(6, DL, MVT::i32), CstOne,

243 SDNode *DSPCFWithCarry = CurDAG->getMachineNode(Mips::INS, DL, MVT::i32, Ops);

244

245

246

247

248

249

251

252 SDValue InsOps[4] = {Zero, OuFlag, CstOne, SDValue(DSPCFWithCarry, 0)};

253 SDNode *DSPCtrlFinal =

254 CurDAG->getMachineNode(Mips::INS, DL, MVT::i32, InsOps);

255

256 SDNode *WrDSP = CurDAG->getMachineNode(Mips::WRDSP, DL, MVT::Glue,

257 SDValue(DSPCtrlFinal, 0), CstOne);

258

260 CurDAG->SelectNodeTo(Node, Mips::ADDWC, VT, MVT::Glue, Operands);

261}

262

263

264bool MipsSEDAGToDAGISel::selectAddrFrameIndex(SDValue Addr, SDValue &Base,

268

269 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);

270 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy);

271 return true;

272 }

273 return false;

274}

275

276

277bool MipsSEDAGToDAGISel::selectAddrFrameIndexOffset(

279 unsigned ShiftAmount = 0) const {

280 if (CurDAG->isBaseWithConstantOffset(Addr)) {

282 if (isIntN(OffsetBits + ShiftAmount, CN->getSExtValue())) {

284

285

286 if (FrameIndexSDNode *FIN =

288 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);

289 else {

291

292

293 const Align Alignment(1ULL << ShiftAmount);

294 if (isAligned(Alignment, CN->getZExtValue()))

295 return false;

296 }

297

298 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr),

299 ValTy);

300 return true;

301 }

302 }

303 return false;

304}

305

306

307

308bool MipsSEDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,

310

311 if (selectAddrFrameIndex(Addr, Base, Offset))

312 return true;

313

314

315 if (Addr.getOpcode() == MipsISD::Wrapper) {

318 return true;

319 }

320

321 if (TM.isPositionIndependent()) {

324 return false;

325 }

326

327

328 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16))

329 return true;

330

331

333

334

335

336

337

338

339

340

348 return true;

349 }

350 }

351 }

352

353 return false;

354}

355

356

357

358bool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,

362 return true;

363}

364

367 return selectAddrRegImm(Addr, Base, Offset) ||

368 selectAddrDefault(Addr, Base, Offset);

369}

370

371bool MipsSEDAGToDAGISel::selectAddrRegImm9(SDValue Addr, SDValue &Base,

373 if (selectAddrFrameIndex(Addr, Base, Offset))

374 return true;

375

376 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 9))

377 return true;

378

379 return false;

380}

381

382

383bool MipsSEDAGToDAGISel::selectAddrRegImm11(SDValue Addr, SDValue &Base,

385 if (selectAddrFrameIndex(Addr, Base, Offset))

386 return true;

387

388 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 11))

389 return true;

390

391 return false;

392}

393

394

395bool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base,

397 if (selectAddrFrameIndex(Addr, Base, Offset))

398 return true;

399

400 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 12))

401 return true;

402

403 return false;

404}

405

406bool MipsSEDAGToDAGISel::selectAddrRegImm16(SDValue Addr, SDValue &Base,

408 if (selectAddrFrameIndex(Addr, Base, Offset))

409 return true;

410

411 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16))

412 return true;

413

414 return false;

415}

416

417bool MipsSEDAGToDAGISel::selectIntAddr11MM(SDValue Addr, SDValue &Base,

419 return selectAddrRegImm11(Addr, Base, Offset) ||

420 selectAddrDefault(Addr, Base, Offset);

421}

422

423bool MipsSEDAGToDAGISel::selectIntAddr12MM(SDValue Addr, SDValue &Base,

425 return selectAddrRegImm12(Addr, Base, Offset) ||

426 selectAddrDefault(Addr, Base, Offset);

427}

428

429bool MipsSEDAGToDAGISel::selectIntAddr16MM(SDValue Addr, SDValue &Base,

431 return selectAddrRegImm16(Addr, Base, Offset) ||

432 selectAddrDefault(Addr, Base, Offset);

433}

434

435bool MipsSEDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,

437 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 7)) {

439 return false;

440

442 unsigned CnstOff = CN->getZExtValue();

443 return (CnstOff == (CnstOff & 0x3c));

444 }

445

446 return false;

447 }

448

449

450

451 if (selectAddrRegImm(Addr, Base, Offset))

452 return false;

453

454 return selectAddrDefault(Addr, Base, Offset);

455}

456

457bool MipsSEDAGToDAGISel::selectIntAddrSImm10(SDValue Addr, SDValue &Base,

459

460 if (selectAddrFrameIndex(Addr, Base, Offset))

461 return true;

462

463 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10))

464 return true;

465

466 return selectAddrDefault(Addr, Base, Offset);

467}

468

469bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl1(SDValue Addr, SDValue &Base,

471 if (selectAddrFrameIndex(Addr, Base, Offset))

472 return true;

473

474 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 1))

475 return true;

476

477 return selectAddrDefault(Addr, Base, Offset);

478}

479

480bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl2(SDValue Addr, SDValue &Base,

482 if (selectAddrFrameIndex(Addr, Base, Offset))

483 return true;

484

485 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 2))

486 return true;

487

488 return selectAddrDefault(Addr, Base, Offset);

489}

490

491bool MipsSEDAGToDAGISel::selectIntAddrSImm10Lsl3(SDValue Addr, SDValue &Base,

493 if (selectAddrFrameIndex(Addr, Base, Offset))

494 return true;

495

496 if (selectAddrFrameIndexOffset(Addr, Base, Offset, 10, 3))

497 return true;

498

499 return selectAddrDefault(Addr, Base, Offset);

500}

501

502

503

504

505

506

507bool MipsSEDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm,

508 unsigned MinSizeInBits) const {

510 return false;

511

513

514 if (!Node)

515 return false;

516

517 APInt SplatValue, SplatUndef;

518 unsigned SplatBitSize;

519 bool HasAnyUndefs;

520

521 if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs,

522 MinSizeInBits, Subtarget->isLittle()))

523 return false;

524

525 Imm = SplatValue;

526

527 return true;

528}

529

530

531

532

533

534

535

536

537

538

539

540

541

542

543

544

545

546bool MipsSEDAGToDAGISel::

548 unsigned ImmBitSize) const {

549 APInt ImmValue;

550 EVT EltTy = N->getValueType(0).getVectorElementType();

551

552 if (N->getOpcode() == ISD::BITCAST)

553 N = N->getOperand(0);

554

555 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&

557

560 Imm = CurDAG->getTargetConstant(ImmValue, SDLoc(N), EltTy);

561 return true;

562 }

563 }

564

565 return false;

566}

567

568

569

570

571

572

573

574

575

576

577

578bool MipsSEDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {

579 APInt ImmValue;

581

582 if (N->getOpcode() == ISD::BITCAST)

583 N = N->getOperand(0);

584

585 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&

588

589 if (Log2 != -1) {

590 Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy);

591 return true;

592 }

593 }

594

595 return false;

596}

597

598

599

600

601

602

603

604

605

606

607

608

609bool MipsSEDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {

610 APInt ImmValue;

612

613 if (N->getOpcode() == ISD::BITCAST)

614 N = N->getOperand(0);

615

616 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&

618

619

621 Imm = CurDAG->getTargetConstant(ImmValue.popcount() - 1, SDLoc(N), EltTy);

622 return true;

623 }

624 }

625

626 return false;

627}

628

629

630

631

632

633

634

635

636

637

638

639

640bool MipsSEDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {

641 APInt ImmValue;

643

644 if (N->getOpcode() == ISD::BITCAST)

645 N = N->getOperand(0);

646

647 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&

649 if (ImmValue.isMask()) {

650 Imm = CurDAG->getTargetConstant(ImmValue.popcount() - 1, SDLoc(N), EltTy);

651 return true;

652 }

653 }

654

655 return false;

656}

657

658bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N,

660 APInt ImmValue;

662

663 if (N->getOpcode() == ISD::BITCAST)

664 N = N->getOperand(0);

665

666 if (selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&

668 int32_t Log2 = (~ImmValue).exactLogBase2();

669

670 if (Log2 != -1) {

671 Imm = CurDAG->getTargetConstant(Log2, SDLoc(N), EltTy);

672 return true;

673 }

674 }

675

676 return false;

677}

678

679

680bool MipsSEDAGToDAGISel::selectVSplatImmEq1(SDValue N) const {

681 APInt ImmValue;

683

684 if (N->getOpcode() == ISD::BITCAST)

685 N = N->getOperand(0);

686

687 return selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&

689}

690

691bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {

692 unsigned Opcode = Node->getOpcode();

693 SDLoc DL(Node);

694

695

696

697

698

699 switch(Opcode) {

700 default: break;

701

704 MVT VT = Subtarget->isGP64bit() ? MVT::i64 : MVT::i32;

710

711 SDValue ops[] = {cond, Hi1, Lo1, Hi2, Lo2};

712 EVT NodeTys[] = {VT, VT};

714 ? Mips::PseudoD_SELECT_I64

715 : Mips::PseudoD_SELECT_I,

716 DL, NodeTys, ops));

717 return true;

718 }

719

721 selectAddE(Node, DL);

722 return true;

723 }

724

727 if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {

730 Mips::ZERO_64, MVT::i64);

732 CurDAG->getMachineNode(Mips::DMTC1, DL, MVT::f64, Zero));

733 } else if (Subtarget->isFP64bit()) {

735 Mips::ZERO, MVT::i32);

737 MVT::f64, Zero, Zero));

738 } else {

740 Mips::ZERO, MVT::i32);

742 MVT::f64, Zero, Zero));

743 }

744 return true;

745 }

746 break;

747 }

748

751 int64_t Imm = CN->getSExtValue();

752 unsigned Size = CN->getValueSizeInBits(0);

753

755 break;

756

757 MipsAnalyzeImmediate AnalyzeImm;

758

761

763 SDLoc DL(CN);

764 SDNode *RegOpnd;

766 DL, MVT::i64);

767

768

769

770

771 if (Inst->Opc == Mips::LUi64)

772 RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd);

773 else

774 RegOpnd =

775 CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,

776 CurDAG->getRegister(Mips::ZERO_64, MVT::i64),

777 ImmOpnd);

778

779

780 for (++Inst; Inst != Seq.end(); ++Inst) {

782 MVT::i64);

783 RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,

784 SDValue(RegOpnd, 0), ImmOpnd);

785 }

786

788 return true;

789 }

790

792 const unsigned IntrinsicOpcode = Node->getConstantOperandVal(1);

793 switch (IntrinsicOpcode) {

794 default:

795 break;

796

797 case Intrinsic::mips_cfcmsa: {

801 getMSACtrlReg(RegIdx), MVT::i32);

803 return true;

804 }

805 case Intrinsic::mips_ldr_d:

806 case Intrinsic::mips_ldr_w: {

807 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_ldr_d) ? Mips::LDR_D

808 : Mips::LDR_W;

809

810 SDLoc DL(Node);

811 assert(Node->getNumOperands() == 4 && "Unexpected number of operands.");

812 const SDValue &Chain = Node->getOperand(0);

816

818 (void)Intrinsic;

821 "Invalid instruction operand.");

822

823

824 const ConstantInt *Val =

827 CurDAG->getTargetConstant(*Val, DL, Constant.getValueType());

828

830

832 assert(Node->getValueType(0).is128BitVector());

833 assert(Node->getValueType(1) == MVT::Other);

835

837

838 return true;

839 }

840 }

841 break;

842 }

843

845 switch (Node->getConstantOperandVal(0)) {

846 default:

847 break;

848

849 case Intrinsic::mips_move_v:

850

851

853 Node->getValueType(0),

854 Node->getOperand(1)));

855 return true;

856 }

857 break;

858 }

859

861 const unsigned IntrinsicOpcode = Node->getConstantOperandVal(1);

862 switch (IntrinsicOpcode) {

863 default:

864 break;

865

866 case Intrinsic::mips_ctcmsa: {

871 getMSACtrlReg(RegIdx), Value);

873 return true;

874 }

875 case Intrinsic::mips_str_d:

876 case Intrinsic::mips_str_w: {

877 unsigned Op = (IntrinsicOpcode == Intrinsic::mips_str_d) ? Mips::STR_D

878 : Mips::STR_W;

879

880 SDLoc DL(Node);

881 assert(Node->getNumOperands() == 5 && "Unexpected number of operands.");

882 const SDValue &Chain = Node->getOperand(0);

884 const SDValue &Vec = Node->getOperand(2);

887

889 (void)Intrinsic;

892 "Invalid instruction operand.");

893

894

895 const ConstantInt *Val =

898 CurDAG->getTargetConstant(*Val, DL, Constant.getValueType());

899

901

903 assert(Node->getValueType(0) == MVT::Other);

905

907 return true;

908 }

909 }

910 break;

911 }

912

914 MVT ResTy = Node->getSimpleValueType(0);

915 assert((ResTy == MVT::f64 || ResTy == MVT::f32) &&

916 "Unsupported float type!");

917 unsigned Opc = 0;

918 if (ResTy == MVT::f64)

919 Opc = (Subtarget->isFP64bit() ? Mips::FABS_D64 : Mips::FABS_D32);

920 else

921 Opc = Mips::FABS_S;

922

923 if (Subtarget->inMicroMipsMode()) {

924 switch (Opc) {

925 case Mips::FABS_D64:

926 Opc = Mips::FABS_D64_MM;

927 break;

928 case Mips::FABS_D32:

929 Opc = Mips::FABS_D32_MM;

930 break;

931 case Mips::FABS_S:

932 Opc = Mips::FABS_S_MM;

933 break;

934 default:

935 llvm_unreachable("Unknown opcode for MIPS floating point abs!");

936 }

937 }

938

940 CurDAG->getMachineNode(Opc, DL, ResTy, Node->getOperand(0)));

941

942 return true;

943 }

944

945

946

947

948

949

950

951 case MipsISD::Ins: {

952

953

954 if (Node->getValueType(0) != MVT::i32 && Node->getValueType(0) != MVT::i64)

955 return false;

956

957 if (Node->getNumOperands() != 4)

958 return false;

959

962 return false;

963

964 MVT ResTy = Node->getSimpleValueType(0);

965 uint64_t Pos = Node->getConstantOperandVal(1);

966 uint64_t Size = Node->getConstantOperandVal(2);

967

968

970 return false;

971

972 if (Pos + Size > 64)

973 return false;

974

975 if (ResTy != MVT::i32 && ResTy != MVT::i64)

976 return false;

977

978 unsigned Opcode = 0;

979 if (ResTy == MVT::i32) {

980 if (Pos + Size <= 32)

981 Opcode = Mips::INS;

982 } else {

983 if (Pos + Size <= 32)

984 Opcode = Mips::DINS;

985 else if (Pos < 32 && 1 < Size)

986 Opcode = Mips::DINSM;

987 else

988 Opcode = Mips::DINSU;

989 }

990

991 if (Opcode) {

993 Node->getOperand(0), CurDAG->getTargetConstant(Pos, DL, MVT::i32),

994 CurDAG->getTargetConstant(Size, DL, MVT::i32), Node->getOperand(3)};

995

997 return true;

998 }

999

1000 return false;

1001 }

1002

1003 case MipsISD::ThreadPointer: {

1005 unsigned RdhwrOpc, DestReg;

1006

1007 if (PtrVT == MVT::i32) {

1008 RdhwrOpc = Mips::RDHWR;

1009 DestReg = Mips::V1;

1010 } else {

1011 RdhwrOpc = Mips::RDHWR64;

1012 DestReg = Mips::V1_64;

1013 }

1014

1015 SDNode *Rdhwr =

1016 CurDAG->getMachineNode(RdhwrOpc, DL, Node->getValueType(0), MVT::Glue,

1017 CurDAG->getRegister(Mips::HWR29, MVT::i32),

1018 CurDAG->getTargetConstant(0, DL, MVT::i32));

1021 SDValue ResNode = CurDAG->getCopyFromReg(Chain, DL, DestReg, PtrVT,

1024 return true;

1025 }

1026

1028

1029

1030

1031

1032

1033

1034

1035

1036

1037

1038

1039

1040 const MipsABIInfo &ABI =

1041 static_cast<const MipsTargetMachine &>(TM).getABI();

1042

1044 APInt SplatValue, SplatUndef;

1045 unsigned SplatBitSize;

1046 bool HasAnyUndefs;

1047 unsigned LdiOp;

1049 EVT ViaVecTy;

1050

1052 return false;

1053

1054 if (!BVN->isConstantSplat(SplatValue, SplatUndef, SplatBitSize,

1055 HasAnyUndefs, 8,

1057 return false;

1058

1059 switch (SplatBitSize) {

1060 default:

1061 return false;

1062 case 8:

1063 LdiOp = Mips::LDI_B;

1064 ViaVecTy = MVT::v16i8;

1065 break;

1066 case 16:

1067 LdiOp = Mips::LDI_H;

1068 ViaVecTy = MVT::v8i16;

1069 break;

1070 case 32:

1071 LdiOp = Mips::LDI_W;

1072 ViaVecTy = MVT::v4i32;

1073 break;

1074 case 64:

1075 LdiOp = Mips::LDI_D;

1076 ViaVecTy = MVT::v2i64;

1077 break;

1078 }

1079

1080 SDNode *Res = nullptr;

1081

1082

1083

1084

1085

1089

1090 Res = CurDAG->getMachineNode(LdiOp, DL, ViaVecTy, Imm);

1092 ((ABI.IsO32() && SplatBitSize < 64) ||

1093 (ABI.IsN32() || ABI.IsN64()))) {

1094

1095

1096

1097

1098

1099 bool Is32BitSplat = ABI.IsO32() || SplatBitSize < 64;

1100 const unsigned ADDiuOp = Is32BitSplat ? Mips::ADDiu : Mips::DADDiu;

1101 const MVT SplatMVT = Is32BitSplat ? MVT::i32 : MVT::i64;

1103 Is32BitSplat ? Mips::ZERO : Mips::ZERO_64, SplatMVT);

1104

1105 const unsigned FILLOp =

1106 SplatBitSize == 16

1107 ? Mips::FILL_H

1108 : (SplatBitSize == 32 ? Mips::FILL_W

1109 : (SplatBitSize == 64 ? Mips::FILL_D : 0));

1110

1111 assert(FILLOp != 0 && "Unknown FILL Op for splat synthesis!");

1112 assert((ABI.IsO32() || (FILLOp != Mips::FILL_D)) &&

1113 "Attempting to use fill.d on MIPS32!");

1114

1117

1118 Res = CurDAG->getMachineNode(ADDiuOp, DL, SplatMVT, ZeroVal, LoVal);

1119 Res = CurDAG->getMachineNode(FILLOp, DL, ViaVecTy, SDValue(Res, 0));

1120

1121 } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 32) {

1122

1123

1126 SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32);

1127

1130

1131 if (Hi)

1132 Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal);

1133

1134 if (Lo)

1135 Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,

1136 Hi ? SDValue(Res, 0) : ZeroVal, LoVal);

1137

1138 assert((Hi || Lo) && "Zero case reached 32 bit case splat synthesis!");

1139 Res =

1140 CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32, SDValue(Res, 0));

1141

1142 } else if (SplatValue.isSignedIntN(32) && SplatBitSize == 64 &&

1143 (ABI.IsN32() || ABI.IsN64())) {

1144

1145

1146

1149 SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32);

1150

1153

1154 if (Hi)

1155 Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal);

1156

1157 if (Lo)

1158 Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,

1159 Hi ? SDValue(Res, 0) : ZeroVal, LoVal);

1160

1161 Res = CurDAG->getMachineNode(

1162 Mips::SUBREG_TO_REG, DL, MVT::i64,

1163 CurDAG->getTargetConstant(((Hi >> 15) & 0x1), DL, MVT::i64),

1165 CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64));

1166

1167 Res =

1168 CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64, SDValue(Res, 0));

1169

1171

1172

1173

1174

1175

1176

1177

1178

1179

1180

1181

1182

1183

1184

1185

1186

1187

1188

1189

1190

1191

1192

1193

1194

1195

1200

1203 SDValue HigherVal = CurDAG->getTargetConstant(Higher, DL, MVT::i32);

1204 SDValue HighestVal = CurDAG->getTargetConstant(Highest, DL, MVT::i32);

1205 SDValue ZeroVal = CurDAG->getRegister(Mips::ZERO, MVT::i32);

1206

1207

1208

1209

1210

1211

1212

1213

1214

1215

1216

1217

1218

1219

1220

1221

1222

1223 if (Hi)

1224 Res = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HiVal);

1225

1226 if (Lo)

1227 Res = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,

1228 Hi ? SDValue(Res, 0) : ZeroVal, LoVal);

1229

1230 SDNode *HiRes;

1231 if (Highest)

1232 HiRes = CurDAG->getMachineNode(Mips::LUi, DL, MVT::i32, HighestVal);

1233

1234 if (Higher)

1235 HiRes = CurDAG->getMachineNode(Mips::ORi, DL, MVT::i32,

1236 Highest ? SDValue(HiRes, 0) : ZeroVal,

1237 HigherVal);

1238

1239

1240 if (ABI.IsO32()) {

1241 Res = CurDAG->getMachineNode(Mips::FILL_W, DL, MVT::v4i32,

1242 (Hi || Lo) ? SDValue(Res, 0) : ZeroVal);

1243

1244 Res = CurDAG->getMachineNode(

1245 Mips::INSERT_W, DL, MVT::v4i32, SDValue(Res, 0),

1246 (Highest || Higher) ? SDValue(HiRes, 0) : ZeroVal,

1247 CurDAG->getTargetConstant(1, DL, MVT::i32));

1248

1250 const TargetRegisterClass *RC =

1252

1253 Res = CurDAG->getMachineNode(

1254 Mips::COPY_TO_REGCLASS, DL, ViaVecTy, SDValue(Res, 0),

1255 CurDAG->getTargetConstant(RC->getID(), DL, MVT::i32));

1256

1257 Res = CurDAG->getMachineNode(

1258 Mips::SPLATI_D, DL, MVT::v2i64, SDValue(Res, 0),

1259 CurDAG->getTargetConstant(0, DL, MVT::i32));

1260 } else if (ABI.IsN64() || ABI.IsN32()) {

1261

1262 SDValue Zero64Val = CurDAG->getRegister(Mips::ZERO_64, MVT::i64);

1263 const bool HiResNonZero = Highest || Higher;

1264 const bool ResNonZero = Hi || Lo;

1265

1266 if (HiResNonZero)

1267 HiRes = CurDAG->getMachineNode(

1268 Mips::SUBREG_TO_REG, DL, MVT::i64,

1269 CurDAG->getTargetConstant(((Highest >> 15) & 0x1), DL, MVT::i64),

1271 CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64));

1272

1273 if (ResNonZero)

1274 Res = CurDAG->getMachineNode(

1275 Mips::SUBREG_TO_REG, DL, MVT::i64,

1276 CurDAG->getTargetConstant(((Hi >> 15) & 0x1), DL, MVT::i64),

1278 CurDAG->getTargetConstant(Mips::sub_32, DL, MVT::i64));

1279

1280

1281

1282

1283

1284

1285

1286

1287 if (ResNonZero) {

1290 const ConstantInt *Const32 = ConstantInt::get(Int32Ty, 32);

1295

1296 Res = CurDAG->getMachineNode(Mips::DINSU, DL, MVT::i64, Ops);

1297 } else if (HiResNonZero) {

1298 Res = CurDAG->getMachineNode(

1299 Mips::DSLL32, DL, MVT::i64, SDValue(HiRes, 0),

1300 CurDAG->getTargetConstant(0, DL, MVT::i32));

1301 } else

1303 "Zero splat value handled by non-zero 64bit splat synthesis!");

1304

1305 Res = CurDAG->getMachineNode(Mips::FILL_D, DL, MVT::v2i64,

1307 } else

1309

1310 } else

1311 return false;

1312

1313 if (ResVecTy != ViaVecTy) {

1314

1315

1316

1317

1319 MVT ResVecTySimple = ResVecTy.getSimpleVT();

1320 const TargetRegisterClass *RC = TLI->getRegClassFor(ResVecTySimple);

1321 Res = CurDAG->getMachineNode(Mips::COPY_TO_REGCLASS, DL,

1322 ResVecTy, SDValue(Res, 0),

1324 MVT::i32));

1325 }

1326

1328 return true;

1329 }

1330

1331 }

1332

1333 return false;

1334}

1335

1336bool MipsSEDAGToDAGISel::SelectInlineAsmMemoryOperand(

1338 std::vector &OutOps) {

1340

1341 switch(ConstraintID) {

1342 default:

1344

1348 OutOps.push_back(Base);

1349 OutOps.push_back(Offset);

1350 return false;

1351 }

1352 OutOps.push_back(Op);

1353 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));

1354 return false;

1356

1357

1358

1359

1360

1362 OutOps.push_back(Base);

1363 OutOps.push_back(Offset);

1364 return false;

1365 }

1366 OutOps.push_back(Op);

1367 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));

1368 return false;

1370

1371

1372 if (Subtarget->inMicroMipsMode()) {

1373

1375 OutOps.push_back(Base);

1376 OutOps.push_back(Offset);

1377 return false;

1378 }

1379 } else if (Subtarget->hasMips32r6()) {

1380

1382 OutOps.push_back(Base);

1383 OutOps.push_back(Offset);

1384 return false;

1385 }

1386 } else if (selectAddrRegImm16(Op, Base, Offset)) {

1387

1388 OutOps.push_back(Base);

1389 OutOps.push_back(Offset);

1390 return false;

1391 }

1392

1393 OutOps.push_back(Op);

1394 OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));

1395 return false;

1396 }

1397 return true;

1398}

1399

1403

unsigned const MachineRegisterInfo * MRI

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

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static uint64_t getConstant(const Value *IndexValue)

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

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

Class for arbitrary precision integers.

LLVM_ABI APInt getLoBits(unsigned numBits) const

Compute an APInt containing numBits lowbits from this APInt.

uint64_t getZExtValue() const

Get zero extended value.

unsigned popcount() const

Count the number of bits set.

unsigned getBitWidth() const

Return the number of bits in the APInt.

bool isNegative() const

Determine sign of this APInt.

int32_t exactLogBase2() const

bool isSignedIntN(unsigned N) const

Check if this APInt has an N-bits signed integer value.

bool isShiftedMask() const

Return true if this APInt value contains a non-empty sequence of ones with the remainder zero.

bool isMask(unsigned numBits) const

bool isIntN(unsigned N) const

Check if this APInt has an N-bits unsigned integer value.

APInt lshr(unsigned shiftAmt) const

Logical right-shift function.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const

Check if this is a constant splat, and if so, find the smallest element size that splats the vector.

Legacy analysis pass which computes a DominatorTree.

FunctionPass class - This class is used to implement most global optimizations.

static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)

This static method is the primary way of constructing an IntegerType.

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

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

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.

LLVM_ABI void setReg(Register Reg)

Change the register this operand corresponds to.

MachineInstr * getParent()

getParent - Return the instruction that this operand belongs to.

Register getReg() const

getReg - Returns the register number.

static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

defusechain_iterator< true, false, false, true, false > use_iterator

use_iterator/use_begin/use_end - Walk all uses of the specified register.

MipsDAGToDAGISelLegacy(std::unique_ptr< SelectionDAGISel > S)

bool runOnMachineFunction(MachineFunction &MF) override

const MipsSubtarget * Subtarget

Keep a pointer to the MipsSubtarget around so that we can make the right decision when generating cod...

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

Definition MipsSEISelDAGToDAG.cpp:42

MipsSEDAGToDAGISelLegacy(MipsTargetMachine &TM, CodeGenOptLevel OL)

Definition MipsSEISelDAGToDAG.cpp:1400

bool inMips16Mode() const

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

Represents one node in the SelectionDAG.

uint64_t getAsZExtVal() const

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

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

SDValue getValue(unsigned R) const

EVT getValueType() const

Return the ValueType of the referenced return value.

const SDValue & getOperand(unsigned i) const

unsigned getOpcode() const

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

const TargetLowering * TLI

const TargetInstrInfo * TII

void ReplaceNode(SDNode *F, SDNode *T)

Replace all uses of F with T, then remove F from the DAG.

const TargetLowering * getTargetLowering() const

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

unsigned getID() const

Return the register class ID number.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

@ ADDC

Carry-setting nodes for multiple precision addition and subtraction.

@ ADD

Simple integer binary arithmetic operators.

@ INTRINSIC_VOID

OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...

@ TargetGlobalAddress

TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...

@ TargetConstant

TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...

@ INTRINSIC_WO_CHAIN

RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...

@ ADDE

Carry-using nodes for multiple precision addition and subtraction.

@ INTRINSIC_W_CHAIN

RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...

@ BUILD_VECTOR

BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...

@ Implicit

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

@ Undef

Value of the register doesn't matter.

NodeAddr< NodeBase * > Node

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.

FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty

bool isAligned(Align Lhs, uint64_t SizeInBytes)

Checks that SizeInBytes is a multiple of the alignment.

FunctionPass * createMipsSEISelDag(MipsTargetMachine &TM, CodeGenOptLevel OptLevel)

Definition MipsSEISelDAGToDAG.cpp:1404

CodeGenOptLevel

Code generation optimization level.

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

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

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

constexpr bool isIntN(unsigned N, int64_t x)

Checks if an signed integer fits into the given (dynamic) bit width.

constexpr int64_t SignExtend64(uint64_t x)

Sign-extend the number in the bottom B bits of X to a 64-bit integer.

unsigned Log2(Align A)

Returns the log2 of the alignment.

Implement std::hash so that hash_code can be used in STL containers.

TypeSize getSizeInBits() const

Return the size of the specified value type in bits.

MVT getSimpleVT() const

Return the SimpleValueType held in the specified simple EVT.

bool is128BitVector() const

Return true if this is a 128-bit vector type.

EVT getVectorElementType() const

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