Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Driver/ToolChains/Arch/PPC.cpp
Line
Count
Source (jump to first uncovered line)
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
0
static std::string getPPCGenericTargetCPU(const llvm::Triple &T) {
24
  // LLVM may default to generating code for the native CPU,
25
  // but, like gcc, we default to a more generic option for
26
  // each architecture. (except on AIX)
27
0
  if (T.isOSAIX())
28
0
    return "pwr7";
29
0
  else if (T.getArch() == llvm::Triple::ppc64le)
30
0
    return "ppc64le";
31
0
  else if (T.getArch() == llvm::Triple::ppc64)
32
0
    return "ppc64";
33
0
  else
34
0
    return "ppc";
35
0
}
36
37
0
static std::string normalizeCPUName(StringRef CPUName, const llvm::Triple &T) {
38
  // Clang/LLVM does not actually support code generation
39
  // for the 405 CPU. However, there are uses of this CPU ID
40
  // in projects that previously used GCC and rely on Clang
41
  // accepting it. Clang has always ignored it and passed the
42
  // generic CPU ID to the back end.
43
0
  if (CPUName == "generic" || CPUName == "405")
44
0
    return getPPCGenericTargetCPU(T);
45
46
0
  if (CPUName == "native") {
47
0
    std::string CPU = std::string(llvm::sys::getHostCPUName());
48
0
    if (!CPU.empty() && CPU != "generic")
49
0
      return CPU;
50
0
    else
51
0
      return getPPCGenericTargetCPU(T);
52
0
  }
53
54
0
  return llvm::StringSwitch<const char *>(CPUName)
55
0
      .Case("common", "generic")
56
0
      .Case("440fp", "440")
57
0
      .Case("630", "pwr3")
58
0
      .Case("G3", "g3")
59
0
      .Case("G4", "g4")
60
0
      .Case("G4+", "g4+")
61
0
      .Case("8548", "e500")
62
0
      .Case("G5", "g5")
63
0
      .Case("power3", "pwr3")
64
0
      .Case("power4", "pwr4")
65
0
      .Case("power5", "pwr5")
66
0
      .Case("power5x", "pwr5x")
67
0
      .Case("power6", "pwr6")
68
0
      .Case("power6x", "pwr6x")
69
0
      .Case("power7", "pwr7")
70
0
      .Case("power8", "pwr8")
71
0
      .Case("power9", "pwr9")
72
0
      .Case("power10", "pwr10")
73
0
      .Case("future", "future")
74
0
      .Case("powerpc", "ppc")
75
0
      .Case("powerpc64", "ppc64")
76
0
      .Case("powerpc64le", "ppc64le")
77
0
      .Default(CPUName.data());
78
0
}
79
80
/// Get the (LLVM) name of the PowerPC cpu we are tuning for.
81
0
std::string ppc::getPPCTuneCPU(const ArgList &Args, const llvm::Triple &T) {
82
0
  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))
83
0
    return normalizeCPUName(A->getValue(), T);
84
0
  return getPPCGenericTargetCPU(T);
85
0
}
86
87
/// Get the (LLVM) name of the PowerPC cpu we are targeting.
88
std::string ppc::getPPCTargetCPU(const Driver &D, const ArgList &Args,
89
0
                                 const llvm::Triple &T) {
90
0
  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
91
0
    return normalizeCPUName(A->getValue(), T);
92
0
  return getPPCGenericTargetCPU(T);
93
0
}
94
95
0
const char *ppc::getPPCAsmModeForCPU(StringRef Name) {
96
0
  return llvm::StringSwitch<const char *>(Name)
97
0
      .Case("pwr7", "-mpower7")
98
0
      .Case("power7", "-mpower7")
99
0
      .Case("pwr8", "-mpower8")
100
0
      .Case("power8", "-mpower8")
101
0
      .Case("ppc64le", "-mpower8")
102
0
      .Case("pwr9", "-mpower9")
103
0
      .Case("power9", "-mpower9")
104
0
      .Case("pwr10", "-mpower10")
105
0
      .Case("power10", "-mpower10")
106
0
      .Default("-many");
107
0
}
108
109
void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
110
                               const ArgList &Args,
111
0
                               std::vector<StringRef> &Features) {
112
0
  if (Triple.getSubArch() == llvm::Triple::PPCSubArch_spe)
113
0
    Features.push_back("+spe");
114
115
0
  handleTargetFeaturesGroup(D, Triple, Args, Features,
116
0
                            options::OPT_m_ppc_Features_Group);
117
118
0
  ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
119
0
  if (FloatABI == ppc::FloatABI::Soft)
120
0
    Features.push_back("-hard-float");
121
122
0
  ppc::ReadGOTPtrMode ReadGOT = ppc::getPPCReadGOTPtrMode(D, Triple, Args);
123
0
  if (ReadGOT == ppc::ReadGOTPtrMode::SecurePlt)
124
0
    Features.push_back("+secure-plt");
125
0
}
126
127
ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple,
128
0
                                              const ArgList &Args) {
129
0
  if (Args.getLastArg(options::OPT_msecure_plt))
130
0
    return ppc::ReadGOTPtrMode::SecurePlt;
131
0
  if (Triple.isPPC32SecurePlt())
132
0
    return ppc::ReadGOTPtrMode::SecurePlt;
133
0
  else
134
0
    return ppc::ReadGOTPtrMode::Bss;
135
0
}
136
137
0
ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) {
138
0
  ppc::FloatABI ABI = ppc::FloatABI::Invalid;
139
0
  if (Arg *A =
140
0
          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
141
0
                          options::OPT_mfloat_abi_EQ)) {
142
0
    if (A->getOption().matches(options::OPT_msoft_float))
143
0
      ABI = ppc::FloatABI::Soft;
144
0
    else if (A->getOption().matches(options::OPT_mhard_float))
145
0
      ABI = ppc::FloatABI::Hard;
146
0
    else {
147
0
      ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue())
148
0
                .Case("soft", ppc::FloatABI::Soft)
149
0
                .Case("hard", ppc::FloatABI::Hard)
150
0
                .Default(ppc::FloatABI::Invalid);
151
0
      if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
152
0
        D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
153
0
        ABI = ppc::FloatABI::Hard;
154
0
      }
155
0
    }
156
0
  }
157
158
  // If unspecified, choose the default based on the platform.
159
0
  if (ABI == ppc::FloatABI::Invalid) {
160
0
    ABI = ppc::FloatABI::Hard;
161
0
  }
162
163
0
  return ABI;
164
0
}
165
166
0
bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
167
0
  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
168
0
  return A && (A->getValue() == StringRef(Value));
169
0
}