1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- MBlazeTargetObjectFile.cpp - MBlaze object files ------------------===//
2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//                     The LLVM Compiler Infrastructure
4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source
6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details.
7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//
8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===//
9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "MBlazeTargetObjectFile.h"
11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "MBlazeSubtarget.h"
12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/DerivedTypes.h"
13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/GlobalVariable.h"
14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCContext.h"
15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/MC/MCSectionELF.h"
16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetData.h"
17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetMachine.h"
18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/CommandLine.h"
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ELF.h"
20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm;
21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid MBlazeTargetObjectFile::
23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanInitialize(MCContext &Ctx, const TargetMachine &TM) {
24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  TargetLoweringObjectFileELF::Initialize(Ctx, TM);
25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SmallDataSection =
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getContext().getELFSection(".sdata", ELF::SHT_PROGBITS,
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               ELF::SHF_WRITE |ELF::SHF_ALLOC,
29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               SectionKind::getDataRel());
30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  SmallBSSSection =
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               ELF::SHF_WRITE |ELF::SHF_ALLOC,
34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                               SectionKind::getBSS());
35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// A address must be loaded from a small section if its size is less than the
39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// small section size threshold. Data in this section must be addressed using
40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// gp_rel operator.
41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic bool IsInSmallSection(uint64_t Size) {
42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return Size > 0 && Size <= 8;
43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool MBlazeTargetObjectFile::
46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanIsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM) const {
47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// IsGlobalInSmallSection - Return true if this global address should be
54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// placed into small data/bss section.
55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool MBlazeTargetObjectFile::
56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanIsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       SectionKind Kind) const {
58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Only global variables, not functions.
59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!GVA)
61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // We can only do this for datarel or BSS objects for now.
64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (!Kind.isBSS() && !Kind.isDataRel())
65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // If this is a internal constant string, there is a special
68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // section for it, but not in small data/bss.
69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Kind.isMergeable1ByteCString())
70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return false;
71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Type *Ty = GV->getType()->getElementType();
73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return IsInSmallSection(TM.getTargetData()->getTypeAllocSize(Ty));
74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanconst MCSection *MBlazeTargetObjectFile::
77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman                       Mangler *Mang, const TargetMachine &TM) const {
79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*"
80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // sections?
81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Handle Small Section classification here.
83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind))
84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return SmallBSSSection;
85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind))
86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman    return SmallDataSection;
87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman
88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  // Otherwise, we work the same as ELF.
89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman  return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM);
90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}
91