mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-28 22:24:28 +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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162340 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -1578,8 +1578,8 @@ SDValue MipsTargetLowering::LowerGlobalAddress(SDValue Op,
|
|||||||
SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
|
SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
|
||||||
MipsII::MO_GPREL);
|
MipsII::MO_GPREL);
|
||||||
SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, dl, VTs, &GA, 1);
|
SDValue GPRelNode = DAG.getNode(MipsISD::GPRel, dl, VTs, &GA, 1);
|
||||||
SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(MVT::i32);
|
SDValue GPReg = DAG.getRegister(Mips::GP, MVT::i32);
|
||||||
return DAG.getNode(ISD::ADD, dl, MVT::i32, GOT, GPRelNode);
|
return DAG.getNode(ISD::ADD, dl, MVT::i32, GPReg, GPRelNode);
|
||||||
}
|
}
|
||||||
// %hi/%lo relocation
|
// %hi/%lo relocation
|
||||||
SDValue GAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
|
SDValue GAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
|
||||||
|
@ -131,6 +131,12 @@ getReservedRegs(const MachineFunction &MF) const {
|
|||||||
Reserved.set(Mips::RA_64);
|
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;
|
return Reserved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@ using namespace llvm;
|
|||||||
void MipsSubtarget::anchor() { }
|
void MipsSubtarget::anchor() { }
|
||||||
|
|
||||||
MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,
|
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),
|
MipsGenSubtargetInfo(TT, CPU, FS),
|
||||||
MipsArchVersion(Mips32), MipsABI(UnknownABI), IsLittle(little),
|
MipsArchVersion(Mips32), MipsABI(UnknownABI), IsLittle(little),
|
||||||
IsSingleFloat(false), IsFP64bit(false), IsGP64bit(false), HasVFPU(false),
|
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 ?
|
// Is the target system Linux ?
|
||||||
if (TT.find("linux") == std::string::npos)
|
if (TT.find("linux") == std::string::npos)
|
||||||
IsLinux = false;
|
IsLinux = false;
|
||||||
|
|
||||||
|
// Set UseSmallSection.
|
||||||
|
UseSmallSection = !IsLinux && (RM == Reloc::Static);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -65,6 +65,9 @@ protected:
|
|||||||
// isLinux - Target system is Linux. Is false we consider ELFOS for now.
|
// isLinux - Target system is Linux. Is false we consider ELFOS for now.
|
||||||
bool IsLinux;
|
bool IsLinux;
|
||||||
|
|
||||||
|
// UseSmallSection - Small section is used.
|
||||||
|
bool UseSmallSection;
|
||||||
|
|
||||||
/// Features related to the presence of specific instructions.
|
/// Features related to the presence of specific instructions.
|
||||||
|
|
||||||
// HasSEInReg - SEB and SEH (signext in register) instructions.
|
// HasSEInReg - SEB and SEH (signext in register) instructions.
|
||||||
@ -109,7 +112,7 @@ public:
|
|||||||
/// This constructor initializes the data members to match that
|
/// This constructor initializes the data members to match that
|
||||||
/// of the specified triple.
|
/// of the specified triple.
|
||||||
MipsSubtarget(const std::string &TT, const std::string &CPU,
|
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
|
/// ParseSubtargetFeatures - Parses features string setting specified
|
||||||
/// subtarget options. Definition of function is auto generated by tblgen.
|
/// subtarget options. Definition of function is auto generated by tblgen.
|
||||||
@ -133,6 +136,7 @@ public:
|
|||||||
bool inMips16Mode() const { return InMips16Mode; }
|
bool inMips16Mode() const { return InMips16Mode; }
|
||||||
bool isAndroid() const { return IsAndroid; }
|
bool isAndroid() const { return IsAndroid; }
|
||||||
bool isLinux() const { return IsLinux; }
|
bool isLinux() const { return IsLinux; }
|
||||||
|
bool useSmallSection() const { return UseSmallSection; }
|
||||||
|
|
||||||
bool hasStandardEncoding() const { return !inMips16Mode(); }
|
bool hasStandardEncoding() const { return !inMips16Mode(); }
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ MipsTargetMachine(const Target &T, StringRef TT,
|
|||||||
CodeGenOpt::Level OL,
|
CodeGenOpt::Level OL,
|
||||||
bool isLittle)
|
bool isLittle)
|
||||||
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
|
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
|
||||||
Subtarget(TT, CPU, FS, isLittle),
|
Subtarget(TT, CPU, FS, isLittle, RM),
|
||||||
DataLayout(isLittle ?
|
DataLayout(isLittle ?
|
||||||
(Subtarget.isABI_N64() ?
|
(Subtarget.isABI_N64() ?
|
||||||
"e-p:64:64:64-i8:8:32-i16:16:32-i64:64:64-f128:128:128-n32" :
|
"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,
|
IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
|
||||||
SectionKind Kind) const {
|
SectionKind Kind) const {
|
||||||
|
|
||||||
// Only use small section for non linux targets.
|
|
||||||
const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
|
const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
|
||||||
if (Subtarget.isLinux())
|
|
||||||
|
// Return if small section is not available.
|
||||||
|
if (!Subtarget.useSmallSection())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Only global variables, not functions.
|
// Only global variables, not functions.
|
||||||
|
12
test/CodeGen/Mips/small-section-reserve-gp.ll
Normal file
12
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
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user