From 3724600253a3f3183fdf80c11580c4e8e924def5 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sat, 19 Jul 2008 13:14:11 +0000 Subject: [PATCH] Add TargetAsmInfo for all ELF-based targets llvm-svn: 53786 --- include/llvm/Target/ELFTargetAsmInfo.h | 38 ++++++ lib/Target/ELFTargetAsmInfo.cpp | 164 +++++++++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 include/llvm/Target/ELFTargetAsmInfo.h create mode 100644 lib/Target/ELFTargetAsmInfo.cpp diff --git a/include/llvm/Target/ELFTargetAsmInfo.h b/include/llvm/Target/ELFTargetAsmInfo.h new file mode 100644 index 00000000000..7afadf0dd7c --- /dev/null +++ b/include/llvm/Target/ELFTargetAsmInfo.h @@ -0,0 +1,38 @@ +//===---- ELFTargetAsmInfo.h - 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ELF_TARGET_ASM_INFO_H +#define LLVM_ELF_TARGET_ASM_INFO_H + +#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + class GlobalValue; + class GlobalVariable; + + class ELFTargetAsmInfo: public TargetAsmInfo { + explicit ELFTargetAsmInfo(const TargetMachine &TM); + + virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; + virtual std::string PrintSectionFlags(unsigned flags) const; + const Section* MergeableConstSection(const GlobalVariable *GV) const; + const Section* MergeableStringSection(const GlobalVariable *GV) const; + protected: + const TargetMachine* ETM; + }; +} + + +#endif // LLVM_ELF_TARGET_ASM_INFO_H diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp new file mode 100644 index 00000000000..9ca9709293e --- /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(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(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(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(GV)->getInitializer(); + const ConstantArray *CVA = cast(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; +} +