blob: 05c01ef7a5d9b40bce059421bff5d0df46da2930 [file] [log] [blame]
Wesley Pecka70f28c2010-02-23 19:15:24 +00001//===-- MBlazeTargetObjectFile.cpp - MBlaze object files ------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MBlazeTargetObjectFile.h"
11#include "MBlazeSubtarget.h"
12#include "llvm/DerivedTypes.h"
13#include "llvm/GlobalVariable.h"
Chris Lattner287df1b2010-04-08 21:34:17 +000014#include "llvm/MC/MCContext.h"
Wesley Pecka70f28c2010-02-23 19:15:24 +000015#include "llvm/MC/MCSectionELF.h"
16#include "llvm/Target/TargetData.h"
17#include "llvm/Target/TargetMachine.h"
18#include "llvm/Support/CommandLine.h"
19using namespace llvm;
20
21void MBlazeTargetObjectFile::
22Initialize(MCContext &Ctx, const TargetMachine &TM) {
23 TargetLoweringObjectFileELF::Initialize(Ctx, TM);
24
25 SmallDataSection =
Chris Lattner287df1b2010-04-08 21:34:17 +000026 getContext().getELFSection(".sdata", MCSectionELF::SHT_PROGBITS,
27 MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
28 SectionKind::getDataRel());
Wesley Pecka70f28c2010-02-23 19:15:24 +000029
30 SmallBSSSection =
Chris Lattner287df1b2010-04-08 21:34:17 +000031 getContext().getELFSection(".sbss", MCSectionELF::SHT_NOBITS,
32 MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
33 SectionKind::getBSS());
Wesley Pecka70f28c2010-02-23 19:15:24 +000034
35}
36
37// A address must be loaded from a small section if its size is less than the
38// small section size threshold. Data in this section must be addressed using
39// gp_rel operator.
40static bool IsInSmallSection(uint64_t Size) {
41 return Size > 0 && Size <= 8;
42}
43
44bool MBlazeTargetObjectFile::
45IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM) const {
46 if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
47 return false;
48
49 return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
50}
51
52/// IsGlobalInSmallSection - Return true if this global address should be
53/// placed into small data/bss section.
54bool MBlazeTargetObjectFile::
55IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
56 SectionKind Kind) const {
57 // Only global variables, not functions.
58 const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
59 if (!GVA)
60 return false;
61
62 // We can only do this for datarel or BSS objects for now.
63 if (!Kind.isBSS() && !Kind.isDataRel())
64 return false;
65
66 // If this is a internal constant string, there is a special
67 // section for it, but not in small data/bss.
68 if (Kind.isMergeable1ByteCString())
69 return false;
70
71 const Type *Ty = GV->getType()->getElementType();
72 return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty));
73}
74
75const MCSection *MBlazeTargetObjectFile::
76SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
77 Mangler *Mang, const TargetMachine &TM) const {
78 // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*"
79 // sections?
80
81 // Handle Small Section classification here.
82 if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind))
83 return SmallBSSSection;
84 if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind))
85 return SmallDataSection;
86
87 // Otherwise, we work the same as ELF.
88 return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM);
89}