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"
120b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
130b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
140b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h"
15287df1bc0309962770b6c176f2d143795dd3cc2fChris Lattner#include "llvm/MC/MCContext.h"
16a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/MC/MCSectionELF.h"
17a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Support/CommandLine.h"
18c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola#include "llvm/Support/ELF.h"
19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h"
20a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckusing namespace llvm;
21a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
22a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckvoid MBlazeTargetObjectFile::
23a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckInitialize(MCContext &Ctx, const TargetMachine &TM) {
24a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  TargetLoweringObjectFileELF::Initialize(Ctx, TM);
25a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
26a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  SmallDataSection =
27c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola    getContext().getELFSection(".sdata", ELF::SHT_PROGBITS,
281c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola                               ELF::SHF_WRITE |ELF::SHF_ALLOC,
29287df1bc0309962770b6c176f2d143795dd3cc2fChris Lattner                               SectionKind::getDataRel());
30a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
31a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  SmallBSSSection =
32c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola    getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
331c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola                               ELF::SHF_WRITE |ELF::SHF_ALLOC,
34287df1bc0309962770b6c176f2d143795dd3cc2fChris Lattner                               SectionKind::getBSS());
35a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
36a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck}
37a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
38a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// A address must be loaded from a small section if its size is less than the
39a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// small section size threshold. Data in this section must be addressed using
40a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// gp_rel operator.
41a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckstatic bool IsInSmallSection(uint64_t Size) {
42a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  return Size > 0 && Size <= 8;
43a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck}
44a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
45a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckbool MBlazeTargetObjectFile::
46a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckIsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM) const {
47a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
48a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    return false;
49a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
50a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
51a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck}
52a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
53a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// IsGlobalInSmallSection - Return true if this global address should be
54a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// placed into small data/bss section.
55a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckbool MBlazeTargetObjectFile::
56a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckIsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
57a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck                       SectionKind Kind) const {
58a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  // Only global variables, not functions.
59a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
60a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  if (!GVA)
61a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    return false;
62a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
63a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  // We can only do this for datarel or BSS objects for now.
64a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  if (!Kind.isBSS() && !Kind.isDataRel())
65a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    return false;
66a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
67a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  // If this is a internal constant string, there is a special
68a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  // section for it, but not in small data/bss.
69a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  if (Kind.isMergeable1ByteCString())
70a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    return false;
71a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
72db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Ty = GV->getType()->getElementType();
733574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow  return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty));
74a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck}
75a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
76a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckconst MCSection *MBlazeTargetObjectFile::
77a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
78a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck                       Mangler *Mang, const TargetMachine &TM) const {
79a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*"
80a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  // sections?
81a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
82a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  // Handle Small Section classification here.
83a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind))
84a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    return SmallBSSSection;
85a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind))
86a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck    return SmallDataSection;
87a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck
88a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  // Otherwise, we work the same as ELF.
89a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck  return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM);
90a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck}
91