Add register Mips::GP to the list of reserved registers if target is bare-metal

to prevent it from being clobbered. mips uses $gp to access small data section.

This bug was originally reported by Carl Norum.

llvm-svn: 162340
This commit is contained in:
Akira Hatanaka 2012-08-22 03:18:13 +00:00
parent 9d957842e1
commit ad4950258b
7 changed files with 34 additions and 7 deletions

View File

@ -1578,8 +1578,8 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op,
SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
MipsII::MO_GPREL);
SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, dl, VTs, &GA, 1);
SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32);
return DAG.getNode(ISD::ADD, dl, MVT::i32, GOT, GPRelNode);
SDValue GPReg = DAG.getRegister(Mips::GP, MVT::i32);
return DAG.getNode(ISD::ADD, dl, MVT::i32, GPReg, GPRelNode);
}
// %hi/%lo relocation
SDValue GAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,

View File

@ -131,6 +131,12 @@ getReservedRegs(const MachineFunction &MF) const {
Reserved.set(Mips::RA_64);
}
// Reserve GP if small section is used.
if (Subtarget.useSmallSection()) {
Reserved.set(Mips::GP);
Reserved.set(Mips::GP_64);
}
return Reserved;
}

View File

@ -25,7 +25,8 @@ using namespace llvm;
void MipsSubtarget::anchor() { }
MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,
const std::string &FS, bool little) :
const std::string &FS, bool little,
Reloc::Model RM) :
MipsGenSubtargetInfo(TT, CPU, FS),
MipsArchVersion(Mips32), MipsABI(UnknownABI), IsLittle(little),
IsSingleFloat(false), IsFP64bit(false), IsGP64bit(false), HasVFPU(false),
@ -54,6 +55,9 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,
// Is the target system Linux ?
if (TT.find("linux") == std::string::npos)
IsLinux = false;
// Set UseSmallSection.
UseSmallSection = !IsLinux && (RM == Reloc::Static);
}
bool

View File

@ -65,6 +65,9 @@ protected:
// isLinux - Target system is Linux. Is false we consider ELFOS for now.
bool IsLinux;
// UseSmallSection - Small section is used.
bool UseSmallSection;
/// Features related to the presence of specific instructions.
// HasSEInReg - SEB and SEH (signext in register) instructions.
@ -109,7 +112,7 @@ public:
/// This constructor initializes the data members to match that
/// of the specified triple.
MipsSubtarget(const std::string &TT, const std::string &CPU,
const std::string &FS, bool little);
const std::string &FS, bool little, Reloc::Model RM);
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
@ -133,6 +136,7 @@ public:
bool inMips16Mode() const { return InMips16Mode; }
bool isAndroid() const { return IsAndroid; }
bool isLinux() const { return IsLinux; }
bool useSmallSection() const { return UseSmallSection; }
bool hasStandardEncoding() const { return !inMips16Mode(); }

View File

@ -42,7 +42,7 @@ MipsTargetMachine(const Target &T, StringRef TT,
CodeGenOpt::Level OL,
bool isLittle)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS, isLittle),
Subtarget(TT, CPU, FS, isLittle, RM),
DataLayout(isLittle ?
(Subtarget.isABI_N64() ?
"e-p:64:64:64-i8:8:32-i16:16:32-i64:64:64-f128:128:128-n32" :

View File

@ -60,9 +60,10 @@ bool MipsTargetObjectFile::
IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
SectionKind Kind) const {
// Only use small section for non linux targets.
const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
if (Subtarget.isLinux())
// Return if small section is not available.
if (!Subtarget.useSmallSection())
return false;
// Only global variables, not functions.

View File

@ -0,0 +1,12 @@
; RUN: llc -mtriple=mipsel-sde-elf -march=mipsel -relocation-model=static < %s \
; RUN: | FileCheck %s
@i = internal unnamed_addr global i32 0, align 4
define i32 @geti() nounwind readonly {
entry:
; CHECK: addiu ${{[0-9]+}}, $gp, %gp_rel(i)
%0 = load i32* @i, align 4
ret i32 %0
}