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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

67#include

68#include

69#include

70#include

71

72#define DEBUG_TYPE "mips-fastisel"

73

74using namespace llvm;

75

77

78namespace {

79

80class MipsFastISel final : public FastISel {

81

82

83 class Address {

84 public:

85 enum BaseKind { RegBase, FrameIndexBase };

86

87 private:

88 BaseKind Kind = RegBase;

89 union {

90 unsigned Reg;

91 int FI;

93

95

97

98 public:

99

101

102 void setKind(BaseKind K) { Kind = K; }

103 BaseKind getKind() const { return Kind; }

104 bool isRegBase() const { return Kind == RegBase; }

105 bool isFIBase() const { return Kind == FrameIndexBase; }

106

107 void setReg(unsigned Reg) {

108 assert(isRegBase() && "Invalid base register access!");

110 }

111

112 unsigned getReg() const {

113 assert(isRegBase() && "Invalid base register access!");

114 return Base.Reg;

115 }

116

117 void setFI(unsigned FI) {

118 assert(isFIBase() && "Invalid base frame index access!");

119 Base.FI = FI;

120 }

121

122 unsigned getFI() const {

123 assert(isFIBase() && "Invalid base frame index access!");

124 return Base.FI;

125 }

126

127 void setOffset(int64_t Offset_) { Offset = Offset_; }

129 void setGlobalValue(const GlobalValue *G) { GV = G; }

130 const GlobalValue *getGlobalValue() { return GV; }

131 };

132

133

134

140

141

143

144 bool fastLowerArguments() override;

145 bool fastLowerCall(CallLoweringInfo &CLI) override;

146 bool fastLowerIntrinsicCall(const IntrinsicInst *II) override;

147

148 bool UnsupportedFPMode;

149

150

151

152private:

153

162 bool selectFPToInt(const Instruction *I, bool IsSigned);

167 bool selectDivRem(const Instruction *I, unsigned ISDOpcode);

168

169

170 bool isTypeLegal(Type *Ty, MVT &VT);

171 bool isTypeSupported(Type *Ty, MVT &VT);

172 bool isLoadTypeLegal(Type *Ty, MVT &VT);

173 bool computeAddress(const Value *Obj, Address &Addr);

174 bool computeCallAddress(const Value *V, Address &Addr);

175 void simplifyAddress(Address &Addr);

176

177

179 bool emitLoad(MVT VT, unsigned &ResultReg, Address &Addr);

180 bool emitStore(MVT VT, unsigned SrcReg, Address &Addr);

181 unsigned emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, bool isZExt);

182 bool emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg,

183

184 bool IsZExt);

185 bool emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);

186

187 bool emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);

188 bool emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,

189 unsigned DestReg);

190 bool emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,

191 unsigned DestReg);

192

193 unsigned getRegEnsuringSimpleIntegerWidening(const Value *, bool IsUnsigned);

194

195 unsigned emitLogicalOp(unsigned ISDOpc, MVT RetVT, const Value *LHS,

197

198 unsigned materializeFP(const ConstantFP *CFP, MVT VT);

199 unsigned materializeGV(const GlobalValue *GV, MVT VT);

200 unsigned materializeInt(const Constant *C, MVT VT);

201 unsigned materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);

202 unsigned materializeExternalCallSym(MCSymbol *Syn);

203

205 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc));

206 }

207

209 return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),

210 DstReg);

211 }

212

214 unsigned MemReg, int64_t MemOffset) {

216 }

217

219 unsigned MemReg, int64_t MemOffset) {

220 return emitInst(Opc, DstReg).addReg(MemReg).addImm(MemOffset);

221 }

222

223 unsigned fastEmitInst_rr(unsigned MachineInstOpcode,

225 unsigned Op0, unsigned Op1);

226

227

228

231 unsigned Op3) {

232 return 0;

233 }

234

235

236private:

239 unsigned &NumBytes);

240 bool finishCall(CallLoweringInfo &CLI, MVT RetVT, unsigned NumBytes);

241

244 }

245

246public:

247

256 }

257

260 bool fastSelectInstruction(const Instruction *I) override;

261

262#include "MipsGenFastISel.inc"

263};

264

265}

266

267[[maybe_unused]] static bool CC_Mips(unsigned ValNo, MVT ValVT, MVT LocVT,

271

278

285

286#include "MipsGenCallingConv.inc"

287

290}

291

292unsigned MipsFastISel::emitLogicalOp(unsigned ISDOpc, MVT RetVT,

294

297

298 unsigned Opc;

299 switch (ISDOpc) {

301 Opc = Mips::AND;

302 break;

304 Opc = Mips::OR;

305 break;

307 Opc = Mips::XOR;

308 break;

309 default:

311 }

312

314 if (!LHSReg)

315 return 0;

316

317 unsigned RHSReg;

319 RHSReg = materializeInt(C, MVT::i32);

320 else

321 RHSReg = getRegForValue(RHS);

322 if (!RHSReg)

323 return 0;

324

325 Register ResultReg = createResultReg(&Mips::GPR32RegClass);

326 if (!ResultReg)

327 return 0;

328

329 emitInst(Opc, ResultReg).addReg(LHSReg).addReg(RHSReg);

330 return ResultReg;

331}

332

333Register MipsFastISel::fastMaterializeAlloca(const AllocaInst *AI) {

335 "Alloca should always return a pointer.");

336

337 DenseMap<const AllocaInst *, int>::iterator SI =

338 FuncInfo.StaticAllocaMap.find(AI);

339

340 if (SI != FuncInfo.StaticAllocaMap.end()) {

341 Register ResultReg = createResultReg(&Mips::GPR32RegClass);

342 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::LEA_ADDiu),

343 ResultReg)

346 return ResultReg;

347 }

348

350}

351

352unsigned MipsFastISel::materializeInt(const Constant *C, MVT VT) {

353 if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1)

354 return 0;

355 const TargetRegisterClass *RC = &Mips::GPR32RegClass;

357 return materialize32BitInt(CI->getZExtValue(), RC);

358}

359

360unsigned MipsFastISel::materialize32BitInt(int64_t Imm,

361 const TargetRegisterClass *RC) {

362 Register ResultReg = createResultReg(RC);

363

365 unsigned Opc = Mips::ADDiu;

366 emitInst(Opc, ResultReg).addReg(Mips::ZERO).addImm(Imm);

367 return ResultReg;

369 emitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm);

370 return ResultReg;

371 }

372 unsigned Lo = Imm & 0xFFFF;

373 unsigned Hi = (Imm >> 16) & 0xFFFF;

374 if (Lo) {

375

376 Register TmpReg = createResultReg(RC);

377 emitInst(Mips::LUi, TmpReg).addImm(Hi);

378 emitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo);

379 } else {

380 emitInst(Mips::LUi, ResultReg).addImm(Hi);

381 }

382 return ResultReg;

383}

384

385unsigned MipsFastISel::materializeFP(const ConstantFP *CFP, MVT VT) {

386 if (UnsupportedFPMode)

387 return 0;

389 if (VT == MVT::f32) {

390 const TargetRegisterClass *RC = &Mips::FGR32RegClass;

391 Register DestReg = createResultReg(RC);

392 unsigned TempReg = materialize32BitInt(Imm, &Mips::GPR32RegClass);

393 emitInst(Mips::MTC1, DestReg).addReg(TempReg);

394 return DestReg;

395 } else if (VT == MVT::f64) {

396 const TargetRegisterClass *RC = &Mips::AFGR64RegClass;

397 Register DestReg = createResultReg(RC);

398 unsigned TempReg1 = materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass);

399 unsigned TempReg2 =

400 materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass);

401 emitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1);

402 return DestReg;

403 }

404 return 0;

405}

406

407unsigned MipsFastISel::materializeGV(const GlobalValue *GV, MVT VT) {

408

409 if (VT != MVT::i32)

410 return 0;

411 const TargetRegisterClass *RC = &Mips::GPR32RegClass;

412 Register DestReg = createResultReg(RC);

414 bool IsThreadLocal = GVar && GVar->isThreadLocal();

415

416 if (IsThreadLocal)

417 return 0;

418 emitInst(Mips::LW, DestReg)

423 Register TempReg = createResultReg(RC);

424 emitInst(Mips::ADDiu, TempReg)

425 .addReg(DestReg)

427 DestReg = TempReg;

428 }

