}
-/// SwitchSection - Switch to the specified section of the executable if we
-/// are not already in it!
+/// SwitchToTextSection - Switch to the specified text section of the executable
+/// if we are not already in it!
///
-void AsmPrinter::SwitchSection(const char *NewSection, const GlobalValue *GV) {
+void AsmPrinter::SwitchToTextSection(const char *NewSection,
+ const GlobalValue *GV) {
std::string NS;
// Microsoft ML/MASM has a fundamentally different approach to handling
return;
}
- bool isData = strcmp(NewSection , ".data") == 0;
-
if (GV && GV->hasSection())
NS = GV->getSection();
- else if (isData)
- NS = "_data";
else
NS = "_text";
if (!CurrentSection.empty())
O << CurrentSection << "\tends\n\n";
CurrentSection = NS;
- O << CurrentSection << (isData ? "\tsegment 'DATA'\n"
- : "\tsegment 'CODE'\n");
+ O << CurrentSection << "\tsegment 'CODE'\n";
}
} else {
if (GV && GV->hasSection())
}
}
+/// SwitchToTextSection - Switch to the specified text section of the executable
+/// if we are not already in it!
+///
+void AsmPrinter::SwitchToDataSection(const char *NewSection,
+ const GlobalValue *GV) {
+ std::string NS;
+
+ // Microsoft ML/MASM has a fundamentally different approach to handling
+ // sections.
+
+ if (MLSections) {
+ if (*NewSection == 0) {
+ // Simply end the current section, if any.
+ if (!CurrentSection.empty()) {
+ O << CurrentSection << "\tends\n\n";
+ CurrentSection.clear();
+ }
+ return;
+ }
+
+ if (GV && GV->hasSection())
+ NS = GV->getSection();
+ else
+ NS = "_data";
+
+ if (CurrentSection != NS) {
+ if (!CurrentSection.empty())
+ O << CurrentSection << "\tends\n\n";
+ CurrentSection = NS;
+ O << CurrentSection << "\tsegment 'DATA'\n";
+ }
+ } else {
+ if (GV && GV->hasSection())
+ NS = SwitchToSectionDirective + GV->getSection();
+ else
+ NS = std::string("\t")+NewSection;
+
+ if (CurrentSection != NS) {
+ CurrentSection = NS;
+ if (!CurrentSection.empty())
+ O << CurrentSection << '\n';
+ }
+ }
+}
+
+
bool AsmPrinter::doInitialization(Module &M) {
Mang = new Mangler(M, GlobalPrefix);
<< M.getModuleInlineAsm()
<< "\n" << CommentString << " End of file scope inline assembly\n";
- SwitchSection("", 0); // Reset back to no section.
+ SwitchToDataSection("", 0); // Reset back to no section.
if (MachineDebugInfo *DebugInfo = getAnalysisToUpdate<MachineDebugInfo>()) {
DebugInfo->AnalyzeModule(M);
if (CP.empty()) return;
const TargetData *TD = TM.getTargetData();
- SwitchSection(ConstantPoolSection, 0);
+ SwitchToDataSection(ConstantPoolSection, 0);
EmitAlignment(MCP->getConstantPoolAlignment());
for (unsigned i = 0, e = CP.size(); i != e; ++i) {
O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << '_' << i
TM.getRelocationModel() == Reloc::DynamicNoPIC) &&
"Unhandled relocation model emitting jump table information!");
- SwitchSection(JumpTableSection, 0);
+ SwitchToDataSection(JumpTableSection, 0);
EmitAlignment(Log2_32(TD->getPointerAlignment()));
for (unsigned i = 0, e = JT.size(); i != e; ++i) {
O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() << '_' << i
return true; // No need to emit this at all.
if (GV->getName() == "llvm.global_ctors" && GV->use_empty()) {
- SwitchSection(StaticCtorsSection, 0);
+ SwitchToDataSection(StaticCtorsSection, 0);
EmitAlignment(2, 0);
EmitXXStructorList(GV->getInitializer());
return true;
}
if (GV->getName() == "llvm.global_dtors" && GV->use_empty()) {
- SwitchSection(StaticDtorsSection, 0);
+ SwitchToDataSection(StaticDtorsSection, 0);
EmitAlignment(2, 0);
EmitXXStructorList(GV->getInitializer());
return true;
///
void DwarfWriter::EmitInitial() const {
// Dwarf sections base addresses.
- Asm->SwitchSection(DwarfFrameSection, 0);
+ Asm->SwitchToDataSection(DwarfFrameSection, 0);
EmitLabel("section_frame", 0);
- Asm->SwitchSection(DwarfInfoSection, 0);
+ Asm->SwitchToDataSection(DwarfInfoSection, 0);
EmitLabel("section_info", 0);
EmitLabel("info", 0);
- Asm->SwitchSection(DwarfAbbrevSection, 0);
+ Asm->SwitchToDataSection(DwarfAbbrevSection, 0);
EmitLabel("section_abbrev", 0);
EmitLabel("abbrev", 0);
- Asm->SwitchSection(DwarfARangesSection, 0);
+ Asm->SwitchToDataSection(DwarfARangesSection, 0);
EmitLabel("section_aranges", 0);
- Asm->SwitchSection(DwarfMacInfoSection, 0);
+ Asm->SwitchToDataSection(DwarfMacInfoSection, 0);
EmitLabel("section_macinfo", 0);
- Asm->SwitchSection(DwarfLineSection, 0);
+ Asm->SwitchToDataSection(DwarfLineSection, 0);
EmitLabel("section_line", 0);
EmitLabel("line", 0);
- Asm->SwitchSection(DwarfLocSection, 0);
+ Asm->SwitchToDataSection(DwarfLocSection, 0);
EmitLabel("section_loc", 0);
- Asm->SwitchSection(DwarfPubNamesSection, 0);
+ Asm->SwitchToDataSection(DwarfPubNamesSection, 0);
EmitLabel("section_pubnames", 0);
- Asm->SwitchSection(DwarfStrSection, 0);
+ Asm->SwitchToDataSection(DwarfStrSection, 0);
EmitLabel("section_str", 0);
- Asm->SwitchSection(DwarfRangesSection, 0);
+ Asm->SwitchToDataSection(DwarfRangesSection, 0);
EmitLabel("section_ranges", 0);
- Asm->SwitchSection(TextSection, 0);
+ Asm->SwitchToDataSection(TextSection, 0);
EmitLabel("text_begin", 0);
- Asm->SwitchSection(DataSection, 0);
+ Asm->SwitchToDataSection(DataSection, 0);
EmitLabel("data_begin", 0);
}
///
void DwarfWriter::EmitDebugInfo() const {
// Start debug info section.
- Asm->SwitchSection(DwarfInfoSection, 0);
+ Asm->SwitchToDataSection(DwarfInfoSection, 0);
// Process each compile unit.
for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
// Check to see if it is worth the effort.
if (!Abbreviations.empty()) {
// Start the debug abbrev section.
- Asm->SwitchSection(DwarfAbbrevSection, 0);
+ Asm->SwitchToDataSection(DwarfAbbrevSection, 0);
EmitLabel("abbrev_begin", 0);
const int MaxLineDelta = 255 + MinLineDelta;
// Start the dwarf line section.
- Asm->SwitchSection(DwarfLineSection, 0);
+ Asm->SwitchToDataSection(DwarfLineSection, 0);
// Construct the section header.
AddressSize : -AddressSize;
// Start the dwarf frame section.
- Asm->SwitchSection(DwarfFrameSection, 0);
+ Asm->SwitchToDataSection(DwarfFrameSection, 0);
EmitDifference("frame_common_end", 0,
"frame_common_begin", 0);
/// section.
void DwarfWriter::EmitFunctionDebugFrame() {
// Start the dwarf frame section.
- Asm->SwitchSection(DwarfFrameSection, 0);
+ Asm->SwitchToDataSection(DwarfFrameSection, 0);
EmitDifference("frame_end", SubprogramCount,
"frame_begin", SubprogramCount);
///
void DwarfWriter::EmitDebugPubNames() {
// Start the dwarf pubnames section.
- Asm->SwitchSection(DwarfPubNamesSection, 0);
+ Asm->SwitchToDataSection(DwarfPubNamesSection, 0);
// Process each compile unit.
for (unsigned i = 0, N = CompileUnits.size(); i < N; ++i) {
// Check to see if it is worth the effort.
if (!StringPool.empty()) {
// Start the dwarf str section.
- Asm->SwitchSection(DwarfStrSection, 0);
+ Asm->SwitchToDataSection(DwarfStrSection, 0);
// For each of strings in the string pool.
for (unsigned StringID = 1, N = StringPool.size();
///
void DwarfWriter::EmitDebugLoc() {
// Start the dwarf loc section.
- Asm->SwitchSection(DwarfLocSection, 0);
+ Asm->SwitchToDataSection(DwarfLocSection, 0);
O << "\n";
}
///
void DwarfWriter::EmitDebugARanges() {
// Start the dwarf aranges section.
- Asm->SwitchSection(DwarfARangesSection, 0);
+ Asm->SwitchToDataSection(DwarfARangesSection, 0);
// FIXME - Mock up
#if 0
///
void DwarfWriter::EmitDebugRanges() {
// Start the dwarf ranges section.
- Asm->SwitchSection(DwarfRangesSection, 0);
+ Asm->SwitchToDataSection(DwarfRangesSection, 0);
O << "\n";
}
///
void DwarfWriter::EmitDebugMacInfo() {
// Start the dwarf macinfo section.
- Asm->SwitchSection(DwarfMacInfoSection, 0);
+ Asm->SwitchToDataSection(DwarfMacInfoSection, 0);
O << "\n";
}
EOL("Dwarf End Module");
// Standard sections final addresses.
- Asm->SwitchSection(TextSection, 0);
+ Asm->SwitchToTextSection(TextSection, 0);
EmitLabel("text_end", 0);
- Asm->SwitchSection(DataSection, 0);
+ Asm->SwitchToDataSection(DataSection, 0);
EmitLabel("data_end", 0);
// Compute DIE offsets and sizes.
// Print out labels for the function.
const Function *F = MF.getFunction();
- SwitchSection(".text", F);
+ SwitchToTextSection(".text", F);
EmitAlignment(4, F);
switch (F->getLinkage()) {
default: assert(0 && "Unknown linkage type!");
if (C->isNullValue() &&
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
I->hasWeakLinkage() /* FIXME: Verify correct */)) {
- SwitchSection("\t.section .data", I);
+ SwitchToDataSection("\t.section .data", I);
if (I->hasInternalLinkage())
O << "\t.local " << name << "\n";
// Nonnull linkonce -> weak
O << "\t.weak " << name << "\n";
O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
- SwitchSection("", I);
+ SwitchToDataSection("", I);
break;
case GlobalValue::AppendingLinkage:
// FIXME: appending linkage variables should go into a section of
O << "\t.globl " << name << "\n";
// FALL THROUGH
case GlobalValue::InternalLinkage:
- SwitchSection(C->isNullValue() ? "\t.section .bss" :
- "\t.section .data", I);
+ SwitchToDataSection(C->isNullValue() ? "\t.section .bss" :
+ "\t.section .data", I);
break;
case GlobalValue::GhostLinkage:
std::cerr << "GhostLinkage cannot appear in AlphaAsmPrinter!\n";
EmitConstantPool(MF.getConstantPool());
// Print out labels for the function.
- SwitchSection("\n\t.section .text, \"ax\", \"progbits\"\n", MF.getFunction());
+ SwitchToTextSection("\n\t.section .text, \"ax\", \"progbits\"\n",
+ MF.getFunction());
// ^^ means "Allocated instruXions in mem, initialized"
EmitAlignment(5);
O << "\t.global\t" << CurrentFnName << "\n";
if (C->isNullValue() &&
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
I->hasWeakLinkage() /* FIXME: Verify correct */)) {
- SwitchSection(".data", I);
+ SwitchToDataSection(".data", I);
if (I->hasInternalLinkage()) {
O << "\t.lcomm " << name << "#," << TD->getTypeSize(C->getType())
<< "," << (1 << Align);
O << "\t.weak " << name << "\n";
O << "\t.section\t.llvm.linkonce.d." << name
<< ", \"aw\", \"progbits\"\n";
- SwitchSection("", I);
+ SwitchToDataSection("", I);
break;
case GlobalValue::AppendingLinkage:
// FIXME: appending linkage variables should go into a section of
O << "\t.global " << name << "\n";
// FALL THROUGH
case GlobalValue::InternalLinkage:
- SwitchSection(C->isNullValue() ? ".bss" : ".data", I);
+ SwitchToDataSection(C->isNullValue() ? ".bss" : ".data", I);
break;
case GlobalValue::GhostLinkage:
std::cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n";
switch (F->getLinkage()) {
default: assert(0 && "Unknown linkage type!");
case Function::InternalLinkage: // Symbols default to internal.
- SwitchSection(".text", F);
+ SwitchToTextSection(".text", F);
break;
case Function::ExternalLinkage:
- SwitchSection(".text", F);
+ SwitchToTextSection(".text", F);
O << "\t.globl\t" << CurrentFnName << "\n";
break;
case Function::WeakLinkage:
case Function::LinkOnceLinkage:
- SwitchSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions",
- F);
+ SwitchToTextSection(
+ ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F);
O << "\t.globl\t" << CurrentFnName << "\n";
O << "\t.weak_definition\t" << CurrentFnName << "\n";
break;
O << "\t.zerofill __DATA, __common, " << name << ", "
<< Size << ", " << Align;
} else if (I->hasInternalLinkage()) {
- SwitchSection(".data", I);
+ SwitchToDataSection(".data", I);
O << LCOMMDirective << name << "," << Size << "," << Align;
} else {
- SwitchSection(".data", I);
+ SwitchToDataSection(".data", I);
O << ".comm " << name << "," << Size;
}
O << "\t\t; '" << I->getName() << "'\n";
case GlobalValue::WeakLinkage:
O << "\t.globl " << name << '\n'
<< "\t.weak_definition " << name << '\n';
- SwitchSection(".section __DATA,__datacoal_nt,coalesced", I);
+ SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I);
break;
case GlobalValue::AppendingLinkage:
// FIXME: appending linkage variables should go into a section of
O << "\t.globl " << name << "\n";
// FALL THROUGH
case GlobalValue::InternalLinkage:
- SwitchSection(".data", I);
+ SwitchToDataSection(".data", I);
break;
default:
std::cerr << "Unknown linkage type!";
if (TM.getRelocationModel() == Reloc::PIC) {
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
i != e; ++i) {
- SwitchSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
- "pure_instructions,32", 0);
+ SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
+ "pure_instructions,32", 0);
EmitAlignment(2);
O << "L" << *i << "$stub:\n";
O << "\t.indirect_symbol " << *i << "\n";
O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n";
O << "\tmtctr r12\n";
O << "\tbctr\n";
- SwitchSection(".lazy_symbol_pointer", 0);
+ SwitchToDataSection(".lazy_symbol_pointer", 0);
O << "L" << *i << "$lazy_ptr:\n";
O << "\t.indirect_symbol " << *i << "\n";
O << "\t.long dyld_stub_binding_helper\n";
} else {
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
i != e; ++i) {
- SwitchSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
- "pure_instructions,16", 0);
+ SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
+ "pure_instructions,16", 0);
EmitAlignment(4);
O << "L" << *i << "$stub:\n";
O << "\t.indirect_symbol " << *i << "\n";
O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n";
O << "\tmtctr r12\n";
O << "\tbctr\n";
- SwitchSection(".lazy_symbol_pointer", 0);
+ SwitchToDataSection(".lazy_symbol_pointer", 0);
O << "L" << *i << "$lazy_ptr:\n";
O << "\t.indirect_symbol " << *i << "\n";
O << "\t.long dyld_stub_binding_helper\n";
// Output stubs for external and common global variables.
if (GVStubs.begin() != GVStubs.end()) {
- SwitchSection(".non_lazy_symbol_pointer", 0);
+ SwitchToDataSection(".non_lazy_symbol_pointer", 0);
for (std::set<std::string>::iterator I = GVStubs.begin(),
E = GVStubs.end(); I != E; ++I) {
O << "L" << *I << "$non_lazy_ptr:\n";
}
bool AIXAsmPrinter::doInitialization(Module &M) {
- SwitchSection("", 0);
+ SwitchToDataSection("", 0);
const TargetData *TD = TM.getTargetData();
O << "\t.machine \"ppc64\"\n"
CurrentFnName = Mang->getValueName(MF.getFunction());
// Print out labels for the function.
- O << "\t.text\n";
- O << "\t.align 16\n";
+ SwitchToTextSection(".text", MF.getFunction());
+ EmitAlignment(4, MF.getFunction());
O << "\t.globl\t" << CurrentFnName << "\n";
O << "\t.type\t" << CurrentFnName << ", #function\n";
O << CurrentFnName << ":\n";
if (C->isNullValue() &&
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
I->hasWeakLinkage() /* FIXME: Verify correct */)) {
- SwitchSection(".data", I);
+ SwitchToDataSection(".data", I);
if (I->hasInternalLinkage())
O << "\t.local " << name << "\n";
case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
// Nonnull linkonce -> weak
O << "\t.weak " << name << "\n";
- SwitchSection("", I);
+ SwitchToDataSection("", I);
O << "\t.section\t\".llvm.linkonce.d." << name
<< "\",\"aw\",@progbits\n";
break;
// FALL THROUGH
case GlobalValue::InternalLinkage:
if (C->isNullValue())
- SwitchSection(".bss", I);
+ SwitchToDataSection(".bss", I);
else
- SwitchSection(".data", I);
+ SwitchToDataSection(".data", I);
break;
case GlobalValue::GhostLinkage:
std::cerr << "Should not have any unmaterialized functions!\n";
switch (F->getLinkage()) {
default: assert(0 && "Unknown linkage type!");
case Function::InternalLinkage: // Symbols default to internal.
- SwitchSection(".text", F);
+ SwitchToTextSection(".text", F);
EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
break;
case Function::ExternalLinkage:
- SwitchSection(".text", F);
+ SwitchToTextSection(".text", F);
EmitAlignment(4, F); // FIXME: This should be parameterized somewhere.
O << "\t.globl\t" << CurrentFnName << "\n";
break;
case Function::WeakLinkage:
case Function::LinkOnceLinkage:
if (forDarwin) {
- SwitchSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions",
- F);
+ SwitchToTextSection(
+ ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F);
O << "\t.globl\t" << CurrentFnName << "\n";
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";
+ SwitchToTextSection("", F);
O << "\t.weak " << CurrentFnName << "\n";
}
break;
O << "\t.zerofill __DATA__, __common, " << name << ", "
<< Size << ", " << Align;
} else {
- SwitchSection(".data", I);
+ SwitchToDataSection(".data", I);
if (LCOMMDirective != NULL) {
if (I->hasInternalLinkage()) {
O << LCOMMDirective << name << "," << Size;
if (forDarwin) {
O << "\t.globl " << name << "\n"
<< "\t.weak_definition " << name << "\n";
- SwitchSection(".section __DATA,__datacoal_nt,coalesced", I);
+ SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I);
} else {
O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n";
O << "\t.weak " << name << "\n";
O << "\t.globl " << name << "\n";
// FALL THROUGH
case GlobalValue::InternalLinkage:
- SwitchSection(".data", I);
+ SwitchToDataSection(".data", I);
break;
default:
assert(0 && "Unknown linkage type!");
}
if (forDarwin) {
- SwitchSection("", 0);
+ SwitchToDataSection("", 0);
// Output stubs for dynamically-linked functions
unsigned j = 1;
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
i != e; ++i, ++j) {
- SwitchSection(".section __IMPORT,__jump_table,symbol_stubs,"
- "self_modifying_code+pure_instructions,5", 0);
+ SwitchToDataSection(".section __IMPORT,__jump_table,symbol_stubs,"
+ "self_modifying_code+pure_instructions,5", 0);
O << "L" << *i << "$stub:\n";
O << "\t.indirect_symbol " << *i << "\n";
O << "\thlt ; hlt ; hlt ; hlt ; hlt\n";
// Output stubs for external and common global variables.
if (GVStubs.begin() != GVStubs.end())
- SwitchSection(".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0);
+ SwitchToDataSection(
+ ".section __IMPORT,__pointers,non_lazy_symbol_pointers", 0);
for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end();
i != e; ++i) {
O << "L" << *i << "$non_lazy_ptr:\n";
EmitConstantPool(MF.getConstantPool());
// Print out labels for the function.
- SwitchSection(".code", MF.getFunction());
+ SwitchToTextSection(".code", MF.getFunction());
EmitAlignment(4);
if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage)
O << "\tpublic " << CurrentFnName << "\n";
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
case GlobalValue::WeakLinkage:
- SwitchSection("", 0);
+ SwitchToDataSection("", 0);
O << name << "?\tsegment common 'COMMON'\n";
bCustomSegment = true;
// FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
// are also available.
break;
case GlobalValue::AppendingLinkage:
- SwitchSection("", 0);
+ SwitchToDataSection("", 0);
O << name << "?\tsegment public 'DATA'\n";
bCustomSegment = true;
// FIXME: the default alignment is 16 bytes, but 1, 2, 4, and 256
O << "\tpublic " << name << "\n";
// FALL THROUGH
case GlobalValue::InternalLinkage:
- SwitchSection(".data", I);
+ SwitchToDataSection(".data", I);
break;
default:
assert(0 && "Unknown linkage type!");
// Bypass X86SharedAsmPrinter::doFinalization().
AsmPrinter::doFinalization(M);
- SwitchSection("", 0);
+ SwitchToDataSection("", 0);
O << "\tend\n";
return false; // success
}