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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

77#include

78#include

79#include

80#include

81

82using namespace llvm;

84

85#define DEBUG_TYPE "asmprinter"

86

87STATISTIC(NumTOCEntries, "Number of Total TOC Entries Emitted.");

88STATISTIC(NumTOCConstPool, "Number of Constant Pool TOC Entries.");

90 "Number of Internal Linkage Global TOC Entries.");

92 "Number of External Linkage Global TOC Entries.");

93STATISTIC(NumTOCJumpTable, "Number of Jump Table TOC Entries.");

94STATISTIC(NumTOCThreadLocal, "Number of Thread Local TOC Entries.");

95STATISTIC(NumTOCBlockAddress, "Number of Block Address TOC Entries.");

96STATISTIC(NumTOCEHBlock, "Number of EH Block TOC Entries.");

97

99 "aix-ssp-tb-bit", cl::init(false),

100 cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden);

101

102

103

104

105

106namespace llvm {

107template <>

108struct DenseMapInfo<std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>> {

109 using TOCKey = std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>;

110

113 }

116 }

121 }

123};

124}

125

126namespace {

127

128enum {

129

130 Tag_GNU_Power_ABI_FP = 4,

131 Tag_GNU_Power_ABI_Vector = 8,

132 Tag_GNU_Power_ABI_Struct_Return = 12,

133

134

135 Val_GNU_Power_ABI_NoFloat = 0b00,

136 Val_GNU_Power_ABI_HardFloat_DP = 0b01,

137 Val_GNU_Power_ABI_SoftFloat_DP = 0b10,

138 Val_GNU_Power_ABI_HardFloat_SP = 0b11,

139

140 Val_GNU_Power_ABI_LDBL_IBM128 = 0b0100,

141 Val_GNU_Power_ABI_LDBL_64 = 0b1000,

142 Val_GNU_Power_ABI_LDBL_IEEE128 = 0b1100,

143};

144

145class PPCAsmPrinter : public AsmPrinter {

146protected:

147

148

149

150

151

152

153

158

159

160

161

163

164public:

166 std::unique_ptr Streamer)

168

169 StringRef getPassName() const override { return "PowerPC Assembly Printer"; }

170

171 enum TOCEntryType {

172 TOCType_ConstantPool,

173 TOCType_GlobalExternal,

174 TOCType_GlobalInternal,

175 TOCType_JumpTable,

176 TOCType_ThreadLocal,

177 TOCType_BlockAddress,

178 TOCType_EHBlock

179 };

180

183 MCSymbolRefExpr::VariantKind::VK_None);

184

186 if (TOC.empty())

187 TOC.clear();

189 }

190

192

193

194

195

197

200 const char *ExtraCode, raw_ostream &O) override;

202 const char *ExtraCode, raw_ostream &O) override;

203

214 return Changed;

215 }

216};

217

218

219class PPCLinuxAsmPrinter : public PPCAsmPrinter {

220public:

222 std::unique_ptr Streamer)

223 : PPCAsmPrinter(TM, std::move(Streamer)) {}

224

225 StringRef getPassName() const override {

226 return "Linux PPC Assembly Printer";

227 }

228

229 void emitGNUAttributes(Module &M);

230

231 void emitStartOfAsmFile(Module &M) override;

232 void emitEndOfAsmFile(Module &) override;

233

234 void emitFunctionEntryLabel() override;

235

236 void emitFunctionBodyStart() override;

237 void emitFunctionBodyEnd() override;

239};

240

241class PPCAIXAsmPrinter : public PPCAsmPrinter {

242private:

243

244

246

247

248

249 std::string FormatIndicatorAndUniqueModId;

250

251

252

254 GOAliasMap;

255

256 uint16_t getNumberOfVRSaved();

257 void emitTracebackTable();

258

260

261 void emitGlobalVariableHelper(const GlobalVariable *);

262

263

265

266public:

267 PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr Streamer)

268 : PPCAsmPrinter(TM, std::move(Streamer)) {

269 if (MAI->isLittleEndian())

271 "cannot create AIX PPC Assembly Printer for a little-endian target");

272 }

273

274 StringRef getPassName() const override { return "AIX PPC Assembly Printer"; }

275

276 bool doInitialization(Module &M) override;

277

279 bool IsCtor) override;

280

282

283 void emitGlobalVariable(const GlobalVariable *GV) override;

284

285 void emitFunctionDescriptor() override;

286

287 void emitFunctionEntryLabel() override;

288

289 void emitFunctionBodyEnd() override;

290

291 void emitPGORefs(Module &M);

292

293 void emitGCOVRefs();

294

295 void emitEndOfAsmFile(Module &) override;

296

298

300

301 bool doFinalization(Module &M) override;

302

303 void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;

304

305 void emitModuleCommandLines(Module &M) override;

306};

307

308}

309

310void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,

312

314 getSymbol(GV)->print(O, MAI);

316}

317

318void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,

322

325

327

328

329

331 return;

332 }

335 return;

336

339 return;

341 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'

343 return;

345 GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);

346 return;

348 PrintSymbolOperand(MO, O);

349 return;

350 }

351

352 default:

353 O << "<unknown operand type: " << (unsigned)MO.getType() << ">";

354 return;

355 }

356}

357

358

359

360bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,

362

363 if (ExtraCode && ExtraCode[0]) {

364 if (ExtraCode[1] != 0) return true;

365

366 switch (ExtraCode[0]) {

367 default:

368

370 case 'L':

371

372 if (MI->getOperand(OpNo).isReg() ||

373 OpNo+1 == MI->getNumOperands() ||

374 MI->getOperand(OpNo+1).isReg())

375 return true;

376 ++OpNo;

377 break;

378 case 'I':

379

380

381 if (MI->getOperand(OpNo).isImm())

382 O << "i";

383 return false;

384 case 'x':

385 if(MI->getOperand(OpNo).isReg())

386 return true;

387

388

391 Reg = PPC::VSX32 + (Reg - PPC::V0);

393 Reg = PPC::VSX32 + (Reg - PPC::VF0);

398 return false;

399 }

400 }

401

403 return false;

404}

405

406

407

408

409bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,

410 const char *ExtraCode,

412 if (ExtraCode && ExtraCode[0]) {

413 if (ExtraCode[1] != 0) return true;

414

415 switch (ExtraCode[0]) {

416 default: return true;

417 case 'L':

418 O << getDataLayout().getPointerSize() << "(";

420 O << ")";

421 return false;

422 case 'y':

423 O << "0, ";

425 return false;

426 case 'I':

427

428

429 if (MI->getOperand(OpNo).isImm())

430 O << "i";

431 return false;

432 case 'U':

433 case 'X':

434

435

436

437

438

439

440 assert(MI->getOperand(OpNo).isReg());

441 return false;

442 }

443 }

444

445 assert(MI->getOperand(OpNo).isReg());

446 O << "0(";

448 O << ")";

449 return false;

450}

451

453 ++NumTOCEntries;

454 switch (Type) {

455 case PPCAsmPrinter::TOCType_ConstantPool:

456 ++NumTOCConstPool;

457 break;

458 case PPCAsmPrinter::TOCType_GlobalInternal:

459 ++NumTOCGlobalInternal;

460 break;

461 case PPCAsmPrinter::TOCType_GlobalExternal:

462 ++NumTOCGlobalExternal;

463 break;

464 case PPCAsmPrinter::TOCType_JumpTable:

465 ++NumTOCJumpTable;

466 break;

467 case PPCAsmPrinter::TOCType_ThreadLocal:

468 ++NumTOCThreadLocal;

469 break;

470 case PPCAsmPrinter::TOCType_BlockAddress:

471 ++NumTOCBlockAddress;

472 break;

473 case PPCAsmPrinter::TOCType_EHBlock:

474 ++NumTOCEHBlock;

475 break;

476 }

477}

478

483

484

485

487 return ModuleModel;

488

490 assert(GV && "expected global for MO_GlobalAddress");

491

493}

494

496 switch (CM) {

499 return;

502 return;

503 default:

505 }

506}

507

508

509

510

512PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym, TOCEntryType Type,

514

515 if (TOC.contains({Sym, Kind}))

517

519 if (!TOCEntry)

520 TOCEntry = createTempSymbol("C");

521 return TOCEntry;

522}

523

525 unsigned NumNOPBytes = MI.getOperand(1).getImm();

526

527 auto &Ctx = OutStreamer->getContext();

528 MCSymbol *MILabel = Ctx.createTempSymbol();

529 OutStreamer->emitLabel(MILabel);

530

532 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");

533

534

537 ++MII;

538 while (NumNOPBytes > 0) {

539 if (MII == MBB.end() || MII->isCall() ||

540 MII->getOpcode() == PPC::DBG_VALUE ||

541 MII->getOpcode() == TargetOpcode::PATCHPOINT ||

542 MII->getOpcode() == TargetOpcode::STACKMAP)

543 break;

544 ++MII;

545 NumNOPBytes -= 4;

546 }

547

548

549 for (unsigned i = 0; i < NumNOPBytes; i += 4)

550 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));

551}

552

553

554

556 auto &Ctx = OutStreamer->getContext();

557 MCSymbol *MILabel = Ctx.createTempSymbol();

558 OutStreamer->emitLabel(MILabel);

559

562

563 unsigned EncodedBytes = 0;

564 const MachineOperand &CalleeMO = Opers.getCallTarget();

565

566 if (CalleeMO.isImm()) {

567 int64_t CallTarget = CalleeMO.getImm();

568 if (CallTarget) {

569 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&

570 "High 16 bits of call target should be zero.");

571 Register ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();

572 EncodedBytes = 0;

573

574 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)

575 .addReg(ScratchReg)

576 .addImm((CallTarget >> 32) & 0xFFFF));

577 ++EncodedBytes;

578 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)

579 .addReg(ScratchReg)

580 .addReg(ScratchReg)

581 .addImm(32).addImm(16));

582 ++EncodedBytes;

583 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)

584 .addReg(ScratchReg)

585 .addReg(ScratchReg)

586 .addImm((CallTarget >> 16) & 0xFFFF));

587 ++EncodedBytes;

588 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)

589 .addReg(ScratchReg)

590 .addReg(ScratchReg)

591 .addImm(CallTarget & 0xFFFF));

592

593

595 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)

596 .addReg(PPC::X2)

597 .addImm(TOCSaveOffset)

598 .addReg(PPC::X1));

599 ++EncodedBytes;

600

601

602

604

605

606

607 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)

608 .addReg(PPC::X2)

609 .addImm(8)

610 .addReg(ScratchReg));

611 ++EncodedBytes;

612 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)

613 .addReg(ScratchReg)

614 .addImm(0)

615 .addReg(ScratchReg));

616 ++EncodedBytes;

617 }

618

619 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)

620 .addReg(ScratchReg));

621 ++EncodedBytes;

622 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));

623 ++EncodedBytes;

624

625

626 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)

627 .addReg(PPC::X2)

628 .addImm(TOCSaveOffset)