429 return DestReg;

430}

431

432unsigned MipsFastISel::materializeExternalCallSym(MCSymbol *Sym) {

433 const TargetRegisterClass *RC = &Mips::GPR32RegClass;

434 Register DestReg = createResultReg(RC);

435 emitInst(Mips::LW, DestReg)

438 return DestReg;

439}

440

441

442

443Register MipsFastISel::fastMaterializeConstant(const Constant *C) {

445

446

450

452 return (UnsupportedFPMode) ? 0 : materializeFP(CFP, VT);

454 return materializeGV(GV, VT);

456 return materializeInt(C, VT);

457

459}

460

461bool MipsFastISel::computeAddress(const Value *Obj, Address &Addr) {

462 const User *U = nullptr;

463 unsigned Opcode = Instruction::UserOp1;

465

466

467 if (FuncInfo.StaticAllocaMap.count(static_cast<const AllocaInst *>(Obj)) ||

468 FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB) {

469 Opcode = I->getOpcode();

470 U = I;

471 }

473 Opcode = C->getOpcode();

474 U = C;

475 }

476 switch (Opcode) {

477 default:

478 break;

479 case Instruction::BitCast:

480

481 return computeAddress(U->getOperand(0), Addr);

482 case Instruction::GetElementPtr: {

483 Address SavedAddr = Addr;

484 int64_t TmpOffset = Addr.getOffset();

485

486

489 ++i, ++GTI) {

492 const StructLayout *SL = DL.getStructLayout(STy);

495 } else {

497 while (true) {

499

500 TmpOffset += CI->getSExtValue() * S;

501 break;

502 }

503 if (canFoldAddIntoGEP(U, Op)) {

504

505 ConstantInt *CI =

508

510 continue;

511 }

512

513 goto unsupported_gep;

514 }

515 }

516 }

517

518 Addr.setOffset(TmpOffset);

519 if (computeAddress(U->getOperand(0), Addr))

520 return true;

521

522 Addr = SavedAddr;

523 unsupported_gep:

524 break;

525 }

526 case Instruction::Alloca: {

528 DenseMap<const AllocaInst *, int>::iterator SI =

529 FuncInfo.StaticAllocaMap.find(AI);

530 if (SI != FuncInfo.StaticAllocaMap.end()) {

531 Addr.setKind(Address::FrameIndexBase);

532 Addr.setFI(SI->second);

533 return true;

534 }

535 break;

536 }

537 }

538 Addr.setReg(getRegForValue(Obj));

539 return Addr.getReg() != 0;

540}

541

542bool MipsFastISel::computeCallAddress(const Value *V, Address &Addr) {

543 const User *U = nullptr;

544 unsigned Opcode = Instruction::UserOp1;

545

547

548

549 if (I->getParent() == FuncInfo.MBB->getBasicBlock()) {

550 Opcode = I->getOpcode();

551 U = I;

552 }

554 Opcode = C->getOpcode();

555 U = C;

556 }

557

558 switch (Opcode) {

559 default:

560 break;

561 case Instruction::BitCast:

562

563 return computeCallAddress(U->getOperand(0), Addr);

564 break;

565 case Instruction::IntToPtr:

566

569 return computeCallAddress(U->getOperand(0), Addr);

570 break;

571 case Instruction::PtrToInt:

572

574 return computeCallAddress(U->getOperand(0), Addr);

575 break;

576 }

577

579 Addr.setGlobalValue(GV);

580 return true;

581 }

582

583

584 if (!Addr.getGlobalValue()) {

585 Addr.setReg(getRegForValue(V));

586 return Addr.getReg() != 0;

587 }

588

589 return false;

590}

591

592bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) {

594

595 if (evt == MVT::Other || !evt.isSimple())

596 return false;

598

599

600

602}

603

604bool MipsFastISel::isTypeSupported(Type *Ty, MVT &VT) {

606 return false;

607

608 if (isTypeLegal(Ty, VT))

609 return true;

610

611

612

613 if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)

614 return true;

615

616 return false;

617}

618

619bool MipsFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {

620 if (isTypeLegal(Ty, VT))

621 return true;

622

623

624

625 if (VT == MVT::i8 || VT == MVT::i16)

626 return true;

627 return false;

628}

629

630

631

632

633

634bool MipsFastISel::emitCmp(unsigned ResultReg, const CmpInst *CI) {

637 unsigned LeftReg = getRegEnsuringSimpleIntegerWidening(Left, IsUnsigned);

638 if (LeftReg == 0)

639 return false;

640 unsigned RightReg = getRegEnsuringSimpleIntegerWidening(Right, IsUnsigned);

641 if (RightReg == 0)

642 return false;

644

645 switch (P) {

646 default:

647 return false;

649 Register TempReg = createResultReg(&Mips::GPR32RegClass);

650 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);

651 emitInst(Mips::SLTiu, ResultReg).addReg(TempReg).addImm(1);

652 break;

653 }

655 Register TempReg = createResultReg(&Mips::GPR32RegClass);

656 emitInst(Mips::XOR, TempReg).addReg(LeftReg).addReg(RightReg);

657 emitInst(Mips::SLTu, ResultReg).addReg(Mips::ZERO).addReg(TempReg);

658 break;

659 }

661 emitInst(Mips::SLTu, ResultReg).addReg(RightReg).addReg(LeftReg);

662 break;

664 emitInst(Mips::SLTu, ResultReg).addReg(LeftReg).addReg(RightReg);

665 break;

667 Register TempReg = createResultReg(&Mips::GPR32RegClass);

668 emitInst(Mips::SLTu, TempReg).addReg(LeftReg).addReg(RightReg);

669 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);

670 break;

671 }

673 Register TempReg = createResultReg(&Mips::GPR32RegClass);

674 emitInst(Mips::SLTu, TempReg).addReg(RightReg).addReg(LeftReg);

675 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);

676 break;

677 }

679 emitInst(Mips::SLT, ResultReg).addReg(RightReg).addReg(LeftReg);

680 break;

682 emitInst(Mips::SLT, ResultReg).addReg(LeftReg).addReg(RightReg);

683 break;

685 Register TempReg = createResultReg(&Mips::GPR32RegClass);

686 emitInst(Mips::SLT, TempReg).addReg(LeftReg).addReg(RightReg);

687 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);

688 break;

689 }

691 Register TempReg = createResultReg(&Mips::GPR32RegClass);

692 emitInst(Mips::SLT, TempReg).addReg(RightReg).addReg(LeftReg);

693 emitInst(Mips::XORi, ResultReg).addReg(TempReg).addImm(1);

694 break;

695 }

702 if (UnsupportedFPMode)

703 return false;

704 bool IsFloat = Left->getType()->isFloatTy();

705 bool IsDouble = Left->getType()->isDoubleTy();

706 if (!IsFloat && !IsDouble)

707 return false;

708 unsigned Opc, CondMovOpc;

709 switch (P) {

711 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;

712 CondMovOpc = Mips::MOVT_I;

713 break;

715 Opc = IsFloat ? Mips::C_EQ_S : Mips::C_EQ_D32;

716 CondMovOpc = Mips::MOVF_I;

717 break;

719 Opc = IsFloat ? Mips::C_OLT_S : Mips::C_OLT_D32;

720 CondMovOpc = Mips::MOVT_I;

721 break;

723 Opc = IsFloat ? Mips::C_OLE_S : Mips::C_OLE_D32;

724 CondMovOpc = Mips::MOVT_I;

725 break;

727 Opc = IsFloat ? Mips::C_ULE_S : Mips::C_ULE_D32;

728 CondMovOpc = Mips::MOVF_I;

729 break;

731 Opc = IsFloat ? Mips::C_ULT_S : Mips::C_ULT_D32;

732 CondMovOpc = Mips::MOVF_I;

733 break;

734 default:

736 }

