Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1364,6 +1364,8 @@ def malign_loops_EQ : Joined<["-"], "malign-loops=">, Group; def malign_jumps_EQ : Joined<["-"], "malign-jumps=">, Group; def mfancy_math_387 : Flag<["-"], "mfancy-math-387">, Group; +def mlong_calls : Flag<["-"], "mlong-calls">, Group, + HelpText<"ARM: Generate an indirect jump to enable jumps further than 64M, Hexagon: Generate constant-extended branches.">; def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group; def mappletvos_version_min_EQ : Joined<["-"], "mappletvos-version-min=">, Alias; def mtvos_simulator_version_min_EQ : Joined<["-"], "mtvos-simulator-version-min=">, Alias; @@ -1507,8 +1509,6 @@ HelpText<"Allow use of CRC instructions (ARM only)">; def mnocrc : Flag<["-"], "mnocrc">, Group, HelpText<"Disallow use of CRC instructions (ARM only)">; -def mlong_calls : Flag<["-"], "mlong-calls">, Group, - HelpText<"Generate an indirect jump to enable jumps further than 64M">; def mno_long_calls : Flag<["-"], "mno-long-calls">, Group, HelpText<"Restore the default behaviour of not generating long calls">; Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -6079,6 +6079,7 @@ static const TargetInfo::GCCRegAlias GCCRegAliases[]; std::string CPU; bool HasHVX, HasHVXDouble; + bool UseLongCalls; public: HexagonTargetInfo(const llvm::Triple &Triple, const TargetOptions &) @@ -6103,6 +6104,7 @@ UseBitFieldTypeAlignment = true; ZeroLengthBitfieldBoundary = 32; HasHVX = HasHVXDouble = false; + UseLongCalls = false; } ArrayRef getTargetBuiltins() const override { @@ -6137,15 +6139,19 @@ .Case("hexagon", true) .Case("hvx", HasHVX) .Case("hvx-double", HasHVXDouble) + .Case("long-calls", UseLongCalls) .Default(false); } + bool handleTargetFeatures(std::vector &Features, + DiagnosticsEngine &Diags) override; + bool initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector &FeaturesVec) const override; - bool handleTargetFeatures(std::vector &Features, - DiagnosticsEngine &Diags) override; + void setFeatureEnabled(llvm::StringMap &Features, StringRef Name, + bool Enabled) const override; BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; @@ -6226,6 +6232,11 @@ HasHVX = HasHVXDouble = true; else if (F == "-hvx-double") HasHVXDouble = false; + + if (F == "+long-calls") + UseLongCalls = true; + else if (F == "-long-calls") + UseLongCalls = false; } return true; } @@ -6236,10 +6247,23 @@ // Default for v60: -hvx, -hvx-double. Features["hvx"] = false; Features["hvx-double"] = false; + Features["long-calls"] = false; return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } +void HexagonTargetInfo::setFeatureEnabled(llvm::StringMap &Features, + StringRef Name, bool Enabled) const { + if (Enabled) { + if (Name == "hvx-double") + Features["hvx"] = true; + } else { + if (Name == "hvx") + Features["hvx-double"] = false; + } + Features[Name] = Enabled; +} + const char *const HexagonTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2536,28 +2536,17 @@ static void getHexagonTargetFeatures(const ArgList &Args, std::vector &Features) { - bool HasHVX = false, HasHVXD = false; - - // FIXME: This should be able to use handleTargetFeaturesGroup except it is - // doing dependent option handling here rather than in initFeatureMap or a - // similar handler. - for (auto &A : Args) { - auto &Opt = A->getOption(); - if (Opt.matches(options::OPT_mhexagon_hvx)) - HasHVX = true; - else if (Opt.matches(options::OPT_mno_hexagon_hvx)) - HasHVXD = HasHVX = false; - else if (Opt.matches(options::OPT_mhexagon_hvx_double)) - HasHVXD = HasHVX = true; - else if (Opt.matches(options::OPT_mno_hexagon_hvx_double)) - HasHVXD = false; - else - continue; - A->claim(); + handleTargetFeaturesGroup(Args, Features, + options::OPT_m_hexagon_Features_Group); + + bool UseLongCalls = false; + if (Arg *A = Args.getLastArg(options::OPT_mlong_calls, + options::OPT_mno_long_calls)) { + if (A->getOption().matches(options::OPT_mlong_calls)) + UseLongCalls = true; } - Features.push_back(HasHVX ? "+hvx" : "-hvx"); - Features.push_back(HasHVXD ? "+hvx-double" : "-hvx-double"); + Features.push_back(UseLongCalls ? "+long-calls" : "-long-calls"); } static void getWebAssemblyTargetFeatures(const ArgList &Args, Index: test/Driver/hexagon-long-calls.c =================================================================== --- /dev/null +++ test/Driver/hexagon-long-calls.c @@ -0,0 +1,15 @@ +// RUN: %clang -target hexagon -### %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-DEFAULT + +// RUN: %clang -target hexagon -### -mlong-calls %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-LONG-CALLS + +// RUN: %clang -target hexagon -### -mlong-calls -mno-long-calls %s 2>&1 \ +// RUN: | FileCheck %s -check-prefix CHECK-NO-LONG-CALLS + +// CHECK-DEFAULT-NOT: "-target-feature" "+long-calls" + +// CHECK-LONG-CALLS: "-target-feature" "+long-calls" + +// CHECK-NO-LONG-CALLS-NOT: "-target-feature" "+long-calls" +