LLVM: lib/Target/PowerPC/PPCFastISel.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55using namespace llvm;

56

57#define DEBUG_TYPE "ppcfastisel"

58

59namespace {

60

61struct Address {

62 enum {

63 RegBase,

64 FrameIndexBase

66

67 union {

68 unsigned Reg;

69 int FI;

71

73

74

78 }

79};

80

81class PPCFastISel final : public FastISel {

82

89

90 public:

98

99

100 private:

101 bool fastSelectInstruction(const Instruction *I) override;

104 bool tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,

105 const LoadInst *LI) override;

106 bool fastLowerArguments() override;

108 Register fastEmitInst_ri(unsigned MachineInstOpcode,

111 Register fastEmitInst_r(unsigned MachineInstOpcode,

113 Register fastEmitInst_rr(unsigned MachineInstOpcode,

116

117 bool fastLowerCall(CallLoweringInfo &CLI) override;

118

119

120 private:

127 bool SelectIToFP(const Instruction *I, bool IsSigned);

128 bool SelectFPToI(const Instruction *I, bool IsSigned);

129 bool SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode);

133

134

135 private:

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

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

138 bool isValueAvailable(const Value *V) const;

140 return RC->getID() == PPC::VSFRCRegClassID;

141 }

143 return RC->getID() == PPC::VSSRCRegClassID;

144 }

146 unsigned Flag = 0, unsigned SubReg = 0) {

147 Register TmpReg = createResultReg(ToRC);

149 TII.get(TargetOpcode::COPY), TmpReg).addReg(SrcReg, Flag, SubReg);

150 return TmpReg;

151 }

152 bool PPCEmitCmp(const Value *Src1Value, const Value *Src2Value, bool isZExt,

154 bool PPCEmitLoad(MVT VT, Register &ResultReg, Address &Addr,

156 unsigned FP64LoadOpc = PPC::LFD);

157 bool PPCEmitStore(MVT VT, Register SrcReg, Address &Addr);

158 bool PPCComputeAddress(const Value *Obj, Address &Addr);

159 void PPCSimplifyAddress(Address &Addr, bool &UseOffset, Register &IndexReg);

161 bool IsZExt);

165 bool UseSExt = true);

169 bool IsSigned);

171

172

173 private:

179 unsigned &NumBytes, bool IsVarArg);

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

181

182 private:

183 #include "PPCGenFastISel.inc"

184

185};

186

187}

188

190 switch (Pred) {

191

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

216 default:

217 return std::nullopt;

218

222

227

232

237

242

246

249

252 }

253}

254

255

256

257

258bool PPCFastISel::isTypeLegal(Type *Ty, MVT &VT) {

260

261

262 if (Evt == MVT::Other || !Evt.isSimple()) return false;

264

265

266

268}

269

270

271

272bool PPCFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) {

273 if (isTypeLegal(Ty, VT)) return true;

274

275

276

277 if (VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32) {

278 return true;

279 }

280

281 return false;

282}

283

284bool PPCFastISel::isValueAvailable(const Value *V) const {

286 return true;

287

289 return FuncInfo.getMBB(I->getParent()) == FuncInfo.MBB;

290}

291

292

293

294bool PPCFastISel::PPCComputeAddress(const Value *Obj, Address &Addr) {

295 const User *U = nullptr;

296 unsigned Opcode = Instruction::UserOp1;

298

299

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

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

302 Opcode = I->getOpcode();

303 U = I;

304 }

306 Opcode = C->getOpcode();

307 U = C;

308 }

309

310 switch (Opcode) {

311 default:

312 break;

313 case Instruction::BitCast:

314

315 return PPCComputeAddress(U->getOperand(0), Addr);

316 case Instruction::IntToPtr:

317

320 return PPCComputeAddress(U->getOperand(0), Addr);

321 break;

322 case Instruction::PtrToInt:

323

325 return PPCComputeAddress(U->getOperand(0), Addr);

326 break;

327 case Instruction::GetElementPtr: {

328 Address SavedAddr = Addr;

329 int64_t TmpOffset = Addr.Offset;

330

331

332

335 II != IE; ++II, ++GTI) {

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

341 } else {

343 for (;;) {

345

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

347 break;

348 }

349 if (canFoldAddIntoGEP(U, Op)) {

350

351 ConstantInt *CI =

354

356 continue;

357 }

358

359 goto unsupported_gep;

360 }

361 }

362 }

363

364

365 Addr.Offset = TmpOffset;

366 if (PPCComputeAddress(U->getOperand(0), Addr)) return true;

367

368

369 Addr = SavedAddr;

370

371 unsupported_gep:

372 break;

373 }

374 case Instruction::Alloca: {

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

377 FuncInfo.StaticAllocaMap.find(AI);

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

379 Addr.BaseType = Address::FrameIndexBase;

380 Addr.Base.FI = SI->second;

381 return true;

382 }

383 break;

384 }

385 }

386

387

388

389

390

391

392

393

394 if (Addr.Base.Reg == 0)

395 Addr.Base.Reg = getRegForValue(Obj);

396

397

398

399 if (Addr.Base.Reg != 0)

400 MRI.setRegClass(Addr.Base.Reg, &PPC::G8RC_and_G8RC_NOX0RegClass);

401

402 return Addr.Base.Reg != 0;

403}

404

405

406

407

408void PPCFastISel::PPCSimplifyAddress(Address &Addr, bool &UseOffset,

410

411

413 UseOffset = false;

414

415

416

417

418 if (!UseOffset && Addr.BaseType == Address::FrameIndexBase) {

419 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);

420 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDI8),

422 Addr.Base.Reg = ResultReg;

423 Addr.BaseType = Address::RegBase;

424 }

425

426 if (!UseOffset) {

427 IntegerType *OffsetTy = Type::getInt64Ty(*Context);

429 IndexReg = PPCMaterializeInt(Offset, MVT::i64);

430 assert(IndexReg && "Unexpected error in PPCMaterializeInt!");

431 }

432}

433

434

435

436

437bool PPCFastISel::PPCEmitLoad(MVT VT, Register &ResultReg, Address &Addr,

438 const TargetRegisterClass *RC,

439 bool IsZExt, unsigned FP64LoadOpc) {

440 unsigned Opc;

441 bool UseOffset = true;

442 bool HasSPE = Subtarget->hasSPE();

443

444

445

446

447

448

449

450

451 const TargetRegisterClass *UseRC =

452 (ResultReg ? MRI.getRegClass(ResultReg) :

453 (RC ? RC :

454 (VT == MVT::f64 ? (HasSPE ? &PPC::SPERCRegClass : &PPC::F8RCRegClass) :

455 (VT == MVT::f32 ? (HasSPE ? &PPC::GPRCRegClass : &PPC::F4RCRegClass) :

456 (VT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :

457 &PPC::GPRC_and_GPRC_NOR0RegClass)))));

458

459 bool Is32BitInt = UseRC->hasSuperClassEq(&PPC::GPRCRegClass);

460

462 default:

463 return false;

464 case MVT::i8:

465 Opc = Is32BitInt ? PPC::LBZ : PPC::LBZ8;

466 break;

467 case MVT::i16:

468 Opc = (IsZExt ? (Is32BitInt ? PPC::LHZ : PPC::LHZ8)

469 : (Is32BitInt ? PPC::LHA : PPC::LHA8));

470 break;

471 case MVT::i32:

472 Opc = (IsZExt ? (Is32BitInt ? PPC::LWZ : PPC::LWZ8)

473 : (Is32BitInt ? PPC::LWA_32 : PPC::LWA));

474 if ((Opc == PPC::LWA || Opc == PPC::LWA_32) && ((Addr.Offset & 3) != 0))

475 UseOffset = false;

476 break;

477 case MVT::i64:

478 Opc = PPC::LD;

480 "64-bit load with 32-bit target??");

481 UseOffset = ((Addr.Offset & 3) == 0);

482 break;

483 case MVT::f32:

484 Opc = Subtarget->hasSPE() ? PPC::SPELWZ : PPC::LFS;

485 break;

486 case MVT::f64:

