LLVM API Documentation
00001 //===-- MipsTargetObjectFile.cpp - Mips Object Files ----------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "MipsTargetObjectFile.h" 00011 #include "MipsSubtarget.h" 00012 #include "llvm/IR/DataLayout.h" 00013 #include "llvm/IR/DerivedTypes.h" 00014 #include "llvm/IR/GlobalVariable.h" 00015 #include "llvm/MC/MCContext.h" 00016 #include "llvm/MC/MCSectionELF.h" 00017 #include "llvm/Support/CommandLine.h" 00018 #include "llvm/Support/ELF.h" 00019 #include "llvm/Target/TargetMachine.h" 00020 using namespace llvm; 00021 00022 static cl::opt<unsigned> 00023 SSThreshold("mips-ssection-threshold", cl::Hidden, 00024 cl::desc("Small data and bss section threshold size (default=8)"), 00025 cl::init(8)); 00026 00027 void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ 00028 TargetLoweringObjectFileELF::Initialize(Ctx, TM); 00029 InitializeELF(TM.Options.UseInitArray); 00030 00031 SmallDataSection = 00032 getContext().getELFSection(".sdata", ELF::SHT_PROGBITS, 00033 ELF::SHF_WRITE |ELF::SHF_ALLOC, 00034 SectionKind::getDataRel()); 00035 00036 SmallBSSSection = 00037 getContext().getELFSection(".sbss", ELF::SHT_NOBITS, 00038 ELF::SHF_WRITE |ELF::SHF_ALLOC, 00039 SectionKind::getBSS()); 00040 } 00041 00042 // A address must be loaded from a small section if its size is less than the 00043 // small section size threshold. Data in this section must be addressed using 00044 // gp_rel operator. 00045 static bool IsInSmallSection(uint64_t Size) { 00046 return Size > 0 && Size <= SSThreshold; 00047 } 00048 00049 bool MipsTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV, 00050 const TargetMachine &TM) const { 00051 if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) 00052 return false; 00053 00054 return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM)); 00055 } 00056 00057 /// IsGlobalInSmallSection - Return true if this global address should be 00058 /// placed into small data/bss section. 00059 bool MipsTargetObjectFile:: 00060 IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM, 00061 SectionKind Kind) const { 00062 00063 const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); 00064 00065 // Return if small section is not available. 00066 if (!Subtarget.useSmallSection()) 00067 return false; 00068 00069 // Only global variables, not functions. 00070 const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV); 00071 if (!GVA) 00072 return false; 00073 00074 // We can only do this for datarel or BSS objects for now. 00075 if (!Kind.isBSS() && !Kind.isDataRel()) 00076 return false; 00077 00078 // If this is a internal constant string, there is a special 00079 // section for it, but not in small data/bss. 00080 if (Kind.isMergeable1ByteCString()) 00081 return false; 00082 00083 Type *Ty = GV->getType()->getElementType(); 00084 return IsInSmallSection( 00085 TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(Ty)); 00086 } 00087 00088 00089 00090 const MCSection *MipsTargetObjectFile:: 00091 SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, 00092 Mangler &Mang, const TargetMachine &TM) const { 00093 // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*" 00094 // sections? 00095 00096 // Handle Small Section classification here. 00097 if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind)) 00098 return SmallBSSSection; 00099 if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind)) 00100 return SmallDataSection; 00101 00102 // Otherwise, we work the same as ELF. 00103 return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM); 00104 }