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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang/lib/Driver/ToolChains/Arch/CSKY.cpp