Darwin ABI issues: weak, linkonce, etc. dynamic-no-pic support is complete.
Also fixed a function stub bug. Added weak and linkonce support for
x86 Linux.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26038 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp
index 353cd54..301bcfe 100755
--- a/lib/Target/X86/X86ATTAsmPrinter.cpp
+++ b/lib/Target/X86/X86ATTAsmPrinter.cpp
@@ -33,12 +33,32 @@
EmitConstantPool(MF.getConstantPool());
// Print out labels for the function.
- SwitchSection("\t.text\n", MF.getFunction());
- EmitAlignment(4); // FIXME: This should be parameterized somewhere.
- if (!MF.getFunction()->hasInternalLinkage())
+ const Function *F = MF.getFunction();
+ switch (F->getLinkage()) {
+ default: assert(0 && "Unknown linkage type!");
+ case Function::InternalLinkage: // Symbols default to internal.
+ SwitchSection(".text", F);
+ EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
+ break;
+ case Function::ExternalLinkage:
+ SwitchSection(".text", F);
+ EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
O << "\t.globl\t" << CurrentFnName << "\n";
- if (HasDotTypeDotSizeDirective)
- O << "\t.type\t" << CurrentFnName << ", @function\n";
+ break;
+ case Function::WeakLinkage:
+ case Function::LinkOnceLinkage:
+ if (forDarwin) {
+ SwitchSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions",
+ F);
+ O << "\t.weak_definition\t" << CurrentFnName << "\n";
+ } else {
+ EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
+ O << "\t.section\t.llvm.linkonce.t." << CurrentFnName
+ << ",\"ax\",@progbits\n";
+ O << "\t.weak " << CurrentFnName << "\n";
+ }
+ break;
+ }
O << CurrentFnName << ":\n";
// Print out code for the function.
@@ -95,27 +115,24 @@
return;
case MachineOperand::MO_GlobalAddress: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
- // Darwin block shameless ripped from PowerPCAsmPrinter.cpp
+ bool isMemOp = Modifier && !strcmp(Modifier, "mem");
+ // Darwin block shameless ripped from PPCAsmPrinter.cpp
if (forDarwin) {
- if (!isCallOp) O << '$';
+ if (!isMemOp && !isCallOp) O << '$';
GlobalValue *GV = MO.getGlobal();
std::string Name = Mang->getValueName(GV);
-
- // Dynamically-resolved functions need a stub for the function. Be
- // wary however not to output $stub for external functions whose addresses
- // are taken. Those should be emitted as $non_lazy_ptr below.
- Function *F = dyn_cast<Function>(GV);
- if (F && isCallOp && F->isExternal()) {
- FnStubs.insert(Name);
- O << "L" << Name << "$stub";
- } else if (GV->hasLinkOnceLinkage()) {
- // Link-once, External, or Weakly-linked global variables need
- // non-lazily-resolved stubs
- LinkOnceStubs.insert(Name);
- O << "L" << Name << "$non_lazy_ptr";
- } else if (GV->isExternal() || GV->hasWeakLinkage()) {
- GVStubs.insert(Name);
- O << "L" << Name << "$non_lazy_ptr";
+ // Link-once, External, or Weakly-linked global variables need
+ // non-lazily-resolved stubs
+ if (GV->isExternal() || GV->hasWeakLinkage() ||
+ GV->hasLinkOnceLinkage()) {
+ // Dynamically-resolved functions need a stub for the function.
+ if (isCallOp && isa<Function>(GV) && cast<Function>(GV)->isExternal()) {
+ FnStubs.insert(Name);
+ O << "L" << Name << "$stub";
+ } else {
+ GVStubs.insert(Name);
+ O << "L" << Name << "$non_lazy_ptr";
+ }
} else {
O << Mang->getValueName(GV);
}
@@ -126,7 +143,7 @@
O << Offset;
return;
}
- if (!isCallOp) O << '$';
+ if (!isMemOp && !isCallOp) O << '$';
O << Mang->getValueName(MO.getGlobal());
int Offset = MO.getOffset();
if (Offset > 0)
@@ -137,13 +154,14 @@
}
case MachineOperand::MO_ExternalSymbol: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
+ bool isMemOp = Modifier && !strcmp(Modifier, "mem");
if (isCallOp && forDarwin) {
std::string Name(GlobalPrefix); Name += MO.getSymbolName();
FnStubs.insert(Name);
O << "L" << Name << "$stub";
return;
}
- if (!isCallOp) O << '$';
+ if (!isMemOp && !isCallOp) O << '$';
O << GlobalPrefix << MO.getSymbolName();
return;
}
@@ -197,7 +215,7 @@
}
if (DispSpec.isGlobalAddress()) {
- printOperand(MI, Op+3, "call");
+ printOperand(MI, Op+3, "mem");
} else {
int DispVal = DispSpec.getImmedValue();
if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg()))