487 Opc = FP64LoadOpc;

488 break;

489 }

490

491

492

494 PPCSimplifyAddress(Addr, UseOffset, IndexReg);

495

496

497

498 bool IsVSSRC = isVSSRCRegClass(UseRC);

499 bool IsVSFRC = isVSFRCRegClass(UseRC);

500 bool Is32VSXLoad = IsVSSRC && Opc == PPC::LFS;

501 bool Is64VSXLoad = IsVSFRC && Opc == PPC::LFD;

502 if ((Is32VSXLoad || Is64VSXLoad) &&

503 (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&

504 (Addr.Offset == 0)) {

505 UseOffset = false;

506 }

507

508 if (!ResultReg)

509 ResultReg = createResultReg(UseRC);

510

511

512

513

514 if (Addr.BaseType == Address::FrameIndexBase) {

515

516 if (Is32VSXLoad || Is64VSXLoad) return false;

517

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

520 Addr.Offset),

522 MFI.getObjectAlign(Addr.Base.FI));

523

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

526

527

528 } else if (UseOffset) {

529

530 if (Is32VSXLoad || Is64VSXLoad) return false;

531

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

534

535

536 } else {

537

538

539

540 switch (Opc) {

542 case PPC::LBZ: Opc = PPC::LBZX; break;

543 case PPC::LBZ8: Opc = PPC::LBZX8; break;

544 case PPC::LHZ: Opc = PPC::LHZX; break;

545 case PPC::LHZ8: Opc = PPC::LHZX8; break;

546 case PPC::LHA: Opc = PPC::LHAX; break;

547 case PPC::LHA8: Opc = PPC::LHAX8; break;

548 case PPC::LWZ: Opc = PPC::LWZX; break;

549 case PPC::LWZ8: Opc = PPC::LWZX8; break;

550 case PPC::LWA: Opc = PPC::LWAX; break;

551 case PPC::LWA_32: Opc = PPC::LWAX_32; break;

552 case PPC::LD: Opc = PPC::LDX; break;

553 case PPC::LFS: Opc = IsVSSRC ? PPC::LXSSPX : PPC::LFSX; break;

554 case PPC::LFD: Opc = IsVSFRC ? PPC::LXSDX : PPC::LFDX; break;

555 case PPC::EVLDD: Opc = PPC::EVLDDX; break;

556 case PPC::SPELWZ: Opc = PPC::SPELWZX; break;

557 }

558

559 auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc),

560 ResultReg);

561

562

563

564

565

566 if (IndexReg)

567 MIB.addReg(Addr.Base.Reg).addReg(IndexReg);

568 else

569 MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);

570 }

571

572 return true;

573}

574

575

576bool PPCFastISel::SelectLoad(const Instruction *I) {

577

579 return false;

580

581

582 MVT VT;

583 if (!isLoadTypeLegal(I->getType(), VT))

584 return false;

585

586

588 if (!PPCComputeAddress(I->getOperand(0), Addr))

589 return false;

590

591

592

593

594 Register AssignedReg = FuncInfo.ValueMap[I];

595 const TargetRegisterClass *RC =

596 AssignedReg ? MRI.getRegClass(AssignedReg) : nullptr;

597

599 if (!PPCEmitLoad(VT, ResultReg, Addr, RC, true,

600 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))

601 return false;

602 updateValueMap(I, ResultReg);

603 return true;

604}

605

606

607bool PPCFastISel::PPCEmitStore(MVT VT, Register SrcReg, Address &Addr) {

608 assert(SrcReg && "Nothing to store!");

609 unsigned Opc;

610 bool UseOffset = true;

611

612 const TargetRegisterClass *RC = MRI.getRegClass(SrcReg);

613 bool Is32BitInt = RC->hasSuperClassEq(&PPC::GPRCRegClass);

614

616 default:

617 return false;

618 case MVT::i8:

619 Opc = Is32BitInt ? PPC::STB : PPC::STB8;

620 break;

621 case MVT::i16:

622 Opc = Is32BitInt ? PPC::STH : PPC::STH8;

623 break;

624 case MVT::i32:

625 assert(Is32BitInt && "Not GPRC for i32??");

626 Opc = PPC::STW;

627 break;

628 case MVT::i64:

629 Opc = PPC::STD;

630 UseOffset = ((Addr.Offset & 3) == 0);

631 break;

632 case MVT::f32:

633 Opc = Subtarget->hasSPE() ? PPC::SPESTW : PPC::STFS;

634 break;

635 case MVT::f64:

636 Opc = Subtarget->hasSPE() ? PPC::EVSTDD : PPC::STFD;

637 break;

638 }

639

640

641

643 PPCSimplifyAddress(Addr, UseOffset, IndexReg);

644

645

646

647 bool IsVSSRC = isVSSRCRegClass(RC);

648 bool IsVSFRC = isVSFRCRegClass(RC);

649 bool Is32VSXStore = IsVSSRC && Opc == PPC::STFS;

650 bool Is64VSXStore = IsVSFRC && Opc == PPC::STFD;

651 if ((Is32VSXStore || Is64VSXStore) &&

652 (Addr.BaseType != Address::FrameIndexBase) && UseOffset &&

653 (Addr.Offset == 0)) {

654 UseOffset = false;

655 }

656

657

658

659

660 if (Addr.BaseType == Address::FrameIndexBase) {

661

662 if (Is32VSXStore || Is64VSXStore) return false;

663

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

666 Addr.Offset),

668 MFI.getObjectAlign(Addr.Base.FI));

669

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

675

676

677 } else if (UseOffset) {

678

679 if (Is32VSXStore || Is64VSXStore)

680 return false;

681

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

684

685

686 } else {

687

688

689

690 switch (Opc) {

692 case PPC::STB: Opc = PPC::STBX; break;

693 case PPC::STH : Opc = PPC::STHX; break;

694 case PPC::STW : Opc = PPC::STWX; break;

695 case PPC::STB8: Opc = PPC::STBX8; break;

696 case PPC::STH8: Opc = PPC::STHX8; break;

697 case PPC::STW8: Opc = PPC::STWX8; break;

698 case PPC::STD: Opc = PPC::STDX; break;

699 case PPC::STFS: Opc = IsVSSRC ? PPC::STXSSPX : PPC::STFSX; break;

700 case PPC::STFD: Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX; break;

701 case PPC::EVSTDD: Opc = PPC::EVSTDDX; break;

702 case PPC::SPESTW: Opc = PPC::SPESTWX; break;

703 }

704

705 auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(Opc))

707

708

709

710

711

712 if (IndexReg)

714 else

715 MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);

716 }

717

718 return true;

719}

720

721

722bool PPCFastISel::SelectStore(const Instruction *I) {

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

725

726

728 return false;

729

730

731 MVT VT;

732 if (!isLoadTypeLegal(Op0->getType(), VT))

733 return false;

734

735

736 SrcReg = getRegForValue(Op0);

737 if (!SrcReg)

738 return false;

739

740

742 if (!PPCComputeAddress(I->getOperand(1), Addr))

743 return false;

744

745 if (!PPCEmitStore(VT, SrcReg, Addr))

746 return false;

747

748 return true;

749}

750

751

752bool PPCFastISel::SelectBranch(const Instruction *I) {

754 MachineBasicBlock *BrBB = FuncInfo.MBB;

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

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

757

758

760 if (isValueAvailable(CI)) {

761 std::optionalPPC::Predicate OptPPCPred =

763 if (!OptPPCPred)

764 return false;

765

767

768

769 if (FuncInfo.MBB->isLayoutSuccessor(TBB)) {

772 }

773

774 Register CondReg = createResultReg(&PPC::CRRCRegClass);

775

777 CondReg, PPCPred))

778 return false;

779

780 BuildMI(*BrBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::BCC))

785 return true;

786 }

787 } else if (const ConstantInt *CI =

790 MachineBasicBlock *Target = (Imm == 0) ? FBB : TBB;

791 fastEmitBranch(Target, MIMD.getDL());

792 return true;

793 }

794

795

796

797

798

799

800

801 return false;

