diff options
Diffstat (limited to 'contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 651 |
1 files changed, 343 insertions, 308 deletions
diff --git a/contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 49fd2f904a24..4f1c3c73e710 100644 --- a/contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/contrib/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -68,13 +68,12 @@ namespace { class PPCAsmPrinter : public AsmPrinter { protected: MapVector<MCSymbol*, MCSymbol*> TOC; - const PPCSubtarget &Subtarget; - uint64_t TOCLabelID; + const PPCSubtarget *Subtarget; StackMaps SM; public: - explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) - : AsmPrinter(TM, Streamer), - Subtarget(TM.getSubtarget<PPCSubtarget>()), TOCLabelID(0), SM(*this) {} + explicit PPCAsmPrinter(TargetMachine &TM, + std::unique_ptr<MCStreamer> Streamer) + : AsmPrinter(TM, std::move(Streamer)), SM(*this) {} const char *getPassName() const override { return "PowerPC Assembly Printer"; @@ -99,13 +98,19 @@ namespace { const MachineInstr &MI); void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM, const MachineInstr &MI); + void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK); + bool runOnMachineFunction(MachineFunction &MF) override { + Subtarget = &MF.getSubtarget<PPCSubtarget>(); + return AsmPrinter::runOnMachineFunction(MF); + } }; /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux class PPCLinuxAsmPrinter : public PPCAsmPrinter { public: - explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) - : PPCAsmPrinter(TM, Streamer) {} + explicit PPCLinuxAsmPrinter(TargetMachine &TM, + std::unique_ptr<MCStreamer> Streamer) + : PPCAsmPrinter(TM, std::move(Streamer)) {} const char *getPassName() const override { return "Linux PPC Assembly Printer"; @@ -124,8 +129,9 @@ namespace { /// OS X class PPCDarwinAsmPrinter : public PPCAsmPrinter { public: - explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) - : PPCAsmPrinter(TM, Streamer) {} + explicit PPCDarwinAsmPrinter(TargetMachine &TM, + std::unique_ptr<MCStreamer> Streamer) + : PPCAsmPrinter(TM, std::move(Streamer)) {} const char *getPassName() const override { return "Darwin PPC Assembly Printer"; @@ -144,6 +150,7 @@ static const char *stripRegisterPrefix(const char *RegName) { switch (RegName[0]) { case 'r': case 'f': + case 'q': // for QPX case 'v': if (RegName[1] == 's') return RegName + 2; @@ -156,7 +163,7 @@ static const char *stripRegisterPrefix(const char *RegName) { void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { - const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); + const DataLayout *DL = TM.getDataLayout(); const MachineOperand &MO = MI->getOperand(OpNo); switch (MO.getType()) { @@ -164,7 +171,8 @@ void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg()); // Linux assembler (Others?) does not take register mnemonics. // FIXME - What about special registers used in mfspr/mtspr? - if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); + if (!Subtarget->isDarwin()) + RegName = stripRegisterPrefix(RegName); O << RegName; return; } @@ -279,7 +287,8 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, case 'y': // A memory reference for an X-form instruction { const char *RegName = "r0"; - if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); + if (!Subtarget->isDarwin()) + RegName = stripRegisterPrefix(RegName); O << RegName << ", "; printOperand(MI, OpNo, O); return false; @@ -311,17 +320,9 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, /// exists for it. If not, create one. Then return a symbol that references /// the TOC entry. MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) { - const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); MCSymbol *&TOCEntry = TOC[Sym]; - - // To avoid name clash check if the name already exists. - while (!TOCEntry) { - if (OutContext.LookupSymbol(Twine(DL->getPrivateGlobalPrefix()) + - "C" + Twine(TOCLabelID++)) == nullptr) { - TOCEntry = GetTempSymbol("C", TOCLabelID); - } - } - + if (!TOCEntry) + TOCEntry = createTempSymbol("C"); return TOCEntry; } @@ -400,12 +401,45 @@ void PPCAsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM, EmitToStreamer(OutStreamer, MCInstBuilder(PPC::NOP)); } +/// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a +/// call to __tls_get_addr to the current output stream. +void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI, + MCSymbolRefExpr::VariantKind VK) { + StringRef Name = "__tls_get_addr"; + MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name); + MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; + + assert(MI->getOperand(0).isReg() && + ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) || + (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) && + "GETtls[ld]ADDR[32] must define GPR3"); + assert(MI->getOperand(1).isReg() && + ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) || + (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) && + "GETtls[ld]ADDR[32] must read GPR3"); + + if (!Subtarget->isPPC64() && !Subtarget->isDarwin() && + TM.getRelocationModel() == Reloc::PIC_) + Kind = MCSymbolRefExpr::VK_PLT; + const MCSymbolRefExpr *TlsRef = + MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext); + const MachineOperand &MO = MI->getOperand(2); + const GlobalValue *GValue = MO.getGlobal(); + MCSymbol *MOSymbol = getSymbol(GValue); + const MCExpr *SymVar = MCSymbolRefExpr::Create(MOSymbol, VK, OutContext); + EmitToStreamer(*OutStreamer, + MCInstBuilder(Subtarget->isPPC64() ? + PPC::BL8_NOP_TLS : PPC::BL_TLS) + .addExpr(TlsRef) + .addExpr(SymVar)); +} + /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to /// the current output stream. /// void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCInst TmpInst; - bool isPPC64 = Subtarget.isPPC64(); + bool isPPC64 = Subtarget->isPPC64(); bool isDarwin = Triple(TM.getTargetTriple()).isOSDarwin(); const Module *M = MF->getFunction()->getParent(); PICLevel::Level PL = M->getPICLevel(); @@ -416,9 +450,9 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { case TargetOpcode::DBG_VALUE: llvm_unreachable("Should be handled target independently"); case TargetOpcode::STACKMAP: - return LowerSTACKMAP(OutStreamer, SM, *MI); + return LowerSTACKMAP(*OutStreamer, SM, *MI); case TargetOpcode::PATCHPOINT: - return LowerPATCHPOINT(OutStreamer, SM, *MI); + return LowerPATCHPOINT(*OutStreamer, SM, *MI); case PPC::MoveGOTtoLR: { // Transform %LR = MoveGOTtoLR @@ -428,7 +462,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { // blrl // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local MCSymbol *GOTSymbol = - OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); + OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); const MCExpr *OffsExpr = MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_LOCAL, @@ -437,7 +471,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { OutContext); // Emit the 'bl'. - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr)); return; } case PPC::MovePCtoLR: @@ -449,13 +483,13 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCSymbol *PICBase = MF->getPICBaseSymbol(); // Emit the 'bl'. - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL) + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL) // FIXME: We would like an efficient form for this, so we don't have to do // a lot of extra uniquing. .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext))); // Emit the label. - OutStreamer.EmitLabel(PICBase); + OutStreamer->EmitLabel(PICBase); return; } case PPC::UpdateGBR: { @@ -478,16 +512,16 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { // Step 1: lwz %Rt, .L$poff - .L$pb(%Ri) TmpInst.getOperand(1) = - MCOperand::CreateExpr(MCBinaryExpr::CreateSub(Exp, PB, OutContext)); + MCOperand::createExpr(MCBinaryExpr::CreateSub(Exp, PB, OutContext)); TmpInst.getOperand(0) = TR; TmpInst.getOperand(2) = PICR; - EmitToStreamer(OutStreamer, TmpInst); + EmitToStreamer(*OutStreamer, TmpInst); TmpInst.setOpcode(PPC::ADD4); TmpInst.getOperand(0) = PICR; TmpInst.getOperand(1) = TR; TmpInst.getOperand(2) = PICR; - EmitToStreamer(OutStreamer, TmpInst); + EmitToStreamer(*OutStreamer, TmpInst); return; } case PPC::LWZtoc: { @@ -515,7 +549,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const MCExpr *Exp = MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_GOT, OutContext); - TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); + TmpInst.getOperand(1) = MCOperand::createExpr(Exp); } else { MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); @@ -523,12 +557,12 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_None, OutContext); const MCExpr *PB = - MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC")), + MCSymbolRefExpr::Create(OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext); Exp = MCBinaryExpr::CreateSub(Exp, PB, OutContext); - TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); + TmpInst.getOperand(1) = MCOperand::createExpr(Exp); } - EmitToStreamer(OutStreamer, TmpInst); + EmitToStreamer(*OutStreamer, TmpInst); return; } case PPC::LDtocJTI: @@ -560,8 +594,8 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const MCExpr *Exp = MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC, OutContext); - TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); - EmitToStreamer(OutStreamer, TmpInst); + TmpInst.getOperand(1) = MCOperand::createExpr(Exp); + EmitToStreamer(*OutStreamer, TmpInst); return; } @@ -607,8 +641,8 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const MCExpr *Exp = MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA, OutContext); - TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); - EmitToStreamer(OutStreamer, TmpInst); + TmpInst.getOperand(2) = MCOperand::createExpr(Exp); + EmitToStreamer(*OutStreamer, TmpInst); return; } case PPC::LDtocL: { @@ -649,8 +683,8 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const MCExpr *Exp = MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, OutContext); - TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); - EmitToStreamer(OutStreamer, TmpInst); + TmpInst.getOperand(1) = MCOperand::createExpr(Exp); + EmitToStreamer(*OutStreamer, TmpInst); return; } case PPC::ADDItocL: { @@ -683,24 +717,24 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const MCExpr *Exp = MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO, OutContext); - TmpInst.getOperand(2) = MCOperand::CreateExpr(Exp); - EmitToStreamer(OutStreamer, TmpInst); + TmpInst.getOperand(2) = MCOperand::createExpr(Exp); + EmitToStreamer(*OutStreamer, TmpInst); return; } case PPC::ADDISgotTprelHA: { // Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym> // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha - assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); + assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); const MachineOperand &MO = MI->getOperand(2); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); const MCExpr *SymGotTprel = MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA, OutContext); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) - .addReg(MI->getOperand(0).getReg()) - .addReg(PPC::X2) - .addExpr(SymGotTprel)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addExpr(SymGotTprel)); return; } case PPC::LDgotTprelL: @@ -716,17 +750,17 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const MCExpr *Exp = MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO, OutContext); - TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); - EmitToStreamer(OutStreamer, TmpInst); + TmpInst.getOperand(1) = MCOperand::createExpr(Exp); + EmitToStreamer(*OutStreamer, TmpInst); return; } case PPC::PPC32PICGOT: { - MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); - MCSymbol *GOTRef = OutContext.CreateTempSymbol(); - MCSymbol *NextInstr = OutContext.CreateTempSymbol(); + MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); + MCSymbol *GOTRef = OutContext.createTempSymbol(); + MCSymbol *NextInstr = OutContext.createTempSymbol(); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BL) + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL) // FIXME: We would like an efficient form for this, so we don't have to do // a lot of extra uniquing. .addExpr(MCSymbolRefExpr::Create(NextInstr, OutContext))); @@ -734,52 +768,52 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(GOTSymbol, OutContext), MCSymbolRefExpr::Create(GOTRef, OutContext), OutContext); - OutStreamer.EmitLabel(GOTRef); - OutStreamer.EmitValue(OffsExpr, 4); - OutStreamer.EmitLabel(NextInstr); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR) - .addReg(MI->getOperand(0).getReg())); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LWZ) - .addReg(MI->getOperand(1).getReg()) - .addImm(0) - .addReg(MI->getOperand(0).getReg())); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADD4) - .addReg(MI->getOperand(0).getReg()) - .addReg(MI->getOperand(1).getReg()) - .addReg(MI->getOperand(0).getReg())); + OutStreamer->EmitLabel(GOTRef); + OutStreamer->EmitValue(OffsExpr, 4); + OutStreamer->EmitLabel(NextInstr); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR) + .addReg(MI->getOperand(0).getReg())); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ) + .addReg(MI->getOperand(1).getReg()) + .addImm(0) + .addReg(MI->getOperand(0).getReg())); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addReg(MI->getOperand(0).getReg())); return; } case PPC::PPC32GOT: { - MCSymbol *GOTSymbol = OutContext.GetOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); + MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_")); const MCExpr *SymGotTlsL = MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, OutContext); const MCExpr *SymGotTlsHA = MCSymbolRefExpr::Create(GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, OutContext); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LI) - .addReg(MI->getOperand(0).getReg()) - .addExpr(SymGotTlsL)); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) - .addReg(MI->getOperand(0).getReg()) - .addReg(MI->getOperand(0).getReg()) - .addExpr(SymGotTlsHA)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI) + .addReg(MI->getOperand(0).getReg()) + .addExpr(SymGotTlsL)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(0).getReg()) + .addExpr(SymGotTlsHA)); return; } case PPC::ADDIStlsgdHA: { // Transform: %Xd = ADDIStlsgdHA %X2, <ga:@sym> // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha - assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); + assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); const MachineOperand &MO = MI->getOperand(2); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); const MCExpr *SymGotTlsGD = MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA, OutContext); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) - .addReg(MI->getOperand(0).getReg()) - .addReg(PPC::X2) - .addExpr(SymGotTlsGD)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addExpr(SymGotTlsGD)); return; } case PPC::ADDItlsgdL: @@ -791,32 +825,40 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const MachineOperand &MO = MI->getOperand(2); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); - const MCExpr *SymGotTlsGD = - MCSymbolRefExpr::Create(MOSymbol, Subtarget.isPPC64() ? - MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO : - MCSymbolRefExpr::VK_PPC_GOT_TLSGD, - OutContext); - EmitToStreamer(OutStreamer, - MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI) + const MCExpr *SymGotTlsGD = MCSymbolRefExpr::Create( + MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO + : MCSymbolRefExpr::VK_PPC_GOT_TLSGD, + OutContext); + EmitToStreamer(*OutStreamer, + MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addExpr(SymGotTlsGD)); return; } + case PPC::GETtlsADDR: + // Transform: %X3 = GETtlsADDR %X3, <ga:@sym> + // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd) + case PPC::GETtlsADDR32: { + // Transform: %R3 = GETtlsADDR32 %R3, <ga:@sym> + // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT + EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD); + return; + } case PPC::ADDIStlsldHA: { // Transform: %Xd = ADDIStlsldHA %X2, <ga:@sym> // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha - assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC"); + assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC"); const MachineOperand &MO = MI->getOperand(2); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); const MCExpr *SymGotTlsLD = MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA, OutContext); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS8) - .addReg(MI->getOperand(0).getReg()) - .addReg(PPC::X2) - .addExpr(SymGotTlsLD)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addExpr(SymGotTlsLD)); return; } case PPC::ADDItlsldL: @@ -828,16 +870,24 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const MachineOperand &MO = MI->getOperand(2); const GlobalValue *GValue = MO.getGlobal(); MCSymbol *MOSymbol = getSymbol(GValue); - const MCExpr *SymGotTlsLD = - MCSymbolRefExpr::Create(MOSymbol, Subtarget.isPPC64() ? - MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO : - MCSymbolRefExpr::VK_PPC_GOT_TLSLD, - OutContext); - EmitToStreamer(OutStreamer, - MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI) - .addReg(MI->getOperand(0).getReg()) - .addReg(MI->getOperand(1).getReg()) - .addExpr(SymGotTlsLD)); + const MCExpr *SymGotTlsLD = MCSymbolRefExpr::Create( + MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO + : MCSymbolRefExpr::VK_PPC_GOT_TLSLD, + OutContext); + EmitToStreamer(*OutStreamer, + MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addExpr(SymGotTlsLD)); + return; + } + case PPC::GETtlsldADDR: + // Transform: %X3 = GETtlsldADDR %X3, <ga:@sym> + // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld) + case PPC::GETtlsldADDR32: { + // Transform: %R3 = GETtlsldADDR32 %R3, <ga:@sym> + // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT + EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD); return; } case PPC::ADDISdtprelHA: @@ -852,11 +902,12 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const MCExpr *SymDtprel = MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA, OutContext); - EmitToStreamer(OutStreamer, - MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDIS8 : PPC::ADDIS) - .addReg(MI->getOperand(0).getReg()) - .addReg(Subtarget.isPPC64() ? PPC::X3 : PPC::R3) - .addExpr(SymDtprel)); + EmitToStreamer( + *OutStreamer, + MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDIS8 : PPC::ADDIS) + .addReg(MI->getOperand(0).getReg()) + .addReg(Subtarget->isPPC64() ? PPC::X3 : PPC::R3) + .addExpr(SymDtprel)); return; } case PPC::ADDIdtprelL: @@ -871,41 +922,41 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { const MCExpr *SymDtprel = MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO, OutContext); - EmitToStreamer(OutStreamer, - MCInstBuilder(Subtarget.isPPC64() ? PPC::ADDI8 : PPC::ADDI) - .addReg(MI->getOperand(0).getReg()) - .addReg(MI->getOperand(1).getReg()) - .addExpr(SymDtprel)); + EmitToStreamer(*OutStreamer, + MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addExpr(SymDtprel)); return; } case PPC::MFOCRF: case PPC::MFOCRF8: - if (!Subtarget.hasMFOCRF()) { + if (!Subtarget->hasMFOCRF()) { // Transform: %R3 = MFOCRF %CR7 // Into: %R3 = MFCR ;; cr7 unsigned NewOpcode = MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8; - OutStreamer.AddComment(PPCInstPrinter:: - getRegisterName(MI->getOperand(1).getReg())); - EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode) + OutStreamer->AddComment(PPCInstPrinter:: + getRegisterName(MI->getOperand(1).getReg())); + EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode) .addReg(MI->getOperand(0).getReg())); return; } break; case PPC::MTOCRF: case PPC::MTOCRF8: - if (!Subtarget.hasMFOCRF()) { + if (!Subtarget->hasMFOCRF()) { // Transform: %CR7 = MTOCRF %R3 // Into: MTCRF mask, %R3 ;; cr7 unsigned NewOpcode = MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8; unsigned Mask = 0x80 >> OutContext.getRegisterInfo() ->getEncodingValue(MI->getOperand(0).getReg()); - OutStreamer.AddComment(PPCInstPrinter:: - getRegisterName(MI->getOperand(0).getReg())); - EmitToStreamer(OutStreamer, MCInstBuilder(NewOpcode) - .addImm(Mask) - .addReg(MI->getOperand(1).getReg())); + OutStreamer->AddComment(PPCInstPrinter:: + getRegisterName(MI->getOperand(0).getReg())); + EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode) + .addImm(Mask) + .addReg(MI->getOperand(1).getReg())); return; } break; @@ -919,7 +970,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { // suite shows a handful of test cases that fail this check for // Darwin. Those need to be investigated before this sanity test // can be enabled for those subtargets. - if (!Subtarget.isDarwin()) { + if (!Subtarget->isDarwin()) { unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1; const MachineOperand &MO = MI->getOperand(OpNum); if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4) @@ -931,32 +982,32 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { } LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin); - EmitToStreamer(OutStreamer, TmpInst); + EmitToStreamer(*OutStreamer, TmpInst); } void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) { - if (Subtarget.isELFv2ABI()) { + if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) { PPCTargetStreamer *TS = - static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); + static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer()); if (TS) TS->emitAbiVersion(2); } - if (Subtarget.isPPC64() || TM.getRelocationModel() != Reloc::PIC_) + if (static_cast<const PPCTargetMachine &>(TM).isPPC64() || + TM.getRelocationModel() != Reloc::PIC_) return AsmPrinter::EmitStartOfAsmFile(M); if (M.getPICLevel() == PICLevel::Small) return AsmPrinter::EmitStartOfAsmFile(M); - OutStreamer.SwitchSection(OutContext.getELFSection(".got2", - ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, - SectionKind::getReadOnly())); + OutStreamer->SwitchSection(OutContext.getELFSection( + ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC)); - MCSymbol *TOCSym = OutContext.GetOrCreateSymbol(Twine(".LTOC")); - MCSymbol *CurrentPos = OutContext.CreateTempSymbol(); + MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC")); + MCSymbol *CurrentPos = OutContext.createTempSymbol(); - OutStreamer.EmitLabel(CurrentPos); + OutStreamer->EmitLabel(CurrentPos); // The GOT pointer points to the middle of the GOT, in order to reference the // entire 64kB range. 0x8000 is the midpoint. @@ -965,121 +1016,93 @@ void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) { MCConstantExpr::Create(0x8000, OutContext), OutContext); - OutStreamer.EmitAssignment(TOCSym, tocExpr); + OutStreamer->EmitAssignment(TOCSym, tocExpr); - OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); + OutStreamer->SwitchSection(getObjFileLowering().getTextSection()); } void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { // linux/ppc32 - Normal entry label. - if (!Subtarget.isPPC64() && + if (!Subtarget->isPPC64() && (TM.getRelocationModel() != Reloc::PIC_ || MF->getFunction()->getParent()->getPICLevel() == PICLevel::Small)) return AsmPrinter::EmitFunctionEntryLabel(); - if (!Subtarget.isPPC64()) { + if (!Subtarget->isPPC64()) { const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>(); if (PPCFI->usesPICBase()) { MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(); MCSymbol *PICBase = MF->getPICBaseSymbol(); - OutStreamer.EmitLabel(RelocSymbol); + OutStreamer->EmitLabel(RelocSymbol); const MCExpr *OffsExpr = MCBinaryExpr::CreateSub( - MCSymbolRefExpr::Create(OutContext.GetOrCreateSymbol(Twine(".LTOC")), + MCSymbolRefExpr::Create(OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext), MCSymbolRefExpr::Create(PICBase, OutContext), OutContext); - OutStreamer.EmitValue(OffsExpr, 4); - OutStreamer.EmitLabel(CurrentFnSym); + OutStreamer->EmitValue(OffsExpr, 4); + OutStreamer->EmitLabel(CurrentFnSym); return; } else return AsmPrinter::EmitFunctionEntryLabel(); } // ELFv2 ABI - Normal entry label. - if (Subtarget.isELFv2ABI()) + if (Subtarget->isELFv2ABI()) return AsmPrinter::EmitFunctionEntryLabel(); // Emit an official procedure descriptor. - MCSectionSubPair Current = OutStreamer.getCurrentSection(); - const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".opd", - ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, - SectionKind::getReadOnly()); - OutStreamer.SwitchSection(Section); - OutStreamer.EmitLabel(CurrentFnSym); - OutStreamer.EmitValueToAlignment(8); - MCSymbol *Symbol1 = - OutContext.GetOrCreateSymbol(".L." + Twine(CurrentFnSym->getName())); + MCSectionSubPair Current = OutStreamer->getCurrentSection(); + MCSectionELF *Section = OutStreamer->getContext().getELFSection( + ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); + OutStreamer->SwitchSection(Section); + OutStreamer->EmitLabel(CurrentFnSym); + OutStreamer->EmitValueToAlignment(8); + MCSymbol *Symbol1 = CurrentFnSymForSize; // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function // entry point. - OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), - 8 /*size*/); - MCSymbol *Symbol2 = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); + OutStreamer->EmitValue(MCSymbolRefExpr::Create(Symbol1, OutContext), + 8 /*size*/); + MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC.")); // Generates a R_PPC64_TOC relocation for TOC base insertion. - OutStreamer.EmitValue(MCSymbolRefExpr::Create(Symbol2, - MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext), - 8/*size*/); + OutStreamer->EmitValue( + MCSymbolRefExpr::Create(Symbol2, MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext), + 8/*size*/); // Emit a null environment pointer. - OutStreamer.EmitIntValue(0, 8 /* size */); - OutStreamer.SwitchSection(Current.first, Current.second); - - MCSymbol *RealFnSym = OutContext.GetOrCreateSymbol( - ".L." + Twine(CurrentFnSym->getName())); - OutStreamer.EmitLabel(RealFnSym); - CurrentFnSymForSize = RealFnSym; + OutStreamer->EmitIntValue(0, 8 /* size */); + OutStreamer->SwitchSection(Current.first, Current.second); } bool PPCLinuxAsmPrinter::doFinalization(Module &M) { - const DataLayout *TD = TM.getSubtargetImpl()->getDataLayout(); + const DataLayout *TD = TM.getDataLayout(); bool isPPC64 = TD->getPointerSizeInBits() == 64; PPCTargetStreamer &TS = - static_cast<PPCTargetStreamer &>(*OutStreamer.getTargetStreamer()); + static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer()); if (!TOC.empty()) { - const MCSectionELF *Section; - + MCSectionELF *Section; + if (isPPC64) - Section = OutStreamer.getContext().getELFSection(".toc", - ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, - SectionKind::getReadOnly()); - else - Section = OutStreamer.getContext().getELFSection(".got2", - ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC, - SectionKind::getReadOnly()); - OutStreamer.SwitchSection(Section); + Section = OutStreamer->getContext().getELFSection( + ".toc", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); + else + Section = OutStreamer->getContext().getELFSection( + ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); + OutStreamer->SwitchSection(Section); for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), E = TOC.end(); I != E; ++I) { - OutStreamer.EmitLabel(I->second); + OutStreamer->EmitLabel(I->second); MCSymbol *S = I->first; if (isPPC64) TS.emitTCEntry(*S); else - OutStreamer.EmitSymbolValue(S, 4); - } - } - - MachineModuleInfoELF &MMIELF = - MMI->getObjFileInfo<MachineModuleInfoELF>(); - - MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); - if (!Stubs.empty()) { - OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); - for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { - // L_foo$stub: - OutStreamer.EmitLabel(Stubs[i].first); - // .long _foo - OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(), - OutContext), - isPPC64 ? 8 : 4/*size*/); + OutStreamer->EmitSymbolValue(S, 4); } - - Stubs.clear(); - OutStreamer.AddBlankLine(); } return AsmPrinter::doFinalization(M); @@ -1103,36 +1126,36 @@ void PPCLinuxAsmPrinter::EmitFunctionBodyStart() { // // This ensures we have r2 set up correctly while executing the function // body, no matter which entry point is called. - if (Subtarget.isELFv2ABI() + if (Subtarget->isELFv2ABI() // Only do all that if the function uses r2 in the first place. && !MF->getRegInfo().use_empty(PPC::X2)) { - MCSymbol *GlobalEntryLabel = OutContext.CreateTempSymbol(); - OutStreamer.EmitLabel(GlobalEntryLabel); + MCSymbol *GlobalEntryLabel = OutContext.createTempSymbol(); + OutStreamer->EmitLabel(GlobalEntryLabel); const MCSymbolRefExpr *GlobalEntryLabelExp = MCSymbolRefExpr::Create(GlobalEntryLabel, OutContext); - MCSymbol *TOCSymbol = OutContext.GetOrCreateSymbol(StringRef(".TOC.")); + MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC.")); const MCExpr *TOCDeltaExpr = MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(TOCSymbol, OutContext), GlobalEntryLabelExp, OutContext); const MCExpr *TOCDeltaHi = PPCMCExpr::CreateHa(TOCDeltaExpr, false, OutContext); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) - .addReg(PPC::X2) - .addReg(PPC::X12) - .addExpr(TOCDeltaHi)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS) + .addReg(PPC::X2) + .addReg(PPC::X12) + .addExpr(TOCDeltaHi)); const MCExpr *TOCDeltaLo = PPCMCExpr::CreateLo(TOCDeltaExpr, false, OutContext); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDI) - .addReg(PPC::X2) - .addReg(PPC::X2) - .addExpr(TOCDeltaLo)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI) + .addReg(PPC::X2) + .addReg(PPC::X2) + .addExpr(TOCDeltaLo)); - MCSymbol *LocalEntryLabel = OutContext.CreateTempSymbol(); - OutStreamer.EmitLabel(LocalEntryLabel); + MCSymbol *LocalEntryLabel = OutContext.createTempSymbol(); + OutStreamer->EmitLabel(LocalEntryLabel); const MCSymbolRefExpr *LocalEntryLabelExp = MCSymbolRefExpr::Create(LocalEntryLabel, OutContext); const MCExpr *LocalOffsetExp = @@ -1140,7 +1163,7 @@ void PPCLinuxAsmPrinter::EmitFunctionBodyStart() { GlobalEntryLabelExp, OutContext); PPCTargetStreamer *TS = - static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); + static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer()); if (TS) TS->emitLocalEntry(CurrentFnSym, LocalOffsetExp); @@ -1158,9 +1181,9 @@ void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() { // FIXME: We should fill in the eight-byte mandatory fields as described in // the PPC64 ELF ABI (this is a low-priority item because GDB does not // currently make use of these fields). - if (Subtarget.isPPC64()) { - OutStreamer.EmitIntValue(0, 4/*size*/); - OutStreamer.EmitIntValue(0, 8/*size*/); + if (Subtarget->isPPC64()) { + OutStreamer->EmitIntValue(0, 4/*size*/); + OutStreamer->EmitIntValue(0, 8/*size*/); } } @@ -1189,74 +1212,89 @@ void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { "ppc64le" }; - unsigned Directive = Subtarget.getDarwinDirective(); - if (Subtarget.hasMFOCRF() && Directive < PPC::DIR_970) - Directive = PPC::DIR_970; - if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) - Directive = PPC::DIR_7400; - if (Subtarget.isPPC64() && Directive < PPC::DIR_64) - Directive = PPC::DIR_64; + // Get the numerically largest directive. + // FIXME: How should we merge darwin directives? + unsigned Directive = PPC::DIR_NONE; + for (const Function &F : M) { + const PPCSubtarget &STI = TM.getSubtarget<PPCSubtarget>(F); + unsigned FDir = STI.getDarwinDirective(); + Directive = Directive > FDir ? FDir : STI.getDarwinDirective(); + if (STI.hasMFOCRF() && Directive < PPC::DIR_970) + Directive = PPC::DIR_970; + if (STI.hasAltivec() && Directive < PPC::DIR_7400) + Directive = PPC::DIR_7400; + if (STI.isPPC64() && Directive < PPC::DIR_64) + Directive = PPC::DIR_64; + } + assert(Directive <= PPC::DIR_64 && "Directive out of range."); assert(Directive < array_lengthof(CPUDirectives) && "CPUDirectives[] might not be up-to-date!"); PPCTargetStreamer &TStreamer = - *static_cast<PPCTargetStreamer *>(OutStreamer.getTargetStreamer()); + *static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer()); TStreamer.emitMachine(CPUDirectives[Directive]); // Prime text sections so they are adjacent. This reduces the likelihood a // large data or debug section causes a branch to exceed 16M limit. const TargetLoweringObjectFileMachO &TLOFMacho = static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); - OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); + OutStreamer->SwitchSection(TLOFMacho.getTextCoalSection()); if (TM.getRelocationModel() == Reloc::PIC_) { - OutStreamer.SwitchSection( + OutStreamer->SwitchSection( OutContext.getMachOSection("__TEXT", "__picsymbolstub1", MachO::S_SYMBOL_STUBS | MachO::S_ATTR_PURE_INSTRUCTIONS, 32, SectionKind::getText())); } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { - OutStreamer.SwitchSection( + OutStreamer->SwitchSection( OutContext.getMachOSection("__TEXT","__symbol_stub1", MachO::S_SYMBOL_STUBS | MachO::S_ATTR_PURE_INSTRUCTIONS, 16, SectionKind::getText())); } - OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); + OutStreamer->SwitchSection(getObjFileLowering().getTextSection()); } static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { // Remove $stub suffix, add $lazy_ptr. StringRef NoStub = Sym->getName().substr(0, Sym->getName().size()-5); - return Ctx.GetOrCreateSymbol(NoStub + "$lazy_ptr"); + return Ctx.getOrCreateSymbol(NoStub + "$lazy_ptr"); } static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { // Add $tmp suffix to $stub, yielding $stub$tmp. - return Ctx.GetOrCreateSymbol(Sym->getName() + "$tmp"); + return Ctx.getOrCreateSymbol(Sym->getName() + "$tmp"); } void PPCDarwinAsmPrinter:: EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { - bool isPPC64 = - TM.getSubtargetImpl()->getDataLayout()->getPointerSizeInBits() == 64; - bool isDarwin = Subtarget.isDarwin(); - + bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; + + // Construct a local MCSubtargetInfo and shadow EmitToStreamer here. + // This is because the MachineFunction won't exist (but have not yet been + // freed) and since we're at the global level we can use the default + // constructed subtarget. + std::unique_ptr<MCSubtargetInfo> STI(TM.getTarget().createMCSubtargetInfo( + TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString())); + auto EmitToStreamer = [&STI] (MCStreamer &S, const MCInst &Inst) { + S.EmitInstruction(Inst, *STI); + }; + const TargetLoweringObjectFileMachO &TLOFMacho = static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); // .lazy_symbol_pointer - const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); - + MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); + // Output stubs for dynamically-linked functions if (TM.getRelocationModel() == Reloc::PIC_) { - const MCSection *StubSection = - OutContext.getMachOSection("__TEXT", "__picsymbolstub1", - MachO::S_SYMBOL_STUBS | - MachO::S_ATTR_PURE_INSTRUCTIONS, - 32, SectionKind::getText()); + MCSection *StubSection = OutContext.getMachOSection( + "__TEXT", "__picsymbolstub1", + MachO::S_SYMBOL_STUBS | MachO::S_ATTR_PURE_INSTRUCTIONS, 32, + SectionKind::getText()); for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { - OutStreamer.SwitchSection(StubSection); + OutStreamer->SwitchSection(StubSection); EmitAlignment(4); MCSymbol *Stub = Stubs[i].first; @@ -1264,8 +1302,8 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); - OutStreamer.EmitLabel(Stub); - OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); + OutStreamer->EmitLabel(Stub); + OutStreamer->EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); const MCExpr *Anon = MCSymbolRefExpr::Create(AnonSymbol, OutContext); const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); @@ -1273,110 +1311,108 @@ EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { MCBinaryExpr::CreateSub(LazyPtrExpr, Anon, OutContext); // mflr r0 - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R0)); // bcl 20, 31, AnonSymbol - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCLalways).addExpr(Anon)); - OutStreamer.EmitLabel(AnonSymbol); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCLalways).addExpr(Anon)); + OutStreamer->EmitLabel(AnonSymbol); // mflr r11 - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR).addReg(PPC::R11)); // addis r11, r11, ha16(LazyPtr - AnonSymbol) - const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, isDarwin, OutContext); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::ADDIS) + const MCExpr *SubHa16 = PPCMCExpr::CreateHa(Sub, true, OutContext); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS) .addReg(PPC::R11) .addReg(PPC::R11) .addExpr(SubHa16)); // mtlr r0 - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR).addReg(PPC::R0)); // ldu r12, lo16(LazyPtr - AnonSymbol)(r11) // lwzu r12, lo16(LazyPtr - AnonSymbol)(r11) - const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, isDarwin, OutContext); - EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) + const MCExpr *SubLo16 = PPCMCExpr::CreateLo(Sub, true, OutContext); + EmitToStreamer(*OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) .addReg(PPC::R12) .addExpr(SubLo16).addExpr(SubLo16) .addReg(PPC::R11)); // mtctr r12 - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); // bctr - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTR)); - OutStreamer.SwitchSection(LSPSection); - OutStreamer.EmitLabel(LazyPtr); - OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); + OutStreamer->SwitchSection(LSPSection); + OutStreamer->EmitLabel(LazyPtr); + OutStreamer->EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); MCSymbol *DyldStubBindingHelper = - OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); + OutContext.getOrCreateSymbol(StringRef("dyld_stub_binding_helper")); if (isPPC64) { // .quad dyld_stub_binding_helper - OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); + OutStreamer->EmitSymbolValue(DyldStubBindingHelper, 8); } else { // .long dyld_stub_binding_helper - OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); + OutStreamer->EmitSymbolValue(DyldStubBindingHelper, 4); } } - OutStreamer.AddBlankLine(); + OutStreamer->AddBlankLine(); return; } - - const MCSection *StubSection = - OutContext.getMachOSection("__TEXT","__symbol_stub1", - MachO::S_SYMBOL_STUBS | - MachO::S_ATTR_PURE_INSTRUCTIONS, - 16, SectionKind::getText()); + + MCSection *StubSection = OutContext.getMachOSection( + "__TEXT", "__symbol_stub1", + MachO::S_SYMBOL_STUBS | MachO::S_ATTR_PURE_INSTRUCTIONS, 16, + SectionKind::getText()); for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { MCSymbol *Stub = Stubs[i].first; MCSymbol *RawSym = Stubs[i].second.getPointer(); MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); const MCExpr *LazyPtrExpr = MCSymbolRefExpr::Create(LazyPtr, OutContext); - OutStreamer.SwitchSection(StubSection); + OutStreamer->SwitchSection(StubSection); EmitAlignment(4); - OutStreamer.EmitLabel(Stub); - OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); + OutStreamer->EmitLabel(Stub); + OutStreamer->EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); // lis r11, ha16(LazyPtr) const MCExpr *LazyPtrHa16 = - PPCMCExpr::CreateHa(LazyPtrExpr, isDarwin, OutContext); - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::LIS) + PPCMCExpr::CreateHa(LazyPtrExpr, true, OutContext); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LIS) .addReg(PPC::R11) .addExpr(LazyPtrHa16)); // ldu r12, lo16(LazyPtr)(r11) // lwzu r12, lo16(LazyPtr)(r11) const MCExpr *LazyPtrLo16 = - PPCMCExpr::CreateLo(LazyPtrExpr, isDarwin, OutContext); - EmitToStreamer(OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) + PPCMCExpr::CreateLo(LazyPtrExpr, true, OutContext); + EmitToStreamer(*OutStreamer, MCInstBuilder(isPPC64 ? PPC::LDU : PPC::LWZU) .addReg(PPC::R12) .addExpr(LazyPtrLo16).addExpr(LazyPtrLo16) .addReg(PPC::R11)); // mtctr r12 - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR).addReg(PPC::R12)); // bctr - EmitToStreamer(OutStreamer, MCInstBuilder(PPC::BCTR)); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTR)); - OutStreamer.SwitchSection(LSPSection); - OutStreamer.EmitLabel(LazyPtr); - OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); + OutStreamer->SwitchSection(LSPSection); + OutStreamer->EmitLabel(LazyPtr); + OutStreamer->EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); MCSymbol *DyldStubBindingHelper = - OutContext.GetOrCreateSymbol(StringRef("dyld_stub_binding_helper")); + OutContext.getOrCreateSymbol(StringRef("dyld_stub_binding_helper")); if (isPPC64) { // .quad dyld_stub_binding_helper - OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 8); + OutStreamer->EmitSymbolValue(DyldStubBindingHelper, 8); } else { // .long dyld_stub_binding_helper - OutStreamer.EmitSymbolValue(DyldStubBindingHelper, 4); + OutStreamer->EmitSymbolValue(DyldStubBindingHelper, 4); } } - OutStreamer.AddBlankLine(); + OutStreamer->AddBlankLine(); } bool PPCDarwinAsmPrinter::doFinalization(Module &M) { - bool isPPC64 = - TM.getSubtargetImpl()->getDataLayout()->getPointerSizeInBits() == 64; + bool isPPC64 = TM.getDataLayout()->getPointerSizeInBits() == 64; // Darwin/PPC always uses mach-o. const TargetLoweringObjectFileMachO &TLOFMacho = @@ -1409,19 +1445,19 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { // Output macho stubs for external and common global variables. if (!Stubs.empty()) { // Switch with ".non_lazy_symbol_pointer" directive. - OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); + OutStreamer->SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); EmitAlignment(isPPC64 ? 3 : 2); for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { // L_foo$stub: - OutStreamer.EmitLabel(Stubs[i].first); + OutStreamer->EmitLabel(Stubs[i].first); // .indirect_symbol _foo MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; - OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); + OutStreamer->EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); if (MCSym.getInt()) // External to current translation unit. - OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/); + OutStreamer->EmitIntValue(0, isPPC64 ? 8 : 4/*size*/); else // Internal to current translation unit. // @@ -1429,32 +1465,32 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { // need to be indirect and pc-rel. We accomplish this by using NLPs. // However, sometimes the types are local to the file. So we need to // fill in the value for the NLP in those cases. - OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), - OutContext), + OutStreamer->EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), + OutContext), isPPC64 ? 8 : 4/*size*/); } Stubs.clear(); - OutStreamer.AddBlankLine(); + OutStreamer->AddBlankLine(); } Stubs = MMIMacho.GetHiddenGVStubList(); if (!Stubs.empty()) { - OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); + OutStreamer->SwitchSection(getObjFileLowering().getDataSection()); EmitAlignment(isPPC64 ? 3 : 2); for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { // L_foo$stub: - OutStreamer.EmitLabel(Stubs[i].first); + OutStreamer->EmitLabel(Stubs[i].first); // .long _foo - OutStreamer.EmitValue(MCSymbolRefExpr:: - Create(Stubs[i].second.getPointer(), - OutContext), - isPPC64 ? 8 : 4/*size*/); + OutStreamer->EmitValue(MCSymbolRefExpr:: + Create(Stubs[i].second.getPointer(), + OutContext), + isPPC64 ? 8 : 4/*size*/); } Stubs.clear(); - OutStreamer.AddBlankLine(); + OutStreamer->AddBlankLine(); } // Funny Darwin hack: This flag tells the linker that no global symbols @@ -1462,7 +1498,7 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { // implementation of multiple entry points). If this doesn't occur, the // linker can safely perform dead code stripping. Since LLVM never generates // code that does this, it is always safe to set. - OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); + OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); return AsmPrinter::doFinalization(M); } @@ -1471,13 +1507,12 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { /// for a MachineFunction to the given output stream, in a format that the /// Darwin assembler can deal with. /// -static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm, - MCStreamer &Streamer) { - const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); - - if (Subtarget->isDarwin()) - return new PPCDarwinAsmPrinter(tm, Streamer); - return new PPCLinuxAsmPrinter(tm, Streamer); +static AsmPrinter * +createPPCAsmPrinterPass(TargetMachine &tm, + std::unique_ptr<MCStreamer> &&Streamer) { + if (Triple(tm.getTargetTriple()).isMacOSX()) + return new PPCDarwinAsmPrinter(tm, std::move(Streamer)); + return new PPCLinuxAsmPrinter(tm, std::move(Streamer)); } // Force static initialization. |