abeserminji created this revision. Herald added a subscriber: arichardson. In patch https://reviews.llvm.org/D3274 using abs.[ds] instruction is forced, as they should behave in accordance with flags Has2008 and ABS2008. Unfortunately for revisions prior mips32r6 and mips64r6, abs.[ds] is not generating correct result when working with NaNs. To generate a sequence which always produce a correct result but also to allow user more control on how his code is compiled, option -mabs is added where user can choose legacy or 2008. By default legacy mode is used on revisions prior R6. Mips32r6 and mips64r6 use abs2008 mode by default.
This is Clang part of patch. LLVM part can be found here: https://reviews.llvm.org/D35983 Repository: rL LLVM https://reviews.llvm.org/D35982 Files: Basic/Targets/Mips.cpp Basic/Targets/Mips.h Driver/ToolChains/Arch/Mips.cpp Driver/ToolChains/Arch/Mips.h Driver/mips-features.c Preprocessor/init.c clang/Basic/DiagnosticDriverKinds.td clang/Basic/DiagnosticGroups.td clang/Driver/Options.td
Index: Preprocessor/init.c =================================================================== --- Preprocessor/init.c +++ Preprocessor/init.c @@ -4699,6 +4699,16 @@ // RUN: | FileCheck -match-full-lines -check-prefix NOMIPS-NAN2008 %s // NOMIPS-NAN2008-NOT:#define __mips_nan2008 1 // +// RUN: %clang_cc1 -target-cpu mips32r3 -target-feature +abs2008 \ +// RUN: -E -dM -triple=mips-none-none < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefix MIPS-ABS2008 %s +// MIPS-ABS2008:#define __mips_abs2008 1 +// +// RUN: %clang_cc1 -target-cpu mips32r3 -target-feature -abs2008 \ +// RUN: -E -dM -triple=mips-none-none < /dev/null \ +// RUN: | FileCheck -match-full-lines -check-prefix NOMIPS-ABS2008 %s +// NOMIPS-ABS2008-NOT:#define __mips_abs2008 1 +// // RUN: %clang_cc1 -target-feature -fp64 \ // RUN: -E -dM -triple=mips-none-none < /dev/null \ // RUN: | FileCheck -match-full-lines -check-prefix MIPS32-MFP32 %s Index: Driver/mips-features.c =================================================================== --- Driver/mips-features.c +++ Driver/mips-features.c @@ -183,6 +183,18 @@ // RUN: | FileCheck --check-prefix=CHECK-NANLEGACY %s // CHECK-NANLEGACY: "-target-feature" "-nan2008" // +// -mabs=2008 +// RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \ +// RUN: -mabs=2008 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-ABS2008 %s +// CHECK-ABS2008: "-target-feature" "+abs2008" +// +// -mabs=legacy +// RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \ +// RUN: -mabs=legacy 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-ABSLEGACY %s +// CHECK-ABSLEGACY: "-target-feature" "-abs2008" +// // -mcompact-branches=never // RUN: %clang -target mips-linux-gnu -march=mips32r6 -### -c %s \ // RUN: -mcompact-branches=never 2>&1 \ Index: Driver/ToolChains/Arch/Mips.h =================================================================== --- Driver/ToolChains/Arch/Mips.h +++ Driver/ToolChains/Arch/Mips.h @@ -24,15 +24,15 @@ bool isMipsArch(llvm::Triple::ArchType Arch); namespace mips { -typedef enum { NanLegacy = 1, Nan2008 = 2 } NanEncoding; +typedef enum { Legacy = 1, Std2008 = 2 } IEEE754Standard; enum class FloatABI { Invalid, Soft, Hard, }; -NanEncoding getSupportedNanEncoding(StringRef &CPU); +IEEE754Standard getIEEE754Standard(StringRef &CPU); bool hasCompactBranches(StringRef &CPU); void getMipsCPUAndABI(const llvm::opt::ArgList &Args, const llvm::Triple &Triple, StringRef &CPUName, Index: Driver/ToolChains/Arch/Mips.cpp =================================================================== --- Driver/ToolChains/Arch/Mips.cpp +++ Driver/ToolChains/Arch/Mips.cpp @@ -244,14 +244,14 @@ if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { StringRef Val = StringRef(A->getValue()); if (Val == "2008") { - if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008) + if (mips::getIEEE754Standard(CPUName) & mips::Std2008) Features.push_back("+nan2008"); else { Features.push_back("-nan2008"); D.Diag(diag::warn_target_unsupported_nan2008) << CPUName; } } else if (Val == "legacy") { - if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy) + if (mips::getIEEE754Standard(CPUName) & mips::Legacy) Features.push_back("-nan2008"); else { Features.push_back("+nan2008"); @@ -262,6 +262,28 @@ << A->getOption().getName() << Val; } + if (Arg *A = Args.getLastArg(options::OPT_mabs_EQ)) { + StringRef Val = StringRef(A->getValue()); + if (Val == "2008") { + if(mips::getIEEE754Standard(CPUName) & mips::Std2008) { + Features.push_back("+abs2008"); + } else { + Features.push_back("-abs2008"); + D.Diag(diag::warn_target_unsupported_abs2008) << CPUName; + } + } else if (Val == "legacy") { + if(mips::getIEEE754Standard(CPUName) & mips::Legacy) { + Features.push_back("-abs2008"); + } else { + Features.push_back("+abs2008"); + D.Diag(diag::warn_target_unsupported_abslegacy) << CPUName; + } + } else { + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Val; + } + } + AddTargetFeature(Args, Features, options::OPT_msingle_float, options::OPT_mdouble_float, "single-float"); AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16, @@ -304,27 +326,27 @@ AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt,"mt"); } -mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) { - // Strictly speaking, mips32r2 and mips64r2 are NanLegacy-only since Nan2008 - // was first introduced in Release 3. However, other compilers have - // traditionally allowed it for Release 2 so we should do the same. - return (NanEncoding)llvm::StringSwitch<int>(CPU) - .Case("mips1", NanLegacy) - .Case("mips2", NanLegacy) - .Case("mips3", NanLegacy) - .Case("mips4", NanLegacy) - .Case("mips5", NanLegacy) - .Case("mips32", NanLegacy) - .Case("mips32r2", NanLegacy | Nan2008) - .Case("mips32r3", NanLegacy | Nan2008) - .Case("mips32r5", NanLegacy | Nan2008) - .Case("mips32r6", Nan2008) - .Case("mips64", NanLegacy) - .Case("mips64r2", NanLegacy | Nan2008) - .Case("mips64r3", NanLegacy | Nan2008) - .Case("mips64r5", NanLegacy | Nan2008) - .Case("mips64r6", Nan2008) - .Default(NanLegacy); +mips::IEEE754Standard mips::getIEEE754Standard(StringRef &CPU) { + // Strictly speaking, mips32r2 and mips64r2 are not in accordance to standard + // from 2008, it was first introduced in Release 3. However, other compilers + // have traditionally allowed it for Release 2 so we should do the same. + return (IEEE754Standard)llvm::StringSwitch<int>(CPU) + .Case("mips1", Legacy) + .Case("mips2", Legacy) + .Case("mips3", Legacy) + .Case("mips4", Legacy) + .Case("mips5", Legacy) + .Case("mips32", Legacy) + .Case("mips32r2", Legacy | Std2008) + .Case("mips32r3", Legacy | Std2008) + .Case("mips32r5", Legacy | Std2008) + .Case("mips32r6", Std2008) + .Case("mips64", Legacy) + .Case("mips64r2", Legacy | Std2008) + .Case("mips64r3", Legacy | Std2008) + .Case("mips64r5", Legacy | Std2008) + .Case("mips64r6", Std2008) + .Default(Std2008); } bool mips::hasCompactBranches(StringRef &CPU) { Index: Basic/Targets/Mips.h =================================================================== --- Basic/Targets/Mips.h +++ Basic/Targets/Mips.h @@ -46,6 +46,7 @@ bool IsMips16; bool IsMicromips; bool IsNan2008; + bool IsAbs2008; bool IsSingleFloat; bool IsNoABICalls; bool CanUseBSDABICalls; @@ -61,9 +62,9 @@ public: MipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple), IsMips16(false), IsMicromips(false), - IsNan2008(false), IsSingleFloat(false), IsNoABICalls(false), - CanUseBSDABICalls(false), FloatABI(HardFloat), DspRev(NoDSP), - HasMSA(false), DisableMadd4(false), HasFP64(false) { + IsNan2008(false), IsAbs2008(false), IsSingleFloat(false), + IsNoABICalls(false), CanUseBSDABICalls(false), FloatABI(HardFloat), + DspRev(NoDSP), HasMSA(false), DisableMadd4(false), HasFP64(false) { TheCXXABI.set(TargetCXXABI::GenericMIPS); setABI((getTriple().getArch() == llvm::Triple::mips || @@ -77,7 +78,7 @@ Triple.getOS() == llvm::Triple::OpenBSD; } - bool isNaN2008Default() const { + bool isIEEE754_2008Default() const { return CPU == "mips32r6" || CPU == "mips64r6"; } @@ -299,7 +300,8 @@ DiagnosticsEngine &Diags) override { IsMips16 = false; IsMicromips = false; - IsNan2008 = isNaN2008Default(); + IsNan2008 = isIEEE754_2008Default(); + IsAbs2008 = isIEEE754_2008Default(); IsSingleFloat = false; FloatABI = HardFloat; DspRev = NoDSP; @@ -330,6 +332,10 @@ IsNan2008 = true; else if (Feature == "-nan2008") IsNan2008 = false; + else if (Feature == "+abs2008") + IsAbs2008 = true; + else if (Feature == "-abs2008") + IsAbs2008 = false; else if (Feature == "+noabicalls") IsNoABICalls = true; } Index: Basic/Targets/Mips.cpp =================================================================== --- Basic/Targets/Mips.cpp +++ Basic/Targets/Mips.cpp @@ -149,6 +149,9 @@ if (IsNan2008) Builder.defineMacro("__mips_nan2008", Twine(1)); + if (IsAbs2008) + Builder.defineMacro("__mips_abs2008", Twine(1)); + switch (DspRev) { default: break; Index: clang/Driver/Options.td =================================================================== --- clang/Driver/Options.td +++ clang/Driver/Options.td @@ -2052,6 +2052,7 @@ HelpText<"Do not assume that externally defined data is in the small data if" " it meets the -G <size> threshold (MIPS)">; def mnan_EQ : Joined<["-"], "mnan=">, Group<m_Group>; +def mabs_EQ : Joined<["-"], "mabs=">, Group<m_Group>; def mabicalls : Flag<["-"], "mabicalls">, Group<m_Group>, HelpText<"Enable SVR4-style position-independent code (Mips only)">; def mno_abicalls : Flag<["-"], "mno-abicalls">, Group<m_Group>, Index: clang/Basic/DiagnosticGroups.td =================================================================== --- clang/Basic/DiagnosticGroups.td +++ clang/Basic/DiagnosticGroups.td @@ -61,6 +61,7 @@ def DoublePromotion : DiagGroup<"double-promotion">; def EnumTooLarge : DiagGroup<"enum-too-large">; def UnsupportedNan : DiagGroup<"unsupported-nan">; +def UnsupportedAbs : DiagGroup<"unsupported-abs">; def UnsupportedCB : DiagGroup<"unsupported-cb">; def UnsupportedGPOpt : DiagGroup<"unsupported-gpopt">; def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">; Index: clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/Basic/DiagnosticDriverKinds.td +++ clang/Basic/DiagnosticDriverKinds.td @@ -279,6 +279,12 @@ def warn_target_unsupported_nanlegacy : Warning< "ignoring '-mnan=legacy' option because the '%0' architecture does not support it">, InGroup<UnsupportedNan>; +def warn_target_unsupported_abslegacy : Warning< + "ignoring '-mabs=legacy' option because the '%0' architecture does not support it">, + InGroup<UnsupportedAbs>; +def warn_target_unsupported_abs2008 : Warning< + "ignoring '-mabs=2008' option because the '%0' architecture does not support it">, + InGroup<UnsupportedAbs>; def warn_target_unsupported_compact_branches : Warning< "ignoring '-mcompact-branches=' option because the '%0' architecture does not" " support it">, InGroup<UnsupportedCB>;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits