brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.9 KiB · 65f6534 Raw
166 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "CSKY.h"10#include "clang/Driver/Driver.h"11#include "clang/Options/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(A->getValue());28 29    if (ArchKind == llvm::CSKY::ArchKind::INVALID) {30      D.Diag(clang::diag::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(options::OPT_mcpu_EQ)) {37    llvm::CSKY::ArchKind ArchKind = llvm::CSKY::parseCPUArch(A->getValue());38    if (ArchKind == llvm::CSKY::ArchKind::INVALID) {39      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);40      return std::nullopt;41    }42    return std::optional<llvm::StringRef>(llvm::CSKY::getArchName(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::OPT_msoft_float)) {54      ABI = FloatABI::Soft;55    } else if (A->getOption().matches(options::OPT_mhard_float)) {56      ABI = FloatABI::Hard;57    } else {58      ABI = llvm::StringSwitch<csky::FloatABI>(A->getValue())59                .Case("soft", FloatABI::Soft)60                .Case("softfp", FloatABI::SoftFP)61                .Case("hard", FloatABI::Hard)62                .Default(FloatABI::Invalid);63      if (ABI == FloatABI::Invalid) {64        D.Diag(diag::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::CSKYFPUKind75getCSKYFPUFeatures(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("auto", llvm::CSKY::FK_AUTO)81          .Case("fpv2", llvm::CSKY::FK_FPV2)82          .Case("fpv2_divd", llvm::CSKY::FK_FPV2_DIVD)83          .Case("fpv2_sf", llvm::CSKY::FK_FPV2_SF)84          .Case("fpv3", llvm::CSKY::FK_FPV3)85          .Case("fpv3_hf", llvm::CSKY::FK_FPV3_HF)86          .Case("fpv3_hsf", llvm::CSKY::FK_FPV3_HSF)87          .Case("fpv3_sdf", llvm::CSKY::FK_FPV3_SDF)88          .Default(llvm::CSKY::FK_INVALID);89  if (FPUID == llvm::CSKY::FK_INVALID) {90    D.Diag(clang::diag::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(Features, FPUFeature);98          if (it != Features.end())99            Features.erase(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(FPUID, Features)) {107    D.Diag(clang::diag::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(A->getValue());122    if (ArchKind == llvm::CSKY::ArchKind::INVALID) {123      D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);124      return;125    }126    archName = A->getValue();127  }128 129  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {130    llvm::CSKY::ArchKind Kind = llvm::CSKY::parseCPUArch(A->getValue());131    if (Kind == llvm::CSKY::ArchKind::INVALID) {132      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);133      return;134    }135    if (!archName.empty() && Kind != ArchKind) {136      D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);137      return;138    }139    cpuName = A->getValue();140    if (archName.empty())141      archName = llvm::CSKY::getArchName(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("+hard-float-abi");155    Features.push_back("+hard-float");156  } else if (FloatABI == csky::FloatABI::SoftFP) {157    Features.push_back("+hard-float");158  }159 160  uint64_t Extension = llvm::CSKY::getDefaultExtensions(cpuName);161  llvm::CSKY::getExtensionFeatures(Extension, Features);162 163  if (const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ))164    getCSKYFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);165}166