629 .addReg(PPC::X1));

630 ++EncodedBytes;

631 }

632 } else if (CalleeMO.isGlobal()) {

634 MCSymbol *MOSymbol = getSymbol(GValue);

636

637 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)

638 .addExpr(SymVar));

639 EncodedBytes += 2;

640 }

641

642

643 EncodedBytes *= 4;

644

645

646 unsigned NumBytes = Opers.getNumPatchBytes();

647 assert(NumBytes >= EncodedBytes &&

648 "Patchpoint can't request size less than the length of a call.");

649 assert((NumBytes - EncodedBytes) % 4 == 0 &&

650 "Invalid number of NOP bytes requested!");

651 for (unsigned i = EncodedBytes; i < NumBytes; i += 4)

652 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));

653}

654

655

656

657

660 switch (MIOpc) {

661 default:

662 SymName = ".__tls_get_addr";

663 break;

664 case PPC::GETtlsTpointer32AIX:

665 SymName = ".__get_tpointer";

666 break;

667 case PPC::GETtlsMOD32AIX:

668 case PPC::GETtlsMOD64AIX:

669 SymName = ".__tls_get_mod";

670 break;

671 }

672 return Ctx

676}

677

678void PPCAsmPrinter::EmitAIXTlsCallHelper(const MachineInstr *MI) {

680 "Only expecting to emit calls to get the thread pointer on AIX!");

681

683 const MCExpr *TlsRef =

685 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BLA).addExpr(TlsRef));

686}

687

688

689

690void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,

693 unsigned Opcode = PPC::BL8_NOP_TLS;

694

695 assert(MI->getNumOperands() >= 3 && "Expecting at least 3 operands from MI");

699 Opcode = PPC::BL8_NOTOC_TLS;

700 }

701 const Module *M = MF->getFunction().getParent();

702

703 assert(MI->getOperand(0).isReg() &&

704 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||

705 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) &&

706 "GETtls[ld]ADDR[32] must define GPR3");

707 assert(MI->getOperand(1).isReg() &&

708 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) ||

709 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) &&

710 "GETtls[ld]ADDR[32] must read GPR3");

711

713

714

715

716

717 Register VarOffsetReg = Subtarget->isPPC64() ? PPC::X4 : PPC::R4;

718 (void)VarOffsetReg;

719 assert((MI->getOpcode() == PPC::GETtlsMOD32AIX ||

720 MI->getOpcode() == PPC::GETtlsMOD64AIX ||

721 (MI->getOperand(2).isReg() &&

722 MI->getOperand(2).getReg() == VarOffsetReg)) &&

723 "GETtls[ld]ADDR[32] must read GPR4");

724 EmitAIXTlsCallHelper(MI);

725 return;

726 }

727

728 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol("__tls_get_addr");

729

730 if (Subtarget->is32BitELFABI() && isPositionIndependent())

732

733 const MCExpr *TlsRef =

735

736

743 MCSymbol *MOSymbol = getSymbol(GValue);

745 EmitToStreamer(*OutStreamer,

747 : (unsigned)PPC::BL_TLS)

750}

751

752

753

765 default:

767 }

768}

769

770static PPCAsmPrinter::TOCEntryType

772

773

775 return PPCAsmPrinter::TOCType_ThreadLocal;

776

784 return PPCAsmPrinter::TOCType_GlobalExternal;

785

786 return PPCAsmPrinter::TOCType_GlobalInternal;

787 }

789 return PPCAsmPrinter::TOCType_ConstantPool;

791 return PPCAsmPrinter::TOCType_JumpTable;

793 return PPCAsmPrinter::TOCType_BlockAddress;

794 default:

795 llvm_unreachable("Unexpected operand type to get TOC type.");

796 }

797}

798

799

800

801void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {

802 PPC_MC::verifyInstructionPredicates(MI->getOpcode(),

803 getSubtargetInfo().getFeatureBits());

804

806 const bool IsPPC64 = Subtarget->isPPC64();

807 const bool IsAIX = Subtarget->isAIXABI();

808 const bool HasAIXSmallLocalTLS = Subtarget->hasAIXSmallLocalExecTLS() ||

809 Subtarget->hasAIXSmallLocalDynamicTLS();

810 const Module *M = MF->getFunction().getParent();

812

813#ifndef NDEBUG

814

815 if (MI->isInlineAsm()) {

817 if (MO.isReg()) {

819 if (Subtarget->hasSPE()) {

820 if (PPC::F4RCRegClass.contains(Reg) ||

821 PPC::F8RCRegClass.contains(Reg) ||

822 PPC::VFRCRegClass.contains(Reg) ||

823 PPC::VRRCRegClass.contains(Reg) ||

824 PPC::VSFRCRegClass.contains(Reg) ||

825 PPC::VSSRCRegClass.contains(Reg)

826 )

828 } else {

829 if (PPC::SPERCRegClass.contains(Reg))

830 llvm_unreachable("SPE register found in FPU-targeted code!");

831 }

832 }

833 }

834 }

835#endif

836

837 auto getTOCRelocAdjustedExprForXCOFF = [this](const MCExpr *Expr,

839

840

841

842

843

844

846 OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);

849 };

850

851 auto getTOCEntryLoadingExprForXCOFF =

852 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,

855 MCSymbolRefExpr::VariantKind::VK_None) -> const MCExpr * {

856 const unsigned EntryByteSize = IsPPC64 ? 8 : 4;

857 const auto TOCEntryIter = TOC.find({MOSymbol, VK});

858 assert(TOCEntryIter != TOC.end() &&

859 "Could not find the TOC entry for this symbol.");

860 const ptrdiff_t EntryDistanceFromTOCBase =

861 (TOCEntryIter - TOC.begin()) * EntryByteSize;

862 constexpr int16_t PositiveTOCRange = INT16_MAX;

863

864 if (EntryDistanceFromTOCBase > PositiveTOCRange)

865 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);

866

867 return Expr;

868 };

870

871

872

877 assert(MO.isGlobal() && "Only expecting a global MachineOperand here!\n");

880 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE;

882 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;

883

884

889 dbgs() << "Current function uses IE access for default LD vars.\n");

890 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;

891 }

892 llvm_unreachable("Only expecting local-exec or initial-exec accesses!");

893 }

894

895

896

898 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM;

900 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD;

901

902

903

905 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD;

907 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML;

908 return MCSymbolRefExpr::VariantKind::VK_None;

909 };

910

911

912 switch (MI->getOpcode()) {

913 default: break;

914 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {

916 "AIX does not support patchable function entry!");

917

918

919 if (MAI->isLittleEndian())

920 return;

921 const Function &F = MF->getFunction();

922 unsigned Num = 0;

923 (void)F.getFnAttribute("patchable-function-entry")

924 .getValueAsString()

925 .getAsInteger(10, Num);

926 if (!Num)

927 return;

928 emitNops(Num);

929 return;

930 }

931 case TargetOpcode::DBG_VALUE:

933 case TargetOpcode::STACKMAP:

934 return LowerSTACKMAP(SM, *MI);

935 case TargetOpcode::PATCHPOINT:

936 return LowerPATCHPOINT(SM, *MI);

937

938 case PPC::MoveGOTtoLR: {

939

940

941

942

943

944

946 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));

947 const MCExpr *OffsExpr =

950 OutContext),

952 OutContext);

953

954

955 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));

956 return;

957 }

958 case PPC::MovePCtoLR:

959 case PPC::MovePCtoLR8: {

960

961

962

963

964 MCSymbol *PICBase = MF->getPICBaseSymbol();

965

966

967 EmitToStreamer(*OutStreamer,

969

970

972

973

974 OutStreamer->emitLabel(PICBase);

975 return;

976 }

977 case PPC::UpdateGBR: {

978

979

980

981

982

983

984

986 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {

988 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(

990 : ".LTOC");

993

996

998 EmitToStreamer(

999 *OutStreamer,

1000 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));

1001

1003 EmitToStreamer(

1004 *OutStreamer,

1005 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));

1006 return;

1007 } else {

1009 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(*MF);

1016 OutContext);

1019

1020

1025 EmitToStreamer(*OutStreamer, TmpInst);

1026

1031 EmitToStreamer(*OutStreamer, TmpInst);

1032 return;

1033 }

1034 }

1035 case PPC::LWZtoc: {

1036

1038

1039

1041

1044 "Invalid operand for LWZtoc.");

1045

1046

1048

1049

1050

1054 OutContext);

1056 EmitToStreamer(*OutStreamer, TmpInst);

1057 return;

1058 }

1059

1061

1062

1063

1064

1069

1070

1071

1072

1073 if (IsAIX) {

1076 "This pseudo should only be selected for 32-bit small code model.");

1077 Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);

1079

1080

1081 if (isVerbose())

1082 OutStreamer->getCommentOS() << MO << '\n';

1083 EmitToStreamer(*OutStreamer, TmpInst);

1084 return;

1085 }

1086

1087

1088

1090 OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext);

1093 EmitToStreamer(*OutStreamer, TmpInst);

1094 return;

1095 }

1096 case PPC::ADDItoc:

1097 case PPC::ADDItoc8: {

1099 "PseudoOp only valid for small code model AIX");

1100

1101

1103

1104

1105 TmpInst.setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));

1106

1108 assert(MO.isGlobal() && "Invalid operand for ADDItoc[8].");

1109

1110

1112

1115

1117 EmitToStreamer(*OutStreamer, TmpInst);

1118 return;

1119 }

1120 case PPC::LDtocJTI:

1121 case PPC::LDtocCPT:

1122 case PPC::LDtocBA:

1123 case PPC::LDtoc: {

1124

1126

1127

1129

1132 "Invalid operand!");

1133

1134

1136

1138

1139

1140

1141

1144

1149 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);

1150

1151

1152 if (isVerbose() && IsAIX)

1153 OutStreamer->getCommentOS() << MO << '\n';

1154 EmitToStreamer(*OutStreamer, TmpInst);

1155 return;

1156 }

1157 case PPC::ADDIStocHA: {

1159

1161 "Invalid operand for ADDIStocHA.");

1162 assert((IsAIX && !IsPPC64 &&

1164 "This pseudo should only be selected for 32-bit large code model on"

1165 " AIX.");

1166

1167

1169

1170

1172

1173

1175

1177

1178

1179

1180

1181

1182

1183

1186 return false;

1187

1189 if (!GV)

1190 return false;

1191 return GV->hasAttribute("toc-data");

1192 }(MO)) {

1194 }

1195

1199 EmitToStreamer(*OutStreamer, TmpInst);

1200 return;

1201 }

1202 case PPC::LWZtocL: {

1204

1206 "Invalid operand for LWZtocL.");

1207 assert(IsAIX && !IsPPC64 &&

1209 "This pseudo should only be selected for 32-bit large code model on"

1210 " AIX.");

1211

1212

1214

1215

1217

1218

1220

1222

1223

1224

1225

1226

1231 OutContext);

1233 EmitToStreamer(*OutStreamer, TmpInst);

1234 return;