737 Register RegWithZero = createResultReg(&Mips::GPR32RegClass);

738 Register RegWithOne = createResultReg(&Mips::GPR32RegClass);

739 emitInst(Mips::ADDiu, RegWithZero).addReg(Mips::ZERO).addImm(0);

740 emitInst(Mips::ADDiu, RegWithOne).addReg(Mips::ZERO).addImm(1);

742 .addReg(RightReg);

743 emitInst(CondMovOpc, ResultReg)

744 .addReg(RegWithOne)

745 .addReg(Mips::FCC0)

746 .addReg(RegWithZero);

747 break;

748 }

749 }

750 return true;

751}

752

753bool MipsFastISel::emitLoad(MVT VT, unsigned &ResultReg, Address &Addr) {

754

755

756

757 unsigned Opc;

759 case MVT::i32:

760 ResultReg = createResultReg(&Mips::GPR32RegClass);

761 Opc = Mips::LW;

762 break;

763 case MVT::i16:

764 ResultReg = createResultReg(&Mips::GPR32RegClass);

765 Opc = Mips::LHu;

766 break;

767 case MVT::i8:

768 ResultReg = createResultReg(&Mips::GPR32RegClass);

769 Opc = Mips::LBu;

770 break;

771 case MVT::f32:

772 if (UnsupportedFPMode)

773 return false;

774 ResultReg = createResultReg(&Mips::FGR32RegClass);

775 Opc = Mips::LWC1;

776 break;

777 case MVT::f64:

778 if (UnsupportedFPMode)

779 return false;

780 ResultReg = createResultReg(&Mips::AFGR64RegClass);

781 Opc = Mips::LDC1;

782 break;

783 default:

784 return false;

785 }

786 if (Addr.isRegBase()) {

787 simplifyAddress(Addr);

788 emitInstLoad(Opc, ResultReg, Addr.getReg(), Addr.getOffset());

789 return true;

790 }

791 if (Addr.isFIBase()) {

792 unsigned FI = Addr.getFI();

793 int64_t Offset = Addr.getOffset();

794 MachineFrameInfo &MFI = MF->getFrameInfo();

795 MachineMemOperand *MMO = MF->getMachineMemOperand(

798 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc), ResultReg)

802 return true;

803 }

804 return false;

805}

806

807bool MipsFastISel::emitStore(MVT VT, unsigned SrcReg, Address &Addr) {

808

809

810

811 unsigned Opc;

813 case MVT::i8:

814 Opc = Mips::SB;

815 break;

816 case MVT::i16:

817 Opc = Mips::SH;

818 break;

819 case MVT::i32:

820 Opc = Mips::SW;

821 break;

822 case MVT::f32:

823 if (UnsupportedFPMode)

824 return false;

825 Opc = Mips::SWC1;

826 break;

827 case MVT::f64:

828 if (UnsupportedFPMode)

829 return false;

830 Opc = Mips::SDC1;

831 break;

832 default:

833 return false;

834 }

835 if (Addr.isRegBase()) {

836 simplifyAddress(Addr);

837 emitInstStore(Opc, SrcReg, Addr.getReg(), Addr.getOffset());

838 return true;

839 }

840 if (Addr.isFIBase()) {

841 unsigned FI = Addr.getFI();

842 int64_t Offset = Addr.getOffset();

843 MachineFrameInfo &MFI = MF->getFrameInfo();

844 MachineMemOperand *MMO = MF->getMachineMemOperand(

847 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))

852 return true;

853 }

854 return false;

855}

856

857bool MipsFastISel::selectLogicalOp(const Instruction *I) {

858 MVT VT;

859 if (!isTypeSupported(I->getType(), VT))

860 return false;

861

862 unsigned ResultReg;

863 switch (I->getOpcode()) {

864 default:

866 case Instruction::And:

867 ResultReg = emitLogicalOp(ISD::AND, VT, I->getOperand(0), I->getOperand(1));

868 break;

869 case Instruction::Or:

870 ResultReg = emitLogicalOp(ISD::OR, VT, I->getOperand(0), I->getOperand(1));

871 break;

872 case Instruction::Xor:

873 ResultReg = emitLogicalOp(ISD::XOR, VT, I->getOperand(0), I->getOperand(1));

874 break;

875 }

876

877 if (!ResultReg)

878 return false;

879

880 updateValueMap(I, ResultReg);

881 return true;

882}

883

884bool MipsFastISel::selectLoad(const Instruction *I) {

886

887

889 return false;

890

891

892 MVT VT;

893 if (!isLoadTypeLegal(LI->getType(), VT))

894 return false;

895

896

899 return false;

900

901

903 if (!computeAddress(LI->getOperand(0), Addr))

904 return false;

905

906 unsigned ResultReg;

907 if (emitLoad(VT, ResultReg, Addr))

908 return false;

909 updateValueMap(LI, ResultReg);

910 return true;

911}

912

913bool MipsFastISel::selectStore(const Instruction *I) {

915

916 Value *Op0 = SI->getOperand(0);

917 unsigned SrcReg = 0;

918

919

920 if (SI->isAtomic())

921 return false;

922

923

924 MVT VT;

925 if (!isLoadTypeLegal(SI->getOperand(0)->getType(), VT))

926 return false;

927

928

931 return false;

932

933

934 SrcReg = getRegForValue(Op0);

935 if (SrcReg == 0)

936 return false;

937

938

940 if (!computeAddress(SI->getOperand(1), Addr))

941 return false;

942

943 if (emitStore(VT, SrcReg, Addr))

944 return false;

945 return true;

946}

947

948

949

950bool MipsFastISel::selectBranch(const Instruction *I) {

952 MachineBasicBlock *BrBB = FuncInfo.MBB;

953

954

955

956

957

958

959

960 MachineBasicBlock *TBB = FuncInfo.getMBB(BI->getSuccessor(0));

961 MachineBasicBlock *FBB = FuncInfo.getMBB(BI->getSuccessor(1));

962

963

964

965 unsigned ZExtCondReg = 0;

968 ZExtCondReg = createResultReg(&Mips::GPR32RegClass);

969 if (emitCmp(ZExtCondReg, CI))

970 return false;

971 }

972 }

973

974

975 if (ZExtCondReg == 0) {

977 if (CondReg == 0)

978 return false;

979

980 ZExtCondReg = emitIntExt(MVT::i1, CondReg, MVT::i32, true);

981 if (ZExtCondReg == 0)

982 return false;

983 }

984

985 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::BGTZ))

989 return true;

990}

991

992bool MipsFastISel::selectCmp(const Instruction *I) {

994 Register ResultReg = createResultReg(&Mips::GPR32RegClass);

995 if (emitCmp(ResultReg, CI))

996 return false;

997 updateValueMap(I, ResultReg);

998 return true;

999}

1000

1001

1002bool MipsFastISel::selectFPExt(const Instruction *I) {

1003 if (UnsupportedFPMode)

1004 return false;

1005 Value *Src = I->getOperand(0);

1006 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);

1008

1009 if (SrcVT != MVT::f32 || DestVT != MVT::f64)

1010 return false;

1011

1013 getRegForValue(Src);

1014

1015 if (!SrcReg)

1016 return false;

1017

1018 Register DestReg = createResultReg(&Mips::AFGR64RegClass);

1019 emitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);

1020 updateValueMap(I, DestReg);

1021 return true;

1022}

1023

1024bool MipsFastISel::selectSelect(const Instruction *I) {

1026

1028

1029 MVT VT;

1030 if (!isTypeSupported(I->getType(), VT) || UnsupportedFPMode) {

1032 dbgs() << ".. .. gave up (!isTypeSupported || UnsupportedFPMode)\n");

1033 return false;

1034 }

1035

1036 unsigned CondMovOpc;

1037 const TargetRegisterClass *RC;

1038

1040 CondMovOpc = Mips::MOVN_I_I;

1041 RC = &Mips::GPR32RegClass;

