Index: docs/UsersManual.rst =================================================================== --- docs/UsersManual.rst +++ docs/UsersManual.rst @@ -1140,6 +1140,16 @@ This option restricts the generated code to use general registers only. This only applies to the AArch64 architecture. +.. option:: -mcompact-branches=[values] + + Control the usage of compact branches for MIPSR6. + + Valid values are: ``never``, ``optimal`` and ``always``. + The default value is ``optimal`` which generates compact branches + when a delay slot cannot be filled. ``never`` disables the usage of + compact branches and ``always`` generates compact branches whenever + possible. + **-f[no-]max-type-align=[number]** Instruct the code generator to not enforce a higher alignment than the given number (of bytes) when accessing memory via an opaque pointer or reference. Index: include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- include/clang/Basic/DiagnosticDriverKinds.td +++ include/clang/Basic/DiagnosticDriverKinds.td @@ -238,6 +238,9 @@ def warn_target_unsupported_nanlegacy : Warning< "ignoring '-mnan=legacy' option because the '%0' architecture does not support it">, InGroup; +def warn_target_unsupported_compact_branches : Warning< + "ignoring '-mcompact-branches=' option because the '%0' architecture does not" + " support it">, InGroup; def warn_drv_unable_to_find_directory_expected : Warning< "unable to find %0 directory, expected to be in '%1'">, Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -56,6 +56,7 @@ def DoublePromotion : DiagGroup<"double-promotion">; def EnumTooLarge : DiagGroup<"enum-too-large">; def UnsupportedNan : DiagGroup<"unsupported-nan">; +def UnsupportedCB : DiagGroup<"unsupported-cb">; def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">; def NullConversion : DiagGroup<"null-conversion">; def ImplicitConversionFloatingPointToBool : Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1621,6 +1621,7 @@ def mcheck_zero_division : Flag<["-"], "mcheck-zero-division">, Group; def mno_check_zero_division : Flag<["-"], "mno-check-zero-division">, Group; +def mcompact_branches_EQ : Joined<["-"], "mcompact-branches=">, Group; def mdsp : Flag<["-"], "mdsp">, Group; def mno_dsp : Flag<["-"], "mno-dsp">, Group; def mdspr2 : Flag<["-"], "mdspr2">, Group; Index: lib/Driver/Tools.h =================================================================== --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -291,6 +291,7 @@ }; NanEncoding getSupportedNanEncoding(StringRef &CPU); +bool hasCompactBranches(StringRef &CPU); void getMipsCPUAndABI(const llvm::opt::ArgList &Args, const llvm::Triple &Triple, StringRef &CPUName, StringRef &ABIName); Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -1436,6 +1436,20 @@ CmdArgs.push_back(Args.MakeArgString("-mips-ssection-threshold=" + v)); A->claim(); } + + if (Arg *A = Args.getLastArg(options::OPT_mcompact_branches_EQ)) { + StringRef Val = StringRef(A->getValue()); + if (mips::hasCompactBranches(CPUName)) { + if (Val == "never" || Val == "always" || Val == "optimal") { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-mips-compact-branches=" + Val)); + + } else + D.Diag(diag::err_drv_unsupported_option_argument) + << A->getOption().getName() << Val; + } else + D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName; + } } /// getPPCTargetCPU - Get the (LLVM) name of the PowerPC cpu we are targeting. @@ -7065,6 +7079,15 @@ .Default(NanLegacy); } +bool mips::hasCompactBranches(StringRef &CPU) { + // mips32r6 and mips64r6 have compact branches. + + return (bool)llvm::StringSwitch(CPU) + .Case("mips32r6", true) + .Case("mips64r6", true) + .Default(false); +} + bool mips::hasMipsAbiArg(const ArgList &Args, const char *Value) { Arg *A = Args.getLastArg(options::OPT_mabi_EQ); return A && (A->getValue() == StringRef(Value)); Index: test/Driver/mips-features.c =================================================================== --- test/Driver/mips-features.c +++ test/Driver/mips-features.c @@ -116,6 +116,24 @@ // RUN: | FileCheck --check-prefix=CHECK-NANLEGACY %s // CHECK-NANLEGACY: "-target-feature" "-nan2008" // +// -mcompact-branches=never +// RUN: %clang -target mips-linux-gnu -march=mips32r6 -### -c %s \ +// RUN: -mcompact-branches=never 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CBNEVER %s +// CHECK-CBNEVER: "-mllvm" "-mips-compact-branches=never" +// +// -mcompact-branches=optimal +// RUN: %clang -target mips-linux-gnu -march=mips32r6 -### -c %s \ +// RUN: -mcompact-branches=optimal 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CBOPTIMAL %s +// CHECK-CBOPTIMAL: "-mllvm" "-mips-compact-branches=optimal" +// +// -mcompact-branches=always +// RUN: %clang -target mips-linux-gnu -march=mips32r6 -### -c %s \ +// RUN: -mcompact-branches=always 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-CBALWAYS %s +// CHECK-CBALWAYS: "-mllvm" "-mips-compact-branches=always" +// // -mxgot // RUN: %clang -target mips-linux-gnu -### -c %s \ // RUN: -mno-xgot -mxgot 2>&1 \