1235 }

1236 case PPC::ADDIStocHA8: {

1237

1239

1240

1241

1242

1243

1245

1248 "Invalid operand for ADDIStocHA8!");

1249

1251

1253

1254 const bool GlobalToc =

1256

1259

1263

1265

1268

1272 OutContext),

1273 OutContext);

1274

1276 EmitToStreamer(*OutStreamer, TmpInst);

1277 return;

1278 }

1279 case PPC::LDtocL: {

1280

1282

1283

1284

1285

1286

1288

1292 "Invalid operand for LDtocL!");

1293

1296 "LDtocL used on symbol that could be accessed directly is "

1297 "invalid. Must match ADDIStocHA8."));

1298

1300

1306

1311 EmitToStreamer(*OutStreamer, TmpInst);

1312 return;

1313 }

1314 case PPC::ADDItocL:

1315 case PPC::ADDItocL8: {

1316

1318

1319 unsigned Op = MI->getOpcode();

1320

1321

1322

1323 TmpInst.setOpcode(Op == PPC::ADDItocL8 ? (IsAIX ? PPC::LA8 : PPC::ADDI8)

1324 : PPC::LA);

1325

1327 assert((Op == PPC::ADDItocL8)

1329 : MO.isGlobal() && "Invalid operand for ADDItocL8.");

1331 "Interposable definitions must use indirect accesses.");

1332

1333

1335

1337 MOSymbol,

1339 OutContext);

1340

1342 EmitToStreamer(*OutStreamer, TmpInst);

1343 return;

1344 }

1345 case PPC::ADDISgotTprelHA: {

1346

1347

1348 assert(IsPPC64 && "Not supported for 32-bit PowerPC");

1351 MCSymbol *MOSymbol = getSymbol(GValue);

1352 const MCExpr *SymGotTprel =

1354 OutContext);

1355 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)

1356 .addReg(MI->getOperand(0).getReg())

1357 .addReg(MI->getOperand(1).getReg())

1359 return;

1360 }

1361 case PPC::LDgotTprelL:

1362 case PPC::LDgotTprelL32: {

1363

1365

1366

1367 TmpInst.setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);

1370 MCSymbol *MOSymbol = getSymbol(GValue);

1374 OutContext);

1376 EmitToStreamer(*OutStreamer, TmpInst);

1377 return;

1378 }

1379

1380 case PPC::PPC32PICGOT: {

1381 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));

1382 MCSymbol *GOTRef = OutContext.createTempSymbol();

1383 MCSymbol *NextInstr = OutContext.createTempSymbol();

1384

1385 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)

1386

1387

1389 const MCExpr *OffsExpr =

1392 OutContext);

1393 OutStreamer->emitLabel(GOTRef);

1394 OutStreamer->emitValue(OffsExpr, 4);

1395 OutStreamer->emitLabel(NextInstr);

1396 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)

1397 .addReg(MI->getOperand(0).getReg()));

1398 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)

1399 .addReg(MI->getOperand(1).getReg())

1401 .addReg(MI->getOperand(0).getReg()));

1402 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)

1403 .addReg(MI->getOperand(0).getReg())

1404 .addReg(MI->getOperand(1).getReg())

1405 .addReg(MI->getOperand(0).getReg()));

1406 return;

1407 }

1408 case PPC::PPC32GOT: {

1410 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));

1415 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)

1416 .addReg(MI->getOperand(0).getReg())

1418 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)

1419 .addReg(MI->getOperand(0).getReg())

1420 .addReg(MI->getOperand(0).getReg())

1422 return;

1423 }

1424 case PPC::ADDIStlsgdHA: {

1425

1426

1427 assert(IsPPC64 && "Not supported for 32-bit PowerPC");

1430 MCSymbol *MOSymbol = getSymbol(GValue);

1431 const MCExpr *SymGotTlsGD =

1433 OutContext);

1434 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)

1435 .addReg(MI->getOperand(0).getReg())

1436 .addReg(MI->getOperand(1).getReg())

1438 return;

1439 }

1440 case PPC::ADDItlsgdL:

1441

1442

1443 case PPC::ADDItlsgdL32: {

1444

1445

1448 MCSymbol *MOSymbol = getSymbol(GValue);

1452 OutContext);

1453 EmitToStreamer(*OutStreamer,

1455 .addReg(MI->getOperand(0).getReg())

1456 .addReg(MI->getOperand(1).getReg())

1458 return;

1459 }

1460 case PPC::GETtlsMOD32AIX:

1461 case PPC::GETtlsMOD64AIX:

1462

1463

1464

1465 case PPC::GETtlsADDR:

1466

1467

1468 case PPC::GETtlsADDRPCREL:

1469 case PPC::GETtlsADDR32AIX:

1470 case PPC::GETtlsADDR64AIX:

1471

1472

1473

1474 case PPC::GETtlsADDR32: {

1475

1476

1478 return;

1479 }

1480 case PPC::GETtlsTpointer32AIX: {

1481

1482

1483 EmitAIXTlsCallHelper(MI);

1484 return;

1485 }

1486 case PPC::ADDIStlsldHA: {

1487

1488

1489 assert(IsPPC64 && "Not supported for 32-bit PowerPC");

1492 MCSymbol *MOSymbol = getSymbol(GValue);

1493 const MCExpr *SymGotTlsLD =

1495 OutContext);

1496 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)

1497 .addReg(MI->getOperand(0).getReg())

1498 .addReg(MI->getOperand(1).getReg())

1500 return;

1501 }

1502 case PPC::ADDItlsldL:

1503

1504

1505 case PPC::ADDItlsldL32: {

1506

1507

1510 MCSymbol *MOSymbol = getSymbol(GValue);

1514 OutContext);

1515 EmitToStreamer(*OutStreamer,

1517 .addReg(MI->getOperand(0).getReg())

1518 .addReg(MI->getOperand(1).getReg())

1520 return;

1521 }

1522 case PPC::GETtlsldADDR:

1523

1524

1525 case PPC::GETtlsldADDRPCREL:

1526 case PPC::GETtlsldADDR32: {

1527

1528

1530 return;

1531 }

1532 case PPC::ADDISdtprelHA:

1533

1534

1535 case PPC::ADDISdtprelHA32: {

1536

1537

1540 MCSymbol *MOSymbol = getSymbol(GValue);

1541 const MCExpr *SymDtprel =

1543 OutContext);

1544 EmitToStreamer(

1545 *OutStreamer,

1546 MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS)

1547 .addReg(MI->getOperand(0).getReg())

1548 .addReg(MI->getOperand(1).getReg())

1550 return;

1551 }

1552 case PPC::PADDIdtprel: {

1553

1554

1557 MCSymbol *MOSymbol = getSymbol(GValue);

1560 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8)

1561 .addReg(MI->getOperand(0).getReg())

1562 .addReg(MI->getOperand(1).getReg())

1564 return;

1565 }

1566

1567 case PPC::ADDIdtprelL:

1568

1569

1570 case PPC::ADDIdtprelL32: {

1571

1572

1575 MCSymbol *MOSymbol = getSymbol(GValue);

1576 const MCExpr *SymDtprel =

1578 OutContext);

1579 EmitToStreamer(*OutStreamer,

1581 .addReg(MI->getOperand(0).getReg())

1582 .addReg(MI->getOperand(1).getReg())

1584 return;

1585 }

1586 case PPC::MFOCRF:

1587 case PPC::MFOCRF8:

1588 if (!Subtarget->hasMFOCRF()) {

1589

1590

1591 unsigned NewOpcode =

1592 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;

1595 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)

1596 .addReg(MI->getOperand(0).getReg()));

1597 return;

1598 }

1599 break;

1600 case PPC::MTOCRF:

1601 case PPC::MTOCRF8:

1602 if (!Subtarget->hasMFOCRF()) {

1603

1604

1605 unsigned NewOpcode =

1606 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;

1607 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()

1608 ->getEncodingValue(MI->getOperand(0).getReg());

1611 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)

1612 .addImm(Mask)

1613 .addReg(MI->getOperand(1).getReg()));

1614 return;

1615 }

1616 break;

1617 case PPC::LD:

1618 case PPC::STD:

1619 case PPC::LWA_32:

1620 case PPC::LWA: {

1621

1622

1623 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;

1624

1625

1626

1630 TempMO.getOperandNo() == 1)

1631 OpNum = 1;

1632 }

1637 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");

1638 }

1639

1640

1641

1642 [[fallthrough]];

1643 }

1644 case PPC::LBZ:

1645 case PPC::LBZ8:

1646 case PPC::LHA:

1647 case PPC::LHA8:

1648 case PPC::LHZ:

1649 case PPC::LHZ8:

1650 case PPC::LWZ:

1651 case PPC::LWZ8:

1652 case PPC::STB:

1653 case PPC::STB8:

1654 case PPC::STH:

1655 case PPC::STH8:

1656 case PPC::STW:

1657 case PPC::STW8:

1658 case PPC::LFS:

1659 case PPC::STFS:

1660 case PPC::LFD:

1661 case PPC::STFD:

1662 case PPC::ADDI8: {

1663

1664

1665

1666

1667 if (!HasAIXSmallLocalTLS)

1668 break;

1669 bool IsMIADDI8 = MI->getOpcode() == PPC::ADDI8;

1670 unsigned OpNum = IsMIADDI8 ? 2 : 1;

1677

1678 const MCExpr *Expr = getAdjustedFasterLocalExpr(MO, MO.getOffset());

1679 if (Expr)

1681

1682

1683 if (IsMIADDI8)

1685

1686 EmitToStreamer(*OutStreamer, TmpInst);

1687 return;

1688 }

1689

1690 break;

1691 }

1692 case PPC::PseudoEIEIO: {

1693 EmitToStreamer(

1694 *OutStreamer,

1695 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));

1696 EmitToStreamer(

1697 *OutStreamer,

1698 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));

1699 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO));

1700 return;

1701 }

1702 }

1703

1705 EmitToStreamer(*OutStreamer, TmpInst);

1706}

1707

1708

1709

1710

1711

1712

1713

1715PPCAsmPrinter::getAdjustedFasterLocalExpr(const MachineOperand &MO,

1717

1718

1720 return nullptr;

1721

1722 assert(MO.isGlobal() && "Only expecting a global MachineOperand here!");

1726 "Only local-[exec|dynamic] accesses are handled!");

1727

1729

1730

1731

1732 const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.find(GValue);

1733 if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.end())

1734 assert(IsGlobalADeclaration &&

1735 "Only expecting to find extern TLS variables not present in the TLS "

1736 "variable-to-address map!");

1737

1738 unsigned TLSVarAddress =

1739 IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;

1741

1742

1743

1744

1745

1747 getSymbol(GValue),

1750 OutContext);

1753 if (FinalAddress >= 32768) {

1754

1755

1756

1757

1758

1759

1760 ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);

1761

1762 [[maybe_unused]] ptrdiff_t InstDisp = TLSVarAddress + Offset - Delta;