1042 } else if (VT == MVT::f32) {

1043 CondMovOpc = Mips::MOVN_I_S;

1044 RC = &Mips::FGR32RegClass;

1045 } else if (VT == MVT::f64) {

1046 CondMovOpc = Mips::MOVN_I_D32;

1047 RC = &Mips::AFGR64RegClass;

1048 } else

1049 return false;

1050

1053 Register Src1Reg = getRegForValue(SI->getTrueValue());

1054 Register Src2Reg = getRegForValue(SI->getFalseValue());

1056

1057 if (!Src1Reg || !Src2Reg || !CondReg)

1058 return false;

1059

1060 Register ZExtCondReg = createResultReg(&Mips::GPR32RegClass);

1061 if (!ZExtCondReg)

1062 return false;

1063

1064 if (!emitIntExt(MVT::i1, CondReg, MVT::i32, ZExtCondReg, true))

1065 return false;

1066

1067 Register ResultReg = createResultReg(RC);

1068 Register TempReg = createResultReg(RC);

1069

1070 if (!ResultReg || !TempReg)

1071 return false;

1072

1073 emitInst(TargetOpcode::COPY, TempReg).addReg(Src2Reg);

1074 emitInst(CondMovOpc, ResultReg)

1075 .addReg(Src1Reg).addReg(ZExtCondReg).addReg(TempReg);

1076 updateValueMap(I, ResultReg);

1077 return true;

1078}

1079

1080

1081bool MipsFastISel::selectFPTrunc(const Instruction *I) {

1082 if (UnsupportedFPMode)

1083 return false;

1084 Value *Src = I->getOperand(0);

1085 EVT SrcVT = TLI.getValueType(DL, Src->getType(), true);

1087

1088 if (SrcVT != MVT::f64 || DestVT != MVT::f32)

1089 return false;

1090

1091 Register SrcReg = getRegForValue(Src);

1092 if (!SrcReg)

1093 return false;

1094

1095 Register DestReg = createResultReg(&Mips::FGR32RegClass);

1096 if (!DestReg)

1097 return false;

1098

1099 emitInst(Mips::CVT_S_D32, DestReg).addReg(SrcReg);

1100 updateValueMap(I, DestReg);

1101 return true;

1102}

1103

1104

1105bool MipsFastISel::selectFPToInt(const Instruction *I, bool IsSigned) {

1106 if (UnsupportedFPMode)

1107 return false;

1108 MVT DstVT, SrcVT;

1109 if (!IsSigned)

1110 return false;

1111

1112 Type *DstTy = I->getType();

1113 if (!isTypeLegal(DstTy, DstVT))

1114 return false;

1115

1116 if (DstVT != MVT::i32)

1117 return false;

1118

1119 Value *Src = I->getOperand(0);

1120 Type *SrcTy = Src->getType();

1121 if (!isTypeLegal(SrcTy, SrcVT))

1122 return false;

1123

1124 if (SrcVT != MVT::f32 && SrcVT != MVT::f64)

1125 return false;

1126

1127 Register SrcReg = getRegForValue(Src);

1128 if (SrcReg == 0)

1129 return false;

1130

1131

1132

1133 Register DestReg = createResultReg(&Mips::GPR32RegClass);

1134 Register TempReg = createResultReg(&Mips::FGR32RegClass);

1135 unsigned Opc = (SrcVT == MVT::f32) ? Mips::TRUNC_W_S : Mips::TRUNC_W_D32;

1136

1137

1138 emitInst(Opc, TempReg).addReg(SrcReg);

1139 emitInst(Mips::MFC1, DestReg).addReg(TempReg);

1140

1141 updateValueMap(I, DestReg);

1142 return true;

1143}

1144

1145bool MipsFastISel::processCallArgs(CallLoweringInfo &CLI,

1146 SmallVectorImpl &OutVTs,

1147 unsigned &NumBytes) {

1148 CallingConv::ID CC = CLI.CallConv;

1151 for (const ArgListEntry &Arg : CLI.Args)

1152 ArgTys.push_back(Arg.Val->getType());

1153 CCState CCInfo(CC, false, *FuncInfo.MF, ArgLocs, *Context);

1154 CCInfo.AnalyzeCallOperands(OutVTs, CLI.OutFlags, ArgTys,

1155 CCAssignFnForCall(CC));

1156

1157 NumBytes = CCInfo.getStackSize();

1158

1159 if (NumBytes < 16)

1160 NumBytes = 16;

1161

1162 emitInst(Mips::ADJCALLSTACKDOWN).addImm(16).addImm(0);

1163

1164 MVT firstMVT;

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

1166 CCValAssign &VA = ArgLocs[i];

1167 const Value *ArgVal = CLI.OutVals[VA.getValNo()];

1168 MVT ArgVT = OutVTs[VA.getValNo()];

1169

1170 if (i == 0) {

1171 firstMVT = ArgVT;

1172 if (ArgVT == MVT::f32) {

1174 } else if (ArgVT == MVT::f64) {

1177 else

1179 }

1180 } else if (i == 1) {

1181 if ((firstMVT == MVT::f32) || (firstMVT == MVT::f64)) {

1182 if (ArgVT == MVT::f32) {

1184 } else if (ArgVT == MVT::f64) {

1187 else

1189 }

1190 }

1191 }

1192 if (((ArgVT == MVT::i32) || (ArgVT == MVT::f32) || (ArgVT == MVT::i16) ||

1193 (ArgVT == MVT::i8)) &&

1196 case 0:

1198 break;

1199 case 4:

1201 break;

1202 case 8:

1204 break;

1205 case 12:

1207 break;

1208 default:

1209 break;

1210 }

1211 }

1212 Register ArgReg = getRegForValue(ArgVal);

1213 if (!ArgReg)

1214 return false;

1215

1216

1219 break;

1223 MVT SrcVT = ArgVT;

1224 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, false);

1225 if (!ArgReg)

1226 return false;

1227 break;

1228 }

1231 MVT SrcVT = ArgVT;

1232 ArgReg = emitIntExt(SrcVT, ArgReg, DestVT, true);

1233 if (!ArgReg)

1234 return false;

1235 break;

1236 }

1237 default:

1239 }

1240

1241

1243 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,

1245 CLI.OutRegs.push_back(VA.getLocReg());

1248 return false;

1249 } else {

1250

1251

1252

1253

1254

1255 assert(VA.isMemLoc() && "Assuming store on stack.");

1256

1258 continue;

1259

1260

1261

1262

1263

1264

1266

1267 unsigned BEAlign = 0;

1268 if (ArgSize < 8 && !Subtarget->isLittle())

1269 BEAlign = 8 - ArgSize;

1270

1272 Addr.setKind(Address::RegBase);

1273 Addr.setReg(Mips::SP);

1275

1276 Align Alignment = DL.getABITypeAlign(ArgVal->getType());

1277 MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(

1280 (void)(MMO);

1281

1282 return false;

1283 }

1284 }

1285

1286 return true;

1287}

1288

1289bool MipsFastISel::finishCall(CallLoweringInfo &CLI, MVT RetVT,

1290 unsigned NumBytes) {

1291 CallingConv::ID CC = CLI.CallConv;

1292 emitInst(Mips::ADJCALLSTACKUP).addImm(16).addImm(0);

1293 if (RetVT != MVT::isVoid) {

1295 MipsCCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);

1296

1297 CCInfo.AnalyzeCallResult(CLI.Ins, RetCC_Mips);

1298

1299

1300 if (RVLocs.size() != 1)

1301 return false;

1302

1303 MVT CopyVT = RVLocs[0].getValVT();

1304

1305 if (RetVT == MVT::i1 || RetVT == MVT::i8 || RetVT == MVT::i16)

1306 CopyVT = MVT::i32;

1307

1309 if (!ResultReg)

1310 return false;

1311 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,

1312 TII.get(TargetOpcode::COPY),

1313 ResultReg).addReg(RVLocs[0].getLocReg());

1314 CLI.InRegs.push_back(RVLocs[0].getLocReg());

1315

1316 CLI.ResultReg = ResultReg;

1317 CLI.NumResultRegs = 1;