802}

803

804

805

806bool PPCFastISel::PPCEmitCmp(const Value *SrcValue1, const Value *SrcValue2,

807 bool IsZExt, Register DestReg,

812 return false;

814

815 if (SrcVT == MVT::i1 && Subtarget->useCRBits())

816 return false;

817

818

819

820

821

822 int64_t Imm = 0;

823 bool UseImm = false;

824 const bool HasSPE = Subtarget->hasSPE();

825

826

827

829 if (SrcVT == MVT::i64 || SrcVT == MVT::i32 || SrcVT == MVT::i16 ||

830 SrcVT == MVT::i8 || SrcVT == MVT::i1) {

831 const APInt &CIVal = ConstInt->getValue();

835 UseImm = true;

836 }

837 }

838

839 Register SrcReg1 = getRegForValue(SrcValue1);

840 if (!SrcReg1)

841 return false;

842

844 if (!UseImm) {

845 SrcReg2 = getRegForValue(SrcValue2);

846 if (!SrcReg2)

847 return false;

848 }

849

850 unsigned CmpOpc;

851 bool NeedsExt = false;

852

853 auto RC1 = MRI.getRegClass(SrcReg1);

854 auto RC2 = SrcReg2 != 0 ? MRI.getRegClass(SrcReg2) : nullptr;

855

857 default: return false;

858 case MVT::f32:

859 if (HasSPE) {

860 switch (Pred) {

861 default: return false;

863 CmpOpc = PPC::EFSCMPEQ;

864 break;

866 CmpOpc = PPC::EFSCMPLT;

867 break;

869 CmpOpc = PPC::EFSCMPGT;

870 break;

871 }

872 } else {

873 CmpOpc = PPC::FCMPUS;

874 if (isVSSRCRegClass(RC1))

875 SrcReg1 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg1);

876 if (RC2 && isVSSRCRegClass(RC2))

877 SrcReg2 = copyRegToRegClass(&PPC::F4RCRegClass, SrcReg2);

878 }

879 break;

880 case MVT::f64:

881 if (HasSPE) {

882 switch (Pred) {

883 default: return false;

885 CmpOpc = PPC::EFDCMPEQ;

886 break;

888 CmpOpc = PPC::EFDCMPLT;

889 break;

891 CmpOpc = PPC::EFDCMPGT;

892 break;

893 }

894 } else if (isVSFRCRegClass(RC1) || (RC2 && isVSFRCRegClass(RC2))) {

895 CmpOpc = PPC::XSCMPUDP;

896 } else {

897 CmpOpc = PPC::FCMPUD;

898 }

899 break;

900 case MVT::i1:

901 case MVT::i8:

902 case MVT::i16:

903 NeedsExt = true;

904 [[fallthrough]];

905 case MVT::i32:

906 if (!UseImm)

907 CmpOpc = IsZExt ? PPC::CMPLW : PPC::CMPW;

908 else

909 CmpOpc = IsZExt ? PPC::CMPLWI : PPC::CMPWI;

910 break;

911 case MVT::i64:

912 if (!UseImm)

913 CmpOpc = IsZExt ? PPC::CMPLD : PPC::CMPD;

914 else

915 CmpOpc = IsZExt ? PPC::CMPLDI : PPC::CMPDI;

916 break;

917 }

918

919 if (NeedsExt) {

920 Register ExtReg = createResultReg(&PPC::GPRCRegClass);

921 if (!PPCEmitIntExt(SrcVT, SrcReg1, MVT::i32, ExtReg, IsZExt))

922 return false;

923 SrcReg1 = ExtReg;

924

925 if (!UseImm) {

926 Register ExtReg = createResultReg(&PPC::GPRCRegClass);

927 if (!PPCEmitIntExt(SrcVT, SrcReg2, MVT::i32, ExtReg, IsZExt))

928 return false;

929 SrcReg2 = ExtReg;

930 }

931 }

932

933 if (!UseImm)

934 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc), DestReg)

936 else

937 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(CmpOpc), DestReg)

939

940 return true;

941}

942

943

944bool PPCFastISel::SelectFPExt(const Instruction *I) {

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

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

948

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

950 return false;

951

952 Register SrcReg = getRegForValue(Src);

953 if (!SrcReg)

954 return false;

955

956

957 updateValueMap(I, SrcReg);

958 return true;

959}

960

961

962bool PPCFastISel::SelectFPTrunc(const Instruction *I) {

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

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

966

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

968 return false;

969

970 Register SrcReg = getRegForValue(Src);

971 if (!SrcReg)

972 return false;

973

974

976 auto RC = MRI.getRegClass(SrcReg);

977 if (Subtarget->hasSPE()) {

978 DestReg = createResultReg(&PPC::GPRCRegClass);

979 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::EFSCFD),

980 DestReg)

982 } else if (Subtarget->hasP8Vector() && isVSFRCRegClass(RC)) {

983 DestReg = createResultReg(&PPC::VSSRCRegClass);

984 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::XSRSP),

985 DestReg)

987 } else {

988 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);

989 DestReg = createResultReg(&PPC::F4RCRegClass);

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

991 TII.get(PPC::FRSP), DestReg)

993 }

994

995 updateValueMap(I, DestReg);

996 return true;

997}

998

999

1000

1001

1002

1003

1004

1005

1006Register PPCFastISel::PPCMoveToFPReg(MVT SrcVT, Register SrcReg,

1007 bool IsSigned) {

1008

1009

1010 if (SrcVT == MVT::i32) {

1011 Register TmpReg = createResultReg(&PPC::G8RCRegClass);

1012 if (!PPCEmitIntExt(MVT::i32, SrcReg, MVT::i64, TmpReg, !IsSigned))

1014 SrcReg = TmpReg;

1015 }

1016

1017

1019 Addr.BaseType = Address::FrameIndexBase;

1020 Addr.Base.FI = MFI.CreateStackObject(8, Align(8), false);

1021

1022

1023 if (!PPCEmitStore(MVT::i64, SrcReg, Addr))

1025

1026

1027

1028 unsigned LoadOpc = PPC::LFD;

1029

1030 if (SrcVT == MVT::i32) {

1031 if (!IsSigned) {

1032 LoadOpc = PPC::LFIWZX;

1033 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;

1034 } else if (Subtarget->hasLFIWAX()) {

1035 LoadOpc = PPC::LFIWAX;

1036 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;

1037 }

1038 }

1039

1040 const TargetRegisterClass *RC = &PPC::F8RCRegClass;

1042 if (!PPCEmitLoad(MVT::f64, ResultReg, Addr, RC, !IsSigned, LoadOpc))

1044

1045 return ResultReg;

1046}

1047

1048

1049

1050

1051bool PPCFastISel::SelectIToFP(const Instruction *I, bool IsSigned) {

1052 MVT DstVT;

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

1054 if (!isTypeLegal(DstTy, DstVT))

1055 return false;

1056

1057 if (DstVT != MVT::f32 && DstVT != MVT::f64)

1058 return false;

1059

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

1061 EVT SrcEVT = TLI.getValueType(DL, Src->getType(), true);

1063 return false;

1064

1066

1067 if (SrcVT != MVT::i8 && SrcVT != MVT::i16 &&

1068 SrcVT != MVT::i32 && SrcVT != MVT::i64)

1069 return false;

1070

1071 Register SrcReg = getRegForValue(Src);

1072 if (!SrcReg)

1073 return false;

1074

1075

1076 if (Subtarget->hasSPE()) {

1077 unsigned Opc;

1078 if (DstVT == MVT::f32)

1079 Opc = IsSigned ? PPC::EFSCFSI : PPC::EFSCFUI;

1080 else

1081 Opc = IsSigned ? PPC::EFDCFSI : PPC::EFDCFUI;

1082

1083 Register DestReg = createResultReg(&PPC::SPERCRegClass);

1084

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

1087 updateValueMap(I, DestReg);

1088 return true;

1089 }

1090

1091

1092

1093 if (!IsSigned && !Subtarget->hasFPCVT())

1094 return false;

1095

1096

1097

1098

1099

1100

1101 if (DstVT == MVT::f32 && !Subtarget->hasFPCVT())

1102 return false;

1103

1104

1105 if (SrcVT == MVT::i8 || SrcVT == MVT::i16) {

1106 Register TmpReg = createResultReg(&PPC::G8RCRegClass);

1107 if (!PPCEmitIntExt(SrcVT, SrcReg, MVT::i64, TmpReg, !IsSigned))

1108 return false;

1109 SrcVT = MVT::i64;

1110 SrcReg = TmpReg;

1111 }

1112

1113

1114 Register FPReg = PPCMoveToFPReg(SrcVT, SrcReg, IsSigned);

1116 return false;

1117

1118

1119 const TargetRegisterClass *RC = &PPC::F8RCRegClass;

1120 Register DestReg = createResultReg(RC);

1121 unsigned Opc;

1122

1123 if (DstVT == MVT::f32)

1124 Opc = IsSigned ? PPC::FCFIDS : PPC::FCFIDUS;

1125 else

1126 Opc = IsSigned ? PPC::FCFID : PPC::FCFIDU;

1127

1128

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

1131

1132 updateValueMap(I, DestReg);

1133 return true;

1134}

