mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-12 01:18:53 +00:00
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:
parent
9d957842e1
commit
ad4950258b
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(); }
|
||||
|
||||
|
@ -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" :
|
||||
|
@ -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.
|
||||
|
12
llvm/test/CodeGen/Mips/small-section-reserve-gp.ll
Normal file
12
llvm/test/CodeGen/Mips/small-section-reserve-gp.ll
Normal 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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user