1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsTargetObjectFile.cpp - Mips Object Files ----------------------===//
2b71b909bc76f48377fc96547d53a088346852600Chris Lattner//
3b71b909bc76f48377fc96547d53a088346852600Chris Lattner//                     The LLVM Compiler Infrastructure
4b71b909bc76f48377fc96547d53a088346852600Chris Lattner//
5b71b909bc76f48377fc96547d53a088346852600Chris Lattner// This file is distributed under the University of Illinois Open Source
6b71b909bc76f48377fc96547d53a088346852600Chris Lattner// License. See LICENSE.TXT for details.
7b71b909bc76f48377fc96547d53a088346852600Chris Lattner//
84552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===//
9b71b909bc76f48377fc96547d53a088346852600Chris Lattner
10b71b909bc76f48377fc96547d53a088346852600Chris Lattner#include "MipsTargetObjectFile.h"
110046de0550f781b7739ffd5a6fe138cb306a1cf4Bruno Cardoso Lopes#include "MipsSubtarget.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"
16b71b909bc76f48377fc96547d53a088346852600Chris Lattner#include "llvm/MC/MCSectionELF.h"
17b71b909bc76f48377fc96547d53a088346852600Chris Lattner#include "llvm/Support/CommandLine.h"
18c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola#include "llvm/Support/ELF.h"
19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h"
20b71b909bc76f48377fc96547d53a088346852600Chris Lattnerusing namespace llvm;
21b71b909bc76f48377fc96547d53a088346852600Chris Lattner
22b71b909bc76f48377fc96547d53a088346852600Chris Lattnerstatic cl::opt<unsigned>
23b71b909bc76f48377fc96547d53a088346852600Chris LattnerSSThreshold("mips-ssection-threshold", cl::Hidden,
24b71b909bc76f48377fc96547d53a088346852600Chris Lattner            cl::desc("Small data and bss section threshold size (default=8)"),
25b71b909bc76f48377fc96547d53a088346852600Chris Lattner            cl::init(8));
26b71b909bc76f48377fc96547d53a088346852600Chris Lattner
27b71b909bc76f48377fc96547d53a088346852600Chris Lattnervoid MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
28b71b909bc76f48377fc96547d53a088346852600Chris Lattner  TargetLoweringObjectFileELF::Initialize(Ctx, TM);
29fd91d8dd7e18107b35c7332b92d636420517e3cbLogan Chien  InitializeELF(TM.Options.UseInitArray);
3036919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou
31b71b909bc76f48377fc96547d53a088346852600Chris Lattner  SmallDataSection =
32c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola    getContext().getELFSection(".sdata", ELF::SHT_PROGBITS,
331c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola                               ELF::SHF_WRITE |ELF::SHF_ALLOC,
34287df1bc0309962770b6c176f2d143795dd3cc2fChris Lattner                               SectionKind::getDataRel());
3536919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou
36b71b909bc76f48377fc96547d53a088346852600Chris Lattner  SmallBSSSection =
37c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola    getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
381c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola                               ELF::SHF_WRITE |ELF::SHF_ALLOC,
39287df1bc0309962770b6c176f2d143795dd3cc2fChris Lattner                               SectionKind::getBSS());
40b71b909bc76f48377fc96547d53a088346852600Chris Lattner}
41b71b909bc76f48377fc96547d53a088346852600Chris Lattner
4236919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou// A address must be loaded from a small section if its size is less than the
4336919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou// small section size threshold. Data in this section must be addressed using
44b71b909bc76f48377fc96547d53a088346852600Chris Lattner// gp_rel operator.
45b71b909bc76f48377fc96547d53a088346852600Chris Lattnerstatic bool IsInSmallSection(uint64_t Size) {
46b71b909bc76f48377fc96547d53a088346852600Chris Lattner  return Size > 0 && Size <= SSThreshold;
47b71b909bc76f48377fc96547d53a088346852600Chris Lattner}
48b71b909bc76f48377fc96547d53a088346852600Chris Lattner
49b71b909bc76f48377fc96547d53a088346852600Chris Lattnerbool MipsTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV,
504552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka                                                const TargetMachine &TM) const {
51b71b909bc76f48377fc96547d53a088346852600Chris Lattner  if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
52b71b909bc76f48377fc96547d53a088346852600Chris Lattner    return false;
5336919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou
54b71b909bc76f48377fc96547d53a088346852600Chris Lattner  return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
55b71b909bc76f48377fc96547d53a088346852600Chris Lattner}
56b71b909bc76f48377fc96547d53a088346852600Chris Lattner
57b71b909bc76f48377fc96547d53a088346852600Chris Lattner/// IsGlobalInSmallSection - Return true if this global address should be
58b71b909bc76f48377fc96547d53a088346852600Chris Lattner/// placed into small data/bss section.
59b71b909bc76f48377fc96547d53a088346852600Chris Lattnerbool MipsTargetObjectFile::
60b71b909bc76f48377fc96547d53a088346852600Chris LattnerIsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
61b71b909bc76f48377fc96547d53a088346852600Chris Lattner                       SectionKind Kind) const {
620046de0550f781b7739ffd5a6fe138cb306a1cf4Bruno Cardoso Lopes
630046de0550f781b7739ffd5a6fe138cb306a1cf4Bruno Cardoso Lopes  const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
64e7338cd550a4ccde6796d2987b482ea9f0e239efAkira Hatanaka
65e7338cd550a4ccde6796d2987b482ea9f0e239efAkira Hatanaka  // Return if small section is not available.
66e7338cd550a4ccde6796d2987b482ea9f0e239efAkira Hatanaka  if (!Subtarget.useSmallSection())
670046de0550f781b7739ffd5a6fe138cb306a1cf4Bruno Cardoso Lopes    return false;
680046de0550f781b7739ffd5a6fe138cb306a1cf4Bruno Cardoso Lopes
69b71b909bc76f48377fc96547d53a088346852600Chris Lattner  // Only global variables, not functions.
70b71b909bc76f48377fc96547d53a088346852600Chris Lattner  const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV);
71b71b909bc76f48377fc96547d53a088346852600Chris Lattner  if (!GVA)
72b71b909bc76f48377fc96547d53a088346852600Chris Lattner    return false;
7336919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou
74b71b909bc76f48377fc96547d53a088346852600Chris Lattner  // We can only do this for datarel or BSS objects for now.
75b71b909bc76f48377fc96547d53a088346852600Chris Lattner  if (!Kind.isBSS() && !Kind.isDataRel())
76b71b909bc76f48377fc96547d53a088346852600Chris Lattner    return false;
7736919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou
78b71b909bc76f48377fc96547d53a088346852600Chris Lattner  // If this is a internal constant string, there is a special
79b71b909bc76f48377fc96547d53a088346852600Chris Lattner  // section for it, but not in small data/bss.
80b71b909bc76f48377fc96547d53a088346852600Chris Lattner  if (Kind.isMergeable1ByteCString())
81b71b909bc76f48377fc96547d53a088346852600Chris Lattner    return false;
82b71b909bc76f48377fc96547d53a088346852600Chris Lattner
83db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Ty = GV->getType()->getElementType();
843574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow  return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty));
85b71b909bc76f48377fc96547d53a088346852600Chris Lattner}
86b71b909bc76f48377fc96547d53a088346852600Chris Lattner
87b71b909bc76f48377fc96547d53a088346852600Chris Lattner
88b71b909bc76f48377fc96547d53a088346852600Chris Lattner
89b71b909bc76f48377fc96547d53a088346852600Chris Lattnerconst MCSection *MipsTargetObjectFile::
90b71b909bc76f48377fc96547d53a088346852600Chris LattnerSelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       Mangler &Mang, const TargetMachine &TM) const {
92b71b909bc76f48377fc96547d53a088346852600Chris Lattner  // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*"
93b71b909bc76f48377fc96547d53a088346852600Chris Lattner  // sections?
9436919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou
95b71b909bc76f48377fc96547d53a088346852600Chris Lattner  // Handle Small Section classification here.
96b71b909bc76f48377fc96547d53a088346852600Chris Lattner  if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind))
97b71b909bc76f48377fc96547d53a088346852600Chris Lattner    return SmallBSSSection;
98b71b909bc76f48377fc96547d53a088346852600Chris Lattner  if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind))
99b71b909bc76f48377fc96547d53a088346852600Chris Lattner    return SmallDataSection;
10036919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou
101b71b909bc76f48377fc96547d53a088346852600Chris Lattner  // Otherwise, we work the same as ELF.
1024552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka  return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM);
103b71b909bc76f48377fc96547d53a088346852600Chris Lattner}
104