1135

1136

1137

1138

1139

1140

1141Register PPCFastISel::PPCMoveToIntReg(const Instruction *I, MVT VT,

1142 Register SrcReg, bool IsSigned) {

1143

1144

1145

1146

1148 Addr.BaseType = Address::FrameIndexBase;

1149 Addr.Base.FI = MFI.CreateStackObject(8, Align(8), false);

1150

1151

1152 if (!PPCEmitStore(MVT::f64, SrcReg, Addr))

1154

1155

1156

1157 if (VT == MVT::i32)

1158 Addr.Offset = (Subtarget->isLittleEndian()) ? 0 : 4;

1159

1160

1161

1162 Register AssignedReg = FuncInfo.ValueMap[I];

1163 const TargetRegisterClass *RC =

1164 AssignedReg ? MRI.getRegClass(AssignedReg) : nullptr;

1165

1167 if (!PPCEmitLoad(VT, ResultReg, Addr, RC, !IsSigned))

1169

1170 return ResultReg;

1171}

1172

1173

1174

1175

1176bool PPCFastISel::SelectFPToI(const Instruction *I, bool IsSigned) {

1177 MVT DstVT, SrcVT;

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

1179 if (!isTypeLegal(DstTy, DstVT))

1180 return false;

1181

1182 if (DstVT != MVT::i32 && DstVT != MVT::i64)

1183 return false;

1184

1185

1186 if (DstVT == MVT::i64 && !IsSigned && !Subtarget->hasFPCVT() &&

1187 !Subtarget->hasSPE())

1188 return false;

1189

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

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

1192 if (!isTypeLegal(SrcTy, SrcVT))

1193 return false;

1194

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

1196 return false;

1197

1198 Register SrcReg = getRegForValue(Src);

1199 if (!SrcReg)

1200 return false;

1201

1202

1203

1204 const TargetRegisterClass *InRC = MRI.getRegClass(SrcReg);

1205 if (InRC == &PPC::F4RCRegClass)

1206 SrcReg = copyRegToRegClass(&PPC::F8RCRegClass, SrcReg);

1207 else if (InRC == &PPC::VSSRCRegClass)

1208 SrcReg = copyRegToRegClass(&PPC::VSFRCRegClass, SrcReg);

1209

1210

1211

1213 unsigned Opc;

1214 auto RC = MRI.getRegClass(SrcReg);

1215

1216 if (Subtarget->hasSPE()) {

1217 DestReg = createResultReg(&PPC::GPRCRegClass);

1218 if (IsSigned)

1219 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTSIZ : PPC::EFDCTSIZ;

1220 else

1221 Opc = InRC == &PPC::GPRCRegClass ? PPC::EFSCTUIZ : PPC::EFDCTUIZ;

1222 } else if (isVSFRCRegClass(RC)) {

1223 DestReg = createResultReg(&PPC::VSFRCRegClass);

1224 if (DstVT == MVT::i32)

1225 Opc = IsSigned ? PPC::XSCVDPSXWS : PPC::XSCVDPUXWS;

1226 else

1227 Opc = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;

1228 } else {

1229 DestReg = createResultReg(&PPC::F8RCRegClass);

1230 if (DstVT == MVT::i32)

1231 if (IsSigned)

1232 Opc = PPC::FCTIWZ;

1233 else

1234 Opc = Subtarget->hasFPCVT() ? PPC::FCTIWUZ : PPC::FCTIDZ;

1235 else

1236 Opc = IsSigned ? PPC::FCTIDZ : PPC::FCTIDUZ;

1237 }

1238

1239

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

1242

1243

1244 Register IntReg = Subtarget->hasSPE()

1245 ? DestReg

1246 : PPCMoveToIntReg(I, DstVT, DestReg, IsSigned);

1247

1248 if (!IntReg)

1249 return false;

1250

1251 updateValueMap(I, IntReg);

1252 return true;

1253}

1254

1255

1256

1257bool PPCFastISel::SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode) {

1259

1260

1261

1262 if (DestVT != MVT::i16 && DestVT != MVT::i8)

1263 return false;

1264

1265

1266

1267

1268 Register AssignedReg = FuncInfo.ValueMap[I];

1269 const TargetRegisterClass *RC =

1270 (AssignedReg ? MRI.getRegClass(AssignedReg) :

1271 &PPC::GPRC_and_GPRC_NOR0RegClass);

1273

1274 unsigned Opc;

1275 switch (ISDOpcode) {

1276 default: return false;

1278 Opc = IsGPRC ? PPC::ADD4 : PPC::ADD8;

1279 break;

1281 Opc = IsGPRC ? PPC::OR : PPC::OR8;

1282 break;

1284 Opc = IsGPRC ? PPC::SUBF : PPC::SUBF8;

1285 break;

1286 }

1287

1288 Register ResultReg = createResultReg(RC ? RC : &PPC::G8RCRegClass);

1289 Register SrcReg1 = getRegForValue(I->getOperand(0));

1290 if (!SrcReg1)

1291 return false;

1292

1293

1295 const APInt &CIVal = ConstInt->getValue();

1297 bool UseImm = true;

1299 switch (Opc) {

1300 default:

1302 case PPC::ADD4:

1303 Opc = PPC::ADDI;

1304 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);

1305 break;

1306 case PPC::ADD8:

1307 Opc = PPC::ADDI8;

1308 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);

1309 break;

1310 case PPC::OR:

1311 Opc = PPC::ORI;

1312 break;

1313 case PPC::OR8:

1314 Opc = PPC::ORI8;

1315 break;

1316 case PPC::SUBF:

1317 if (Imm == -32768)

1318 UseImm = false;

1319 else {

1320 Opc = PPC::ADDI;

1321 MRI.setRegClass(SrcReg1, &PPC::GPRC_and_GPRC_NOR0RegClass);

1323 }

1324 break;

1325 case PPC::SUBF8:

1326 if (Imm == -32768)

1327 UseImm = false;

1328 else {

1329 Opc = PPC::ADDI8;

1330 MRI.setRegClass(SrcReg1, &PPC::G8RC_and_G8RC_NOX0RegClass);

1332 }

1333 break;

1334 }

1335

1336 if (UseImm) {

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

1338 ResultReg)

1341 updateValueMap(I, ResultReg);

1342 return true;

1343 }

1344 }

1345 }

1346

1347

1348 Register SrcReg2 = getRegForValue(I->getOperand(1));

1349 if (!SrcReg2)

1350 return false;

1351

1352

1355

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

1358 updateValueMap(I, ResultReg);

1359 return true;

1360}

1361

1362

1363

1364bool PPCFastISel::processCallArgs(SmallVectorImpl<Value *> &Args,

1365 SmallVectorImpl &ArgRegs,

1366 SmallVectorImpl &ArgVTs,

1367 SmallVectorImplISD::ArgFlagsTy &ArgFlags,

1368 SmallVectorImpl &RegArgs,

1369 CallingConv::ID CC, unsigned &NumBytes,

1370 bool IsVarArg) {

1372 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, ArgLocs, *Context);

