xref: /llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp (revision 25482b356e51de1f259b3ac7c785ab34977781b4)
1 //===--- PPC.cpp - PPC Helpers for Tools ------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "PPC.h"
10 #include "ToolChains/CommonArgs.h"
11 #include "clang/Driver/Driver.h"
12 #include "clang/Driver/DriverDiagnostic.h"
13 #include "clang/Driver/Options.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/Option/ArgList.h"
16 #include "llvm/TargetParser/Host.h"
17 
18 using namespace clang::driver;
19 using namespace clang::driver::tools;
20 using namespace clang;
21 using namespace llvm::opt;
22 
23 const char *ppc::getPPCAsmModeForCPU(StringRef Name) {
24   return llvm::StringSwitch<const char *>(Name)
25       .Case("pwr7", "-mpower7")
26       .Case("power7", "-mpower7")
27       .Case("pwr8", "-mpower8")
28       .Case("power8", "-mpower8")
29       .Case("ppc64le", "-mpower8")
30       .Case("pwr9", "-mpower9")
31       .Case("power9", "-mpower9")
32       .Case("pwr10", "-mpower10")
33       .Case("power10", "-mpower10")
34       .Case("pwr11", "-mpower11")
35       .Case("power11", "-mpower11")
36       .Default("-many");
37 }
38 
39 void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
40                                const ArgList &Args,
41                                std::vector<StringRef> &Features) {
42   if (Triple.getSubArch() == llvm::Triple::PPCSubArch_spe)
43     Features.push_back("+spe");
44 
45   handleTargetFeaturesGroup(D, Triple, Args, Features,
46                             options::OPT_m_ppc_Features_Group);
47 
48   ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
49   if (FloatABI == ppc::FloatABI::Soft)
50     Features.push_back("-hard-float");
51 
52   ppc::ReadGOTPtrMode ReadGOT = ppc::getPPCReadGOTPtrMode(D, Triple, Args);
53   if (ReadGOT == ppc::ReadGOTPtrMode::SecurePlt)
54     Features.push_back("+secure-plt");
55 
56   bool UseSeparateSections = isUseSeparateSections(Triple);
57   bool HasDefaultDataSections = Triple.isOSBinFormatXCOFF();
58   if (Args.hasArg(options::OPT_maix_small_local_exec_tls) ||
59       Args.hasArg(options::OPT_maix_small_local_dynamic_tls)) {
60     if (!Triple.isOSAIX() || !Triple.isArch64Bit())
61       D.Diag(diag::err_opt_not_valid_on_target)
62           << "-maix-small-local-[exec|dynamic]-tls";
63 
64     // The -maix-small-local-[exec|dynamic]-tls option should only be used with
65     // -fdata-sections, as having data sections turned off with this option
66     // is not ideal for performance. Moreover, the
67     // small-local-[exec|dynamic]-tls region is a limited resource, and should
68     // not be used for variables that may be replaced.
69     if (!Args.hasFlag(options::OPT_fdata_sections,
70                       options::OPT_fno_data_sections,
71                       UseSeparateSections || HasDefaultDataSections))
72       D.Diag(diag::err_drv_argument_only_allowed_with)
73           << "-maix-small-local-[exec|dynamic]-tls" << "-fdata-sections";
74   }
75 }
76 
77 ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple,
78                                               const ArgList &Args) {
79   if (Args.getLastArg(options::OPT_msecure_plt))
80     return ppc::ReadGOTPtrMode::SecurePlt;
81   if (Triple.isPPC32SecurePlt())
82     return ppc::ReadGOTPtrMode::SecurePlt;
83   else
84     return ppc::ReadGOTPtrMode::Bss;
85 }
86 
87 ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) {
88   ppc::FloatABI ABI = ppc::FloatABI::Invalid;
89   if (Arg *A =
90           Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
91                           options::OPT_mfloat_abi_EQ)) {
92     if (A->getOption().matches(options::OPT_msoft_float))
93       ABI = ppc::FloatABI::Soft;
94     else if (A->getOption().matches(options::OPT_mhard_float))
95       ABI = ppc::FloatABI::Hard;
96     else {
97       ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue())
98                 .Case("soft", ppc::FloatABI::Soft)
99                 .Case("hard", ppc::FloatABI::Hard)
100                 .Default(ppc::FloatABI::Invalid);
101       if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
102         D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
103         ABI = ppc::FloatABI::Hard;
104       }
105     }
106   }
107 
108   // If unspecified, choose the default based on the platform.
109   if (ABI == ppc::FloatABI::Invalid) {
110     ABI = ppc::FloatABI::Hard;
111   }
112 
113   return ABI;
114 }
115 
116 bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
117   Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
118   return A && (A->getValue() == StringRef(Value));
119 }
120