Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/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
554
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
554
  if (T.isOSAIX())
28
254
    return "pwr7";
29
300
  else if (T.getArch() == llvm::Triple::ppc64le)
30
76
    return "ppc64le";
31
224
  else if (T.getArch() == llvm::Triple::ppc64)
32
155
    return "ppc64";
33
69
  else
34
69
    return "ppc";
35
554
}
36
37
255
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
255
  if (CPUName == "generic" || 
CPUName == "405"253
)
44
3
    return getPPCGenericTargetCPU(T);
45
46
252
  if (CPUName == "native") {
47
1
    std::string CPU = std::string(llvm::sys::getHostCPUName());
48
1
    if (!CPU.empty() && CPU != "generic")
49
1
      return CPU;
50
0
    else
51
0
      return getPPCGenericTargetCPU(T);
52
1
  }
53
54
251
  return llvm::StringSwitch<const char *>(CPUName)
55
251
      .Case("common", "generic")
56
251
      .Case("440fp", "440")
57
251
      .Case("630", "pwr3")
58
251
      .Case("G3", "g3")
59
251
      .Case("G4", "g4")
60
251
      .Case("G4+", "g4+")
61
251
      .Case("8548", "e500")
62
251
      .Case("G5", "g5")
63
251
      .Case("power3", "pwr3")
64
251
      .Case("power4", "pwr4")
65
251
      .Case("power5", "pwr5")
66
251
      .Case("power5x", "pwr5x")
67
251
      .Case("power6", "pwr6")
68
251
      .Case("power6x", "pwr6x")
69
251
      .Case("power7", "pwr7")
70
251
      .Case("power8", "pwr8")
71
251
      .Case("power9", "pwr9")
72
251
      .Case("power10", "pwr10")
73
251
      .Case("future", "future")
74
251
      .Case("powerpc", "ppc")
75
251
      .Case("powerpc64", "ppc64")
76
251
      .Case("powerpc64le", "ppc64le")
77
251
      .Default(CPUName.data());
78
252
}
79
80
/// Get the (LLVM) name of the PowerPC cpu we are tuning for.
81
2
std::string ppc::getPPCTuneCPU(const ArgList &Args, const llvm::Triple &T) {
82
2
  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))
83
2
    return normalizeCPUName(A->getValue(), T);
84
0
  return getPPCGenericTargetCPU(T);
85
2
}
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
804
                                 const llvm::Triple &T) {
90
804
  if (Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
91
253
    return normalizeCPUName(A->getValue(), T);
92
551
  return getPPCGenericTargetCPU(T);
93
804
}
94
95
12
const char *ppc::getPPCAsmModeForCPU(StringRef Name) {
96
12
  return llvm::StringSwitch<const char *>(Name)
97
12
      .Case("pwr7", "-mpower7")
98
12
      .Case("power7", "-mpower7")
99
12
      .Case("pwr8", "-mpower8")
100
12
      .Case("power8", "-mpower8")
101
12
      .Case("ppc64le", "-mpower8")
102
12
      .Case("pwr9", "-mpower9")
103
12
      .Case("power9", "-mpower9")
104
12
      .Case("pwr10", "-mpower10")
105
12
      .Case("power10", "-mpower10")
106
12
      .Default("-many");
107
12
}
108
109
void ppc::getPPCTargetFeatures(const Driver &D, const llvm::Triple &Triple,
110
                               const ArgList &Args,
111
603
                               std::vector<StringRef> &Features) {
112
603
  if (Triple.getSubArch() == llvm::Triple::PPCSubArch_spe)
113
3
    Features.push_back("+spe");
114
115
603
  handleTargetFeaturesGroup(D, Triple, Args, Features,
116
603
                            options::OPT_m_ppc_Features_Group);
117
118
603
  ppc::FloatABI FloatABI = ppc::getPPCFloatABI(D, Args);
119
603
  if (FloatABI == ppc::FloatABI::Soft)
120
9
    Features.push_back("-hard-float");
121
122
603
  ppc::ReadGOTPtrMode ReadGOT = ppc::getPPCReadGOTPtrMode(D, Triple, Args);
123
603
  if (ReadGOT == ppc::ReadGOTPtrMode::SecurePlt)
124
18
    Features.push_back("+secure-plt");
125
603
}
126
127
ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver &D, const llvm::Triple &Triple,
128
603
                                              const ArgList &Args) {
129
603
  if (Args.getLastArg(options::OPT_msecure_plt))
130
1
    return ppc::ReadGOTPtrMode::SecurePlt;
131
602
  if (Triple.isPPC32SecurePlt())
132
17
    return ppc::ReadGOTPtrMode::SecurePlt;
133
585
  else
134
585
    return ppc::ReadGOTPtrMode::Bss;
135
602
}
136
137
1.20k
ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) {
138
1.20k
  ppc::FloatABI ABI = ppc::FloatABI::Invalid;
139
1.20k
  if (Arg *A =
140
1.20k
          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
141
1.20k
                          options::OPT_mfloat_abi_EQ)) {
142
26
    if (A->getOption().matches(options::OPT_msoft_float))
143
12
      ABI = ppc::FloatABI::Soft;
144
14
    else if (A->getOption().matches(options::OPT_mhard_float))
145
4
      ABI = ppc::FloatABI::Hard;
146
10
    else {
147
10
      ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue())
148
10
                .Case("soft", ppc::FloatABI::Soft)
149
10
                .Case("hard", ppc::FloatABI::Hard)
150
10
                .Default(ppc::FloatABI::Invalid);
151
10
      if (ABI == ppc::FloatABI::Invalid && 
!StringRef(A->getValue()).empty()2
) {
152
2
        D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
153
2
        ABI = ppc::FloatABI::Hard;
154
2
      }
155
10
    }
156
26
  }
157
158
  // If unspecified, choose the default based on the platform.
159
1.20k
  if (ABI == ppc::FloatABI::Invalid) {
160
1.17k
    ABI = ppc::FloatABI::Hard;
161
1.17k
  }
162
163
1.20k
  return ABI;
164
1.20k
}
165
166
94
bool ppc::hasPPCAbiArg(const ArgList &Args, const char *Value) {
167
94
  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
168
94
  return A && 
(A->getValue() == StringRef(Value))21
;
169
94
}