1373

1374

1376 CCInfo.AllocateStack(LinkageSize, Align(8));

1377

1379 for (Value *Arg : Args)

1380 ArgTys.push_back(Arg->getType());

1381 CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, ArgTys, CC_PPC64_ELF_FIS);

1382

1383

1384 for (const CCValAssign &VA : ArgLocs) {

1385 MVT ArgVT = ArgVTs[VA.getValNo()];

1386

1387

1388

1390 !VA.isRegLoc() || VA.needsCustom())

1391 return false;

1392

1393

1395 return false;

1396 }

1397

1398

1399 NumBytes = CCInfo.getStackSize();

1400

1401

1402

1403

1404

1405

1406

1407 NumBytes = std::max(NumBytes, LinkageSize + 64);

1408

1409

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

1413

1414

1415

1416

1417 unsigned NextGPR = PPC::X3;

1418 unsigned NextFPR = PPC::F1;

1419

1420

1421 for (const CCValAssign &VA : ArgLocs) {

1422 Register Arg = ArgRegs[VA.getValNo()];

1423 MVT ArgVT = ArgVTs[VA.getValNo()];

1424

1425

1426 switch (VA.getLocInfo()) {

1427 default:

1430 break;

1432 MVT DestVT = VA.getLocVT();

1433 const TargetRegisterClass *RC =

1434 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;

1435 Register TmpReg = createResultReg(RC);

1436 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg, false))

1438 ArgVT = DestVT;

1439 Arg = TmpReg;

1440 break;

1441 }

1444 MVT DestVT = VA.getLocVT();

1445 const TargetRegisterClass *RC =

1446 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;

1447 Register TmpReg = createResultReg(RC);

1448 if (!PPCEmitIntExt(ArgVT, Arg, DestVT, TmpReg, true))

1450 ArgVT = DestVT;

1451 Arg = TmpReg;

1452 break;

1453 }

1455

1456 llvm_unreachable("Should have bailed before getting here!");

1457 break;

1458 }

1459 }

1460

1461

1462 unsigned ArgReg;

1463 if (ArgVT == MVT::f32 || ArgVT == MVT::f64) {

1464 ArgReg = NextFPR++;

1465 if (CC != CallingConv::Fast)

1466 ++NextGPR;

1467 } else

1468 ArgReg = NextGPR++;

1469

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

1471 TII.get(TargetOpcode::COPY), ArgReg).addReg(Arg);

1473 }

1474

1475 return true;

1476}

1477

1478

1479

1480bool PPCFastISel::finishCall(MVT RetVT, CallLoweringInfo &CLI, unsigned &NumBytes) {

1481 CallingConv::ID CC = CLI.CallConv;

1482

1483

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

1487

1488

1489

1490

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

1493 CCState CCInfo(CC, false, *FuncInfo.MF, RVLocs, *Context);

1495 CCValAssign &VA = RVLocs[0];

1496 assert(RVLocs.size() == 1 && "No support for multi-reg return values!");

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

1498

1500 MVT CopyVT = DestVT;

1501

1502

1503

1504 if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32)

1505 CopyVT = MVT::i64;

1506

1509

1510 if (RetVT == CopyVT) {

1511 const TargetRegisterClass *CpyRC = TLI.getRegClassFor(CopyVT);

1512 ResultReg = copyRegToRegClass(CpyRC, SourcePhysReg);

1513

1514

1515 } else if (CopyVT == MVT::f64) {

1516 ResultReg = createResultReg(TLI.getRegClassFor(RetVT));

1517 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::FRSP),

1518 ResultReg).addReg(SourcePhysReg);

1519

1520

1521

1522

1523

1524 } else if (RetVT == MVT::i8 || RetVT == MVT::i16 || RetVT == MVT::i32) {

1525

1526 SourcePhysReg = (SourcePhysReg - PPC::X0) + PPC::R0;

1527 ResultReg = copyRegToRegClass(&PPC::GPRCRegClass, SourcePhysReg);

1528 }

1529

1530 assert(ResultReg && "ResultReg unset!");

1531 CLI.InRegs.push_back(SourcePhysReg);

1532 CLI.ResultReg = ResultReg;

1533 CLI.NumResultRegs = 1;

1534 }

1535

1536 return true;

1537}

1538

1539bool PPCFastISel::fastLowerCall(CallLoweringInfo &CLI) {

1540 CallingConv::ID CC = CLI.CallConv;

1541 bool IsTailCall = CLI.IsTailCall;

1542 bool IsVarArg = CLI.IsVarArg;

1545

1546 if (!Callee && !Symbol)

1547 return false;

1548

1549

1550 if (IsTailCall || Subtarget->useLongCalls())

1551 return false;

1552

1553

1554 if (IsVarArg)

1555 return false;

1556

1557

1559 return false;

1560

1561

1562

1563 Type *RetTy = CLI.RetTy;

1564 MVT RetVT;

1566 RetVT = MVT::isVoid;

1567 else if (!isTypeLegal(RetTy, RetVT) && RetVT != MVT::i16 &&

1568 RetVT != MVT::i8)

1569 return false;

1570 else if (RetVT == MVT::i1 && Subtarget->useCRBits())

1571

1572 return false;

1573

1574

1575 if (RetVT != MVT::isVoid && RetVT != MVT::i8 && RetVT != MVT::i16 &&

1576 RetVT != MVT::i32 && RetVT != MVT::i64 && RetVT != MVT::f32 &&

1577 RetVT != MVT::f64) {

1579 CCState CCInfo(CC, IsVarArg, *FuncInfo.MF, RVLocs, *Context);

1581 if (RVLocs.size() > 1)

1582 return false;

1583 }

1584

1585

1586

1587 unsigned NumArgs = CLI.OutVals.size();

1588 if (NumArgs > 8)

1589 return false;

1590

1591

1592 SmallVector<Value*, 8> Args;

1596

1597 Args.reserve(NumArgs);

1598 ArgRegs.reserve(NumArgs);

1599 ArgVTs.reserve(NumArgs);

1600 ArgFlags.reserve(NumArgs);

1601

1602 for (unsigned i = 0, ie = NumArgs; i != ie; ++i) {

1603

1604

1605

1606 ISD::ArgFlagsTy Flags = CLI.OutFlags[i];

1608 return false;

1609

1610 Value *ArgValue = CLI.OutVals[i];

1612 MVT ArgVT;

1613 if (!isTypeLegal(ArgTy, ArgVT) && ArgVT != MVT::i16 && ArgVT != MVT::i8)

1614 return false;

1615

1616

1617

1618

1619 if (ArgVT.isVector() || ArgVT == MVT::f128)

1620 return false;

1621

1622 Register Arg = getRegForValue(ArgValue);

1623 if (!Arg)

1624 return false;

1625

1626 Args.push_back(ArgValue);

1630 }

1631

1632

1633 SmallVector<unsigned, 8> RegArgs;

1634 unsigned NumBytes;

1635

1636 if (!processCallArgs(Args, ArgRegs, ArgVTs, ArgFlags,

1637 RegArgs, CC, NumBytes, IsVarArg))

1638 return false;

1639

1640 MachineInstrBuilder MIB;

1641

1642

1644 if (!GV) {

1645

1646

1647

1648

1649

1650 if (CLI.IsPatchPoint)

1651 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::NOP));

1652 else

1653 return false;

1654 } else {

1655

1656

1657 MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,

1658 TII.get(PPC::BL8_NOP));

1659

1661 }

1662

1663

1664 for (unsigned Reg : RegArgs)

1666

1667

1668

1671

1672

1673

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

1675

1676 CLI.Call = MIB;

1677

1678

1679 return finishCall(RetVT, CLI, NumBytes);

1680}

1681

1682

1683bool PPCFastISel::SelectRet(const Instruction *I) {

1684

1685 if (!FuncInfo.CanLowerReturn)

1686 return false;

1687

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

1690

1691

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

1694

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

1698

1699

1701 CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, ValLocs, *Context);

