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,
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;
}
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),
// Is the target system Linux ?
if (TT.find("linux") == std::string::npos)
IsLinux = false;
+
+ // Set UseSmallSection.
+ UseSmallSection = !IsLinux && (RM == Reloc::Static);
}
bool
// 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.
/// 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.
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(); }
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" :
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.
--- /dev/null
+; 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
+}
+