"ignoring '-mabicalls' option as it cannot be used with "
"non position-independent code and the N64 ABI">,
InGroup<OptionIgnored>;
+def err_drv_unsupported_indirect_jump_opt : Error<
+ "'-mindirect-jump=%0' is unsupported with the '%1' architecture">;
+def err_drv_unknown_indirect_jump_opt : Error<
+ "unknown '-mindirect-jump=' option '%0'">;
def warn_drv_unable_to_find_directory_expected : Warning<
"unable to find %0 directory, expected to be in '%1'">,
IgnoredGCCCompat;
def mno_branch_likely : Flag<["-"], "mno-branch-likely">, Group<m_Group>,
IgnoredGCCCompat;
+def mindirect_jump_EQ : Joined<["-"], "mindirect-jump=">,
+ Group<m_Group>,
+ HelpText<"Change indirect jump instructions to inhibit speculation">;
def mdsp : Flag<["-"], "mdsp">, Group<m_Group>;
def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_Group>;
def mdspr2 : Flag<["-"], "mdspr2">, Group<m_Group>;
enum DspRevEnum { NoDSP, DSP1, DSP2 } DspRev;
bool HasMSA;
bool DisableMadd4;
+ bool UseIndirectJumpHazard;
protected:
bool HasFP64;
: TargetInfo(Triple), IsMips16(false), IsMicromips(false),
IsNan2008(false), IsAbs2008(false), IsSingleFloat(false),
IsNoABICalls(false), CanUseBSDABICalls(false), FloatABI(HardFloat),
- DspRev(NoDSP), HasMSA(false), DisableMadd4(false), HasFP64(false) {
+ DspRev(NoDSP), HasMSA(false), DisableMadd4(false),
+ UseIndirectJumpHazard(false), HasFP64(false) {
TheCXXABI.set(TargetCXXABI::GenericMIPS);
setABI((getTriple().getArch() == llvm::Triple::mips ||
IsAbs2008 = false;
else if (Feature == "+noabicalls")
IsNoABICalls = true;
+ else if (Feature == "+use-indirect-jump-hazard")
+ UseIndirectJumpHazard = true;
}
setDataLayout();
AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4,
"nomadd4");
AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt, "mt");
+
+ if (Arg *A = Args.getLastArg(options::OPT_mindirect_jump_EQ)) {
+ StringRef Val = StringRef(A->getValue());
+ if (Val == "hazard") {
+ Arg *B =
+ Args.getLastArg(options::OPT_mmicromips, options::OPT_mno_micromips);
+ Arg *C = Args.getLastArg(options::OPT_mips16, options::OPT_mno_mips16);
+
+ if (B && B->getOption().matches(options::OPT_mmicromips))
+ D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
+ << "hazard" << "micromips";
+ else if (C && C->getOption().matches(options::OPT_mips16))
+ D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
+ << "hazard" << "mips16";
+ else if (mips::supportsIndirectJumpHazardBarrier(CPUName))
+ Features.push_back("+use-indirect-jump-hazard");
+ else
+ D.Diag(diag::err_drv_unsupported_indirect_jump_opt)
+ << "hazard" << CPUName;
+ } else
+ D.Diag(diag::err_drv_unknown_indirect_jump_opt) << Val;
+ }
}
mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) {
return UseFPXX;
}
+
+bool mips::supportsIndirectJumpHazardBarrier(StringRef &CPU) {
+ // Supporting the hazard barrier method of dealing with indirect
+ // jumps requires MIPSR2 support.
+ return llvm::StringSwitch<bool>(CPU)
+ .Case("mips32r2", true)
+ .Case("mips32r3", true)
+ .Case("mips32r5", true)
+ .Case("mips32r6", true)
+ .Case("mips64r2", true)
+ .Case("mips64r3", true)
+ .Case("mips64r5", true)
+ .Case("mips64r6", true)
+ .Case("octeon", true)
+ .Case("p5600", true)
+ .Default(false);
+}
bool shouldUseFPXX(const llvm::opt::ArgList &Args, const llvm::Triple &Triple,
StringRef CPUName, StringRef ABIName,
mips::FloatABI FloatABI);
+bool supportsIndirectJumpHazardBarrier(StringRef &CPU);
} // end namespace mips
} // end namespace target
// RUN: %clang -target -mips-mti-linux-gnu -### -c %s -mno-branch-likely 2>&1 \
// RUN: | FileCheck --check-prefix=NO-BRANCH-LIKELY %s
// NO-BRANCH-LIKELY: argument unused during compilation: '-mno-branch-likely'
+
+// -mindirect-jump=hazard
+// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \
+// RUN: -mindirect-jump=hazard 2>&1 \
+// RUN: | FileCheck --check-prefix=INDIRECT-BH %s
+// INDIRECT-BH: "-target-feature" "+use-indirect-jump-hazard"
--- /dev/null
+// REQUIRES: mips-registered-target
+// -mindirect-jump=hazard -mips32
+// RUN: %clang -target mips-unknown-linux-gnu -mips32 -### -c %s \
+// RUN: -mindirect-jump=hazard 2>&1 | FileCheck %s --check-prefix=MIPS32
+// MIPS32: error: '-mindirect-jump=hazard' is unsupported with the 'mips32' architecture
+
+// -mindirect-jump=hazard -mmicromips
+// RUN: %clang -target mips-unknown-linux-gnu -mmicromips -### -c %s \
+// RUN: -mindirect-jump=hazard 2>&1 | FileCheck %s --check-prefix=MICROMIPS
+// MICROMIPS: error: '-mindirect-jump=hazard' is unsupported with the 'micromips' architecture
+
+// -mindirect-jump=hazard -mips16
+// RUN: %clang -target mips-unknown-linux-gnu -mips16 -### -c %s \
+// RUN: -mindirect-jump=hazard 2>&1 | FileCheck %s --check-prefix=MIPS16
+// MIPS16: error: '-mindirect-jump=hazard' is unsupported with the 'mips16' architecture
+
+// RUN: %clang -target mips-unknown-linux-gnu -### -c %s \
+// RUN: -mindirect-jump=retopline 2>&1 | FileCheck %s --check-prefix=RETOPLINE
+// RETOPLINE: error: unknown '-mindirect-jump=' option 'retopline'
+
+// RUN: %clang -target mips-unknown-linux-gnu -### -mips32 -c %s \
+// RUN: -mindirect-jump=retopline 2>&1 | FileCheck %s --check-prefix=MIXED
+// MIXED: error: unknown '-mindirect-jump=' option 'retopline'