1318 }

1319 return true;

1320}

1321

1322bool MipsFastISel::fastLowerArguments() {

1324

1325 if (!FuncInfo.CanLowerReturn) {

1326 LLVM_DEBUG(dbgs() << ".. gave up (!CanLowerReturn)\n");

1327 return false;

1328 }

1329

1330 const Function *F = FuncInfo.Fn;

1331 if (F->isVarArg()) {

1333 return false;

1334 }

1335

1336 CallingConv::ID CC = F->getCallingConv();

1337 if (CC != CallingConv::C) {

1338 LLVM_DEBUG(dbgs() << ".. gave up (calling convention is not C)\n");

1339 return false;

1340 }

1341

1342 std::array<MCPhysReg, 4> GPR32ArgRegs = {{Mips::A0, Mips::A1, Mips::A2,

1343 Mips::A3}};

1344 std::array<MCPhysReg, 2> FGR32ArgRegs = {{Mips::F12, Mips::F14}};

1345 std::array<MCPhysReg, 2> AFGR64ArgRegs = {{Mips::D6, Mips::D7}};

1346 auto NextGPR32 = GPR32ArgRegs.begin();

1347 auto NextFGR32 = FGR32ArgRegs.begin();

1348 auto NextAFGR64 = AFGR64ArgRegs.begin();

1349

1350 struct AllocatedReg {

1351 const TargetRegisterClass *RC;

1352 unsigned Reg;

1353 AllocatedReg(const TargetRegisterClass *RC, unsigned Reg)

1354 : RC(RC), Reg(Reg) {}

1355 };

1356

1357

1358

1360 for (const auto &FormalArg : F->args()) {

1361 if (FormalArg.hasAttribute(Attribute::InReg) ||

1362 FormalArg.hasAttribute(Attribute::StructRet) ||

1363 FormalArg.hasAttribute(Attribute::ByVal)) {

1364 LLVM_DEBUG(dbgs() << ".. gave up (inreg, structret, byval)\n");

1365 return false;

1366 }

1367

1368 Type *ArgTy = FormalArg.getType();

1369 if (ArgTy->isStructTy() || ArgTy->isArrayTy() || ArgTy->isVectorTy()) {

1370 LLVM_DEBUG(dbgs() << ".. gave up (struct, array, or vector)\n");

1371 return false;

1372 }

1373

1375 LLVM_DEBUG(dbgs() << ".. " << FormalArg.getArgNo() << ": "

1376 << ArgVT << "\n");

1377 if (!ArgVT.isSimple()) {

1378 LLVM_DEBUG(dbgs() << ".. .. gave up (not a simple type)\n");

1379 return false;

1380 }

1381

1382 switch (ArgVT.getSimpleVT().SimpleTy) {

1383 case MVT::i1:

1384 case MVT::i8:

1385 case MVT::i16:

1386 if (!FormalArg.hasAttribute(Attribute::SExt) &&

1387 !FormalArg.hasAttribute(Attribute::ZExt)) {

1388

1389

1390 LLVM_DEBUG(dbgs() << ".. .. gave up (i8/i16 arg is not extended)\n");

1391 return false;

1392 }

1393

1394 if (NextGPR32 == GPR32ArgRegs.end()) {

1395 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n");

1396 return false;

1397 }

1398

1399 LLVM_DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n");

1400 Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++);

1401

1402

1403 NextFGR32 = FGR32ArgRegs.end();

1404 NextAFGR64 = AFGR64ArgRegs.end();

1405 break;

1406

1407 case MVT::i32:

1408 if (FormalArg.hasAttribute(Attribute::ZExt)) {

1409

1410 LLVM_DEBUG(dbgs() << ".. .. gave up (i32 arg is zero extended)\n");

1411 return false;

1412 }

1413

1414 if (NextGPR32 == GPR32ArgRegs.end()) {

1415 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of GPR32 arguments)\n");

1416 return false;

1417 }

1418

1419 LLVM_DEBUG(dbgs() << ".. .. GPR32(" << *NextGPR32 << ")\n");

1420 Allocation.emplace_back(&Mips::GPR32RegClass, *NextGPR32++);

1421

1422

1423 NextFGR32 = FGR32ArgRegs.end();

1424 NextAFGR64 = AFGR64ArgRegs.end();

1425 break;

1426

1427 case MVT::f32:

1428 if (UnsupportedFPMode) {

1429 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n");

1430 return false;

1431 }

1432 if (NextFGR32 == FGR32ArgRegs.end()) {

1433 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of FGR32 arguments)\n");

1434 return false;

1435 }

1436 LLVM_DEBUG(dbgs() << ".. .. FGR32(" << *NextFGR32 << ")\n");

1437 Allocation.emplace_back(&Mips::FGR32RegClass, *NextFGR32++);

1438

1439

1440 if (NextGPR32 != GPR32ArgRegs.end())

1441 NextGPR32++;

1442 if (NextAFGR64 != AFGR64ArgRegs.end())

1443 NextAFGR64++;

1444 break;

1445

1446 case MVT::f64:

1447 if (UnsupportedFPMode) {

1448 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode)\n");

1449 return false;

1450 }

1451 if (NextAFGR64 == AFGR64ArgRegs.end()) {

1452 LLVM_DEBUG(dbgs() << ".. .. gave up (ran out of AFGR64 arguments)\n");

1453 return false;

1454 }

1455 LLVM_DEBUG(dbgs() << ".. .. AFGR64(" << *NextAFGR64 << ")\n");

1456 Allocation.emplace_back(&Mips::AFGR64RegClass, *NextAFGR64++);

1457

1458

1459 if (NextGPR32 != GPR32ArgRegs.end())

1460 NextGPR32++;

1461 if (NextGPR32 != GPR32ArgRegs.end())

1462 NextGPR32++;

1463 if (NextFGR32 != FGR32ArgRegs.end())

1464 NextFGR32++;

1465 break;

1466

1467 default:

1468 LLVM_DEBUG(dbgs() << ".. .. gave up (unknown type)\n");

1469 return false;

1470 }

1471 }

1472

1473 for (const auto &FormalArg : F->args()) {

1474 unsigned ArgNo = FormalArg.getArgNo();

1475 unsigned SrcReg = Allocation[ArgNo].Reg;

1476 Register DstReg = FuncInfo.MF->addLiveIn(SrcReg, Allocation[ArgNo].RC);

1477

1478

1479

1480 Register ResultReg = createResultReg(Allocation[ArgNo].RC);

1481 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,

1482 TII.get(TargetOpcode::COPY), ResultReg)

1483 .addReg(DstReg, getKillRegState(true));

1484 updateValueMap(&FormalArg, ResultReg);

1485 }

1486

1487

1488

1489 unsigned IncomingArgSizeInBytes = 0;

1490

1491

1492

1493

1494 IncomingArgSizeInBytes = std::min(getABI().GetCalleeAllocdArgSizeInBytes(CC),

1495 IncomingArgSizeInBytes);

1496

1497 MF->getInfo()->setFormalArgInfo(IncomingArgSizeInBytes,

1498 false);

1499

1500 return true;

1501}

1502