1764 ((InstDisp < 32768) && (InstDisp >= -32768)) &&

1765 "Expecting the instruction displacement for local-[exec|dynamic] TLS "

1766 "variables to be between [-32768, 32768)!");

1769 }

1770

1771 return Expr;

1772}

1773

1774void PPCLinuxAsmPrinter::emitGNUAttributes(Module &M) {

1775

1776 Metadata *MD = M.getModuleFlag("float-abi");

1777 MDString *FloatABI = dyn_cast_or_null(MD);

1778 if (!FloatABI)

1779 return;

1781

1782 if (flt == "doubledouble")

1783 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,

1784 Val_GNU_Power_ABI_HardFloat_DP |

1785 Val_GNU_Power_ABI_LDBL_IBM128);

1786 else if (flt == "ieeequad")

1787 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,

1788 Val_GNU_Power_ABI_HardFloat_DP |

1789 Val_GNU_Power_ABI_LDBL_IEEE128);

1790 else if (flt == "ieeedouble")

1791 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,

1792 Val_GNU_Power_ABI_HardFloat_DP |

1793 Val_GNU_Power_ABI_LDBL_64);

1794}

1795

1796void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {

1797 if (!Subtarget->isPPC64())

1798 return PPCAsmPrinter::emitInstruction(MI);

1799

1800 switch (MI->getOpcode()) {

1801 default:

1802 break;

1803 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {

1804

1805

1806

1807

1808

1809

1810

1811

1812

1813

1814

1815

1816 if (!MAI->isLittleEndian())

1817 break;

1818 MCSymbol *BeginOfSled = OutContext.createTempSymbol();

1819 MCSymbol *EndOfSled = OutContext.createTempSymbol();

1820 OutStreamer->emitLabel(BeginOfSled);

1821 EmitToStreamer(*OutStreamer,

1824 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));

1825 EmitToStreamer(

1826 *OutStreamer,

1827 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));

1828 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));

1829 EmitToStreamer(*OutStreamer,

1832 OutContext.getOrCreateSymbol("__xray_FunctionEntry"),

1833 OutContext)));

1834 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));

1835 OutStreamer->emitLabel(EndOfSled);

1836 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER, 2);

1837 break;

1838 }

1839 case TargetOpcode::PATCHABLE_RET: {

1840 unsigned RetOpcode = MI->getOperand(0).getImm();

1847 }

1848

1849 bool IsConditional;

1850 if (RetOpcode == PPC::BCCLR) {

1851 IsConditional = true;

1852 } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||

1853 RetOpcode == PPC::TCRETURNai8) {

1854 break;

1855 } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {

1856 IsConditional = false;

1857 } else {

1858 EmitToStreamer(*OutStreamer, RetInst);

1859 return;

1860 }

1861

1863 if (IsConditional) {

1864

1865

1866

1867

1868

1869

1870

1871

1872

1873

1874

1875

1876

1877

1878

1879

1880

1881

1882 FallthroughLabel = OutContext.createTempSymbol();

1883 EmitToStreamer(

1884 *OutStreamer,

1888 .addReg(MI->getOperand(2).getReg())

1892 }

1893

1894

1895

1896

1897

1898

1899

1900

1901

1902

1903

1904

1905 OutStreamer->emitCodeAlignment(Align(8), &getSubtargetInfo());

1906 MCSymbol *BeginOfSled = OutContext.createTempSymbol();

1907 OutStreamer->emitLabel(BeginOfSled);

1908 EmitToStreamer(*OutStreamer, RetInst);

1909 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));

1910 EmitToStreamer(

1911 *OutStreamer,

1912 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));

1913 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));

1914 EmitToStreamer(*OutStreamer,

1917 OutContext.getOrCreateSymbol("__xray_FunctionExit"),

1918 OutContext)));

1919 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));

1920 EmitToStreamer(*OutStreamer, RetInst);

1921 if (IsConditional)

1922 OutStreamer->emitLabel(FallthroughLabel);

1923 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT, 2);

1924 return;

1925 }

1926 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:

1927 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");

1928 case TargetOpcode::PATCHABLE_TAIL_CALL:

1929

1930

1931 llvm_unreachable("Tail call is handled in the normal case. See comments "

1932 "around this assert.");

1933 }

1934 return PPCAsmPrinter::emitInstruction(MI);

1935}

1936

1937void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module &M) {

1938 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {

1940 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());

1942 }

1943

1945 !isPositionIndependent())

1947

1950

1951 OutStreamer->switchSection(OutContext.getELFSection(

1953

1954 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC"));

1955 MCSymbol *CurrentPos = OutContext.createTempSymbol();

1956

1957 OutStreamer->emitLabel(CurrentPos);

1958

1959

1960

1961 const MCExpr *tocExpr =

1964 OutContext);

1965

1966 OutStreamer->emitAssignment(TOCSym, tocExpr);

1967

1968 OutStreamer->switchSection(getObjFileLowering().getTextSection());

1969}

1970

1971void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {

1972

1973 if (!Subtarget->isPPC64() &&

1974 (!isPositionIndependent() ||

1975 MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC))

1977

1978 if (!Subtarget->isPPC64()) {

1980 if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) {

1982 MCSymbol *PICBase = MF->getPICBaseSymbol();

1983 OutStreamer->emitLabel(RelocSymbol);

1984

1985 const MCExpr *OffsExpr =

1988 OutContext),

1990 OutContext);

1991 OutStreamer->emitValue(OffsExpr, 4);

1992 OutStreamer->emitLabel(CurrentFnSym);

1993 return;

1994 } else

1996 }

1997

1998

2000

2001

2002

2003

2005 && !MF->getRegInfo().use_empty(PPC::X2)) {

2007

2008 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));

2010 const MCExpr *TOCDeltaExpr =

2013 OutContext),

2014 OutContext);

2015

2017 OutStreamer->emitValue(TOCDeltaExpr, 8);

2018 }

2020 }

2021

2022

2023 MCSectionSubPair Current = OutStreamer->getCurrentSection();

2026 OutStreamer->switchSection(Section);

2027 OutStreamer->emitLabel(CurrentFnSym);

2028 OutStreamer->emitValueToAlignment(Align(8));

2029 MCSymbol *Symbol1 = CurrentFnSymForSize;

2030

2031

2033 8 );

2034 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC."));

2035

2036 OutStreamer->emitValue(

2038 8);

2039

2040 OutStreamer->emitIntValue(0, 8 );

2041 OutStreamer->switchSection(Current.first, Current.second);

2042}

2043

2044void PPCLinuxAsmPrinter::emitEndOfAsmFile(Module &M) {

2046

2047 bool isPPC64 = DL.getPointerSizeInBits() == 64;

2048

2050 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());

2051

2052

2053

2054

2055

2057 OutStreamer->emitSymbolValue(

2058 GetExternalSymbolSymbol("__parse_hwcap_and_convert_at_platform"),

2059 MAI->getCodePointerSize());

2060 emitGNUAttributes(M);

2061

2062 if (TOC.empty()) {

2063 const char *Name = isPPC64 ? ".toc" : ".got2";

2066 OutStreamer->switchSection(Section);

2067 if (!isPPC64)

2068 OutStreamer->emitValueToAlignment(Align(4));

2069

2070 for (const auto &TOCMapPair : TOC) {

2071 const MCSymbol *const TOCEntryTarget = TOCMapPair.first.first;

2072 MCSymbol *const TOCEntryLabel = TOCMapPair.second;

2073

2074 OutStreamer->emitLabel(TOCEntryLabel);

2075 if (isPPC64)

2076 TS->emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);

2077 else

2078 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);

2079 }

2080 }

2081

2082 PPCAsmPrinter::emitEndOfAsmFile(M);

2083}

2084

2085

2086void PPCLinuxAsmPrinter::emitFunctionBodyStart() {

2087

2088

2089

2090

2091

2092

2093

2094

2095

2096

2097

2098

2099

2100

2101

2102

2103

2104

2105

2106

2107

2108

2109

2110

2111

2112

2113

2114

2115

2116

2117

2119 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||

2120 !MF->getRegInfo().use_empty(PPC::R2);

2124 Subtarget->isELFv2ABI() && UsesX2OrR2;

2125

2126

2127

2128

2129 if (NonPCrelGEPRequired || PCrelGEPRequired) {

2130

2131

2132

2134 OutStreamer->emitLabel(GlobalEntryLabel);

2137

2139 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));

2140 const MCExpr *TOCDeltaExpr =

2142 GlobalEntryLabelExp, OutContext);

2143

2145 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)

2146 .addReg(PPC::X2)

2147 .addReg(PPC::X12)

2148 .addExpr(TOCDeltaHi));

2149

2151 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)

2152 .addReg(PPC::X2)

2153 .addReg(PPC::X2)

2154 .addExpr(TOCDeltaLo));

2155 } else {

2157 const MCExpr *TOCOffsetDeltaExpr =

2159 GlobalEntryLabelExp, OutContext);

2160

2161 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)

2162 .addReg(PPC::X2)

2163 .addExpr(TOCOffsetDeltaExpr)

2164 .addReg(PPC::X12));

2165 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)

2166 .addReg(PPC::X2)

2167 .addReg(PPC::X2)

2168 .addReg(PPC::X12));

2169 }

2170

2172 OutStreamer->emitLabel(LocalEntryLabel);

2175 const MCExpr *LocalOffsetExp =

2177 GlobalEntryLabelExp, OutContext);

2178

2180 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());

2181 TS->emitLocalEntry(cast(CurrentFnSym), LocalOffsetExp);

2183

2184

2185

2186

2187

2188

2189

2190

2191

2192

2193

2194

2195

2196

2197

2198

2199

2200

2201

2202

2203

2204 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||

2205 MF->hasInlineAsm() || (!PPCFI->usesTOCBasePtr() && UsesX2OrR2)) {

2207 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());

2210 }

2211 }

2212}

2213

2214

2215

2216

2217void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {

2218

2219

2220

2221

2222

2223

2224

2225 if (Subtarget->isPPC64()) {

2226 OutStreamer->emitIntValue(0, 4);

2227 OutStreamer->emitIntValue(0, 8);

2228 }

2229}

2230

2231void PPCAIXAsmPrinter::emitLinkage(const GlobalValue *GV,

2237 break;

2244 break;

2247 break;

2249 return;

2252 "InternalLinkage should not have other visibility setting.");

2254 break;

2258 llvm_unreachable("CommonLinkage of XCOFF should not come to this path");

2259 }

2260

2261 assert(LinkageAttr != MCSA_Invalid && "LinkageAttr should not MCSA_Invalid.");

2262

2264 if (TM.getIgnoreXCOFFVisibility()) {

2267 "Cannot not be both dllexport and non-default visibility");

2269

2270

2273 VisibilityAttr = MAI->getExportedVisibilityAttr();

2274 break;

2276 VisibilityAttr = MAI->getHiddenVisibilityAttr();

2277 break;

2279 VisibilityAttr = MAI->getProtectedVisibilityAttr();

2280 break;

2281 }

