| //===-- RISCVTargetParser.cpp - Parser for target features ------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements a target parser to recognise hardware features |
| // FOR RISC-V CPUS. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/TargetParser/RISCVTargetParser.h" |
| #include "llvm/ADT/SmallVector.h" |
| #include "llvm/ADT/StringSwitch.h" |
| #include "llvm/TargetParser/Triple.h" |
| |
| namespace llvm { |
| namespace RISCV { |
| |
| struct CPUInfo { |
| StringLiteral Name; |
| CPUKind Kind; |
| StringLiteral DefaultMarch; |
| bool isInvalid() const { return DefaultMarch.empty(); } |
| bool is64Bit() const { return DefaultMarch.starts_with("rv64"); } |
| }; |
| |
| constexpr CPUInfo RISCVCPUInfo[] = { |
| #define PROC(ENUM, NAME, DEFAULT_MARCH) \ |
| {NAME, CK_##ENUM, DEFAULT_MARCH}, |
| #include "llvm/TargetParser/RISCVTargetParserDef.inc" |
| }; |
| |
| bool checkCPUKind(CPUKind Kind, bool IsRV64) { |
| if (Kind == CK_INVALID) |
| return false; |
| return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64; |
| } |
| |
| bool checkTuneCPUKind(CPUKind Kind, bool IsRV64) { |
| if (Kind == CK_INVALID) |
| return false; |
| #define TUNE_PROC(ENUM, NAME) \ |
| if (Kind == CK_##ENUM) \ |
| return true; |
| #include "llvm/TargetParser/RISCVTargetParserDef.inc" |
| return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64; |
| } |
| |
| CPUKind parseCPUKind(StringRef CPU) { |
| return llvm::StringSwitch<CPUKind>(CPU) |
| #define PROC(ENUM, NAME, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) |
| #include "llvm/TargetParser/RISCVTargetParserDef.inc" |
| .Default(CK_INVALID); |
| } |
| |
| CPUKind parseTuneCPUKind(StringRef TuneCPU, bool IsRV64) { |
| return llvm::StringSwitch<CPUKind>(TuneCPU) |
| #define PROC(ENUM, NAME, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) |
| #define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM) |
| #include "llvm/TargetParser/RISCVTargetParserDef.inc" |
| .Default(CK_INVALID); |
| } |
| |
| StringRef getMArchFromMcpu(StringRef CPU) { |
| CPUKind Kind = parseCPUKind(CPU); |
| return RISCVCPUInfo[static_cast<unsigned>(Kind)].DefaultMarch; |
| } |
| |
| void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) { |
| for (const auto &C : RISCVCPUInfo) { |
| if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) |
| Values.emplace_back(C.Name); |
| } |
| } |
| |
| void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) { |
| for (const auto &C : RISCVCPUInfo) { |
| if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) |
| Values.emplace_back(C.Name); |
| } |
| #define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME)); |
| #include "llvm/TargetParser/RISCVTargetParserDef.inc" |
| } |
| |
| // Get all features except standard extension feature |
| bool getCPUFeaturesExceptStdExt(CPUKind Kind, |
| std::vector<StringRef> &Features) { |
| const CPUInfo &Info = RISCVCPUInfo[static_cast<unsigned>(Kind)]; |
| |
| if (Info.isInvalid()) |
| return false; |
| |
| if (Info.is64Bit()) |
| Features.push_back("+64bit"); |
| else |
| Features.push_back("-64bit"); |
| |
| return true; |
| } |
| |
| bool isX18ReservedByDefault(const Triple &TT) { |
| // X18 is reserved for the ShadowCallStack ABI (even when not enabled). |
| return TT.isOSFuchsia(); |
| } |
| |
| } // namespace RISCV |
| } // namespace llvm |