diff options
Diffstat (limited to 'lib/Target/PowerPC/AsmPrinter')
-rw-r--r-- | lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp | 95 |
1 files changed, 71 insertions, 24 deletions
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp index 3ed7265..8b37167 100644 --- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp @@ -43,14 +43,14 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" -#include <set> +#include "llvm/ADT/StringSet.h" using namespace llvm; STATISTIC(EmittedInsts, "Number of machine instrs printed"); namespace { struct VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter { - std::set<std::string> FnStubs, GVStubs; + StringSet<> FnStubs, GVStubs, HiddenGVStubs; const PPCSubtarget &Subtarget; PPCAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T) @@ -387,10 +387,18 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) { // External or weakly linked global variables need non-lazily-resolved stubs if (TM.getRelocationModel() != Reloc::Static) { - if (((GV->isDeclaration() || GV->hasWeakLinkage() || - GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) { - GVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); + if (GV->isDeclaration() || GV->mayBeOverridden()) { + if (GV->hasHiddenVisibility()) { + if (!GV->isDeclaration() && !GV->hasCommonLinkage()) + O << Name; + else { + HiddenGVStubs.insert(Name); + printSuffixedName(Name, "$non_lazy_ptr"); + } + } else { + GVStubs.insert(Name); + printSuffixedName(Name, "$non_lazy_ptr"); + } if (GV->hasExternalWeakLinkage()) ExtWeakSymbols.insert(GV); return; @@ -416,7 +424,10 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) { void PPCAsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) { std::string Name = getGlobalLinkName(GV); if (TM.getRelocationModel() != Reloc::Static) { - GVStubs.insert(Name); + if (GV->hasHiddenVisibility()) + HiddenGVStubs.insert(Name); + else + GVStubs.insert(Name); printSuffixedName(Name, "$non_lazy_ptr"); return; } @@ -979,51 +990,70 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { // Output stubs for dynamically-linked functions if (TM.getRelocationModel() == Reloc::PIC_) { - for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); + for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs," "pure_instructions,32"); EmitAlignment(4); - std::string p = *i; - std::string L0p = (p[0]=='\"') ? "\"L0$" + p.substr(1) : "L0$" + p ; + const char *p = i->getKeyData(); + bool hasQuote = p[0]=='\"'; printSuffixedName(p, "$stub"); O << ":\n"; - O << "\t.indirect_symbol " << *i << '\n'; + O << "\t.indirect_symbol " << p << '\n'; O << "\tmflr r0\n"; - O << "\tbcl 20,31," << L0p << '\n'; - O << L0p << ":\n"; + O << "\tbcl 20,31,"; + if (hasQuote) + O << "\"L0$" << &p[1]; + else + O << "L0$" << p; + O << '\n'; + if (hasQuote) + O << "\"L0$" << &p[1]; + else + O << "L0$" << p; + O << ":\n"; O << "\tmflr r11\n"; O << "\taddis r11,r11,ha16("; printSuffixedName(p, "$lazy_ptr"); - O << "-" << L0p << ")\n"; + O << "-"; + if (hasQuote) + O << "\"L0$" << &p[1]; + else + O << "L0$" << p; + O << ")\n"; O << "\tmtlr r0\n"; if (isPPC64) O << "\tldu r12,lo16("; else O << "\tlwzu r12,lo16("; printSuffixedName(p, "$lazy_ptr"); - O << "-" << L0p << ")(r11)\n"; + O << "-"; + if (hasQuote) + O << "\"L0$" << &p[1]; + else + O << "L0$" << p; + O << ")(r11)\n"; O << "\tmtctr r12\n"; O << "\tbctr\n"; SwitchToDataSection(".lazy_symbol_pointer"); printSuffixedName(p, "$lazy_ptr"); O << ":\n"; - O << "\t.indirect_symbol " << *i << '\n'; + O << "\t.indirect_symbol " << p << '\n'; if (isPPC64) O << "\t.quad dyld_stub_binding_helper\n"; else O << "\t.long dyld_stub_binding_helper\n"; } } else { - for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); + for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs," "pure_instructions,16"); EmitAlignment(4); - std::string p = *i; + const char *p = i->getKeyData(); printSuffixedName(p, "$stub"); O << ":\n"; - O << "\t.indirect_symbol " << *i << '\n'; + O << "\t.indirect_symbol " << p << '\n'; O << "\tlis r11,ha16("; printSuffixedName(p, "$lazy_ptr"); O << ")\n"; @@ -1038,7 +1068,7 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { SwitchToDataSection(".lazy_symbol_pointer"); printSuffixedName(p, "$lazy_ptr"); O << ":\n"; - O << "\t.indirect_symbol " << *i << '\n'; + O << "\t.indirect_symbol " << p << '\n'; if (isPPC64) O << "\t.quad dyld_stub_binding_helper\n"; else @@ -1061,12 +1091,12 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { // Output stubs for external and common global variables. if (!GVStubs.empty()) { SwitchToDataSection(".non_lazy_symbol_pointer"); - for (std::set<std::string>::iterator I = GVStubs.begin(), - E = GVStubs.end(); I != E; ++I) { - std::string p = *I; + for (StringSet<>::iterator i = GVStubs.begin(), e = GVStubs.end(); + i != e; ++i) { + std::string p = i->getKeyData(); printSuffixedName(p, "$non_lazy_ptr"); O << ":\n"; - O << "\t.indirect_symbol " << *I << '\n'; + O << "\t.indirect_symbol " << p << '\n'; if (isPPC64) O << "\t.quad\t0\n"; else @@ -1074,6 +1104,23 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { } } + if (!HiddenGVStubs.empty()) { + SwitchToSection(TAI->getDataSection()); + for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end(); + i != e; ++i) { + std::string p = i->getKeyData(); + EmitAlignment(isPPC64 ? 3 : 2); + printSuffixedName(p, "$non_lazy_ptr"); + O << ":\n"; + if (isPPC64) + O << "\t.quad\t"; + else + O << "\t.long\t"; + O << p << '\n'; + } + } + + // Emit initial debug information. DW.EndModule(); |