2282 }

2283

2284

2285 if (GV->getThreadLocalMode() == GlobalVariable::LocalDynamicTLSModel &&

2287 return;

2288

2289 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,

2290 VisibilityAttr);

2291}

2292

2293void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {

2294

2296 cast(getObjFileLowering().getSectionForFunctionDescriptor(

2299

2301

2303}

2304

2305uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {

2306

2307

2308

2310 if (Subtarget.isAIXABI() && Subtarget.hasAltivec() &&

2311 TM.getAIXExtendedAltivecABI()) {

2313 for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg)

2314 if (MRI.isPhysRegModified(Reg))

2315

2316 return PPC::V31 - Reg + 1;

2317 }

2318 return 0;

2319}

2320

2321void PPCAIXAsmPrinter::emitFunctionBodyEnd() {

2322

2323 if (TM.getXCOFFTracebackTable())

2324 return;

2325

2326 emitTracebackTable();

2327

2328

2329

2330

2331

2332

2334 (getNumberOfVRSaved() > 0)) {

2335

2336 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());

2339 OutStreamer->emitLabel(EHInfoLabel);

2340

2341

2342 OutStreamer->emitInt32(0);

2343

2344 const DataLayout &DL = MMI->getModule()->getDataLayout();

2345 const unsigned PointerSize = DL.getPointerSize();

2346

2347 OutStreamer->emitValueToAlignment(Align(PointerSize));

2348

2349 OutStreamer->emitIntValue(0, PointerSize);

2350 OutStreamer->emitIntValue(0, PointerSize);

2351 OutStreamer->switchSection(MF->getSection());

2352 }

2353}

2354

2355void PPCAIXAsmPrinter::emitTracebackTable() {

2356

2357

2359 OutStreamer->emitLabel(FuncEnd);

2360

2361 OutStreamer->AddComment("Traceback table begin");

2362

2363 OutStreamer->emitIntValueInHexWithPadding(0, 4 );

2364

2367

2368 auto EmitComment = [&]() {

2369 OutStreamer->AddComment(CommentOS.str());

2370 CommentString.clear();

2371 };

2372

2374 EmitComment();

2375 OutStreamer->emitIntValueInHexWithPadding(Value, Size);

2376 };

2377

2378 unsigned int Version = 0;

2379 CommentOS << "Version = " << Version;

2380 EmitCommentAndValue(Version, 1);

2381

2382

2383

2384

2385

2386

2389

2390 CommentOS << "Language = "

2392 EmitCommentAndValue(LanguageIdentifier, 1);

2393

2394

2395 uint32_t FirstHalfOfMandatoryField = 0;

2396

2397

2398

2399

2401

2404

2405

2406 for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) {

2407 if (MRI.isPhysRegUsed(Reg, true)) {

2409 break;

2410 }

2411 }

2412

2413#define GENBOOLCOMMENT(Prefix, V, Field) \

2414 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \

2415 << #Field

2416

2417#define GENVALUECOMMENT(PrefixAndName, V, Field) \

2418 CommentOS << (PrefixAndName) << " = " \

2419 << static_cast(((V) & (TracebackTable::Field##Mask)) >> \

2420 (TracebackTable::Field##Shift))

2421

2422 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsGlobaLinkage);

2423 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);

2424 EmitComment();

2425

2426 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasTraceBackTableOffset);

2427 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsInternalProcedure);

2428 EmitComment();

2429

2430 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasControlledStorage);

2431 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsTOCless);

2432 EmitComment();

2433

2434 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsFloatingPointPresent);

2435 EmitComment();

2437 IsFloatingPointOperationLogOrAbortEnabled);

2438 EmitComment();

2439

2440 OutStreamer->emitIntValueInHexWithPadding(

2441 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);

2442

2443

2445

2449 if (FrameReg == (Subtarget->isPPC64() ? PPC::X31 : PPC::R31))

2451

2453 if (!MustSaveCRs.empty())

2455

2458

2459 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsInterruptHandler);

2460 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);

2461 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsAllocaUsed);

2462 EmitComment();

2463 GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField,

2464 OnConditionDirective);

2465 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsCRSaved);

2466 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsLRSaved);

2467 EmitComment();

2468 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),

2469 1);

2470

2471

2472 uint32_t SecondHalfOfMandatoryField = 0;

2473

2476 : 0;

2477

2479 for (unsigned Reg = PPC::F14; Reg <= PPC::F31; ++Reg) {

2480 if (MRI.isPhysRegModified(Reg)) {

2481 FPRSaved = PPC::F31 - Reg + 1;

2482 break;

2483 }

2484 }

2487 GENBOOLCOMMENT("", SecondHalfOfMandatoryField, IsBackChainStored);

2488 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, IsFixup);

2489 GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);

2490 EmitComment();

2491 OutStreamer->emitIntValueInHexWithPadding(

2492 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);

2493

2494

2495

2496

2497

2498 bool HasVectorInst = false;

2499 for (unsigned Reg = PPC::V0; Reg <= PPC::V31; ++Reg)

2500 if (MRI.isPhysRegUsed(Reg, true)) {

2501

2502 HasVectorInst = true;

2503 break;

2504 }

2505

2508

2509 uint16_t NumOfVRSaved = getNumberOfVRSaved();

2510 bool ShouldEmitEHBlock =

2512

2513 if (ShouldEmitEHBlock)

2515

2517

2518

2519 unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;

2520 unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;

2521

2522 for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) {

2523 if (MRI.isPhysRegModified(Reg)) {

2524 GPRSaved = GPREnd - Reg + 1;

2525 break;

2526 }

2527 }

2528

2531

2532 GENBOOLCOMMENT("", SecondHalfOfMandatoryField, HasExtensionTable);

2533 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasVectorInfo);

2534 GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);

2535 EmitComment();

2536 OutStreamer->emitIntValueInHexWithPadding(

2537 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);

2538

2539

2541 SecondHalfOfMandatoryField |=

2544 GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField,

2545 NumberOfFixedParms);

2546 EmitComment();

2547 OutStreamer->emitIntValueInHexWithPadding(

2548 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);

2549

2550

2551

2552

2554

2556 SecondHalfOfMandatoryField |=

2559

2560 GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField,

2561 NumberOfFloatingPointParms);

2562 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasParmsOnStack);

2563 EmitComment();

2564 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,

2565 1);

2566

2567

2568

2569

2570 if (NumberOfFixedParms || NumberOfFPParms) {

2572

2576 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,

2578 : XCOFF::parseParmsType(ParmsTypeValue, NumberOfFixedParms,

2579 NumberOfFPParms);

2580

2582 if (ParmsType) {

2583 CommentOS << "Parameter type = " << ParmsType.get();

2584 EmitComment();

2585 }

2586 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,

2587 sizeof(ParmsTypeValue));

2588 }

2589

2590 OutStreamer->AddComment("Function size");

2592 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(

2594 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);

2595 }

2596

2597

2600

2603

2606 int16_t NameLength = Name.size();

2607 CommentOS << "Function name len = "

2608 << static_cast<unsigned int>(NameLength);

2609 EmitCommentAndValue(NameLength, 2);

2610 OutStreamer->AddComment("Function Name");

2611 OutStreamer->emitBytes(Name);

2612 }

2613

2616 OutStreamer->AddComment("AllocaUsed");

2617 OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));

2618 }

2619

2622 if (NumOfVRSaved) {

2623

2626

2627

2628

2629

2630

2632 }

2633

2634

2637

2638

2642

2643 if (HasVectorInst)

2645

2646 GENVALUECOMMENT("NumOfVRsSaved", VRData, NumberOfVRSaved);

2649 EmitComment();

2650 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);

2651

2652 GENVALUECOMMENT("NumOfVectorParams", VRData, NumberOfVectorParms);

2654 EmitComment();

2655 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);

2656

2658

2662 if (VecParmsType) {

2663 CommentOS << "Vector Parameter type = " << VecParmsType.get();

2664 EmitComment();

2665 }

2666 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,

2667 sizeof(VecParmTypeValue));

2668

2669 CommentOS << "Padding";

2670 EmitCommentAndValue(0, 2);

2671 }

2672

2673 uint8_t ExtensionTableFlag = 0;

2675 if (ShouldEmitEHBlock)

2676 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;

2679 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;

2680

2681 CommentOS << "ExtensionTableFlag = "

2683 EmitCommentAndValue(ExtensionTableFlag, sizeof(ExtensionTableFlag));

2684 }

2685

2686 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {

2687 auto &Ctx = OutStreamer->getContext();

2690 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);

2691 const MCSymbol *TOCBaseSym =

2692 cast(getObjFileLowering().getTOCBaseSection())

2693 ->getQualNameSymbol();

2697

2699 OutStreamer->emitValueToAlignment(Align(4));

2700 OutStreamer->AddComment("EHInfo Table");

2701 OutStreamer->emitValue(Exp, DL.getPointerSize());

2702 }

2703#undef GENBOOLCOMMENT

2704#undef GENVALUECOMMENT

2705}

2706

2710

2711

2712

2713 .Case("llvm.used", true)

2714

2715 .Case("llvm.compiler.used", true)

2717}

2718

2721 .Cases("llvm.global_ctors", "llvm.global_dtors", true)

2723}

2724

2726 if (auto *GA = dyn_cast(C))

2727 return getAliasOffset(GA->getAliasee());

2728 if (auto *CE = dyn_cast(C)) {

2730 const MCBinaryExpr *CBE = dyn_cast(LowC);

2731 if (!CBE)

2732 return 0;

2735 auto *RHS = dyn_cast(CBE->getRHS());

2736 if (!RHS)

2738 return RHS->getValue();

2739 }

2740 return 0;

2741}

2742

2744

2745

2748 "GlobalVariables with an alignment requirement stricter than TOC entry "

2749 "size not supported by the toc data transformation.");

2750

2752 assert(GVType->isSized() && "A GlobalVariable's size must be known to be "

2753 "supported by the toc data transformation.");

2755 PointerSize * 8)

2757 "A GlobalVariable with size larger than a TOC entry is not currently "

2758 "supported by the toc data transformation.");

2761 "currently supported by the toc data transformation.");

2762}

2763

2764void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {

2765

2767 return;

2768

2769

2770

2774 TOCDataGlobalVars.push_back(GV);

2775 return;

2776 }

2777

2778 emitGlobalVariableHelper(GV);

2779}

2780

2781void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) {

2783 "Unhandled intrinsic global variable.");

2784

2787

2788 MCSymbolXCOFF *GVSym = cast(getSymbol(GV));

2789

2791 emitLinkage(GV, GVSym);

2792 return;

2793 }

2794

2795 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);

2797 !GVKind.isThreadLocal())

2799 "not supported yet.");

2800

2801

2802 if (isVerbose()) {

2805 false, GV->getParent());

2806 OutStreamer->getCommentOS() << '\n';

2807 }

2808 }

2809

2811 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));

2812

2813

2814 OutStreamer->switchSection(Csect);

2815

2817

2818

