From ae408e6f1e4e2e7658b76b8dec679aeae9a9df99 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sat, 19 Jul 2008 13:16:11 +0000 Subject: [PATCH] Switch MIPS to new ELFTargetAsmInfo. Add few FIXMEs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53790 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/DarwinTargetAsmInfo.cpp | 1 + lib/Target/Mips/MipsAsmPrinter.cpp | 243 ++++++++++++-------------- lib/Target/Mips/MipsTargetAsmInfo.cpp | 5 +- lib/Target/Mips/MipsTargetAsmInfo.h | 3 +- 4 files changed, 114 insertions(+), 138 deletions(-) diff --git a/lib/Target/DarwinTargetAsmInfo.cpp b/lib/Target/DarwinTargetAsmInfo.cpp index 311126d0113..564d1a18357 100644 --- a/lib/Target/DarwinTargetAsmInfo.cpp +++ b/lib/Target/DarwinTargetAsmInfo.cpp @@ -32,6 +32,7 @@ DarwinTargetAsmInfo::DarwinTargetAsmInfo(const TargetMachine &TM) { SectionFlags::Mergeable); EightByteConstantSection_ = getUnnamedSection("\t.literal8\n", SectionFlags::Mergeable); + // Note: 16-byte constant section is subtarget specific and should be provided // there. diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index d37d0874830..4c3bdf47a9d 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -58,12 +58,13 @@ namespace { return "Mips Assembly Printer"; } + virtual std::string getSectionForFunction(const Function &F) const; void printOperand(const MachineInstr *MI, int opNum); void printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier = 0); void printFCCOperand(const MachineInstr *MI, int opNum, const char *Modifier = 0); - + void printModuleLevelGV(const GlobalVariable* GVar); unsigned int getSavedRegsBitmask(bool isFloat, MachineFunction &MF); void printHex32(unsigned int Value); @@ -73,7 +74,7 @@ namespace { void emitFrameDirective(MachineFunction &MF); void emitMaskDirective(MachineFunction &MF); void emitFMaskDirective(MachineFunction &MF); - + bool printInstruction(const MachineInstr *MI); // autogenerated. bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); @@ -241,13 +242,18 @@ emitCurrentABIString(void) return NULL; } +// Substitute old hook with new one temporary +std::string MipsAsmPrinter::getSectionForFunction(const Function &F) const { + return TAI->SectionForGlobal(&F); +} + /// Emit the directives used by GAS on the start of functions void MipsAsmPrinter:: emitFunctionStart(MachineFunction &MF) { // Print out the label for the function. const Function *F = MF.getFunction(); - SwitchToTextSection(getSectionForFunction(*F).c_str(), F); + SwitchToTextSection(TAI->SectionForGlobal(F).c_str()); // 2 bits aligned EmitAlignment(2, F); @@ -467,146 +473,113 @@ doInitialization(Module &M) return false; // success } -bool MipsAsmPrinter:: -doFinalization(Module &M) -{ +void MipsAsmPrinter:: +printModuleLevelGV(const GlobalVariable* GVar) { const TargetData *TD = TM.getTargetData(); - // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), - E = M.global_end(); I != E; ++I) + if (!GVar->hasInitializer()) + return; // External global require no code - // External global require no code - if (I->hasInitializer()) { - - // Check to see if this is a special global - // used by LLVM, if so, emit it. - if (EmitSpecialLLVMGlobal(I)) - continue; - - O << "\n\n"; - std::string name = Mang->getValueName(I); - Constant *C = I->getInitializer(); - const Type *CTy = C->getType(); - unsigned Size = TD->getABITypeSize(CTy); - bool printSizeAndType = true; - - // A data structure or array is aligned in memory to the largest - // alignment boundary required by any data type inside it (this matches - // the Preferred Type Alignment). For integral types, the alignment is - // the type size. - //unsigned Align = TD->getPreferredAlignmentLog(I); - //unsigned Align = TD->getPrefTypeAlignment(C->getType()); - unsigned Align; - if (CTy->getTypeID() == Type::IntegerTyID || - CTy->getTypeID() == Type::VoidTyID) { - assert(!(Size & (Size-1)) && "Alignment is not a power of two!"); - Align = Log2_32(Size); - } else - Align = TD->getPreferredTypeAlignmentShift(CTy); - - // Is this correct ? - if (C->isNullValue() && (I->hasLinkOnceLinkage() || - I->hasInternalLinkage() || I->hasWeakLinkage() || - I->hasCommonLinkage())) - { - if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. - - if (!NoZerosInBSS && TAI->getBSSSection()) - SwitchToDataSection(TAI->getBSSSection(), I); - else - SwitchToDataSection(TAI->getDataSection(), I); - - if (I->hasInternalLinkage()) { - if (TAI->getLCOMMDirective()) - O << TAI->getLCOMMDirective() << name << "," << Size; - else - O << "\t.local\t" << name << "\n"; - } else { - O << TAI->getCOMMDirective() << name << "," << Size; - // The .comm alignment in bytes. - if (TAI->getCOMMDirectiveTakesAlignment()) - O << "," << (1 << Align); - } + // Check to see if this is a special global used by LLVM, if so, emit it. + if (EmitSpecialLLVMGlobal(GVar)) + return; + O << "\n\n"; + std::string SectionName = TAI->SectionForGlobal(GVar); + std::string name = Mang->getValueName(GVar); + Constant *C = GVar->getInitializer(); + const Type *CTy = C->getType(); + unsigned Size = TD->getABITypeSize(CTy); + bool printSizeAndType = true; + + // A data structure or array is aligned in memory to the largest + // alignment boundary required by any data type inside it (this matches + // the Preferred Type Alignment). For integral types, the alignment is + // the type size. + //unsigned Align = TD->getPreferredAlignmentLog(I); + //unsigned Align = TD->getPrefTypeAlignment(C->getType()); + unsigned Align; + if (CTy->getTypeID() == Type::IntegerTyID || + CTy->getTypeID() == Type::VoidTyID) { + assert(!(Size & (Size-1)) && "Alignment is not a power of two!"); + Align = Log2_32(Size); + } else + Align = TD->getPreferredTypeAlignmentShift(CTy); + + // FIXME: ELF supports visibility + + SwitchToDataSection(SectionName.c_str()); + + if (C->isNullValue() && !GVar->hasSection()) { + if (!GVar->isThreadLocal() && + (GVar->hasInternalLinkage() || GVar->isWeakForLinker())) { + if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. + + if (GVar->hasInternalLinkage()) { + if (TAI->getLCOMMDirective()) + O << TAI->getLCOMMDirective() << name << ',' << Size; + else + O << "\t.local\t" << name << '\n'; } else { + O << TAI->getCOMMDirective() << name << ',' << Size; + // The .comm alignment in bytes. + if (TAI->getCOMMDirectiveTakesAlignment()) + O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align); + } + O << '\n'; + return; + } + } + switch (GVar->getLinkage()) { + case GlobalValue::LinkOnceLinkage: + case GlobalValue::CommonLinkage: + case GlobalValue::WeakLinkage: + // FIXME: Verify correct for weak. + // Nonnull linkonce -> weak + O << "\t.weak " << name << "\n"; + break; + case GlobalValue::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of their name + // or something. For now, just emit them as external. + case GlobalValue::ExternalLinkage: + // If external or appending, declare as a global symbol + O << TAI->getGlobalDirective() << name << "\n"; + // Fall Through + case GlobalValue::InternalLinkage: + break; + case GlobalValue::GhostLinkage: + cerr << "Should not have any unmaterialized functions!\n"; + abort(); + case GlobalValue::DLLImportLinkage: + cerr << "DLLImport linkage is not supported by this target!\n"; + abort(); + case GlobalValue::DLLExportLinkage: + cerr << "DLLExport linkage is not supported by this target!\n"; + abort(); + default: + assert(0 && "Unknown linkage type!"); + } + + if (Align) + O << "\t.align " << Align << "\n"; - switch (I->getLinkage()) - { - case GlobalValue::LinkOnceLinkage: - case GlobalValue::CommonLinkage: - case GlobalValue::WeakLinkage: - // FIXME: Verify correct for weak. - // Nonnull linkonce -> weak - O << "\t.weak " << name << "\n"; - SwitchToDataSection("", I); - O << "\t.section\t\".llvm.linkonce.d." << name - << "\",\"aw\",@progbits\n"; - break; - case GlobalValue::AppendingLinkage: - // FIXME: appending linkage variables - // should go into a section of their name or - // something. For now, just emit them as external. - case GlobalValue::ExternalLinkage: - // If external or appending, declare as a global symbol - O << TAI->getGlobalDirective() << name << "\n"; - // Fall Through - case GlobalValue::InternalLinkage: - // FIXME: special handling for ".ctors" & ".dtors" sections - if (I->hasSection() && (I->getSection() == ".ctors" || - I->getSection() == ".dtors")) { - std::string SectionName = ".section " + I->getSection(); - SectionName += ",\"aw\",%progbits"; - SwitchToDataSection(SectionName.c_str()); - } else { - if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection()) - SwitchToDataSection(TAI->getBSSSection(), I); - else if (!I->isConstant()) - SwitchToDataSection(TAI->getDataSection(), I); - else { - // Read-only data. We have two possible scenary here - // 1) Readonly section for strings (char arrays). - // 2) for other types. - if (TAI->getReadOnlySection()) { - const ConstantArray *CVA = dyn_cast(C); - if (CVA && CVA->isString()) { - std::string SectionName = "\t.section\t.rodata.str1.4," - "\"aMS\",@progbits,1"; - SwitchToDataSection(SectionName.c_str()); - printSizeAndType = false; - break; - } - SwitchToDataSection(TAI->getReadOnlySection(), I); - } else - SwitchToDataSection(TAI->getDataSection(), I); - } - } - break; - case GlobalValue::GhostLinkage: - cerr << "Should not have any unmaterialized functions!\n"; - abort(); - case GlobalValue::DLLImportLinkage: - cerr << "DLLImport linkage is not supported by this target!\n"; - abort(); - case GlobalValue::DLLExportLinkage: - cerr << "DLLExport linkage is not supported by this target!\n"; - abort(); - default: - assert(0 && "Unknown linkage type!"); - } - - if (Align) - O << "\t.align " << Align << "\n"; - - if (TAI->hasDotTypeDotSizeDirective() && printSizeAndType) { - O << "\t.type " << name << ",@object\n"; - O << "\t.size " << name << "," << Size << "\n"; - } - O << name << ":\n"; - EmitGlobalConstant(C); - } + if (TAI->hasDotTypeDotSizeDirective() && printSizeAndType) { + O << "\t.type " << name << ",@object\n"; + O << "\t.size " << name << "," << Size << "\n"; } + O << name << ":\n"; + EmitGlobalConstant(C); +} + +bool MipsAsmPrinter:: +doFinalization(Module &M) +{ + // Print out module-level global variables here. + for (Module::const_global_iterator I = M.global_begin(), + E = M.global_end(); I != E; ++I) + printModuleLevelGV(I); + O << "\n"; return AsmPrinter::doFinalization(M); diff --git a/lib/Target/Mips/MipsTargetAsmInfo.cpp b/lib/Target/Mips/MipsTargetAsmInfo.cpp index daed29da914..ceaee4b8c99 100644 --- a/lib/Target/Mips/MipsTargetAsmInfo.cpp +++ b/lib/Target/Mips/MipsTargetAsmInfo.cpp @@ -16,7 +16,8 @@ using namespace llvm; -MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM) { +MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM): + ELFTargetAsmInfo(TM) { AlignmentIsInBytes = false; COMMDirectiveTakesAlignment = true; @@ -33,7 +34,7 @@ MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM) { if (!TM.getSubtarget().hasABICall()) JumpTableDirective = "\t.word\t"; - else + else JumpTableDirective = "\t.gpword\t"; } diff --git a/lib/Target/Mips/MipsTargetAsmInfo.h b/lib/Target/Mips/MipsTargetAsmInfo.h index bb9402615d2..994da830ee1 100644 --- a/lib/Target/Mips/MipsTargetAsmInfo.h +++ b/lib/Target/Mips/MipsTargetAsmInfo.h @@ -15,13 +15,14 @@ #define MIPSTARGETASMINFO_H #include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Target/ELFTargetAsmInfo.h" namespace llvm { // Forward declaration. class MipsTargetMachine; - struct MipsTargetAsmInfo : public TargetAsmInfo { + struct MipsTargetAsmInfo : public ELFTargetAsmInfo { explicit MipsTargetAsmInfo(const MipsTargetMachine &TM); }; -- 2.34.1