[mips] Correct the invocation of GAS in several cases.
Summary:
As a result of this patch, assembling an empty file with GCC and Clang (using
GAS as the assembler) now produces identical objects.
-mfp32/-mfpxx/-mfp64 now form a trinity of options. -mfpxx is the default
when the triple vendor is 'img' or 'mti', the ABI is O32, and the CPU is
between mips2 and mips32r2/mips64r2 (inclusive).
-mno-shared is always given to the assembler to match the effect of
-mabicalls (currently unimplemented but Clang acts as if it is given).
Similarly, -call_nonpic is always given to match the effect of -mplt (also
unimplemented and acts as if given) except when the ABI is 64 in which case
-mplt has no effect so -KPIC is given instead.
-mhard-float/-msoft-float are now passed on.
-modd-spreg/-mno-odd-spreg are now passed on.
-mno-mips16 is correctly passed on. The assembler option is -no-mips16 not
-mno-mips16
Differential Revision: http://reviews.llvm.org/D4515
llvm-svn: 213138
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index b66d78a..fac656d 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -1023,8 +1023,14 @@
}
}
-static void getMIPSTargetFeatures(const Driver &D, const ArgList &Args,
+static void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+ const ArgList &Args,
std::vector<const char *> &Features) {
+ StringRef CPUName;
+ StringRef ABIName;
+ getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+ ABIName = getGnuCompatibleMipsABIName(ABIName);
+
StringRef FloatABI = getMipsFloatABI(D, Args);
if (FloatABI == "soft") {
// FIXME: Note, this is a hack. We need to pass the selected float
@@ -1056,12 +1062,23 @@
"dspr2");
AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
"msa");
- AddTargetFeature(Args, Features, options::OPT_mfp64, options::OPT_mfp32,
- "fp64");
- if (Args.getLastArg(options::OPT_mfpxx)) {
+
+ // Add the last -mfp32/-mfpxx/-mfp64 or if none are given and the ABI is O32
+ // pass -mfpxx
+ if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
+ options::OPT_mfp64)) {
+ if (A->getOption().matches(options::OPT_mfp32))
+ Features.push_back(Args.MakeArgString("-fp64"));
+ else if (A->getOption().matches(options::OPT_mfpxx)) {
+ Features.push_back(Args.MakeArgString("+fpxx"));
+ Features.push_back(Args.MakeArgString("+nooddspreg"));
+ } else
+ Features.push_back(Args.MakeArgString("+fp64"));
+ } else if (mips::isFPXXDefault(Triple, CPUName, ABIName)) {
Features.push_back(Args.MakeArgString("+fpxx"));
Features.push_back(Args.MakeArgString("+nooddspreg"));
}
+
AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
options::OPT_modd_spreg, "nooddspreg");
}
@@ -1612,7 +1629,7 @@
case llvm::Triple::mipsel:
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
- getMIPSTargetFeatures(D, Args, Features);
+ getMIPSTargetFeatures(D, Triple, Args, Features);
break;
case llvm::Triple::arm:
@@ -5201,6 +5218,22 @@
return false;
}
+bool mips::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
+ StringRef ABIName) {
+ if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
+ Triple.getVendorName() != "mti")
+ return false;
+
+ if (ABIName != "32")
+ return false;
+
+ return llvm::StringSwitch<bool>(CPUName)
+ .Cases("mips2", "mips3", "mips4", "mips5", true)
+ .Cases("mips32", "mips32r2", true)
+ .Cases("mips64", "mips64r2", true)
+ .Default(false);
+}
+
llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
// See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
// archs which Darwin doesn't use.
@@ -6897,12 +6930,19 @@
StringRef CPUName;
StringRef ABIName;
getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+ ABIName = getGnuCompatibleMipsABIName(ABIName);
CmdArgs.push_back("-march");
CmdArgs.push_back(CPUName.data());
CmdArgs.push_back("-mabi");
- CmdArgs.push_back(getGnuCompatibleMipsABIName(ABIName).data());
+ CmdArgs.push_back(ABIName.data());
+
+ // LLVM doesn't support -mabicalls yet and acts as if it is always given.
+ CmdArgs.push_back("-mno-shared");
+ // LLVM doesn't support -mplt yet and acts as if it is always given.
+ // However, -mplt has no effect with the N64 ABI.
+ CmdArgs.push_back(ABIName == "64" ? "-KPIC" : "-call_nonpic");
if (getToolChain().getArch() == llvm::Triple::mips ||
getToolChain().getArch() == llvm::Triple::mips64)
@@ -6915,8 +6955,28 @@
CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));
}
- Args.AddLastArg(CmdArgs, options::OPT_mfp32, options::OPT_mfp64);
- Args.AddLastArg(CmdArgs, options::OPT_mips16, options::OPT_mno_mips16);
+ // Add the last -mfp32/-mfpxx/-mfp64 or -mfpxx if it is enabled by default.
+ if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
+ options::OPT_mfp64)) {
+ A->claim();
+ A->render(Args, CmdArgs);
+ } else if (mips::isFPXXDefault(getToolChain().getTriple(), CPUName,
+ ABIName))
+ CmdArgs.push_back("-mfpxx");
+
+ // Pass on -mmips16 or -mno-mips16. However, the assembler equivalent of
+ // -mno-mips16 is actually -no-mips16.
+ if (Arg *A = Args.getLastArg(options::OPT_mips16,
+ options::OPT_mno_mips16)) {
+ if (A->getOption().matches(options::OPT_mips16)) {
+ A->claim();
+ A->render(Args, CmdArgs);
+ } else {
+ A->claim();
+ CmdArgs.push_back("-no-mips16");
+ }
+ }
+
Args.AddLastArg(CmdArgs, options::OPT_mmicromips,
options::OPT_mno_micromips);
Args.AddLastArg(CmdArgs, options::OPT_mdsp, options::OPT_mno_dsp);
@@ -6929,6 +6989,12 @@
CmdArgs.push_back(Args.MakeArgString("-mmsa"));
}
+ Args.AddLastArg(CmdArgs, options::OPT_mhard_float,
+ options::OPT_msoft_float);
+
+ Args.AddLastArg(CmdArgs, options::OPT_modd_spreg,
+ options::OPT_mno_odd_spreg);
+
NeedsKPIC = true;
} else if (getToolChain().getArch() == llvm::Triple::systemz) {
// Always pass an -march option, since our default of z10 is later