summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2008-07-19 13:16:11 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2008-07-19 13:16:11 +0000
commitae408e6f1e4e2e7658b76b8dec679aeae9a9df99 (patch)
tree20245ac67711a135461174e8d5b23840d46498f2 /lib
parentcff2ea06af03fd44758d937455f2b0999cbda60b (diff)
downloadllvm-ae408e6f1e4e2e7658b76b8dec679aeae9a9df99.tar.gz
llvm-ae408e6f1e4e2e7658b76b8dec679aeae9a9df99.tar.bz2
llvm-ae408e6f1e4e2e7658b76b8dec679aeae9a9df99.tar.xz
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
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/DarwinTargetAsmInfo.cpp1
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp243
-rw-r--r--lib/Target/Mips/MipsTargetAsmInfo.cpp5
-rw-r--r--lib/Target/Mips/MipsTargetAsmInfo.h3
4 files changed, 114 insertions, 138 deletions
diff --git a/lib/Target/DarwinTargetAsmInfo.cpp b/lib/Target/DarwinTargetAsmInfo.cpp
index 311126d011..564d1a1835 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 d37d087483..4c3bdf47a9 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<ConstantArray>(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 daed29da91..ceaee4b8c9 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<MipsSubtarget>().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 bb9402615d..994da830ee 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);
};