1503bool MipsFastISel::fastLowerCall(CallLoweringInfo &CLI) {

1504 CallingConv::ID CC = CLI.CallConv;

1505 bool IsTailCall = CLI.IsTailCall;

1506 bool IsVarArg = CLI.IsVarArg;

1509

1510

1511 if (CC == CallingConv::Fast)

1512 return false;

1513

1514

1515 if (IsTailCall)

1516 return false;

1517

1518

1519 if (IsVarArg)

1520 return false;

1521

1522

1523 MVT RetVT;

1524 if (CLI.RetTy->isVoidTy())

1525 RetVT = MVT::isVoid;

1526 else if (!isTypeSupported(CLI.RetTy, RetVT))

1527 return false;

1528

1529 for (auto Flag : CLI.OutFlags)

1530 if (Flag.isInReg() || Flag.isSRet() || Flag.isNest() || Flag.isByVal())

1531 return false;

1532

1533

1535 OutVTs.reserve(CLI.OutVals.size());

1536

1537 for (auto *Val : CLI.OutVals) {

1538 MVT VT;

1539 if (!isTypeLegal(Val->getType(), VT) &&

1540 !(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16))

1541 return false;

1542

1543

1545 return false;

1546

1548 }

1549

1551 if (!computeCallAddress(Callee, Addr))

1552 return false;

1553

1554

1555 unsigned NumBytes;

1556 if (!processCallArgs(CLI, OutVTs, NumBytes))

1557 return false;

1558

1559 if (!Addr.getGlobalValue())

1560 return false;

1561

1562

1563 unsigned DestAddress;

1564 if (Symbol)

1565 DestAddress = materializeExternalCallSym(Symbol);

1566 else

1567 DestAddress = materializeGV(Addr.getGlobalValue(), MVT::i32);

1568 emitInst(TargetOpcode::COPY, Mips::T9).addReg(DestAddress);

1569 MachineInstrBuilder MIB =

1570 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Mips::JALR),

1571 Mips::RA).addReg(Mips::T9);

1572

1573

1574 for (auto Reg : CLI.OutRegs)

1576

1577

1578

1579 MIB.addRegMask(TRI.getCallPreservedMask(*FuncInfo.MF, CC));

1580

1581 CLI.Call = MIB;

1582

1584

1585

1586 if (Symbol)

1588 else

1589 MIB.addSym(FuncInfo.MF->getContext().getOrCreateSymbol(

1591 }

1592

1593

1594 return finishCall(CLI, RetVT, NumBytes);

1595}

1596

1597bool MipsFastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {

1598 switch (II->getIntrinsicID()) {

1599 default:

1600 return false;

1601 case Intrinsic::bswap: {

1602 Type *RetTy = II->getCalledFunction()->getReturnType();

1603

1604 MVT VT;

1605 if (!isTypeSupported(RetTy, VT))

1606 return false;

1607

1608 Register SrcReg = getRegForValue(II->getOperand(0));

1609 if (SrcReg == 0)

1610 return false;

1611 Register DestReg = createResultReg(&Mips::GPR32RegClass);

1612 if (DestReg == 0)

1613 return false;

1614 if (VT == MVT::i16) {

1616 emitInst(Mips::WSBH, DestReg).addReg(SrcReg);

1617 updateValueMap(II, DestReg);

1618 return true;

1619 } else {

1620 unsigned TempReg[3];

1621 for (unsigned &R : TempReg) {

1622 R = createResultReg(&Mips::GPR32RegClass);

1623 if (R == 0)

1624 return false;

1625 }

1626 emitInst(Mips::SLL, TempReg[0]).addReg(SrcReg).addImm(8);

1627 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(8);

1628 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[1]).addImm(0xFF);

1629 emitInst(Mips::OR, DestReg).addReg(TempReg[0]).addReg(TempReg[2]);

1630 updateValueMap(II, DestReg);

1631 return true;

1632 }

1633 } else if (VT == MVT::i32) {

1635 Register TempReg = createResultReg(&Mips::GPR32RegClass);

1636 emitInst(Mips::WSBH, TempReg).addReg(SrcReg);

1637 emitInst(Mips::ROTR, DestReg).addReg(TempReg).addImm(16);

1638 updateValueMap(II, DestReg);

1639 return true;

1640 } else {

1641 unsigned TempReg[8];

1642 for (unsigned &R : TempReg) {

1643 R = createResultReg(&Mips::GPR32RegClass);

1644 if (R == 0)

1645 return false;

1646 }

1647

1648 emitInst(Mips::SRL, TempReg[0]).addReg(SrcReg).addImm(8);

1649 emitInst(Mips::SRL, TempReg[1]).addReg(SrcReg).addImm(24);

1650 emitInst(Mips::ANDi, TempReg[2]).addReg(TempReg[0]).addImm(0xFF00);

1651 emitInst(Mips::OR, TempReg[3]).addReg(TempReg[1]).addReg(TempReg[2]);

1652

1653 emitInst(Mips::ANDi, TempReg[4]).addReg(SrcReg).addImm(0xFF00);

1654 emitInst(Mips::SLL, TempReg[5]).addReg(TempReg[4]).addImm(8);

1655

1656 emitInst(Mips::SLL, TempReg[6]).addReg(SrcReg).addImm(24);

1657 emitInst(Mips::OR, TempReg[7]).addReg(TempReg[3]).addReg(TempReg[5]);

1658 emitInst(Mips::OR, DestReg).addReg(TempReg[6]).addReg(TempReg[7]);

1659 updateValueMap(II, DestReg);

1660 return true;

1661 }

1662 }

1663 return false;

1664 }

1665 case Intrinsic::memcpy:

1666 case Intrinsic::memmove: {

1668

1669 if (MTI->isVolatile())

1670 return false;

1671 if (!MTI->getLength()->getType()->isIntegerTy(32))

1672 return false;

1673 const char *IntrMemName = isa(II) ? "memcpy" : "memmove";

1674 return lowerCallTo(II, IntrMemName, II->arg_size() - 1);

1675 }

1676 case Intrinsic::memset: {

1678

1680 return false;

1682 return false;

1683 return lowerCallTo(II, "memset", II->arg_size() - 1);

1684 }

1685 }

1686 return false;

1687}

1688

1689bool MipsFastISel::selectRet(const Instruction *I) {

1690 const Function &F = *I->getParent()->getParent();

1692

1694

1695 if (!FuncInfo.CanLowerReturn)

1696 return false;

1697

1698

1699 SmallVector<unsigned, 4> RetRegs;

1700

1702 CallingConv::ID CC = F.getCallingConv();

1703

1704

1705 if (CC == CallingConv::Fast)

1706 return false;

1707

1709 GetReturnInfo(CC, F.getReturnType(), F.getAttributes(), Outs, TLI, DL);

1710

1711

1713 MipsCCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs,

1714 I->getContext());

1716 CCInfo.AnalyzeReturn(Outs, RetCC);

1717

1718

1719 if (ValLocs.size() != 1)

1720 return false;

1721

1722 CCValAssign &VA = ValLocs[0];

1724

1725

1728 return false;

1729

1730

1732 return false;

1733

1735 if (Reg == 0)

1736 return false;

1737

1740

1741 if (MRI.getRegClass(SrcReg)->contains(DestReg))

1742 return false;

1743

1746 return false;

1747

1749 return false;

1750

1752 if (RVVT == MVT::f128)

1753 return false;

1754

1755

1756 if (RVVT == MVT::f64 && UnsupportedFPMode) {

1757 LLVM_DEBUG(dbgs() << ".. .. gave up (UnsupportedFPMode\n");

1758 return false;

1759 }

1760

1762

1763 if (RVVT != DestVT) {

1764 if (RVVT != MVT::i1 && RVVT != MVT::i8 && RVVT != MVT::i16)

1765 return false;

1766

1767 if (Outs[0].Flags.isZExt() || Outs[0].Flags.isSExt()) {

1768 bool IsZExt = Outs[0].Flags.isZExt();

1769 SrcReg = emitIntExt(RVVT, SrcReg, DestVT, IsZExt);

1770 if (SrcReg == 0)

1771 return false;

1772 }

1773 }

1774

1775

1776 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,

1777 TII.get(TargetOpcode::COPY), DestReg).addReg(SrcReg);

1778

1779

1781 }

1782 MachineInstrBuilder MIB = emitInst(Mips::RetRA);

1783 for (unsigned Reg : RetRegs)

1785 return true;

1786}

1787

1788bool MipsFastISel::selectTrunc(const Instruction *I) {

1789

1790

1791 Value *Op = I->getOperand(0);

1792

1793 EVT SrcVT, DestVT;

1796

1797 if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)

1798 return false;

1799 if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)

1800 return false;

1801

1802 Register SrcReg = getRegForValue(Op);

1803 if (!SrcReg)

1804 return false;

1805

1806

1807

1808 updateValueMap(I, SrcReg);

1809 return true;

1810}

1811

