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" 124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "MipsTargetMachine.h" 130b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 140b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 150b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h" 16287df1bc0309962770b6c176f2d143795dd3cc2fChris Lattner#include "llvm/MC/MCContext.h" 17b71b909bc76f48377fc96547d53a088346852600Chris Lattner#include "llvm/MC/MCSectionELF.h" 18b71b909bc76f48377fc96547d53a088346852600Chris Lattner#include "llvm/Support/CommandLine.h" 19c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola#include "llvm/Support/ELF.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h" 21b71b909bc76f48377fc96547d53a088346852600Chris Lattnerusing namespace llvm; 22b71b909bc76f48377fc96547d53a088346852600Chris Lattner 23b71b909bc76f48377fc96547d53a088346852600Chris Lattnerstatic cl::opt<unsigned> 24b71b909bc76f48377fc96547d53a088346852600Chris LattnerSSThreshold("mips-ssection-threshold", cl::Hidden, 25b71b909bc76f48377fc96547d53a088346852600Chris Lattner cl::desc("Small data and bss section threshold size (default=8)"), 26b71b909bc76f48377fc96547d53a088346852600Chris Lattner cl::init(8)); 27b71b909bc76f48377fc96547d53a088346852600Chris Lattner 2837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<bool> 2937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesLocalSData("mlocal-sdata", cl::Hidden, 3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("MIPS: Use gp_rel for object-local data."), 3137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::init(true)); 3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 3337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<bool> 3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesExternSData("mextern-sdata", cl::Hidden, 3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("MIPS: Use gp_rel for data that is not defined by the " 3637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "current object."), 3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::init(true)); 3837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 39b71b909bc76f48377fc96547d53a088346852600Chris Lattnervoid MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ 40b71b909bc76f48377fc96547d53a088346852600Chris Lattner TargetLoweringObjectFileELF::Initialize(Ctx, TM); 41fd91d8dd7e18107b35c7332b92d636420517e3cbLogan Chien InitializeELF(TM.Options.UseInitArray); 4236919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou 43ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallDataSection = getContext().getELFSection( 44ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ".sdata", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 45ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 46ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallBSSSection = getContext().getELFSection(".sbss", ELF::SHT_NOBITS, 47ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ELF::SHF_WRITE | ELF::SHF_ALLOC); 484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar this->TM = &static_cast<const MipsTargetMachine &>(TM); 49b71b909bc76f48377fc96547d53a088346852600Chris Lattner} 50b71b909bc76f48377fc96547d53a088346852600Chris Lattner 5136919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou// A address must be loaded from a small section if its size is less than the 5236919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou// small section size threshold. Data in this section must be addressed using 53b71b909bc76f48377fc96547d53a088346852600Chris Lattner// gp_rel operator. 54b71b909bc76f48377fc96547d53a088346852600Chris Lattnerstatic bool IsInSmallSection(uint64_t Size) { 5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // gcc has traditionally not treated zero-sized objects as small data, so this 5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // is effectively part of the ABI. 57b71b909bc76f48377fc96547d53a088346852600Chris Lattner return Size > 0 && Size <= SSThreshold; 58b71b909bc76f48377fc96547d53a088346852600Chris Lattner} 59b71b909bc76f48377fc96547d53a088346852600Chris Lattner 6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Return true if this global address should be placed into small data/bss 6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// section. 6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsTargetObjectFile:: 6337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesIsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM) const { 6437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // We first check the case where global is a declaration, because finding 6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // section kind using getKindForGlobal() is only allowed for global 6637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // definitions. 67b71b909bc76f48377fc96547d53a088346852600Chris Lattner if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) 6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return IsGlobalInSmallSectionImpl(GV, TM); 6936919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou 70b71b909bc76f48377fc96547d53a088346852600Chris Lattner return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM)); 71b71b909bc76f48377fc96547d53a088346852600Chris Lattner} 72b71b909bc76f48377fc96547d53a088346852600Chris Lattner 7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Return true if this global address should be placed into small data/bss 7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// section. 75b71b909bc76f48377fc96547d53a088346852600Chris Lattnerbool MipsTargetObjectFile:: 76b71b909bc76f48377fc96547d53a088346852600Chris LattnerIsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM, 77b71b909bc76f48377fc96547d53a088346852600Chris Lattner SectionKind Kind) const { 7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return (IsGlobalInSmallSectionImpl(GV, TM) && 79cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar (Kind.isData() || Kind.isBSS() || Kind.isCommon())); 8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 810046de0550f781b7739ffd5a6fe138cb306a1cf4Bruno Cardoso Lopes 8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Return true if this global address should be placed into small data/bss 8337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// section. This method does all the work, except for checking the section 8437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// kind. 8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsTargetObjectFile:: 8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesIsGlobalInSmallSectionImpl(const GlobalValue *GV, 8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const TargetMachine &TM) const { 884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const MipsSubtarget &Subtarget = 894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar *static_cast<const MipsTargetMachine &>(TM).getSubtargetImpl(); 90e7338cd550a4ccde6796d2987b482ea9f0e239efAkira Hatanaka 91e7338cd550a4ccde6796d2987b482ea9f0e239efAkira Hatanaka // Return if small section is not available. 92e7338cd550a4ccde6796d2987b482ea9f0e239efAkira Hatanaka if (!Subtarget.useSmallSection()) 930046de0550f781b7739ffd5a6fe138cb306a1cf4Bruno Cardoso Lopes return false; 940046de0550f781b7739ffd5a6fe138cb306a1cf4Bruno Cardoso Lopes 95b71b909bc76f48377fc96547d53a088346852600Chris Lattner // Only global variables, not functions. 96b71b909bc76f48377fc96547d53a088346852600Chris Lattner const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV); 97b71b909bc76f48377fc96547d53a088346852600Chris Lattner if (!GVA) 98b71b909bc76f48377fc96547d53a088346852600Chris Lattner return false; 9936919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou 10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Enforce -mlocal-sdata. 10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!LocalSData && GV->hasLocalLinkage()) 102b71b909bc76f48377fc96547d53a088346852600Chris Lattner return false; 10336919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou 10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Enforce -mextern-sdata. 10537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (!ExternSData && ((GV->hasExternalLinkage() && GV->isDeclaration()) || 10637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines GV->hasCommonLinkage())) 107b71b909bc76f48377fc96547d53a088346852600Chris Lattner return false; 108b71b909bc76f48377fc96547d53a088346852600Chris Lattner 109db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty = GV->getType()->getElementType(); 110cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return IsInSmallSection( 111cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar GV->getParent()->getDataLayout().getTypeAllocSize(Ty)); 112b71b909bc76f48377fc96547d53a088346852600Chris Lattner} 113b71b909bc76f48377fc96547d53a088346852600Chris Lattner 1146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarMCSection * 1156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarMipsTargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV, 1166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionKind Kind, Mangler &Mang, 1176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const TargetMachine &TM) const { 118b71b909bc76f48377fc96547d53a088346852600Chris Lattner // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*" 119b71b909bc76f48377fc96547d53a088346852600Chris Lattner // sections? 12036919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou 121b71b909bc76f48377fc96547d53a088346852600Chris Lattner // Handle Small Section classification here. 122b71b909bc76f48377fc96547d53a088346852600Chris Lattner if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind)) 123b71b909bc76f48377fc96547d53a088346852600Chris Lattner return SmallBSSSection; 124cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Kind.isData() && IsGlobalInSmallSection(GV, TM, Kind)) 125b71b909bc76f48377fc96547d53a088346852600Chris Lattner return SmallDataSection; 12636919ac8a57a691f07129bb903fe32ae182b68c2Che-Liang Chiou 127b71b909bc76f48377fc96547d53a088346852600Chris Lattner // Otherwise, we work the same as ELF. 1284552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM); 129b71b909bc76f48377fc96547d53a088346852600Chris Lattner} 13037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Return true if this constant should be placed into small data section. 132cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarbool MipsTargetObjectFile::IsConstantInSmallSection( 133cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const DataLayout &DL, const Constant *CN, const TargetMachine &TM) const { 1344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return (static_cast<const MipsTargetMachine &>(TM) 1354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar .getSubtargetImpl() 1364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ->useSmallSection() && 137cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar LocalSData && IsInSmallSection(DL.getTypeAllocSize(CN->getType()))); 13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 140cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// Return true if this constant should be placed into small data section. 141cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarMCSection *MipsTargetObjectFile::getSectionForConstant( 142cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const DataLayout &DL, SectionKind Kind, const Constant *C) const { 143cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (IsConstantInSmallSection(DL, C, *TM)) 14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return SmallDataSection; 14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 14637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Otherwise, we work the same as ELF. 147cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return TargetLoweringObjectFileELF::getSectionForConstant(DL, Kind, C); 14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 149