Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/Arch/CSKY.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- CSKY.cpp - CSKY 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 "CSKY.h"
10
#include "ToolChains/CommonArgs.h"
11
#include "clang/Basic/CharInfo.h"
12
#include "clang/Driver/Driver.h"
13
#include "clang/Driver/DriverDiagnostic.h"
14
#include "clang/Driver/Options.h"
15
#include "llvm/ADT/StringSwitch.h"
16
#include "llvm/Option/ArgList.h"
17
#include "llvm/Support/raw_ostream.h"
18
#include "llvm/TargetParser/CSKYTargetParser.h"
19
#include "llvm/TargetParser/Host.h"
20
#include "llvm/TargetParser/TargetParser.h"
21
22
using namespace clang::driver;
23
using namespace clang::driver::tools;
24
using namespace clang;
25
using namespace llvm::opt;
26
27
std::optional<llvm::StringRef>
28
csky::getCSKYArchName(const Driver &D, const ArgList &Args,
29
2
                      const llvm::Triple &Triple) {
30
2
  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
31
1
    llvm::CSKY::ArchKind ArchKind = llvm::CSKY::parseArch(A->getValue());
32
33
1
    if (ArchKind == llvm::CSKY::ArchKind::INVALID) {
34
0
      D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
35
0
      return std::nullopt;
36
0
    }
37
1
    return std::optional<llvm::StringRef>(A->getValue());
38
1
  }
39
40
1
  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {
41
0
    llvm::CSKY::ArchKind ArchKind = llvm::CSKY::parseCPUArch(A->getValue());
42
0
    if (ArchKind == llvm::CSKY::ArchKind::INVALID) {
43
0
      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
44
0
      return std::nullopt;
45
0
    }
46
0
    return std::optional<llvm::StringRef>(llvm::CSKY::getArchName(ArchKind));
47
0
  }
48
49
1
  return std::optional<llvm::StringRef>("ck810");
50
1
}
51
52
34
csky::FloatABI csky::getCSKYFloatABI(const Driver &D, const ArgList &Args) {
53
34
  csky::FloatABI ABI = FloatABI::Soft;
54
34
  if (Arg *A =
55
34
          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
56
34
                          options::OPT_mfloat_abi_EQ)) {
57
10
    if (A->getOption().matches(options::OPT_msoft_float)) {
58
0
      ABI = FloatABI::Soft;
59
10
    } else if (A->getOption().matches(options::OPT_mhard_float)) {
60
10
      ABI = FloatABI::Hard;
61
10
    } else {
62
0
      ABI = llvm::StringSwitch<csky::FloatABI>(A->getValue())
63
0
                .Case("soft", FloatABI::Soft)
64
0
                .Case("softfp", FloatABI::SoftFP)
65
0
                .Case("hard", FloatABI::Hard)
66
0
                .Default(FloatABI::Invalid);
67
0
      if (ABI == FloatABI::Invalid) {
68
0
        D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
69
0
        ABI = FloatABI::Soft;
70
0
      }
71
0
    }
72
10
  }
73
74
34
  return ABI;
75
34
}
76
77
// Handle -mfpu=.
78
static llvm::CSKY::CSKYFPUKind
79
getCSKYFPUFeatures(const Driver &D, const Arg *A, const ArgList &Args,
80
11
                   StringRef FPU, std::vector<StringRef> &Features) {
81
82
11
  llvm::CSKY::CSKYFPUKind FPUID =
83
11
      llvm::StringSwitch<llvm::CSKY::CSKYFPUKind>(FPU)
84
11
          .Case("auto", llvm::CSKY::FK_AUTO)
85
11
          .Case("fpv2", llvm::CSKY::FK_FPV2)
86
11
          .Case("fpv2_divd", llvm::CSKY::FK_FPV2_DIVD)
87
11
          .Case("fpv2_sf", llvm::CSKY::FK_FPV2_SF)
88
11
          .Case("fpv3", llvm::CSKY::FK_FPV3)
89
11
          .Case("fpv3_hf", llvm::CSKY::FK_FPV3_HF)
90
11
          .Case("fpv3_hsf", llvm::CSKY::FK_FPV3_HSF)
91
11
          .Case("fpv3_sdf", llvm::CSKY::FK_FPV3_SDF)
92
11
          .Default(llvm::CSKY::FK_INVALID);
93
11
  if (FPUID == llvm::CSKY::FK_INVALID) {
94
0
    D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
95
0
    return llvm::CSKY::FK_INVALID;
96
0
  }
97
98
11
  auto RemoveTargetFPUFeature =
99
11
      [&Features](ArrayRef<const char *> FPUFeatures) {
100
77
        for (auto FPUFeature : FPUFeatures) {
101
77
          auto it = llvm::find(Features, FPUFeature);
102
77
          if (it != Features.end())
103
7
            Features.erase(it);
104
77
        }
105
11
      };
106
107
11
  RemoveTargetFPUFeature({"+fpuv2_sf", "+fpuv2_df", "+fdivdu", "+fpuv3_hi",
108
11
                          "+fpuv3_hf", "+fpuv3_sf", "+fpuv3_df"});
109
110
11
  if (!llvm::CSKY::getFPUFeatures(FPUID, Features)) {
111
0
    D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
112
0
    return llvm::CSKY::FK_INVALID;
113
0
  }
114
115
11
  return FPUID;
116
11
}
117
118
void csky::getCSKYTargetFeatures(const Driver &D, const llvm::Triple &Triple,
119
                                 const ArgList &Args, ArgStringList &CmdArgs,
120
36
                                 std::vector<llvm::StringRef> &Features) {
121
36
  llvm::StringRef archName;
122
36
  llvm::StringRef cpuName;
123
36
  llvm::CSKY::ArchKind ArchKind = llvm::CSKY::ArchKind::INVALID;
124
36
  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
125
15
    ArchKind = llvm::CSKY::parseArch(A->getValue());
126
15
    if (ArchKind == llvm::CSKY::ArchKind::INVALID) {
127
2
      D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
128
2
      return;
129
2
    }
130
13
    archName = A->getValue();
131
13
  }
132
133
34
  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {
134
9
    llvm::CSKY::ArchKind Kind = llvm::CSKY::parseCPUArch(A->getValue());
135
9
    if (Kind == llvm::CSKY::ArchKind::INVALID) {
136
2
      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
137
2
      return;
138
2
    }
139
7
    if (!archName.empty() && 
Kind != ArchKind0
) {
140
0
      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
141
0
      return;
142
0
    }
143
7
    cpuName = A->getValue();
144
7
    if (archName.empty())
145
7
      archName = llvm::CSKY::getArchName(Kind);
146
7
  }
147
148
32
  if (archName.empty() && 
cpuName.empty()13
) {
149
13
    archName = "ck810";
150
13
    cpuName = "ck810";
151
19
  } else if (!archName.empty() && cpuName.empty()) {
152
12
    cpuName = archName;
153
12
  }
154
155
32
  csky::FloatABI FloatABI = csky::getCSKYFloatABI(D, Args);
156
157
32
  if (FloatABI == csky::FloatABI::Hard) {
158
10
    Features.push_back("+hard-float-abi");
159
10
    Features.push_back("+hard-float");
160
22
  } else if (FloatABI == csky::FloatABI::SoftFP) {
161
0
    Features.push_back("+hard-float");
162
0
  }
163
164
32
  uint64_t Extension = llvm::CSKY::getDefaultExtensions(cpuName);
165
32
  llvm::CSKY::getExtensionFeatures(Extension, Features);
166
167
32
  if (const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ))
168
11
    getCSKYFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
169
32
}