1812bool MipsFastISel::selectIntExt(const Instruction *I) {

1813 Type *DestTy = I->getType();

1814 Value *Src = I->getOperand(0);

1815 Type *SrcTy = Src->getType();

1816

1818 Register SrcReg = getRegForValue(Src);

1819 if (!SrcReg)

1820 return false;

1821

1822 EVT SrcEVT, DestEVT;

1826 return false;

1828 return false;

1829

1832 Register ResultReg = createResultReg(&Mips::GPR32RegClass);

1833

1834 if (!emitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))

1835 return false;

1836 updateValueMap(I, ResultReg);

1837 return true;

1838}

1839

1840bool MipsFastISel::emitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,

1841 unsigned DestReg) {

1842 unsigned ShiftAmt;

1844 default:

1845 return false;

1846 case MVT::i8:

1847 ShiftAmt = 24;

1848 break;

1849 case MVT::i16:

1850 ShiftAmt = 16;

1851 break;

1852 }

1853 Register TempReg = createResultReg(&Mips::GPR32RegClass);

1854 emitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);

1855 emitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);

1856 return true;

1857}

1858

1859bool MipsFastISel::emitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,

1860 unsigned DestReg) {

1862 default:

1863 return false;

1864 case MVT::i8:

1865 emitInst(Mips::SEB, DestReg).addReg(SrcReg);

1866 break;

1867 case MVT::i16:

1868 emitInst(Mips::SEH, DestReg).addReg(SrcReg);

1869 break;

1870 }

1871 return true;

1872}

1873

1874bool MipsFastISel::emitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,

1875 unsigned DestReg) {

1876 if ((DestVT != MVT::i32) && (DestVT != MVT::i16))

1877 return false;

1879 return emitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);

1880 return emitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);

1881}

1882

1883bool MipsFastISel::emitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,

1884 unsigned DestReg) {

1885 int64_t Imm;

1886

1888 default:

1889 return false;

1890 case MVT::i1:

1891 Imm = 1;

1892 break;

1893 case MVT::i8:

1894 Imm = 0xff;

1895 break;

1896 case MVT::i16:

1897 Imm = 0xffff;

1898 break;

1899 }

1900

1901 emitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(Imm);

1902 return true;

1903}

1904

1905bool MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,

1906 unsigned DestReg, bool IsZExt) {

1907

1908

1909

1910

1911 if (((DestVT != MVT::i8) && (DestVT != MVT::i16) && (DestVT != MVT::i32)) ||

1912 ((SrcVT != MVT::i1) && (SrcVT != MVT::i8) && (SrcVT != MVT::i16)))

1913 return false;

1914 if (IsZExt)

1915 return emitIntZExt(SrcVT, SrcReg, DestVT, DestReg);

1916 return emitIntSExt(SrcVT, SrcReg, DestVT, DestReg);

1917}

1918

1919unsigned MipsFastISel::emitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,

1920 bool isZExt) {

1921 unsigned DestReg = createResultReg(&Mips::GPR32RegClass);

1922 bool Success = emitIntExt(SrcVT, SrcReg, DestVT, DestReg, isZExt);

1923 return Success ? DestReg : 0;

1924}

1925

1926bool MipsFastISel::selectDivRem(const Instruction *I, unsigned ISDOpcode) {

1929 return false;

1930

1932 if (DestVT != MVT::i32)

1933 return false;

1934

1935 unsigned DivOpc;

1936 switch (ISDOpcode) {

1937 default:

1938 return false;

1941 DivOpc = Mips::SDIV;

1942 break;

1945 DivOpc = Mips::UDIV;

1946 break;

1947 }

1948

1949 Register Src0Reg = getRegForValue(I->getOperand(0));

1950 Register Src1Reg = getRegForValue(I->getOperand(1));

1951 if (!Src0Reg || !Src1Reg)

1952 return false;

1953

1954 emitInst(DivOpc).addReg(Src0Reg).addReg(Src1Reg);

1957 emitInst(Mips::TEQ).addReg(Src1Reg).addReg(Mips::ZERO).addImm(7);

1958 }

1959

1960 Register ResultReg = createResultReg(&Mips::GPR32RegClass);

1961 if (!ResultReg)

1962 return false;

1963

1965 ? Mips::MFHI

1966 : Mips::MFLO;

1967 emitInst(MFOpc, ResultReg);

1968

1969 updateValueMap(I, ResultReg);

1970 return true;

1971}

1972

1973bool MipsFastISel::selectShift(const Instruction *I) {

1974 MVT RetVT;

1975

1976 if (!isTypeSupported(I->getType(), RetVT))

1977 return false;

1978

1979 Register ResultReg = createResultReg(&Mips::GPR32RegClass);

1980 if (!ResultReg)

1981 return false;

1982

1983 unsigned Opcode = I->getOpcode();

1984 const Value *Op0 = I->getOperand(0);

1985 Register Op0Reg = getRegForValue(Op0);

1986 if (!Op0Reg)

1987 return false;

1988

1989

1990 if (Opcode == Instruction::AShr || Opcode == Instruction::LShr) {

1991 Register TempReg = createResultReg(&Mips::GPR32RegClass);

1992 if (!TempReg)

1993 return false;

1994

1996 bool IsZExt = Opcode == Instruction::LShr;

1997 if (!emitIntExt(Op0MVT, Op0Reg, MVT::i32, TempReg, IsZExt))

1998 return false;

1999

2000 Op0Reg = TempReg;

2001 }

2002

2004 uint64_t ShiftVal = C->getZExtValue();

2005

2006 switch (Opcode) {

2007 default:

2009 case Instruction::Shl:

2010 Opcode = Mips::SLL;

2011 break;

2012 case Instruction::AShr:

2013 Opcode = Mips::SRA;

2014 break;

2015 case Instruction::LShr:

2016 Opcode = Mips::SRL;

2017 break;

2018 }

2019

2020 emitInst(Opcode, ResultReg).addReg(Op0Reg).addImm(ShiftVal);

2021 updateValueMap(I, ResultReg);

2022 return true;

2023 }

2024

2025 Register Op1Reg = getRegForValue(I->getOperand(1));

2026 if (!Op1Reg)

2027 return false;

2028

2029 switch (Opcode) {

2030 default:

2032 case Instruction::Shl:

2033 Opcode = Mips::SLLV;

2034 break;

2035 case Instruction::AShr:

2036 Opcode = Mips::SRAV;

2037 break;

2038 case Instruction::LShr:

2039 Opcode = Mips::SRLV;

2040 break;

2041 }

2042

2043 emitInst(Opcode, ResultReg).addReg(Op0Reg).addReg(Op1Reg);

2044 updateValueMap(I, ResultReg);

2045 return true;

2046}

2047

2048bool MipsFastISel::fastSelectInstruction(const Instruction *I) {

2049 switch (I->getOpcode()) {

2050 default:

2051 break;

2052 case Instruction::Load:

2053 return selectLoad(I);

2054 case Instruction::Store:

2055 return selectStore(I);

2056 case Instruction::SDiv:

2059 return true;

2060 case Instruction::UDiv:

2063 return true;

2064 case Instruction::SRem:

2067 return true;

2068 case Instruction::URem:

2071 return true;

2072 case Instruction::Shl:

2073 case Instruction::LShr:

2074 case Instruction::AShr:

2075 return selectShift(I);

2076 case Instruction::And:

2077 case Instruction::Or:

2078 case Instruction::Xor:

2079 return selectLogicalOp(I);

2080 case Instruction::Br:

2081 return selectBranch(I);

2082 case Instruction::Ret:

2083 return selectRet(I);

2084 case Instruction::Trunc:

2085 return selectTrunc(I);

2086 case Instruction::ZExt:

2087 case Instruction::SExt:

2088 return selectIntExt(I);

2089 case Instruction::FPTrunc:

2090 return selectFPTrunc(I);

2091 case Instruction::FPExt:

2092 return selectFPExt(I);

2093 case Instruction::FPToSI:

2094 return selectFPToInt(I, true);

2095 case Instruction::FPToUI:

2096 return selectFPToInt(I, false);

2097 case Instruction::ICmp:

2098 case Instruction::FCmp:

2099 return selectCmp(I);

2100 case Instruction::Select:

2101 return selectSelect(I);

2102 }

2103 return false;

2104}