1704

1705

1706 if (ValLocs.size() > 1)

1707 return false;

1708

1709

1710

1713 CCValAssign &VA = ValLocs[0];

1714

1716

1717

1718

1719

1722

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

1724 TII.get(TargetOpcode::COPY), RetReg).addReg(SrcReg);

1725

1727

1728 } else {

1730

1731 if (Reg)

1732 return false;

1733

1734

1735 for (unsigned i = 0; i < ValLocs.size(); ++i) {

1736

1737 CCValAssign &VA = ValLocs[i];

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

1741

1744 return false;

1747

1748 if (RVVT != DestVT && RVVT != MVT::i8 &&

1749 RVVT != MVT::i16 && RVVT != MVT::i32)

1750 return false;

1751

1752 if (RVVT != DestVT) {

1754 default:

1757 llvm_unreachable("Full value assign but types don't match?");

1760 const TargetRegisterClass *RC =

1761 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;

1762 Register TmpReg = createResultReg(RC);

1763 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg, true))

1764 return false;

1765 SrcReg = TmpReg;

1766 break;

1767 }

1769 const TargetRegisterClass *RC =

1770 (DestVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;

1771 Register TmpReg = createResultReg(RC);

1772 if (!PPCEmitIntExt(RVVT, SrcReg, DestVT, TmpReg, false))

1773 return false;

1774 SrcReg = TmpReg;

1775 break;

1776 }

1777 }

1778 }

1779

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

1781 TII.get(TargetOpcode::COPY), RetRegs[i])

1783 }

1784 }

1785 }

1786

1787 MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD,

1788 TII.get(PPC::BLR8));

1789

1792

1793 return true;

1794}

1795

1796

1797

1798

1799bool PPCFastISel::PPCEmitIntExt(MVT SrcVT, Register SrcReg, MVT DestVT,

1800 Register DestReg, bool IsZExt) {

1801 if (DestVT != MVT::i32 && DestVT != MVT::i64)

1802 return false;

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

1804 return false;

1805

1806

1807 if (!IsZExt) {

1808 unsigned Opc;

1809 if (SrcVT == MVT::i8)

1810 Opc = (DestVT == MVT::i32) ? PPC::EXTSB : PPC::EXTSB8_32_64;

1811 else if (SrcVT == MVT::i16)

1812 Opc = (DestVT == MVT::i32) ? PPC::EXTSH : PPC::EXTSH8_32_64;

1813 else {

1814 assert(DestVT == MVT::i64 && "Signed extend from i32 to i32??");

1815 Opc = PPC::EXTSW_32_64;

1816 }

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

1819

1820

1821 } else if (DestVT == MVT::i32) {

1822 unsigned MB;

1823 if (SrcVT == MVT::i8)

1824 MB = 24;

1825 else {

1826 assert(SrcVT == MVT::i16 && "Unsigned extend from i32 to i32??");

1827 MB = 16;

1828 }

1829 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::RLWINM),

1830 DestReg)

1832

1833

1834 } else {

1835 unsigned MB;

1836 if (SrcVT == MVT::i8)

1837 MB = 56;

1838 else if (SrcVT == MVT::i16)

1839 MB = 48;

1840 else

1841 MB = 32;

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

1843 TII.get(PPC::RLDICL_32_64), DestReg)

1845 }

1846

1847 return true;

1848}

1849

1850

1851bool PPCFastISel::SelectIndirectBr(const Instruction *I) {

1852 Register AddrReg = getRegForValue(I->getOperand(0));

1853 if (!AddrReg)

1854 return false;

1855

1856 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::MTCTR8))

1858 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::BCTR8));

1859

1861 for (const BasicBlock *SuccBB : IB->successors())

1862 FuncInfo.MBB->addSuccessor(FuncInfo.getMBB(SuccBB));

1863

1864 return true;

1865}

1866

1867

1868bool PPCFastISel::SelectTrunc(const Instruction *I) {

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

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

1872

1873 if (SrcVT != MVT::i64 && SrcVT != MVT::i32 && SrcVT != MVT::i16)

1874 return false;

1875

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

1877 return false;

1878

1879 Register SrcReg = getRegForValue(Src);

1880 if (!SrcReg)

1881 return false;

1882

1883

1884 if (SrcVT == MVT::i64)

1885 SrcReg = copyRegToRegClass(&PPC::GPRCRegClass, SrcReg, 0, PPC::sub_32);

1886

1887 updateValueMap(I, SrcReg);

1888 return true;

1889}

1890

1891

1892bool PPCFastISel::SelectIntExt(const Instruction *I) {

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

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

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

1896

1898 Register SrcReg = getRegForValue(Src);

1899 if (!SrcReg) return false;

1900

1901 EVT SrcEVT, DestEVT;

1905 return false;

1907 return false;

1908

1911

1912

1913

1914

1915

1916 Register AssignedReg = FuncInfo.ValueMap[I];

1917 const TargetRegisterClass *RC =

1918 (AssignedReg ? MRI.getRegClass(AssignedReg) :

1919 (DestVT == MVT::i64 ? &PPC::G8RC_and_G8RC_NOX0RegClass :

1920 &PPC::GPRC_and_GPRC_NOR0RegClass));

1921 Register ResultReg = createResultReg(RC);

1922

1923 if (!PPCEmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, IsZExt))

1924 return false;

1925

1926 updateValueMap(I, ResultReg);

1927 return true;

1928}

1929

1930

1931

1932bool PPCFastISel::fastSelectInstruction(const Instruction *I) {

1933

1934 switch (I->getOpcode()) {

1935 case Instruction::Load:

1936 return SelectLoad(I);

1937 case Instruction::Store:

1938 return SelectStore(I);

1939 case Instruction::Br:

1940 return SelectBranch(I);

1941 case Instruction::IndirectBr:

1942 return SelectIndirectBr(I);

1943 case Instruction::FPExt:

1944 return SelectFPExt(I);

1945 case Instruction::FPTrunc:

1946 return SelectFPTrunc(I);

1947 case Instruction::SIToFP:

1948 return SelectIToFP(I, true);

1949 case Instruction::UIToFP:

1950 return SelectIToFP(I, false);

1951 case Instruction::FPToSI:

1952 return SelectFPToI(I, true);

1953 case Instruction::FPToUI:

1954 return SelectFPToI(I, false);

1955 case Instruction::Add:

1956 return SelectBinaryIntOp(I, ISD::ADD);

1957 case Instruction::Or:

1958 return SelectBinaryIntOp(I, ISD::OR);

1959 case Instruction::Sub:

1960 return SelectBinaryIntOp(I, ISD::SUB);

1961 case Instruction::Ret:

1962 return SelectRet(I);

1963 case Instruction::Trunc:

1964 return SelectTrunc(I);

1965 case Instruction::ZExt:

1966 case Instruction::SExt:

1967 return SelectIntExt(I);

1968

1969

1970

1971 default:

1972 break;

1973 }

1974 return false;

1975}

1976

1977

1978

1979Register PPCFastISel::PPCMaterializeFP(const ConstantFP *CFP, MVT VT) {

1980

1983

1984

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

1987

1988

1989 Align Alignment = DL.getPrefTypeAlign(CFP->getType());

1990 unsigned Idx = MCP.getConstantPoolIndex(cast(CFP), Alignment);

1991 const bool HasSPE = Subtarget->hasSPE();

1992 const TargetRegisterClass *RC;

1993 if (HasSPE)

1994 RC = ((VT == MVT::f32) ? &PPC::GPRCRegClass : &PPC::SPERCRegClass);

1995 else

1996 RC = ((VT == MVT::f32) ? &PPC::F4RCRegClass : &PPC::F8RCRegClass);

1997

1998 Register DestReg = createResultReg(RC);

2000

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

2004

2005 unsigned Opc;

2006

2007 if (HasSPE)

2008 Opc = ((VT == MVT::f32) ? PPC::SPELWZ : PPC::EVLDD);

2009 else

2010 Opc = ((VT == MVT::f32) ? PPC::LFS : PPC::LFD);

2011

2012 Register TmpReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);

