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" 14287df1bc0309962770b6c176f2d143795dd3cc2fChris Lattner#include "llvm/MC/MCContext.h" 15a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/MC/MCSectionELF.h" 16a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Target/TargetData.h" 17a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Target/TargetMachine.h" 18a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Support/CommandLine.h" 19c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola#include "llvm/Support/ELF.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(); 73a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return IsInSmallSection(TM.getTargetData()->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