2105

2106unsigned MipsFastISel::getRegEnsuringSimpleIntegerWidening(const Value *V,

2107 bool IsUnsigned) {

2108 Register VReg = getRegForValue(V);

2109 if (VReg == 0)

2110 return 0;

2112

2113 if (VMVT == MVT::i1)

2114 return 0;

2115

2116 if ((VMVT == MVT::i8) || (VMVT == MVT::i16)) {

2117 Register TempReg = createResultReg(&Mips::GPR32RegClass);

2118 if (!emitIntExt(VMVT, VReg, MVT::i32, TempReg, IsUnsigned))

2119 return 0;

2120 VReg = TempReg;

2121 }

2122 return VReg;

2123}

2124

2125void MipsFastISel::simplifyAddress(Address &Addr) {

2126 if (isInt<16>(Addr.getOffset())) {

2127 unsigned TempReg =

2128 materialize32BitInt(Addr.getOffset(), &Mips::GPR32RegClass);

2129 Register DestReg = createResultReg(&Mips::GPR32RegClass);

2130 emitInst(Mips::ADDu, DestReg).addReg(TempReg).addReg(Addr.getReg());

2131 Addr.setReg(DestReg);

2132 Addr.setOffset(0);

2133 }

2134}

2135

2136unsigned MipsFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,

2137 const TargetRegisterClass *RC,

2138 unsigned Op0, unsigned Op1) {

2139

2140

2141

2142

2143

2144

2145 if (MachineInstOpcode == Mips::MUL) {

2146 Register ResultReg = createResultReg(RC);

2147 const MCInstrDesc &II = TII.get(MachineInstOpcode);

2150 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg)

2155 return ResultReg;

2156 }

2157

2159}

2160

2161namespace llvm {

2162

2165 return new MipsFastISel(funcInfo, libInfo);

2166}

2167

2168}

unsigned const MachineRegisterInfo * MRI

static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)

Select the AArch64 opcode for the basic binary operation GenericOpc (such as G_OR or G_SDIV),...

static void emitLoad(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPostDec)

Emit a load-pair instruction for frame-destroy.

static void emitStore(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator Pos, const TargetInstrInfo &TII, unsigned Reg1, unsigned Reg2, int Offset, bool IsPreDec)

Emit a store-pair instruction for frame-setup.

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

const TargetInstrInfo & TII

This file implements a class to represent arbitrary precision integral constant values and operations...

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

This file contains the simple types necessary to represent the attributes associated with functions a...

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

This file defines the DenseMap class.

This file defines the FastISel class.

Register const TargetRegisterInfo * TRI

Promote Memory to Register

cl::opt< bool > EmitJalrReloc

static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)

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)

Definition MipsFastISel.cpp:279

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

Definition MipsFastISel.cpp:272

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

uint64_t IntrinsicInst * II

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

const SmallVectorImpl< MachineOperand > & Cond

This file defines the SmallVector class.

static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)

This file describes how to lower LLVM code to machine code.

APInt bitcastToAPInt() const

uint64_t getZExtValue() const

Get zero extended value.

an instruction to allocate memory on the stack

PointerType * getType() const

Overload to return most specific pointer type.

BasicBlock * getSuccessor(unsigned i) const

Value * getCondition() const

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

void convertToReg(MCRegister Reg)

Register getLocReg() const

LocInfo getLocInfo() const

int64_t getLocMemOffset() const

unsigned getValNo() const

This class is the base class for the comparison instructions.

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ FCMP_OEQ

0 0 0 1 True if ordered and equal

@ ICMP_SLT

signed less than

@ ICMP_SLE

signed less or equal

@ FCMP_OLT

0 1 0 0 True if ordered and less than

@ FCMP_OGT

0 0 1 0 True if ordered and greater than

@ FCMP_OGE

0 0 1 1 True if ordered and greater than or equal

@ ICMP_UGE

unsigned greater or equal

@ ICMP_UGT

unsigned greater than

@ ICMP_SGT

signed greater than

@ ICMP_ULT

unsigned less than

@ FCMP_OLE

0 1 0 1 True if ordered and less than or equal

@ ICMP_SGE

signed greater or equal

@ FCMP_UNE

1 1 1 0 True if unordered or not equal

@ ICMP_ULE

unsigned less or equal

Predicate getPredicate() const

Return the predicate for this instruction.

ConstantFP - Floating Point Values [float, double].

const APFloat & getValueAPF() const

int64_t getSExtValue() const

Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...

uint64_t getZExtValue() const

Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...

This is an important base class in LLVM.

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

Register fastEmitInst_rr(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0, Register Op1)

Emit a MachineInstr with two register operands and a result register in the given register class.

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

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

bool isThreadLocal() const

If the value is "Thread Local", its value isn't shared by the threads.

bool hasLocalLinkage() const

bool hasInternalLinkage() const

LLVM_ABI bool isAtomic() const LLVM_READONLY

Return true if this instruction has an AtomicOrdering of unordered or higher.

A wrapper class for inspecting calls to intrinsic functions.

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

Align getAlign() const

Return the alignment of the access that is being performed.

const MCInstrDesc & get(unsigned Opcode) const

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

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

bool isVector() const

Return true if this is a vector value type.

bool isInteger() const

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

TypeSize getSizeInBits() const

Returns the size of the specified MVT in bits.

uint64_t getFixedSizeInBits() const

Return the size of the specified fixed width value type in bits.

TypeSize getStoreSize() const

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

int64_t getObjectSize(int ObjectIdx) const

Return the size of the specified object.

const TargetSubtargetInfo & getSubtarget() const

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

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

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 & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const

const MachineInstrBuilder & addFrameIndex(int Idx) const

const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const

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 & addMemOperand(MachineMemOperand *MMO) const

@ MOLoad

The memory access reads data.

@ MOStore

The memory access writes data.

Value * getLength() const

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

Register getGlobalBaseReg(MachineFunction &MF)

bool useSoftFloat() const

const MipsInstrInfo * getInstrInfo() const override

bool inMips16Mode() const

bool systemSupportsUnalignedAccess() const

Does the system support unaligned memory access.

const MipsTargetLowering * getTargetLowering() const override

Wrapper class representing virtual and physical registers.

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

reference emplace_back(ArgTypes &&... Args)

void reserve(size_type N)

void push_back(const T &Elt)

TypeSize getElementOffset(unsigned Idx) const

TargetInstrInfo - Interface to description of machine instruction set.

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

EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const

Return the EVT corresponding to this LLVM type.

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

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

bool isTypeLegal(EVT VT) const

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

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

This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...

Primary interface to the complete machine description for the target machine.

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

True if this is an instance of IntegerType.

const Use * const_op_iterator

Value * getOperand(unsigned i) const

unsigned getNumOperands() const

LLVM Value Representation.

Type * getType() const

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

bool hasOneUse() const

Return true if there is exactly one use of this value.

StructType * getStructTypeOrNull() const

TypeSize getSequentialElementStride(const DataLayout &DL) const

const ParentTy * getParent() const

#define llvm_unreachable(msg)

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

constexpr char Align[]

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

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ C

The default llvm calling convention, compatible with C.

@ AND

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

Flag

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

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

Definition MipsFastISel.cpp:2163

@ Implicit

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

@ Define

Register definition.

@ User

could "use" a pointer

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)

Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...

LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)

Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...

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.

static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)

LLVM_ABI raw_ostream & dbgs()

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

generic_gep_type_iterator<> gep_type_iterator

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

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

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

gep_type_iterator gep_type_begin(const User *GEP)

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

bool isSimple() const

Test if the given EVT is simple (as opposed to being extended).

MVT getSimpleVT() const

Return the SimpleValueType held in the specified simple EVT.

bool isVector() const

Return true if this is a vector value type.

static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)

Stack pointer relative access.

static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)

Return a MachinePointerInfo record that refers to the specified FrameIndex.