2013

2015

2017 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocCPT),

2018 TmpReg)

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

2022 } else {

2023

2024 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDIStocHA8),

2026

2027

2029 Register TmpReg2 = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);

2030 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocL),

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

2035 } else

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

2040 }

2041

2042 return DestReg;

2043}

2044

2045

2046

2047Register PPCFastISel::PPCMaterializeGV(const GlobalValue *GV, MVT VT) {

2048

2051

2052 assert(VT == MVT::i64 && "Non-address!");

2053 const TargetRegisterClass *RC = &PPC::G8RC_and_G8RC_NOX0RegClass;

2054 Register DestReg = createResultReg(RC);

2055

2056

2057

2058

2060

2061

2062

2063

2064

2065

2068

2073

2074

2077 *FuncInfo.MBB, FuncInfo.InsertPt, MIMD,

2078 IsAIXTocData ? TII.get(PPC::ADDItoc8) : TII.get(PPC::LDtoc), DestReg);

2079 if (IsAIXTocData)

2081 else

2083 } else {

2084

2085

2086

2087

2088

2089

2090

2091

2092 Register HighPartReg = createResultReg(RC);

2093 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDIStocHA8),

2095

2097 assert(!IsAIXTocData && "TOC data should always be direct.");

2098 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::LDtocL),

2100 } else {

2101

2102 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDItocL8),

2103 DestReg)

2104 .addReg(HighPartReg)

2106 }

2107 }

2108

2109 return DestReg;

2110}

2111

2112

2113

2114Register PPCFastISel::PPCMaterialize32BitInt(int64_t Imm,

2115 const TargetRegisterClass *RC) {

2116 unsigned Lo = Imm & 0xFFFF;

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

2118

2119 Register ResultReg = createResultReg(RC);

2121

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

2124 TII.get(IsGPRC ? PPC::LI : PPC::LI8), ResultReg)

2126 else if (Lo) {

2127

2128 Register TmpReg = createResultReg(RC);

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

2130 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), TmpReg)

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

2133 TII.get(IsGPRC ? PPC::ORI : PPC::ORI8), ResultReg)

2135 } else

2136

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

2138 TII.get(IsGPRC ? PPC::LIS : PPC::LIS8), ResultReg)

2140

2141 return ResultReg;

2142}

2143

2144

2145

2146Register PPCFastISel::PPCMaterialize64BitInt(int64_t Imm,

2147 const TargetRegisterClass *RC) {

2148 unsigned Remainder = 0;

2149 unsigned Shift = 0;

2150

2151

2152

2155 int64_t ImmSh = static_cast<uint64_t>(Imm) >> Shift;

2156

2158 Imm = ImmSh;

2159 else {

2160 Remainder = Imm;

2161 Shift = 32;

2162 Imm >>= 32;

2163 }

2164 }

2165

2166

2167

2168 Register TmpReg1 = PPCMaterialize32BitInt(Imm, RC);

2169 if (!Shift)

2170 return TmpReg1;

2171

2172

2173

2175 if (Imm) {

2176 TmpReg2 = createResultReg(RC);

2177 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::RLDICR),

2179 } else

2180 TmpReg2 = TmpReg1;

2181

2183 unsigned Hi, Lo;

2184 if ((Hi = (Remainder >> 16) & 0xFFFF)) {

2185 TmpReg3 = createResultReg(RC);

2186 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ORIS8),

2188 } else

2189 TmpReg3 = TmpReg2;

2190

2191 if ((Lo = Remainder & 0xFFFF)) {

2192 Register ResultReg = createResultReg(RC);

2193 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ORI8),

2195 return ResultReg;

2196 }

2197

2198 return TmpReg3;

2199}

2200

2201

2202

2203Register PPCFastISel::PPCMaterializeInt(const ConstantInt *CI, MVT VT,

2204 bool UseSExt) {

2205

2206

2207 if (VT == MVT::i1 && Subtarget->useCRBits()) {

2208 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);

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

2210 TII.get(CI->isZero() ? PPC::CRUNSET : PPC::CRSET), ImmReg);

2211 return ImmReg;

2212 }

2213

2214 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&

2215 VT != MVT::i1)

2217

2218 const TargetRegisterClass *RC =

2219 ((VT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass);

2221

2222

2223

2224

2225

2227 unsigned Opc = (VT == MVT::i64) ? PPC::LI8 : PPC::LI;

2228 Register ImmReg = createResultReg(RC);

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

2231 return ImmReg;

2232 }

2233

2234

2235 if (VT == MVT::i64)

2236 return PPCMaterialize64BitInt(Imm, RC);

2237 else if (VT == MVT::i32)

2238 return PPCMaterialize32BitInt(Imm, RC);

2239

2241}

2242

2243

2244

2245Register PPCFastISel::fastMaterializeConstant(const Constant *C) {

2247

2248

2252

2254 return PPCMaterializeFP(CFP, VT);

2256 return PPCMaterializeGV(GV, VT);

2258

2259

2260

2261

2262

2263 return PPCMaterializeInt(CI, VT, false);

2264

2266}

2267

2268

2269

2270Register PPCFastISel::fastMaterializeAlloca(const AllocaInst *AI) {

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

2272 FuncInfo.StaticAllocaMap.find(AI);

2273

2274

2275 if (SI == FuncInfo.StaticAllocaMap.end())

2277

2278 MVT VT;

2279 if (!isLoadTypeLegal(AI->getType(), VT))

2281

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

2283 Register ResultReg = createResultReg(&PPC::G8RC_and_G8RC_NOX0RegClass);

2284 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(PPC::ADDI8),

2286 return ResultReg;

2287 }

2288

2290}

2291

2292

2293

2294

2295

2296

2297

2298

2299

2300bool PPCFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo,

2301 const LoadInst *LI) {

2302

2303 MVT VT;

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

2305 return false;

2306

2307

2308 bool IsZExt = false;

2309 switch(MI->getOpcode()) {

2310 default:

2311 return false;

2312

2313 case PPC::RLDICL:

2314 case PPC::RLDICL_32_64: {

2315 IsZExt = true;

2316 unsigned MB = MI->getOperand(3).getImm();

2317 if ((VT == MVT::i8 && MB <= 56) ||

2318 (VT == MVT::i16 && MB <= 48) ||

2319 (VT == MVT::i32 && MB <= 32))

2320 break;

2321 return false;

2322 }

2323

2324 case PPC::RLWINM:

2325 case PPC::RLWINM8: {

2326 IsZExt = true;

2327 unsigned MB = MI->getOperand(3).getImm();

2328 if ((VT == MVT::i8 && MB <= 24) ||

2329 (VT == MVT::i16 && MB <= 16))

2330 break;

2331 return false;

2332 }

2333

2334 case PPC::EXTSB:

2335 case PPC::EXTSB8:

2336 case PPC::EXTSB8_32_64:

2337

2338 return false;

2339

2340 case PPC::EXTSH:

2341 case PPC::EXTSH8:

2342 case PPC::EXTSH8_32_64: {

2343 if (VT != MVT::i16 && VT != MVT::i8)

2344 return false;

2345 break;

2346 }

2347

2348 case PPC::EXTSW:

2349 case PPC::EXTSW_32:

2350 case PPC::EXTSW_32_64: {

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

2352 return false;

2353 break;

2354 }

2355 }

2356

2357

2359 if (!PPCComputeAddress(LI->getOperand(0), Addr))

2360 return false;

2361

2362 Register ResultReg = MI->getOperand(0).getReg();

2363

2364 if (!PPCEmitLoad(VT, ResultReg, Addr, nullptr, IsZExt,

2365 Subtarget->hasSPE() ? PPC::EVLDD : PPC::LFD))

2366 return false;

2367

2369 removeDeadCode(I, std::next(I));

2370 return true;

2371}

2372

2373

2374

2375bool PPCFastISel::fastLowerArguments() {

2376

2377

2378

2379

2380 return false;

2381}

2382

2383

2384

