mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-15 05:24:01 +00:00
[mips] Add the following MIPS options that control gp-relative addressing of
small data items: -mgpopt, -mlocal-sdata, -mextern-sdata. Implement gp-relative addressing for constants. Differential Revision: http://reviews.llvm.org/D4903 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221450 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -24,6 +24,17 @@ SSThreshold("mips-ssection-threshold", cl::Hidden,
|
||||
cl::desc("Small data and bss section threshold size (default=8)"),
|
||||
cl::init(8));
|
||||
|
||||
static cl::opt<bool>
|
||||
LocalSData("mlocal-sdata", cl::Hidden,
|
||||
cl::desc("MIPS: Use gp_rel for object-local data."),
|
||||
cl::init(true));
|
||||
|
||||
static cl::opt<bool>
|
||||
ExternSData("mextern-sdata", cl::Hidden,
|
||||
cl::desc("MIPS: Use gp_rel for data that is not defined by the "
|
||||
"current object."),
|
||||
cl::init(true));
|
||||
|
||||
void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
|
||||
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
|
||||
InitializeELF(TM.Options.UseInitArray);
|
||||
@ -37,29 +48,46 @@ void MipsTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
|
||||
getContext().getELFSection(".sbss", ELF::SHT_NOBITS,
|
||||
ELF::SHF_WRITE |ELF::SHF_ALLOC,
|
||||
SectionKind::getBSS());
|
||||
this->TM = &TM;
|
||||
}
|
||||
|
||||
// A address must be loaded from a small section if its size is less than the
|
||||
// small section size threshold. Data in this section must be addressed using
|
||||
// gp_rel operator.
|
||||
static bool IsInSmallSection(uint64_t Size) {
|
||||
// gcc has traditionally not treated zero-sized objects as small data, so this
|
||||
// is effectively part of the ABI.
|
||||
return Size > 0 && Size <= SSThreshold;
|
||||
}
|
||||
|
||||
bool MipsTargetObjectFile::IsGlobalInSmallSection(const GlobalValue *GV,
|
||||
const TargetMachine &TM) const {
|
||||
/// Return true if this global address should be placed into small data/bss
|
||||
/// section.
|
||||
bool MipsTargetObjectFile::
|
||||
IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM) const {
|
||||
// We first check the case where global is a declaration, because finding
|
||||
// section kind using getKindForGlobal() is only allowed for global
|
||||
// definitions.
|
||||
if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage())
|
||||
return false;
|
||||
return IsGlobalInSmallSectionImpl(GV, TM);
|
||||
|
||||
return IsGlobalInSmallSection(GV, TM, getKindForGlobal(GV, TM));
|
||||
}
|
||||
|
||||
/// IsGlobalInSmallSection - Return true if this global address should be
|
||||
/// placed into small data/bss section.
|
||||
/// Return true if this global address should be placed into small data/bss
|
||||
/// section.
|
||||
bool MipsTargetObjectFile::
|
||||
IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
|
||||
SectionKind Kind) const {
|
||||
return (IsGlobalInSmallSectionImpl(GV, TM) &&
|
||||
(Kind.isDataRel() || Kind.isBSS() || Kind.isCommon()));
|
||||
}
|
||||
|
||||
/// Return true if this global address should be placed into small data/bss
|
||||
/// section. This method does all the work, except for checking the section
|
||||
/// kind.
|
||||
bool MipsTargetObjectFile::
|
||||
IsGlobalInSmallSectionImpl(const GlobalValue *GV,
|
||||
const TargetMachine &TM) const {
|
||||
const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
|
||||
|
||||
// Return if small section is not available.
|
||||
@ -71,13 +99,13 @@ IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
|
||||
if (!GVA)
|
||||
return false;
|
||||
|
||||
// We can only do this for datarel or BSS objects for now.
|
||||
if (!Kind.isBSS() && !Kind.isDataRel())
|
||||
// Enforce -mlocal-sdata.
|
||||
if (!LocalSData && GV->hasLocalLinkage())
|
||||
return false;
|
||||
|
||||
// If this is a internal constant string, there is a special
|
||||
// section for it, but not in small data/bss.
|
||||
if (Kind.isMergeable1ByteCString())
|
||||
// Enforce -mextern-sdata.
|
||||
if (!ExternSData && ((GV->hasExternalLinkage() && GV->isDeclaration()) ||
|
||||
GV->hasCommonLinkage()))
|
||||
return false;
|
||||
|
||||
Type *Ty = GV->getType()->getElementType();
|
||||
@ -85,8 +113,6 @@ IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
|
||||
TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(Ty));
|
||||
}
|
||||
|
||||
|
||||
|
||||
const MCSection *MipsTargetObjectFile::
|
||||
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
|
||||
Mangler &Mang, const TargetMachine &TM) const {
|
||||
@ -96,9 +122,27 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
|
||||
// Handle Small Section classification here.
|
||||
if (Kind.isBSS() && IsGlobalInSmallSection(GV, TM, Kind))
|
||||
return SmallBSSSection;
|
||||
if (Kind.isDataNoRel() && IsGlobalInSmallSection(GV, TM, Kind))
|
||||
if (Kind.isDataRel() && IsGlobalInSmallSection(GV, TM, Kind))
|
||||
return SmallDataSection;
|
||||
|
||||
// Otherwise, we work the same as ELF.
|
||||
return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang,TM);
|
||||
}
|
||||
|
||||
/// Return true if this constant should be placed into small data section.
|
||||
bool MipsTargetObjectFile::
|
||||
IsConstantInSmallSection(const Constant *CN, const TargetMachine &TM) const {
|
||||
return (TM.getSubtarget<MipsSubtarget>().useSmallSection() &&
|
||||
LocalSData &&
|
||||
IsInSmallSection(TM.getSubtargetImpl()->getDataLayout()
|
||||
->getTypeAllocSize(CN->getType())));
|
||||
}
|
||||
|
||||
const MCSection *MipsTargetObjectFile::
|
||||
getSectionForConstant(SectionKind Kind, const Constant *C) const {
|
||||
if (IsConstantInSmallSection(C, *TM))
|
||||
return SmallDataSection;
|
||||
|
||||
// Otherwise, we work the same as ELF.
|
||||
return TargetLoweringObjectFileELF::getSectionForConstant(Kind, C);
|
||||
}
|
||||
|
Reference in New Issue
Block a user