2821 Align Alignment = GV->getAlign().value_or(DL.getPreferredAlign(GV));

2825

2827 OutStreamer->emitZeros(Size);

2830 "BSS local toc-data already handled and TLS variables "

2831 "incompatible with XMC_TD");

2832 OutStreamer->emitXCOFFLocalCommonSymbol(

2834 GVSym, Alignment);

2835 } else {

2836 OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);

2837 }

2838 return;

2839 }

2840

2841 MCSymbol *EmittedInitSym = GVSym;

2842

2843

2844 emitLinkage(GV, EmittedInitSym);

2845 for (const GlobalAlias *GA : GOAliasMap[GV])

2846 emitLinkage(GA, getSymbol(GA));

2847

2848 emitAlignment(getGVAlignment(GV, DL), GV);

2849

2850

2851

2852 if (TM.getDataSections() || GV->hasSection()) {

2854 OutStreamer->emitLabel(EmittedInitSym);

2855 }

2856

2857

2858 if (!GOAliasMap[GV].size()) {

2859 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());

2860 return;

2861 }

2862

2863

2864

2865 AliasMapTy AliasList;

2866 for (const GlobalAlias *GA : GOAliasMap[GV])

2867 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);

2868

2869

2870 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),

2871 &AliasList);

2872}

2873

2874void PPCAIXAsmPrinter::emitFunctionDescriptor() {

2876 const unsigned PointerSize = DL.getPointerSizeInBits() == 64 ? 8 : 4;

2877

2878 MCSectionSubPair Current = OutStreamer->getCurrentSection();

2879

2880 OutStreamer->switchSection(

2881 cast(CurrentFnDescSym)->getRepresentedCsect());

2882

2883

2885 OutStreamer->emitLabel(getSymbol(Alias));

2886

2887

2889 PointerSize);

2890

2891 const MCSymbol *TOCBaseSym =

2892 cast(getObjFileLowering().getTOCBaseSection())

2893 ->getQualNameSymbol();

2895 PointerSize);

2896

2897 OutStreamer->emitIntValue(0, PointerSize);

2898

2899 OutStreamer->switchSection(Current.first, Current.second);

2900}

2901

2902void PPCAIXAsmPrinter::emitFunctionEntryLabel() {

2903

2904

2906 PPCAsmPrinter::emitFunctionEntryLabel();

2907

2908

2910 OutStreamer->emitLabel(

2911 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));

2912}

2913

2914void PPCAIXAsmPrinter::emitPGORefs(Module &M) {

2915 if (!OutContext.hasXCOFFSection(

2916 "__llvm_prf_cnts",

2918 return;

2919

2920

2921

2922

2923

2924

2925

2926 bool HasNonZeroLengthPrfCntsSection = false;

2929 if (GV.hasSection() && GV.getSection() == "__llvm_prf_cnts" &&

2930 DL.getTypeAllocSize(GV.getValueType()) > 0) {

2931 HasNonZeroLengthPrfCntsSection = true;

2932 break;

2933 }

2934

2935 if (HasNonZeroLengthPrfCntsSection) {

2936 MCSection *CntsSection = OutContext.getXCOFFSection(

2939 true);

2940

2941 OutStreamer->switchSection(CntsSection);

2942 if (OutContext.hasXCOFFSection(

2943 "__llvm_prf_data",

2945 MCSymbol *S = OutContext.getOrCreateSymbol("__llvm_prf_data[RW]");

2946 OutStreamer->emitXCOFFRefDirective(S);

2947 }

2948 if (OutContext.hasXCOFFSection(

2949 "__llvm_prf_names",

2951 MCSymbol *S = OutContext.getOrCreateSymbol("__llvm_prf_names[RO]");

2952 OutStreamer->emitXCOFFRefDirective(S);

2953 }

2954 if (OutContext.hasXCOFFSection(

2955 "__llvm_prf_vnds",

2957 MCSymbol *S = OutContext.getOrCreateSymbol("__llvm_prf_vnds[RW]");

2958 OutStreamer->emitXCOFFRefDirective(S);

2959 }

2960 }

2961}

2962

2963void PPCAIXAsmPrinter::emitGCOVRefs() {

2964 if (!OutContext.hasXCOFFSection(

2965 "__llvm_gcov_ctr_section",

2967 return;

2968

2969 MCSection *CtrSection = OutContext.getXCOFFSection(

2972 true);

2973

2974 OutStreamer->switchSection(CtrSection);

2977 if (OutContext.hasXCOFFSection(

2978 "__llvm_covinit",

2980 const char *SymbolStr = TM.Options.XCOFFReadOnlyPointers

2981 ? "__llvm_covinit[RO]"

2982 : "__llvm_covinit[RW]";

2983 MCSymbol *S = OutContext.getOrCreateSymbol(SymbolStr);

2984 OutStreamer->emitXCOFFRefDirective(S);

2985 }

2986}

2987

2988void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {

2989

2990

2991 if (M.empty() && TOCDataGlobalVars.empty())

2992 return;

2993

2994 emitPGORefs(M);

2995 emitGCOVRefs();

2996

2997

2998 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());

2999

3001 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());

3002

3003 for (auto &I : TOC) {

3005

3006

3007

3008

3009

3010 if (I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM ||

3011 (Subtarget->hasAIXShLibTLSModelOpt() &&

3012 I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD)) {

3016 Name += cast(I.first.first)->getSymbolTableName();

3017 MCSymbol *S = OutContext.getOrCreateSymbol(Name);

3018 TCEntry = cast(

3019 getObjFileLowering().getSectionForTOCEntry(S, TM));

3020 } else {

3021 TCEntry = cast(

3022 getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));

3023 }

3024 OutStreamer->switchSection(TCEntry);

3025

3026 OutStreamer->emitLabel(I.second);

3027 TS->emitTCEntry(*I.first.first, I.first.second);

3028 }

3029

3030

3031

3032

3033 for (const auto *GV : TOCDataGlobalVars) {

3034 if (!GV->hasCommonLinkage())

3035 emitGlobalVariableHelper(GV);

3036 }

3037 for (const auto *GV : TOCDataGlobalVars) {

3038 if (GV->hasCommonLinkage())

3039 emitGlobalVariableHelper(GV);

3040 }

3041}

3042

3043bool PPCAIXAsmPrinter::doInitialization(Module &M) {

3044 const bool Result = PPCAsmPrinter::doInitialization(M);

3045

3046

3049

3050

3051 for (auto &F : M) {

3054 if (FunCpuId > TargetCpuId)

3055 TargetCpuId = FunCpuId;

3056 }

3057

3058

3059

3060 if (!TargetCpuId) {

3061 StringRef TargetCPU = TM.getTargetCPU();

3064 }

3065

3067 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());

3069

3070 auto setCsectAlignment = [this](const GlobalObject *GO) {

3071

3072 if (GO->isDeclarationForLinker())

3073 return;

3074

3075 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);

3077 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));

3078

3079 Align GOAlign = getGVAlignment(GO, GO->getDataLayout());

3081 };

3082

3083

3084

3085

3087 auto DL = M.getDataLayout();

3088 for (const auto &G : M.globals()) {

3089 if (G.isThreadLocal() && G.isDeclaration()) {

3090 TLSVarAddress = alignTo(TLSVarAddress, getGVAlignment(&G, DL));

3091 TLSVarsToAddressMapping[&G] = TLSVarAddress;

3092 TLSVarAddress += DL.getTypeAllocSize(G.getValueType());

3093 }

3094 }

3095

3096

3097

3098

3099 for (const auto &G : M.globals()) {

3101 continue;

3102

3104

3105

3106 if (FormatIndicatorAndUniqueModId.empty()) {

3108 if (UniqueModuleId != "")

3109

3110

3111

3112 FormatIndicatorAndUniqueModId = "clang_" + UniqueModuleId.substr(1);

3113 else {

3114

3115

3116 auto CurTime =

3117 std::chrono::duration_caststd::chrono::nanoseconds(

3118 std::chrono::steady_clock::now().time_since_epoch())

3119 .count();

3120 FormatIndicatorAndUniqueModId =

3123 llvm::itostr(CurTime);

3124 }

3125 }

3126

3127 emitSpecialLLVMGlobal(&G);

3128 continue;

3129 }

3130

3131 setCsectAlignment(&G);

3132 std::optionalCodeModel::Model OptionalCodeModel = G.getCodeModel();

3133 if (OptionalCodeModel)

3135 *OptionalCodeModel);

3136 }

3137

3138 for (const auto &F : M)

3139 setCsectAlignment(&F);

3140

3141

3142 for (const auto &Alias : M.aliases()) {

3144 if (!Aliasee)

3146 "alias without a base object is not yet supported on AIX");

3147

3149 report_fatal_error("Aliases to common variables are not allowed on AIX:"

3150 "\n\tAlias attribute for " +

3151 Alias.getGlobalIdentifier() +

3152 " is invalid because " + Aliasee->getName() +

3153 " is common.",

3154 false);

3155 }

3156

3158 dyn_cast_or_null(Alias.getAliaseeObject());

3159 if (GVar) {

3160 std::optionalCodeModel::Model OptionalCodeModel = GVar->getCodeModel();

3161 if (OptionalCodeModel)

3163 *OptionalCodeModel);

3164 }

3165

3166 GOAliasMap[Aliasee].push_back(&Alias);

3167 }

3168

3170}

3171

3172void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {

3173 switch (MI->getOpcode()) {

3174 default:

3175 break;

3176 case PPC::TW:

3177 case PPC::TWI:

3178 case PPC::TD:

3179 case PPC::TDI: {

3180 if (MI->getNumOperands() < 5)

3181 break;

3184 if (!LangMO.isImm() || !ReasonMO.isImm())

3185 break;

3186 MCSymbol *TempSym = OutContext.createNamedTempSymbol();

3187 OutStreamer->emitLabel(TempSym);

3188 OutStreamer->emitXCOFFExceptDirective(

3189 CurrentFnSym, TempSym, LangMO.getImm(), ReasonMO.getImm(),

3190 Subtarget->isPPC64() ? MI->getMF()->getInstructionCount() * 8

3191 : MI->getMF()->getInstructionCount() * 4,

3193 break;

3194 }

3195 case PPC::GETtlsMOD32AIX:

3196 case PPC::GETtlsMOD64AIX:

3197 case PPC::GETtlsTpointer32AIX:

3198 case PPC::GETtlsADDR64AIX:

3199 case PPC::GETtlsADDR32AIX: {

3200

3201

3204 ExtSymSDNodeSymbols.insert(TlsGetAddr);

3205 break;

3206 }

3207 case PPC::BL8:

3208 case PPC::BL:

3209 case PPC::BL8_NOP:

3210 case PPC::BL_NOP: {

3214 cast(OutContext.getOrCreateSymbol(MO.getSymbolName()));

3215 ExtSymSDNodeSymbols.insert(S);

3216 }

3217 } break;

3218 case PPC::BL_TLS:

3219 case PPC::BL8_TLS:

3220 case PPC::BL8_TLS_:

3221 case PPC::BL8_NOP_TLS:

3223 case PPC::TAILB:

3224 case PPC::TAILB8:

3225 case PPC::TAILBA:

3226 case PPC::TAILBA8:

3227 case PPC::TAILBCTR:

3228 case PPC::TAILBCTR8:

3229 if (MI->getOperand(0).isSymbol())

3230 report_fatal_error("Tail call for extern symbol not yet supported.");

3231 break;

3232 case PPC::DST:

3233 case PPC::DST64:

3234 case PPC::DSTT:

3235 case PPC::DSTT64:

3236 case PPC::DSTST:

3237 case PPC::DSTST64:

3238 case PPC::DSTSTT:

3239 case PPC::DSTSTT64:

3240 EmitToStreamer(

3241 *OutStreamer,

3242 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));

3243 return;

3244 }

