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