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 // Register info information 00042 const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); 00043 if (Subtarget.isABI_N64() || Subtarget.isABI_N32()) 00044 ReginfoSection = 00045 getContext().getELFSection(".MIPS.options", 00046 ELF::SHT_MIPS_OPTIONS, 00047 ELF::SHF_ALLOC |ELF::SHF_MIPS_NOSTRIP, 00048 SectionKind::getMetadata()); 00049 else 00050 ReginfoSection = 00051 getContext().getELFSection(".reginfo", 00052 ELF::SHT_MIPS_REGINFO, 00053 ELF::SHF_ALLOC, 00054 SectionKind::getMetadata()); 00055 } 00056 00057 // A address must be loaded from a small section if its size is less than the 00058 // small section size threshold. Data in this section must be addressed using 00059 // gp_rel operator. 00060 static bool IsInSmallSection(uint64_t Size) { 00061 return Size > 0 && Size <= SSThreshold; 00062 } 00063 00064 bool MipsTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV, 00065 const TargetMachine &TM) const { 00066 if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) 00067 return false; 00068 00069 return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM)); 00070 } 00071 00072 /// IsGlobalInSmallSection - Return true if this global address should be 00073 /// placed into small data/bss section. 00074 bool MipsTargetObjectFile:: 00075 IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM, 00076 SectionKind Kind) const { 00077 00078 const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>(); 00079 00080 // Return if small section is not available. 00081 if (!Subtarget.useSmallSection()) 00082 return false; 00083 00084 // Only global variables, not functions. 00085 const GlobalVariable *GVA = dyn_cast<GlobalVariable>(GV); 00086 if (!GVA) 00087 return false; 00088 00089 // We can only do this for datarel or BSS objects for now. 00090 if (!Kind.isBSS() && !Kind.isDataRel()) 00091 return false; 00092 00093 // If this is a internal constant string, there is a special 00094 // section for it, but not in small data/bss. 00095 if (Kind.isMergeable1ByteCString()) 00096 return false; 00097 00098 Type *Ty = GV->getType()->getElementType(); 00099 return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty)); 00100 } 00101 00102 00103 00104 const MCSection *MipsTargetObjectFile:: 00105 SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, 00106 Mangler *Mang, const TargetMachine &TM) const { 00107 // TODO: Could also support "weak" symbols as well with ".gnu.linkonce.s.*" 00108 // sections? 00109 00110 // Handle Small Section classification here. 00111 if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind)) 00112 return SmallBSSSection; 00113 if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind)) 00114 return SmallDataSection; 00115 00116 // Otherwise, we work the same as ELF. 00117 return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM); 00118 }