3245 return PPCAsmPrinter::emitInstruction(MI);

3246}

3247

3248bool PPCAIXAsmPrinter::doFinalization(Module &M) {

3249

3251

3252

3253

3254 auto *Sec = OutContext.getObjectFileInfo()->getTextSection();

3255 OutStreamer->switchSectionNoPrint(Sec);

3256 MCSymbol *Sym = Sec->getEndSymbol(OutContext);

3257 OutStreamer->emitLabel(Sym);

3258 }

3259

3260 for (MCSymbol *Sym : ExtSymSDNodeSymbols)

3262 return PPCAsmPrinter::doFinalization(M);

3263}

3264

3266 if (P < 0 || P > 65535)

3268

3269 if (P <= 20)

3270 return P;

3271

3272 if (P < 81)

3273 return 20 + (P - 20) * 16;

3274

3275 if (P <= 1124)

3276 return 1004 + (P - 81);

3277

3278 if (P < 64512)

3279 return 2047 + (P - 1124) * 33878;

3280

3281 return 2147482625u + (P - 64512);

3282}

3283

3285

3286

3287

3288

3289

3290

3291

3292

3293

3294

3295

3296

3297

3299

3300 std::string PrioritySuffix;

3303 return PrioritySuffix;

3304}

3305

3306void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL,

3307 const Constant *List, bool IsCtor) {

3309 preprocessXXStructorList(DL, List, Structors);

3310 if (Structors.empty())

3311 return;

3312

3313 unsigned Index = 0;

3314 for (Structor &S : Structors) {

3315 if (const ConstantExpr *CE = dyn_cast(S.Func))

3316 S.Func = CE->getOperand(0);

3317

3322 llvm::Twine("_", FormatIndicatorAndUniqueModId) +

3323 llvm::Twine("_", llvm::utostr(Index++)),

3324 cast(S.Func));

3325 }

3326}

3327

3328void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV,

3329 unsigned Encoding) {

3330 if (GV) {

3331 TOCEntryType GlobalType = TOCType_GlobalInternal;

3336 GlobalType = TOCType_GlobalExternal;

3337 MCSymbol *TypeInfoSym = TM.getSymbol(GV);

3338 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);

3339 const MCSymbol *TOCBaseSym =

3340 cast(getObjFileLowering().getTOCBaseSection())

3341 ->getQualNameSymbol();

3342 auto &Ctx = OutStreamer->getContext();

3346 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));

3347 } else

3348 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));

3349}

3350

3351

3352

3355 std::unique_ptr &&Streamer) {

3357 return new PPCAIXAsmPrinter(tm, std::move(Streamer));

3358

3359 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));

3360}

3361

3362void PPCAIXAsmPrinter::emitModuleCommandLines(Module &M) {

3363 const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");

3365 return;

3366

3367 std::string S;

3369 for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {

3371 assert(N->getNumOperands() == 1 &&

3372 "llvm.commandline metadata entry can have only one operand");

3373 const MDString *MDS = cast(N->getOperand(0));

3374

3375

3376 RSOS << "@(#)opt " << MDS->getString() << "\n";

3377 RSOS.write('\0');

3378 }

3379 OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());

3380}

3381

3382

3392}

unsigned const MachineRegisterInfo * MRI

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

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

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

#define LLVM_EXTERNAL_VISIBILITY

static bool hasDebugInfo(const MachineFunction *MF)

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

static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)

This file implements a map that provides insertion order iteration.

static void collectTOCStats(PPCAsmPrinter::TOCEntryType Type)

static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV)

static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV)

LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter()

#define GENBOOLCOMMENT(Prefix, V, Field)

static MCSymbol * getMCSymbolForTOCPseudoMO(const MachineOperand &MO, AsmPrinter &AP)

Map a machine operand for a TOC pseudo-machine instruction to its corresponding MCSymbol.

static void setOptionalCodeModel(MCSymbolXCOFF *XSym, CodeModel::Model CM)

static AsmPrinter * createPPCAsmPrinterPass(TargetMachine &tm, std::unique_ptr< MCStreamer > &&Streamer)

static PPCAsmPrinter::TOCEntryType getTOCEntryTypeForMO(const MachineOperand &MO)

static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)

static std::string convertToSinitPriority(int Priority)

static MCSymbol * createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc)

This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX.

#define GENVALUECOMMENT(PrefixAndName, V, Field)

static unsigned mapToSinitPriority(int P)

static void tocDataChecks(unsigned PointerSize, const GlobalVariable *GV)

static cl::opt< bool > EnableSSPCanaryBitInTB("aix-ssp-tb-bit", cl::init(false), cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden)

PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)

Provides a library for accessing information about this process and other processes on the operating ...

static SDValue lowerConstant(SDValue Op, SelectionDAG &DAG, const RISCVSubtarget &Subtarget)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

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

static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)

This file implements a set that has insertion order iteration characteristics.

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

#define STATISTIC(VARNAME, DESC)

This class is intended to be used as a driving class for all asm writers.

virtual void emitInstruction(const MachineInstr *)

Targets should implement this to emit instructions.

MCSymbol * getSymbol(const GlobalValue *GV) const

void emitXRayTable()

Emit a table with all XRay instrumentation points.

virtual MCSymbol * GetCPISymbol(unsigned CPID) const

Return the symbol for the specified constant pool entry.

virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)

Print the MachineOperand as a symbol.

virtual void SetupMachineFunction(MachineFunction &MF)

This should be called when a new MachineFunction is being processed from runOnMachineFunction.

virtual void emitStartOfAsmFile(Module &)

This virtual method can be overridden by targets that want to emit something at the start of their fi...

MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const

Return the symbol for the specified jump table entry.

bool doInitialization(Module &M) override

Set up the AsmPrinter when we are working on a new module.

bool runOnMachineFunction(MachineFunction &MF) override

Emit the specified function out to the OutStreamer.

virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)

Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...

MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const

Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.

virtual void emitFunctionEntryLabel()

EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.

virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)

Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.

A constant value that is initialized with an expression using other constant values.

This is an important base class in LLVM.

This class represents an Operation in the Expression.

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

unsigned getPointerSize(unsigned AS=0) const

Layout pointer size in bytes, rounded up to a whole number of bytes.

TypeSize getTypeSizeInBits(Type *Ty) const

Size examples:

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

static GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)

If a parent module is specified, the alias is automatically inserted into the end of the specified mo...

MaybeAlign getAlign() const

Returns the alignment of the given variable or function.

bool hasSection() const

Check if this global has a custom object file section.

VisibilityTypes getVisibility() const

bool isDeclaration() const

Return true if the primary definition of this global value is outside of the current translation unit...

LinkageTypes getLinkage() const

bool hasDefaultVisibility() const

bool hasPrivateLinkage() const

ThreadLocalMode getThreadLocalMode() const

bool hasDLLExportStorageClass() const

bool isDeclarationForLinker() const

Module * getParent()

Get the module that this global value is contained inside of...

const GlobalObject * getAliaseeObject() const

@ DefaultVisibility

The GV is visible.

@ HiddenVisibility

The GV is hidden.

@ ProtectedVisibility

The GV is protected.

const DataLayout & getDataLayout() const

Get the data layout of the module this global belongs to.

bool hasCommonLinkage() const

bool hasAppendingLinkage() const

LinkageTypes

An enumeration for the kinds of linkage for global values.

@ PrivateLinkage

Like Internal, but omit from symbol table.

@ CommonLinkage

Tentative definitions.

@ InternalLinkage

Rename collisions when linking (static functions).

@ LinkOnceAnyLinkage

Keep one copy of function when linking (inline)

@ WeakODRLinkage

Same, but only replaced by something equivalent.

@ ExternalLinkage

Externally visible function.

@ WeakAnyLinkage

Keep one copy of named function when linking (weak)

@ AppendingLinkage

Special purpose, only applies to global arrays.

@ AvailableExternallyLinkage

Available for inspection, not emission.

@ ExternalWeakLinkage

ExternalWeak linkage description.

@ LinkOnceODRLinkage

Same, but only replaced by something equivalent.

Type * getValueType() const

bool hasAttribute(Attribute::AttrKind Kind) const

Return true if the attribute exists.

bool hasInitializer() const

Definitions have initializers, declarations don't.

std::optional< CodeModel::Model > getCodeModel() const

Get the custom code model of this global if it has one.

Binary assembler expressions.

const MCExpr * getRHS() const

Get the right-hand side expression of the binary operator.

static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

Opcode getOpcode() const

Get the kind of this binary expression.

static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

MCSectionXCOFF * getXCOFFSection(StringRef Section, SectionKind K, std::optional< XCOFF::CsectProperties > CsectProp=std::nullopt, bool MultiSymbolsAllowed=false, std::optional< XCOFF::DwarfSectionSubtypeFlags > DwarfSubtypeFlags=std::nullopt)

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

MCInstBuilder & addReg(MCRegister Reg)

Add a new register operand.

MCInstBuilder & addImm(int64_t Val)

Add a new integer immediate operand.

MCInstBuilder & addExpr(const MCExpr *Val)

Add a new MCExpr operand.

Instances of this class represent a single low-level machine instruction.

void addOperand(const MCOperand Op)

void setOpcode(unsigned Op)

const MCOperand & getOperand(unsigned i) const

Instances of this class represent operands of the MCInst class.

static MCOperand createExpr(const MCExpr *Val)

MCRegister getReg() const

Returns the register number.

This represents a section on linux, lots of unix variants and some bare metal systems.

XCOFF::StorageMappingClass getMappingClass() const

MCSymbolXCOFF * getQualNameSymbol() const

Instances of this class represent a uniqued identifier for a section in the current translation unit.

void setAlignment(Align Value)

void ensureMinAlignment(Align MinAlignment)

Makes sure that Alignment is at least MinAlignment.

Represent a reference to a symbol from inside an expression.

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)

StringRef getSymbolTableName() const

void setPerSymbolCodeModel(MCSymbolXCOFF::CodeModel Model)

void setStorageClass(XCOFF::StorageClass SC)

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

void print(raw_ostream &OS, const MCAsmInfo *MAI) const

print - Print the value to the stream OS.

StringRef getString() const

