Update the darwin handling of linkonce & weak functions and GV stubs. This

should work in all permutations.

llvm-svn: 24728
This commit is contained in:
Chris Lattner 2005-12-16 00:22:14 +00:00
parent 9f62a2a51d
commit 575751151c
1 changed files with 63 additions and 57 deletions

View File

@ -43,7 +43,7 @@ namespace {
class PPCAsmPrinter : public AsmPrinter { class PPCAsmPrinter : public AsmPrinter {
public: public:
std::set<std::string> FnStubs, GVStubs, LinkOnceStubs; std::set<std::string> FnStubs, GVStubs;
PPCAsmPrinter(std::ostream &O, TargetMachine &TM) PPCAsmPrinter(std::ostream &O, TargetMachine &TM)
: AsmPrinter(O, TM) {} : AsmPrinter(O, TM) {}
@ -123,19 +123,22 @@ namespace {
void printCallOperand(const MachineInstr *MI, unsigned OpNo) { void printCallOperand(const MachineInstr *MI, unsigned OpNo) {
const MachineOperand &MO = MI->getOperand(OpNo); const MachineOperand &MO = MI->getOperand(OpNo);
if (!PPCGenerateStaticCode) { if (!PPCGenerateStaticCode) {
if (MO.getType() == MachineOperand::MO_GlobalAddress) {
GlobalValue *GV = MO.getGlobal();
if (((GV->isExternal() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage()))) {
// Dynamically-resolved functions need a stub for the function.
std::string Name = Mang->getValueName(GV);
FnStubs.insert(Name);
O << "L" << Name << "$stub";
return;
}
}
if (MO.getType() == MachineOperand::MO_ExternalSymbol) { if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
std::string Name(GlobalPrefix); Name += MO.getSymbolName(); std::string Name(GlobalPrefix); Name += MO.getSymbolName();
FnStubs.insert(Name); FnStubs.insert(Name);
O << "L" << Name << "$stub"; O << "L" << Name << "$stub";
return; return;
} else if (MO.getType() == MachineOperand::MO_GlobalAddress &&
isa<Function>(MO.getGlobal()) &&
cast<Function>(MO.getGlobal())->isExternal()) {
// Dynamically-resolved functions need a stub for the function.
std::string Name = Mang->getValueName(MO.getGlobal());
FnStubs.insert(Name);
O << "L" << Name << "$stub";
return;
} }
} }
@ -145,9 +148,8 @@ namespace {
O << (int)MI->getOperand(OpNo).getImmedValue()*4; O << (int)MI->getOperand(OpNo).getImmedValue()*4;
} }
void printPICLabel(const MachineInstr *MI, unsigned OpNo) { void printPICLabel(const MachineInstr *MI, unsigned OpNo) {
// FIXME: should probably be converted to cout.width and cout.fill O << "\"L" << getFunctionNumber() << "$pb\"\n";
O << "\"L0000" << getFunctionNumber() << "$pb\"\n"; O << "\"L" << getFunctionNumber() << "$pb\":";
O << "\"L0000" << getFunctionNumber() << "$pb\":";
} }
void printSymbolHi(const MachineInstr *MI, unsigned OpNo) { void printSymbolHi(const MachineInstr *MI, unsigned OpNo) {
if (MI->getOperand(OpNo).isImmediate()) { if (MI->getOperand(OpNo).isImmediate()) {
@ -156,7 +158,7 @@ namespace {
O << "ha16("; O << "ha16(";
printOp(MI->getOperand(OpNo)); printOp(MI->getOperand(OpNo));
if (PICEnabled) if (PICEnabled)
O << "-\"L0000" << getFunctionNumber() << "$pb\")"; O << "-\"L" << getFunctionNumber() << "$pb\")";
else else
O << ')'; O << ')';
} }
@ -168,7 +170,7 @@ namespace {
O << "lo16("; O << "lo16(";
printOp(MI->getOperand(OpNo)); printOp(MI->getOperand(OpNo));
if (PICEnabled) if (PICEnabled)
O << "-\"L0000" << getFunctionNumber() << "$pb\")"; O << "-\"L" << getFunctionNumber() << "$pb\")";
else else
O << ')'; O << ')';
} }
@ -295,25 +297,29 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() O << PrivateGlobalPrefix << "CPI" << getFunctionNumber()
<< '_' << MO.getConstantPoolIndex(); << '_' << MO.getConstantPoolIndex();
return; return;
case MachineOperand::MO_ExternalSymbol: case MachineOperand::MO_ExternalSymbol:
// Computing the address of an external symbol, not calling it.
if (!PPCGenerateStaticCode) {
std::string Name(GlobalPrefix); Name += MO.getSymbolName();
GVStubs.insert(Name);
O << "L" << Name << "$non_lazy_ptr";
return;
}
O << GlobalPrefix << MO.getSymbolName(); O << GlobalPrefix << MO.getSymbolName();
return; return;
case MachineOperand::MO_GlobalAddress: { case MachineOperand::MO_GlobalAddress: {
// Computing the address of a global symbol, not calling it.
GlobalValue *GV = MO.getGlobal(); GlobalValue *GV = MO.getGlobal();
std::string Name = Mang->getValueName(GV); std::string Name = Mang->getValueName(GV);
// External or weakly linked global variables need non-lazily-resolved stubs // External or weakly linked global variables need non-lazily-resolved stubs
if (!PPCGenerateStaticCode && if (!PPCGenerateStaticCode) {
((GV->isExternal() || GV->hasWeakLinkage() || if (((GV->isExternal() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage()))) { GV->hasLinkOnceLinkage()))) {
if (GV->hasLinkOnceLinkage())
LinkOnceStubs.insert(Name);
else
GVStubs.insert(Name); GVStubs.insert(Name);
O << "L" << Name << "$non_lazy_ptr"; O << "L" << Name << "$non_lazy_ptr";
return; return;
}
} }
O << Name; O << Name;
@ -375,10 +381,25 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
// Print out labels for the function. // Print out labels for the function.
const Function *F = MF.getFunction(); const Function *F = MF.getFunction();
SwitchSection(".text", F); switch (F->getLinkage()) {
EmitAlignment(4, F); default: assert(0 && "Unknown linkage type!");
if (!F->hasInternalLinkage()) case Function::InternalLinkage: // Symbols default to internal.
SwitchSection(".text", F);
EmitAlignment(4, F);
break;
case Function::ExternalLinkage:
SwitchSection(".text", F);
EmitAlignment(4, F);
O << "\t.globl\t" << CurrentFnName << "\n"; O << "\t.globl\t" << CurrentFnName << "\n";
break;
case Function::WeakLinkage:
case Function::LinkOnceLinkage:
SwitchSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions",
F);
O << "\t.globl\t" << CurrentFnName << "\n";
O << "\t.weak_definition\t" << CurrentFnName << "\n";
break;
}
O << CurrentFnName << ":\n"; O << CurrentFnName << ":\n";
// Print out code for the function. // Print out code for the function.
@ -446,16 +467,10 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
} else { } else {
switch (I->getLinkage()) { switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage: case GlobalValue::LinkOnceLinkage:
SwitchSection("", 0);
O << ".section __TEXT,__textcoal_nt,coalesced,no_toc\n"
<< ".weak_definition " << name << '\n'
<< ".private_extern " << name << '\n'
<< ".section __DATA,__datacoal_nt,coalesced,no_toc\n";
LinkOnceStubs.insert(name);
break;
case GlobalValue::WeakLinkage: case GlobalValue::WeakLinkage:
O << ".weak_definition " << name << '\n' O << ".weak_definition " << name << '\n'
<< ".private_extern " << name << '\n'; << ".private_extern " << name << '\n';
SwitchSection(".section __DATA,__datacoal_nt,coalesced", I);
break; break;
case GlobalValue::AppendingLinkage: case GlobalValue::AppendingLinkage:
// FIXME: appending linkage variables should go into a section of // FIXME: appending linkage variables should go into a section of
@ -482,8 +497,8 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
if (PICEnabled) { if (PICEnabled) {
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
i != e; ++i) { i != e; ++i) {
O << ".data\n"; SwitchSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
O<<".section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n"; "pure_instructions,32", 0);
EmitAlignment(2); EmitAlignment(2);
O << "L" << *i << "$stub:\n"; O << "L" << *i << "$stub:\n";
O << "\t.indirect_symbol " << *i << "\n"; O << "\t.indirect_symbol " << *i << "\n";
@ -496,8 +511,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n"; O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n";
O << "\tmtctr r12\n"; O << "\tmtctr r12\n";
O << "\tbctr\n"; O << "\tbctr\n";
O << ".data\n"; SwitchSection(".lazy_symbol_pointer", 0);
O << ".lazy_symbol_pointer\n";
O << "L" << *i << "$lazy_ptr:\n"; O << "L" << *i << "$lazy_ptr:\n";
O << "\t.indirect_symbol " << *i << "\n"; O << "\t.indirect_symbol " << *i << "\n";
O << "\t.long dyld_stub_binding_helper\n"; O << "\t.long dyld_stub_binding_helper\n";
@ -505,7 +519,8 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
} else { } else {
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
i != e; ++i) { i != e; ++i) {
O<<"\t.section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16\n"; SwitchSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
"pure_instructions,16", 0);
EmitAlignment(4); EmitAlignment(4);
O << "L" << *i << "$stub:\n"; O << "L" << *i << "$stub:\n";
O << "\t.indirect_symbol " << *i << "\n"; O << "\t.indirect_symbol " << *i << "\n";
@ -513,7 +528,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n"; O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n";
O << "\tmtctr r12\n"; O << "\tmtctr r12\n";
O << "\tbctr\n"; O << "\tbctr\n";
O << "\t.lazy_symbol_pointer\n"; SwitchSection(".lazy_symbol_pointer", 0);
O << "L" << *i << "$lazy_ptr:\n"; O << "L" << *i << "$lazy_ptr:\n";
O << "\t.indirect_symbol " << *i << "\n"; O << "\t.indirect_symbol " << *i << "\n";
O << "\t.long dyld_stub_binding_helper\n"; O << "\t.long dyld_stub_binding_helper\n";
@ -522,23 +537,14 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
O << "\n"; O << "\n";
// Output stubs for external global variables // Output stubs for external and common global variables.
if (GVStubs.begin() != GVStubs.end()) if (GVStubs.begin() != GVStubs.end()) {
O << ".data\n.non_lazy_symbol_pointer\n"; SwitchSection(".non_lazy_symbol_pointer", 0);
for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end(); for (std::set<std::string>::iterator I = GVStubs.begin(),
i != e; ++i) { E = GVStubs.end(); I != E; ++I) {
O << "L" << *i << "$non_lazy_ptr:\n"; O << "L" << *I << "$non_lazy_ptr:\n";
O << "\t.indirect_symbol " << *i << "\n"; O << "\t.indirect_symbol " << *I << "\n";
O << "\t.long\t0\n"; O << "\t.long\t0\n";
}
// Output stubs for link-once variables
if (LinkOnceStubs.begin() != LinkOnceStubs.end()) {
O << ".data\n.align 2\n";
for (std::set<std::string>::iterator i = LinkOnceStubs.begin(),
e = LinkOnceStubs.end(); i != e; ++i) {
O << "L" << *i << "$non_lazy_ptr:\n"
<< "\t.long\t" << *i << '\n';
} }
} }