diff options
author | Chris Lattner <sabre@nondot.org> | 2009-08-13 06:28:06 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-08-13 06:28:06 +0000 |
commit | b71b909bc76f48377fc96547d53a088346852600 (patch) | |
tree | 28cc4d39046f706a31051767e47ee87e01f2a679 /lib/Target/Mips/MipsTargetObjectFile.cpp | |
parent | d4c00c0f558193b492aed9ab6aacf84bf1d3fb4e (diff) | |
download | llvm-b71b909bc76f48377fc96547d53a088346852600.tar.gz llvm-b71b909bc76f48377fc96547d53a088346852600.tar.bz2 llvm-b71b909bc76f48377fc96547d53a088346852600.tar.xz |
reintroduce support for Mips "small" section handling. This is
implemented somewhat differently than before, but it should have
the same functionality and the previous testcase passes again.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78900 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/MipsTargetObjectFile.cpp')
-rw-r--r-- | lib/Target/Mips/MipsTargetObjectFile.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/lib/Target/Mips/MipsTargetObjectFile.cpp b/lib/Target/Mips/MipsTargetObjectFile.cpp new file mode 100644 index 0000000000..85e9d65a32 --- /dev/null +++ b/lib/Target/Mips/MipsTargetObjectFile.cpp @@ -0,0 +1,93 @@ +//===-- MipsTargetObjectFile.cpp - Mips object files ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MipsTargetObjectFile.h" +#include "llvm/DerivedTypes.h" +#include "llvm/GlobalVariable.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Support/CommandLine.h" +using namespace llvm; + +static cl::opt<unsigned> +SSThreshold("mips-ssection-threshold", cl::Hidden, + cl::desc("Small data and bss section threshold size (default=8)"), + cl::init(8)); + +void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ + TargetLoweringObjectFileELF::Initialize(Ctx, TM); + + SmallDataSection = + getELFSection(".sdata", MCSectionELF::SHT_PROGBITS, + MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC, + SectionKind::getDataRel()); + + SmallBSSSection = + getELFSection(".sbss", MCSectionELF::SHT_NOBITS, + MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC, + SectionKind::getBSS()); + +} + +// A address must be loaded from a small section if its size is less than the +// small section size threshold. Data in this section must be addressed using +// gp_rel operator. +static bool IsInSmallSection(uint64_t Size) { + return Size > 0 && Size <= SSThreshold; +} + +bool MipsTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV, + const TargetMachine &TM) const { + if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) + return false; + + return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM)); +} + +/// IsGlobalInSmallSection - Return true if this global address should be +/// placed into small data/bss section. +bool MipsTargetObjectFile:: +IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM, + SectionKind Kind) const { + // Only global variables, not functions. + const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV); + if (!GVA) + return false; + + // We can only do this for datarel or BSS objects for now. + if (!Kind.isBSS() && !Kind.isDataRel()) + return false; + + // If this is a internal constant string, there is a special + // section for it, but not in small data/bss. + if (Kind.isMergeable1ByteCString()) + return false; + + const Type *Ty = GV->getType()->getElementType(); + return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty)); +} + + + +const MCSection *MipsTargetObjectFile:: +SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const { + // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*" + // sections? + + // Handle Small Section classification here. + if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind)) + return SmallBSSSection; + if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind)) + return SmallDataSection; + + // Otherwise, we work the same as ELF. + return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM); +} |