aboutsummaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp109
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp61
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp8
-rw-r--r--lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp127
4 files changed, 162 insertions, 143 deletions
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index ef2d460fab..30f9fec867 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -1196,71 +1196,76 @@ void ARMAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
if (Subtarget->isTargetELF())
O << "\t.type " << *GVarSym << ",%object\n";
+ SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
const MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
+ getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
OutStreamer.SwitchSection(TheSection);
+ // Handle the zerofill directive on darwin, which is a special form of BSS
+ // emission.
+ if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
+ TargetLoweringObjectFileMachO &TLOFMacho =
+ static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
+ if (TheSection == TLOFMacho.getDataCommonSection()) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+ // .zerofill __DATA, __common, _foo, 400, 5
+ OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align);
+ return;
+ }
+ }
+
// FIXME: get this stuff from section kind flags.
if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal() &&
// Don't put things that should go in the cstring section into "comm".
- !TheSection->getKind().isMergeableCString()) {
- if (GVar->hasExternalLinkage()) {
- if (const char *Directive = MAI->getZeroFillDirective()) {
- O << "\t.globl\t" << *GVarSym << "\n";
- O << Directive << "__DATA, __common, " << *GVarSym
- << ", " << Size << ", " << Align << "\n";
- return;
- }
- }
+ !TheSection->getKind().isMergeableCString() &&
+ (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
- if (GVar->hasLocalLinkage() || GVar->isWeakForLinker()) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (isDarwin) {
- if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size
- << ',' << Align;
- } else if (GVar->hasCommonLinkage()) {
- O << MAI->getCOMMDirective() << *GVarSym << ',' << Size
- << ',' << Align;
- } else {
- OutStreamer.SwitchSection(TheSection);
- O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective();
- O << *GVarSym << '\n';
- EmitAlignment(Align, GVar);
- O << *GVarSym << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- EmitGlobalConstant(C);
- return;
- }
- } else if (MAI->getLCOMMDirective() != NULL) {
- if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << *GVarSym << "," << Size;
- } else {
- O << MAI->getCOMMDirective() << *GVarSym << "," << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+ if (isDarwin) {
+ if (GVar->hasLocalLinkage()) {
+ O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size
+ << ',' << Align;
+ } else if (GVar->hasCommonLinkage()) {
+ O << MAI->getCOMMDirective() << *GVarSym << ',' << Size
+ << ',' << Align;
+ } else {
+ OutStreamer.SwitchSection(TheSection);
+ O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective();
+ O << *GVarSym << '\n';
+ EmitAlignment(Align, GVar);
+ O << *GVarSym << ":";
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString() << ' ';
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
}
+ O << '\n';
+ EmitGlobalConstant(C);
+ return;
+ }
+ } else if (MAI->getLCOMMDirective() != NULL) {
+ if (GVar->hasLocalLinkage()) {
+ O << MAI->getLCOMMDirective() << *GVarSym << "," << Size;
} else {
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << *GVarSym << '\n';
O << MAI->getCOMMDirective() << *GVarSym << "," << Size;
if (MAI->getCOMMDirectiveTakesAlignment())
- O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
- }
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+ O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
}
- O << "\n";
- return;
+ } else {
+ if (GVar->hasLocalLinkage())
+ O << "\t.local\t" << *GVarSym << '\n';
+ O << MAI->getCOMMDirective() << *GVarSym << "," << Size;
+ if (MAI->getCOMMDirectiveTakesAlignment())
+ O << "," << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+ }
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString() << ' ';
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
}
+ O << "\n";
+ return;
}
switch (GVar->getLinkage()) {
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index db37a1ab66..fad1c27fac 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -721,25 +721,25 @@ void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
!GVar->hasSection() &&
(GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (GVar->hasExternalLinkage()) {
- O << "\t.global " << *GVarSym << '\n';
- O << "\t.type " << *GVarSym << ", @object\n";
- O << *GVarSym << ":\n";
- O << "\t.zero " << Size << '\n';
- } else if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size;
- } else {
- O << ".comm " << *GVarSym << ',' << Size;
- }
- if (VerboseAsm) {
- O << "\t\t" << MAI->getCommentString() << " '";
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- O << "'";
- }
- O << '\n';
- return;
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ if (GVar->hasExternalLinkage()) {
+ O << "\t.global " << *GVarSym << '\n';
+ O << "\t.type " << *GVarSym << ", @object\n";
+ O << *GVarSym << ":\n";
+ O << "\t.zero " << Size << '\n';
+ } else if (GVar->hasLocalLinkage()) {
+ O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size;
+ } else {
+ O << ".comm " << *GVarSym << ',' << Size;
+ }
+ if (VerboseAsm) {
+ O << "\t\t" << MAI->getCommentString() << " '";
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+ O << "'";
+ }
+ O << '\n';
+ return;
}
switch (GVar->getLinkage()) {
@@ -944,10 +944,25 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
unsigned Size = TD->getTypeAllocSize(Type);
unsigned Align = TD->getPreferredAlignmentLog(GVar);
+ SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
const MCSection *TheSection =
- getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
+ getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
OutStreamer.SwitchSection(TheSection);
+ // Handle the zerofill directive on darwin, which is a special form of BSS
+ // emission.
+ if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
+ TargetLoweringObjectFileMachO &TLOFMacho =
+ static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
+ if (TheSection == TLOFMacho.getDataCommonSection()) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+ // .zerofill __DATA, __common, _foo, 400, 5
+ OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align);
+ return;
+ }
+ }
+
/// FIXME: Drive this off the section!
if (C->isNullValue() && /* FIXME: Verify correct */
!GVar->hasSection() &&
@@ -957,11 +972,7 @@ void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
!TheSection->getKind().isMergeableCString()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
- if (GVar->hasExternalLinkage()) {
- O << "\t.globl " << *GVarSym << '\n';
- O << "\t.zerofill __DATA, __common, " << *GVarSym << ", "
- << Size << ", " << Align;
- } else if (GVar->hasLocalLinkage()) {
+ if (GVar->hasLocalLinkage()) {
O << MAI->getLCOMMDirective() << *GVarSym << ',' << Size << ',' << Align;
} else if (!GVar->hasCommonLinkage()) {
O << "\t.globl " << *GVarSym << '\n' << MAI->getWeakDefDirective();
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index 93cb420d62..26a181aea0 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -750,6 +750,9 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,
ConstDataCoalSection
= getMachOSection("__DATA","__const_coal", MCSectionMachO::S_COALESCED,
SectionKind::getText());
+ DataCommonSection
+ = getMachOSection("__DATA","__common", MCSectionMachO::S_ZEROFILL,
+ SectionKind::getBSS());
ConstDataSection // .const_data
= getMachOSection("__DATA", "__const", 0,
SectionKind::getReadOnlyWithRel());
@@ -915,6 +918,11 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
if (Kind.isReadOnlyWithRel())
return ConstDataSection;
+ // Put zero initialized globals with strong external linkage in the
+ // DATA, __common section with the .zerofill directive.
+ if (Kind.isBSS() && GV->hasExternalLinkage())
+ return DataCommonSection;
+
// Otherwise, just drop the variable in the normal data section.
return DataSection;
}
diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
index a24a4f1746..3c290e8efd 100644
--- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
+++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp
@@ -664,88 +664,83 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
const TargetData *TD = TM.getTargetData();
- MCSymbol *GVSym = GetGlobalValueSymbol(GVar);
+ MCSymbol *GVarSym = GetGlobalValueSymbol(GVar);
Constant *C = GVar->getInitializer();
const Type *Type = C->getType();
unsigned Size = TD->getTypeAllocSize(Type);
unsigned Align = TD->getPreferredAlignmentLog(GVar);
- printVisibility(GVSym, GVar->getVisibility());
+ printVisibility(GVarSym, GVar->getVisibility());
if (Subtarget->isTargetELF())
- O << "\t.type\t" << *GVSym << ",@object\n";
+ O << "\t.type\t" << *GVarSym << ",@object\n";
SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
const MCSection *TheSection =
getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
OutStreamer.SwitchSection(TheSection);
+ // Handle the zerofill directive on darwin, which is a special form of BSS
+ // emission.
+ if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective()) {
+ TargetLoweringObjectFileMachO &TLOFMacho =
+ static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
+ if (TheSection == TLOFMacho.getDataCommonSection()) {
+ // .globl _foo
+ OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+ // .zerofill __DATA, __common, _foo, 400, 5
+ OutStreamer.EmitZerofill(TheSection, GVarSym, Size, 1 << Align);
+ return;
+ }
+ }
+
// FIXME: get this stuff from section kind flags.
if (C->isNullValue() && !GVar->hasSection() &&
// Don't put things that should go in the cstring section into "comm".
- !TheSection->getKind().isMergeableCString()) {
- if (GVar->hasExternalLinkage()) {
- if (MAI->hasZeroFillDirective()) {
- // .globl _foo
- OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
- // .zerofill __DATA, __common, _foo, 400, 5
- TargetLoweringObjectFileMachO &TLOFMacho =
- static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
- // FIXME: This stuff should already be handled by SectionForGlobal!
- const MCSection *TheSection =
- TLOFMacho.getMachOSection("__DATA", "__common",
- MCSectionMachO::S_ZEROFILL,
- SectionKind::getBSS());
-
- OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << Align);
- return;
- }
- }
-
- if (!GVar->isThreadLocal() &&
- (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
- if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
-
- if (MAI->getLCOMMDirective() != NULL) {
- if (GVar->hasLocalLinkage()) {
- O << MAI->getLCOMMDirective() << *GVSym << ',' << Size;
- if (Subtarget->isTargetDarwin())
- O << ',' << Align;
- } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) {
- OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
- O << MAI->getWeakDefDirective() << *GVSym << '\n';
- EmitAlignment(Align, GVar);
- O << *GVSym << ":";
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
- }
- O << '\n';
- EmitGlobalConstant(C);
- return;
- } else {
- O << MAI->getCOMMDirective() << *GVSym << ',' << Size;
- if (MAI->getCOMMDirectiveTakesAlignment())
- O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+ !TheSection->getKind().isMergeableCString() &&
+ !GVar->isThreadLocal() &&
+ (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
+ if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
+
+ if (const char *LComm = MAI->getLCOMMDirective()) {
+ if (GVar->hasLocalLinkage()) {
+ O << LComm << *GVarSym << ',' << Size;
+ if (Subtarget->isTargetDarwin())
+ O << ',' << Align;
+ } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) {
+ OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+ O << MAI->getWeakDefDirective() << *GVarSym << '\n';
+ EmitAlignment(Align, GVar);
+ O << *GVarSym << ":";
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString() << ' ';
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
}
+ O << '\n';
+ EmitGlobalConstant(C);
+ return;
} else {
- if (!Subtarget->isTargetCygMing()) {
- if (GVar->hasLocalLinkage())
- O << "\t.local\t" << *GVSym << '\n';
- }
- O << MAI->getCOMMDirective() << *GVSym << ',' << Size;
+ O << MAI->getCOMMDirective() << *GVarSym << ',' << Size;
if (MAI->getCOMMDirectiveTakesAlignment())
O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
}
- if (VerboseAsm) {
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << ' ';
- WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
+ } else {
+ if (!Subtarget->isTargetCygMing()) {
+ if (GVar->hasLocalLinkage())
+ O << "\t.local\t" << *GVarSym << '\n';
}
- O << '\n';
- return;
+ O << MAI->getCOMMDirective() << *GVarSym << ',' << Size;
+ if (MAI->getCOMMDirectiveTakesAlignment())
+ O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+ }
+ if (VerboseAsm) {
+ O.PadToColumn(MAI->getCommentColumn());
+ O << MAI->getCommentString() << ' ';
+ WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
}
+ O << '\n';
+ return;
}
switch (GVar->getLinkage()) {
@@ -756,13 +751,13 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
case GlobalValue::WeakODRLinkage:
case GlobalValue::LinkerPrivateLinkage:
if (Subtarget->isTargetDarwin()) {
- OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
- O << MAI->getWeakDefDirective() << *GVSym << '\n';
+ OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
+ O << MAI->getWeakDefDirective() << *GVarSym << '\n';
} else if (Subtarget->isTargetCygMing()) {
- OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
+ OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
O << "\t.linkonce same_size\n";
} else
- O << "\t.weak\t" << *GVSym << '\n';
+ O << "\t.weak\t" << *GVarSym << '\n';
break;
case GlobalValue::DLLExportLinkage:
case GlobalValue::AppendingLinkage:
@@ -770,7 +765,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
// their name or something. For now, just emit them as external.
case GlobalValue::ExternalLinkage:
// If external or appending, declare as a global symbol
- OutStreamer.EmitSymbolAttribute(GVSym, MCStreamer::Global);
+ OutStreamer.EmitSymbolAttribute(GVarSym, MCStreamer::Global);
break;
case GlobalValue::PrivateLinkage:
case GlobalValue::InternalLinkage:
@@ -780,7 +775,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
}
EmitAlignment(Align, GVar);
- O << *GVSym << ":";
+ O << *GVarSym << ":";
if (VerboseAsm){
O.PadToColumn(MAI->getCommentColumn());
O << MAI->getCommentString() << ' ';
@@ -791,7 +786,7 @@ void X86AsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
EmitGlobalConstant(C);
if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << *GVSym << ", " << Size << '\n';
+ O << "\t.size\t" << *GVarSym << ", " << Size << '\n';
}
void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {