Path: blob/main/contrib/llvm-project/clang/lib/Driver/ToolChains/Arch/CSKY.cpp
35294 views
//===--- CSKY.cpp - CSKY Helpers for Tools --------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "CSKY.h"9#include "ToolChains/CommonArgs.h"10#include "clang/Basic/CharInfo.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/Support/raw_ostream.h"17#include "llvm/TargetParser/CSKYTargetParser.h"18#include "llvm/TargetParser/Host.h"19#include "llvm/TargetParser/TargetParser.h"2021using namespace clang::driver;22using namespace clang::driver::tools;23using namespace clang;24using namespace llvm::opt;2526std::optional<llvm::StringRef>27csky::getCSKYArchName(const Driver &D, const ArgList &Args,28const llvm::Triple &Triple) {29if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {30llvm::CSKY::ArchKind ArchKind = llvm::CSKY::parseArch(A->getValue());3132if (ArchKind == llvm::CSKY::ArchKind::INVALID) {33D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);34return std::nullopt;35}36return std::optional<llvm::StringRef>(A->getValue());37}3839if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {40llvm::CSKY::ArchKind ArchKind = llvm::CSKY::parseCPUArch(A->getValue());41if (ArchKind == llvm::CSKY::ArchKind::INVALID) {42D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);43return std::nullopt;44}45return std::optional<llvm::StringRef>(llvm::CSKY::getArchName(ArchKind));46}4748return std::optional<llvm::StringRef>("ck810");49}5051csky::FloatABI csky::getCSKYFloatABI(const Driver &D, const ArgList &Args) {52csky::FloatABI ABI = FloatABI::Soft;53if (Arg *A =54Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,55options::OPT_mfloat_abi_EQ)) {56if (A->getOption().matches(options::OPT_msoft_float)) {57ABI = FloatABI::Soft;58} else if (A->getOption().matches(options::OPT_mhard_float)) {59ABI = FloatABI::Hard;60} else {61ABI = llvm::StringSwitch<csky::FloatABI>(A->getValue())62.Case("soft", FloatABI::Soft)63.Case("softfp", FloatABI::SoftFP)64.Case("hard", FloatABI::Hard)65.Default(FloatABI::Invalid);66if (ABI == FloatABI::Invalid) {67D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);68ABI = FloatABI::Soft;69}70}71}7273return ABI;74}7576// Handle -mfpu=.77static llvm::CSKY::CSKYFPUKind78getCSKYFPUFeatures(const Driver &D, const Arg *A, const ArgList &Args,79StringRef FPU, std::vector<StringRef> &Features) {8081llvm::CSKY::CSKYFPUKind FPUID =82llvm::StringSwitch<llvm::CSKY::CSKYFPUKind>(FPU)83.Case("auto", llvm::CSKY::FK_AUTO)84.Case("fpv2", llvm::CSKY::FK_FPV2)85.Case("fpv2_divd", llvm::CSKY::FK_FPV2_DIVD)86.Case("fpv2_sf", llvm::CSKY::FK_FPV2_SF)87.Case("fpv3", llvm::CSKY::FK_FPV3)88.Case("fpv3_hf", llvm::CSKY::FK_FPV3_HF)89.Case("fpv3_hsf", llvm::CSKY::FK_FPV3_HSF)90.Case("fpv3_sdf", llvm::CSKY::FK_FPV3_SDF)91.Default(llvm::CSKY::FK_INVALID);92if (FPUID == llvm::CSKY::FK_INVALID) {93D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);94return llvm::CSKY::FK_INVALID;95}9697auto RemoveTargetFPUFeature =98[&Features](ArrayRef<const char *> FPUFeatures) {99for (auto FPUFeature : FPUFeatures) {100auto it = llvm::find(Features, FPUFeature);101if (it != Features.end())102Features.erase(it);103}104};105106RemoveTargetFPUFeature({"+fpuv2_sf", "+fpuv2_df", "+fdivdu", "+fpuv3_hi",107"+fpuv3_hf", "+fpuv3_sf", "+fpuv3_df"});108109if (!llvm::CSKY::getFPUFeatures(FPUID, Features)) {110D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);111return llvm::CSKY::FK_INVALID;112}113114return FPUID;115}116117void csky::getCSKYTargetFeatures(const Driver &D, const llvm::Triple &Triple,118const ArgList &Args, ArgStringList &CmdArgs,119std::vector<llvm::StringRef> &Features) {120llvm::StringRef archName;121llvm::StringRef cpuName;122llvm::CSKY::ArchKind ArchKind = llvm::CSKY::ArchKind::INVALID;123if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {124ArchKind = llvm::CSKY::parseArch(A->getValue());125if (ArchKind == llvm::CSKY::ArchKind::INVALID) {126D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);127return;128}129archName = A->getValue();130}131132if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ)) {133llvm::CSKY::ArchKind Kind = llvm::CSKY::parseCPUArch(A->getValue());134if (Kind == llvm::CSKY::ArchKind::INVALID) {135D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);136return;137}138if (!archName.empty() && Kind != ArchKind) {139D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);140return;141}142cpuName = A->getValue();143if (archName.empty())144archName = llvm::CSKY::getArchName(Kind);145}146147if (archName.empty() && cpuName.empty()) {148archName = "ck810";149cpuName = "ck810";150} else if (!archName.empty() && cpuName.empty()) {151cpuName = archName;152}153154csky::FloatABI FloatABI = csky::getCSKYFloatABI(D, Args);155156if (FloatABI == csky::FloatABI::Hard) {157Features.push_back("+hard-float-abi");158Features.push_back("+hard-float");159} else if (FloatABI == csky::FloatABI::SoftFP) {160Features.push_back("+hard-float");161}162163uint64_t Extension = llvm::CSKY::getDefaultExtensions(cpuName);164llvm::CSKY::getExtensionFeatures(Extension, Features);165166if (const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ))167getCSKYFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);168}169170171