2385Register PPCFastISel::fastEmit_i(MVT Ty, MVT VT, unsigned Opc, uint64_t Imm) {

2386

2389

2390

2391

2392 if (VT == MVT::i1 && Subtarget->useCRBits()) {

2393 Register ImmReg = createResultReg(&PPC::CRBITRCRegClass);

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

2395 TII.get(Imm == 0 ? PPC::CRUNSET : PPC::CRSET), ImmReg);

2396 return ImmReg;

2397 }

2398

2399 if (VT != MVT::i64 && VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 &&

2400 VT != MVT::i1)

2402

2403 const TargetRegisterClass *RC = ((VT == MVT::i64) ? &PPC::G8RCRegClass :

2404 &PPC::GPRCRegClass);

2405 if (VT == MVT::i64)

2406 return PPCMaterialize64BitInt(Imm, RC);

2407 else

2408 return PPCMaterialize32BitInt(Imm, RC);

2409}

2410

2411

2412

2413

2414

2415

2416

2417

2418

2419

2420

2421

2422Register PPCFastISel::fastEmitInst_ri(unsigned MachineInstOpcode,

2423 const TargetRegisterClass *RC,

2424 Register Op0, uint64_t Imm) {

2425 if (MachineInstOpcode == PPC::ADDI)

2426 MRI.setRegClass(Op0, &PPC::GPRC_and_GPRC_NOR0RegClass);

2427 else if (MachineInstOpcode == PPC::ADDI8)

2428 MRI.setRegClass(Op0, &PPC::G8RC_and_G8RC_NOX0RegClass);

2429

2430 const TargetRegisterClass *UseRC =

2431 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :

2432 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));

2433

2435}

2436

2437

2438

2439

2440Register PPCFastISel::fastEmitInst_r(unsigned MachineInstOpcode,

2441 const TargetRegisterClass *RC,

2443 const TargetRegisterClass *UseRC =

2444 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :

2445 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));

2446

2448}

2449

2450

2451

2452

2453Register PPCFastISel::fastEmitInst_rr(unsigned MachineInstOpcode,

2454 const TargetRegisterClass *RC,

2456 const TargetRegisterClass *UseRC =

2457 (RC == &PPC::GPRCRegClass ? &PPC::GPRC_and_GPRC_NOR0RegClass :

2458 (RC == &PPC::G8RCRegClass ? &PPC::G8RC_and_G8RC_NOX0RegClass : RC));

2459

2461}

2462

2463namespace llvm {

2464

2467

2469 if (Subtarget.isPPC64())

2470 return new PPCFastISel(FuncInfo, LibInfo);

2471 return nullptr;

2472 }

2473}

unsigned const MachineRegisterInfo * MRI

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

const TargetInstrInfo & TII

static ARMCC::CondCodes getComparePred(CmpInst::Predicate Pred)

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

This file defines the FastISel class.

This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...

Register const TargetRegisterInfo * TRI

Promote Memory to Register

uint64_t IntrinsicInst * II

static std::optional< PPC::Predicate > getComparePred(CmpInst::Predicate Pred)

Definition PPCFastISel.cpp:189

static constexpr MCPhysReg FPReg

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

BaseType

A given derived pointer can have multiple base pointers through phi/selects.

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

uint64_t getZExtValue() const

Get zero extended value.

int64_t getSExtValue() const

Get sign 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

Register getLocReg() const

LocInfo getLocInfo() const

unsigned getValNo() const

Predicate

This enumeration lists the possible predicates for CmpInst subclasses.

@ FCMP_OEQ

0 0 0 1 True if ordered and equal

@ FCMP_TRUE

1 1 1 1 Always true (always folded)

@ ICMP_SLT

signed less than

@ ICMP_SLE

signed less or equal

@ FCMP_OLT

0 1 0 0 True if ordered and less than

@ FCMP_ULE

1 1 0 1 True if unordered, less than, or equal

@ 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

@ FCMP_ULT

1 1 0 0 True if unordered or less than

@ FCMP_ONE

0 1 1 0 True if ordered and operands are unequal

@ FCMP_UEQ

1 0 0 1 True if unordered or equal

@ ICMP_ULT

unsigned less than

@ FCMP_UGT

1 0 1 0 True if unordered or greater than

@ FCMP_OLE

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

@ FCMP_ORD

0 1 1 1 True if ordered (no nans)

@ ICMP_SGE

signed greater or equal

@ FCMP_UNE

1 1 1 0 True if unordered or not equal

@ ICMP_ULE

unsigned less or equal

@ FCMP_UGE

1 0 1 1 True if unordered, greater than, or equal

@ FCMP_FALSE

0 0 0 0 Always false (always folded)

@ FCMP_UNO

1 0 0 0 True if unordered: isnan(X) | isnan(Y)

ConstantFP - Floating Point Values [float, double].

This is the shared class of boolean and integer constants.

bool isZero() const

This is just a convenience method to make client code smaller for a common code.

static ConstantInt * getSigned(IntegerType *Ty, int64_t V)

Return a ConstantInt with the specified value for the specified type.

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_ri(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0, uint64_t Imm)

Emit a MachineInstr with a register operand, an immediate, and a result register in the given registe...

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.

Register fastEmitInst_r(unsigned MachineInstOpcode, const TargetRegisterClass *RC, Register Op0)

Emit a MachineInstr with one register operand and a result register in the given register class.

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

MachineBasicBlock::iterator InsertPt

MBB - The current insert position inside the current block.

MachineBasicBlock * MBB

MBB - The current block.

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.

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

An instruction for reading from memory.

const MCInstrDesc & get(unsigned Opcode) const

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

bool isVector() const

Return true if this is a vector value type.

TypeSize getSizeInBits() const

Returns the size of the specified MVT in bits.

MachineInstrBundleIterator< MachineInstr > iterator

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 & addFrameIndex(int Idx) const

const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const

const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const

const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) 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

Representation of each machine instruction.

@ MOLoad

The memory access reads data.

@ MOStore

The memory access writes data.

unsigned getLinkageSize() const

getLinkageSize - Return the size of the PowerPC ABI linkage area.

PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...

const PPCFrameLowering * getFrameLowering() const override

bool isUsingPCRelativeCalls() const

const PPCTargetLowering * getTargetLowering() const override

const PPCInstrInfo * getInstrInfo() const override

bool isLittleEndian() const

bool isGVIndirectSymbol(const GlobalValue *GV) const

True if the GV will be accessed via an indirect symbol.

Wrapper class representing virtual and physical registers.

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

void reserve(size_type N)

void push_back(const T &Elt)

TypeSize getElementOffset(unsigned Idx) const

TargetInstrInfo - Interface to description of machine instruction set.

unsigned getCallFrameSetupOpcode() const

These methods return the opcode of the frame setup/destroy instructions if they exist (-1 otherwise).

unsigned getCallFrameDestroyOpcode() const

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.

const Triple & getTargetTriple() const

CodeModel::Model getCodeModel() const

Returns the code model.

unsigned getID() const

Return the register class ID number.

bool hasSuperClassEq(const TargetRegisterClass *RC) const

Returns true if RC is a super-class of or equal to this class.

bool isOSAIX() const

Tests whether the OS is AIX.

The instances of the Type class are immutable: once they are created, they are never changed.

bool isIntegerTy() const

True if this is an instance of IntegerType.

bool isVoidTy() const

Return true if this is 'void'.

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.

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.

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

unsigned ID

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

@ C

The default llvm calling convention, compatible with C.

@ ADD

Simple integer binary arithmetic operators.

Predicate

Predicate - These are "(BI << 5) | BO" for various predicates.

FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)

Definition PPCFastISel.cpp:2465

Predicate InvertPredicate(Predicate Opcode)

Invert the specified predicate. != -> ==, < -> >=.

@ Implicit

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

@ User

could "use" a pointer

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

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 RetCC_PPC64_ELF_FIS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)

int countr_zero(T Val)

Count number of 0's from the least significant bit to the most stopping at the first 1.

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

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

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.

static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)

Return a MachinePointerInfo record that refers to the constant pool.

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

Return a MachinePointerInfo record that refers to the specified FrameIndex.