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