diff options
author | asl <asl@91177308-0d34-0410-b5e6-96231b3b80d8> | 2008-07-19 13:14:11 +0000 |
---|---|---|
committer | asl <asl@91177308-0d34-0410-b5e6-96231b3b80d8> | 2008-07-19 13:14:11 +0000 |
commit | e0d0f486879dce4bebfe667bb1d906a313c67123 (patch) | |
tree | 9c08f319f44ec1d24dffecb62d149bf7d2c39306 /lib | |
parent | f6fe8c49dfab2ba5dd14d4305a618189f2932323 (diff) | |
download | external_llvm-e0d0f486879dce4bebfe667bb1d906a313c67123.zip external_llvm-e0d0f486879dce4bebfe667bb1d906a313c67123.tar.gz external_llvm-e0d0f486879dce4bebfe667bb1d906a313c67123.tar.bz2 |
Add TargetAsmInfo for all ELF-based targets
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53786 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ELFTargetAsmInfo.cpp | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp new file mode 100644 index 0000000..9ca9709 --- /dev/null +++ b/lib/Target/ELFTargetAsmInfo.cpp @@ -0,0 +1,164 @@ +//===-- ELFTargetAsmInfo.cpp - ELF asm properties ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines target asm properties related what form asm statements +// should take in general on ELF-based targets +// +//===----------------------------------------------------------------------===// + +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Function.h" +#include "llvm/GlobalVariable.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Target/ELFTargetAsmInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetData.h" + +using namespace llvm; + +ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) { + ETM = &TM; + + TextSection_ = getUnnamedSection("\t.text", SectionFlags::Code); + DataSection_ = getUnnamedSection("\t.data", SectionFlags::Writeable); + BSSSection_ = getUnnamedSection("\t.bss", + SectionFlags::Writeable | SectionFlags::BSS); + ReadOnlySection_ = getNamedSection("\t.rodata", SectionFlags::None); + TLSDataSection_ = getNamedSection("\t.tdata", + SectionFlags::Writeable | SectionFlags::TLS); + TLSBSSSection_ = getNamedSection("\t.tbss", + SectionFlags::Writeable | SectionFlags::TLS | SectionFlags::BSS); + +} + +const Section* +ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { + SectionKind::Kind Kind = SectionKindForGlobal(GV); + + if (const Function *F = dyn_cast<Function>(GV)) { + switch (F->getLinkage()) { + default: assert(0 && "Unknown linkage type!"); + case Function::InternalLinkage: + case Function::DLLExportLinkage: + case Function::ExternalLinkage: + return getTextSection_(); + case Function::WeakLinkage: + case Function::LinkOnceLinkage: + std::string Name = UniqueSectionForGlobal(GV, Kind); + unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str()); + return getNamedSection(Name.c_str(), Flags); + } + } else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { + if (GVar->isWeakForLinker()) { + std::string Name = UniqueSectionForGlobal(GVar, Kind); + unsigned Flags = SectionFlagsForGlobal(GVar, Name.c_str()); + return getNamedSection(Name.c_str(), Flags); + } else { + switch (Kind) { + case SectionKind::Data: + return getDataSection_(); + case SectionKind::BSS: + // ELF targets usually have BSS sections + return getBSSSection_(); + case SectionKind::ROData: + return getReadOnlySection_(); + case SectionKind::RODataMergeStr: + return MergeableStringSection(GVar); + case SectionKind::RODataMergeConst: + return MergeableConstSection(GVar); + case SectionKind::ThreadData: + // ELF targets usually support TLS stuff + return getTLSDataSection_(); + case SectionKind::ThreadBSS: + return getTLSBSSSection_(); + default: + assert(0 && "Unsuported section kind for global"); + } + } + } else + assert(0 && "Unsupported global"); +} + +const Section* +ELFTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { + const TargetData *TD = ETM->getTargetData(); + Constant *C = cast<GlobalVariable>(GV)->getInitializer(); + const Type *Type = C->getType(); + + // FIXME: string here is temporary, until stuff will fully land in. + // We cannot use {Four,Eight,Sixteen}ByteConstantSection here, since it's + // currently directly used by asmprinter. + unsigned Size = TD->getABITypeSize(Type); + if (Size == 4 || Size == 8 || Size == 16) { + std::string Name = ".rodata.cst" + utostr(Size); + + return getNamedSection(Name.c_str(), + SectionFlags::setEntitySize(SectionFlags::Mergeable, + Size)); + } + + return getReadOnlySection_(); +} + +const Section* +ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { + const TargetData *TD = ETM->getTargetData(); + Constant *C = cast<GlobalVariable>(GV)->getInitializer(); + const ConstantArray *CVA = cast<ConstantArray>(C); + const Type *Type = CVA->getType()->getElementType(); + + unsigned Size = TD->getABITypeSize(Type); + if (Size <= 16) { + // We also need alignment here + const TargetData *TD = ETM->getTargetData(); + unsigned Align = TD->getPreferredAlignment(GV); + if (Align < Size) + Align = Size; + + std::string Name = getCStringSection() + utostr(Size) + '.' + utostr(Align); + unsigned Flags = SectionFlags::setEntitySize(SectionFlags::Mergeable | + SectionFlags::Strings, + Size); + return getNamedSection(Name.c_str(), Flags); + } + + return getReadOnlySection_(); +} + +std::string ELFTargetAsmInfo::PrintSectionFlags(unsigned flags) const { + std::string Flags = ",\""; + + if (!(flags & SectionFlags::Debug)) + Flags += 'a'; + if (flags & SectionFlags::Code) + Flags += 'x'; + if (flags & SectionFlags::Writeable) + Flags += 'w'; + if (flags & SectionFlags::Mergeable) + Flags += 'M'; + if (flags & SectionFlags::Strings) + Flags += 'S'; + if (flags & SectionFlags::TLS) + Flags += 'T'; + + Flags += "\""; + + // FIXME: There can be exceptions here + if (flags & SectionFlags::BSS) + Flags += ",@nobits"; + else + Flags += ",@progbits"; + + if (unsigned entitySize = SectionFlags::getEntitySize(flags)) + Flags += "," + utostr(entitySize); + + return Flags; +} + |