MCSymbol * getSymbol() const

Return the MCSymbol for this basic block.

uint64_t getStackSize() const

Return the number of bytes that must be allocated to hold all of the fixed size frame objects.

const TargetSubtargetInfo & getSubtarget() const

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

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

MachineFrameInfo & getFrameInfo()

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

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

MCSection * getSection() const

Returns the Section this function belongs to.

Ty * getInfo()

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

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

const GlobalValue * getGlobal() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

MachineBasicBlock * getMBB() const

bool isCPI() const

isCPI - Tests if this is a MO_ConstantPoolIndex operand.

bool isImm() const

isImm - Tests if this is a MO_Immediate operand.

bool isSymbol() const

isSymbol - Tests if this is a MO_ExternalSymbol operand.

bool isJTI() const

isJTI - Tests if this is a MO_JumpTableIndex operand.

const BlockAddress * getBlockAddress() const

unsigned getTargetFlags() const

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

MachineOperandType getType() const

getType - Returns the MachineOperandType for this operand.

const char * getSymbolName() const

bool isBlockAddress() const

isBlockAddress - Tests if this is a MO_BlockAddress operand.

Register getReg() const

getReg - Returns the register number.

@ MO_Immediate

Immediate operand.

@ MO_ConstantPoolIndex

Address of indexed Constant in Constant Pool.

@ MO_GlobalAddress

Address of a global value.

@ MO_BlockAddress

Address of a basic block.

@ MO_MachineBasicBlock

MachineBasicBlock reference.

@ MO_Register

Register operand.

@ MO_JumpTableIndex

Address of indexed Jump Table for switch.

int64_t getOffset() const

Return the offset from the symbol in this operand.

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

This class implements a map that also provides access to all stored values in a deterministic order.

iterator find(const KeyT &Key)

A Module instance is used to store all the information related to an LLVM module.

MDNode * getOperand(unsigned i) const

unsigned getNumOperands() const

uint64_t getTOCSaveOffset() const

getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.

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

uint32_t getParmsType() const

MCSymbol * getPICOffsetSymbol(MachineFunction &MF) const

const SmallVectorImpl< Register > & getMustSaveCRs() const

unsigned getFloatingPointParmsNum() const

bool isAIXFuncUseTLSIEForLD() const

MCSymbol * getGlobalEPSymbol(MachineFunction &MF) const

MCSymbol * getLocalEPSymbol(MachineFunction &MF) const

unsigned getVectorParmsNum() const

int getVarArgsFrameIndex() const

bool usesTOCBasePtr() const

bool hasVectorParms() const

uint32_t getVecExtParmsType() const

MCSymbol * getTOCOffsetSymbol(MachineFunction &MF) const

unsigned getFixedParmsNum() const

static const char * getRegisterName(MCRegister Reg)

static bool hasTLSFlag(unsigned TF)

static const PPCMCExpr * createLo(const MCExpr *Expr, MCContext &Ctx)

static const PPCMCExpr * createHa(const MCExpr *Expr, MCContext &Ctx)

bool is32BitELFABI() const

const PPCFrameLowering * getFrameLowering() const override

bool isPPC64() const

isPPC64 - Return true if we are generating code for 64-bit pointer mode.

bool isUsingPCRelativeCalls() const

CodeModel::Model getCodeModel(const TargetMachine &TM, const GlobalValue *GV) const

Calculates the effective code model for argument GV.

const PPCRegisterInfo * getRegisterInfo() const override

bool isGVIndirectSymbol(const GlobalValue *GV) const

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

Common code between 32-bit and 64-bit PowerPC targets.

bool hasGlibcHWCAPAccess() const

virtual void emitAbiVersion(int AbiVersion)

virtual void emitTCEntry(const MCSymbol &S, MCSymbolRefExpr::VariantKind Kind)

virtual void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset)

virtual void emitMachine(StringRef CPU)

virtual StringRef getPassName() const

getPassName - Return a nice clean name for a pass.

MI-level patchpoint operands.

Wrapper class representing virtual and physical registers.

SectionKind - This is a simple POD value that classifies the properties of a section.

bool isThreadBSSLocal() const

static SectionKind getText()

static SectionKind getData()

bool isThreadLocal() const

bool isGlobalWriteableData() const

A SetVector that performs no allocations if smaller than a certain size.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

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

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

void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)

Generate a stackmap record for a patchpoint instruction.

void recordStackMap(const MCSymbol &L, const MachineInstr &MI)

Generate a stackmap record for a stackmap instruction.

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

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)

static bool ShouldSetSSPCanaryBitInTB(const MachineFunction *MF)

static MCSymbol * getEHInfoTableSymbol(const MachineFunction *MF)

static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV)

static bool ShouldEmitEHBlock(const MachineFunction *MF)

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

const Triple & getTargetTriple() const

Target - Wrapper for Target specific information.

Triple - Helper class for working with autoconf configuration names.

bool isOSAIX() const

Tests whether the OS is AIX.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

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

bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const

Return true if it makes sense to take the size of this type.

LLVM Value Representation.

void print(raw_ostream &O, bool IsForDebug=false) const

Implement operator<< on Value.

Align getPointerAlignment(const DataLayout &DL) const

Returns an alignment of the pointer value.

void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const

Print the name of this Value out to the specified raw_ostream.

StringRef getName() const

Return a constant reference to the value's name.

This class implements an extremely fast bulk output stream that can only output to a stream.

A raw_ostream that writes to an std::string.

A raw_ostream that writes to an SmallVector or SmallString.

static Pid getProcessId()

Get the process's identifier.

#define llvm_unreachable(msg)

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

constexpr std::underlying_type_t< E > Mask()

Get a bitmask with 1s in all places up to the high-order bit of E's largest value.

@ C

The default llvm calling convention, compatible with C.

Flag

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

@ MO_TLSLDM_FLAG

MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...

@ MO_TPREL_PCREL_FLAG

MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.

@ MO_GOT_TPREL_PCREL_FLAG

MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...

@ MO_TLSGDM_FLAG

MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...

@ MO_TLSLD_FLAG

MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.

@ MO_TPREL_FLAG

MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...

@ MO_GOT_TLSLD_PCREL_FLAG

MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...

@ MO_TLSGD_FLAG

MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...

@ MO_GOT_TLSGD_PCREL_FLAG

MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...

StringRef getNormalizedPPCTargetCPU(const Triple &T, StringRef CPUName="")

Predicate

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

const char * stripRegisterPrefix(const char *RegName)

stripRegisterPrefix - This method strips the character prefix from a register name so that only the n...

Predicate InvertPredicate(Predicate Opcode)

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

static bool isVRRegister(unsigned Reg)

static bool isVFRegister(unsigned Reg)

@ CE

Windows NT (Windows on ARM)

Reg

All possible values of the reg field in the ModR/M byte.

void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)

SmallString< 32 > getExtendedTBTableFlagString(uint8_t Flag)

XCOFF::CFileCpuId getCpuID(StringRef CPU)

Expected< SmallString< 32 > > parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum, unsigned VectorParmsNum)

Expected< SmallString< 32 > > parseParmsType(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum)

Expected< SmallString< 32 > > parseVectorParmsType(uint32_t Value, unsigned ParmsNum)

@ TCPU_INVALID

Invalid id - assumes POWER for old objects.

StorageMappingClass

Storage Mapping Class definitions.

@ XMC_RO

Read Only Constant.

@ XMC_TD

Scalar data item in the TOC.

StringRef getTCPUString(XCOFF::CFileCpuId TCPU)

StringRef getNameForTracebackTableLanguageId(TracebackTable::LanguageID LangId)

constexpr uint8_t AllocRegNo

@ XTY_SD

Csect definition for initialized storage.

@ XTY_ER

External reference.

initializer< Ty > init(const Ty &Val)

unsigned combineHashValue(unsigned a, unsigned b)

Simplistic combination of 32-bit hash values into 32-bit hash values.

constexpr uint64_t PointerSize

aarch64 pointer size.

Linkage

Describes symbol linkage. This can be used to resolve definition clashes.

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

Target & getThePPC64LETarget()

auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)

Get the size of a range.

bool LowerPPCMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &OutMO, AsmPrinter &AP)

Target & getThePPC32Target()

std::string getUniqueModuleId(Module *M)

Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...

std::pair< MCSection *, uint32_t > MCSectionSubPair

void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)

raw_ostream & dbgs()

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

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)

format_hex_no_prefix - Output N as a fixed width hexadecimal.

Target & getThePPC64Target()

uint64_t get_threadid()

Return the current thread id, as used in various OS system calls.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

Target & getThePPC32LETarget()

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

const char * toString(DWARFSectionKind Kind)

@ MCSA_Global

.type _foo, @gnu_unique_object

@ MCSA_Extern

.extern (XCOFF)

@ MCSA_LGlobal

.lglobl (XCOFF)

@ MCSA_Invalid

Not a valid directive.

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

This struct is a compact representation of a valid (non-zero power of two) alignment.

uint64_t value() const

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

static unsigned getHashValue(const TOCKey &PairVal)

static bool isEqual(const TOCKey &A, const TOCKey &B)

std::pair< const MCSymbol *, MCSymbolRefExpr::VariantKind > TOCKey

static TOCKey getTombstoneKey()

static TOCKey getEmptyKey()

An information struct used to provide DenseMap with the various necessary components for a given valu...

Align valueOrOne() const

For convenience, returns a valid alignment or 1 if undefined.

static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn)

RegisterAsmPrinter - Register an AsmPrinter implementation for the given target.

static constexpr uint32_t FPRSavedMask

static constexpr uint16_t NumberOfVRSavedMask

static constexpr uint8_t NumberOfFloatingPointParmsShift

static constexpr uint32_t NumberOfFixedParmsMask

static constexpr uint16_t HasVMXInstructionMask

static constexpr uint32_t IsLRSavedMask

static constexpr uint16_t HasVarArgsMask

static constexpr uint32_t IsAllocaUsedMask

static constexpr uint16_t IsVRSavedOnStackMask

static constexpr uint16_t NumberOfVectorParmsMask

static constexpr uint32_t IsFloatingPointPresentMask

static constexpr uint32_t FPRSavedShift

static constexpr uint32_t NumberOfFloatingPointParmsMask

static constexpr uint32_t HasControlledStorageMask

static constexpr uint32_t HasExtensionTableMask

static constexpr uint32_t HasTraceBackTableOffsetMask

static constexpr uint32_t IsCRSavedMask

static constexpr uint8_t NumberOfFixedParmsShift

static constexpr uint32_t GPRSavedMask

static constexpr uint8_t NumberOfVectorParmsShift

static constexpr uint32_t HasParmsOnStackMask

static constexpr uint32_t IsFunctionNamePresentMask

static constexpr uint32_t IsBackChainStoredMask

static constexpr uint32_t IsInterruptHandlerMask

static constexpr uint32_t HasVectorInfoMask

static constexpr uint8_t NumberOfVRSavedShift

static constexpr uint32_t GPRSavedShift