1*bdd1243dSDimitry Andric //===-- RISCVTargetParser.cpp - Parser for target features ------*- C++ -*-===// 2*bdd1243dSDimitry Andric // 3*bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*bdd1243dSDimitry Andric // 7*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 8*bdd1243dSDimitry Andric // 9*bdd1243dSDimitry Andric // This file implements a target parser to recognise hardware features 10*bdd1243dSDimitry Andric // FOR RISC-V CPUS. 11*bdd1243dSDimitry Andric // 12*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 13*bdd1243dSDimitry Andric 14*bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParser.h" 15*bdd1243dSDimitry Andric #include "llvm/ADT/SmallVector.h" 16*bdd1243dSDimitry Andric #include "llvm/ADT/StringSwitch.h" 17*bdd1243dSDimitry Andric 18*bdd1243dSDimitry Andric namespace llvm { 19*bdd1243dSDimitry Andric namespace RISCV { 20*bdd1243dSDimitry Andric 21*bdd1243dSDimitry Andric struct CPUInfo { 22*bdd1243dSDimitry Andric StringLiteral Name; 23*bdd1243dSDimitry Andric CPUKind Kind; 24*bdd1243dSDimitry Andric StringLiteral DefaultMarch; 25*bdd1243dSDimitry Andric bool isInvalid() const { return DefaultMarch.empty(); } 26*bdd1243dSDimitry Andric bool is64Bit() const { return DefaultMarch.starts_with("rv64"); } 27*bdd1243dSDimitry Andric }; 28*bdd1243dSDimitry Andric 29*bdd1243dSDimitry Andric constexpr CPUInfo RISCVCPUInfo[] = { 30*bdd1243dSDimitry Andric #define PROC(ENUM, NAME, DEFAULT_MARCH) \ 31*bdd1243dSDimitry Andric {NAME, CK_##ENUM, DEFAULT_MARCH}, 32*bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParserDef.inc" 33*bdd1243dSDimitry Andric }; 34*bdd1243dSDimitry Andric 35*bdd1243dSDimitry Andric bool checkCPUKind(CPUKind Kind, bool IsRV64) { 36*bdd1243dSDimitry Andric if (Kind == CK_INVALID) 37*bdd1243dSDimitry Andric return false; 38*bdd1243dSDimitry Andric return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64; 39*bdd1243dSDimitry Andric } 40*bdd1243dSDimitry Andric 41*bdd1243dSDimitry Andric bool checkTuneCPUKind(CPUKind Kind, bool IsRV64) { 42*bdd1243dSDimitry Andric if (Kind == CK_INVALID) 43*bdd1243dSDimitry Andric return false; 44*bdd1243dSDimitry Andric #define TUNE_PROC(ENUM, NAME) \ 45*bdd1243dSDimitry Andric if (Kind == CK_##ENUM) \ 46*bdd1243dSDimitry Andric return true; 47*bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParserDef.inc" 48*bdd1243dSDimitry Andric return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64; 49*bdd1243dSDimitry Andric } 50*bdd1243dSDimitry Andric 51*bdd1243dSDimitry Andric CPUKind parseCPUKind(StringRef CPU) { 52*bdd1243dSDimitry Andric return llvm::StringSwitch<CPUKind>(CPU) 53*bdd1243dSDimitry Andric #define PROC(ENUM, NAME, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) 54*bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParserDef.inc" 55*bdd1243dSDimitry Andric .Default(CK_INVALID); 56*bdd1243dSDimitry Andric } 57*bdd1243dSDimitry Andric 58*bdd1243dSDimitry Andric CPUKind parseTuneCPUKind(StringRef TuneCPU, bool IsRV64) { 59*bdd1243dSDimitry Andric return llvm::StringSwitch<CPUKind>(TuneCPU) 60*bdd1243dSDimitry Andric #define PROC(ENUM, NAME, DEFAULT_MARCH) .Case(NAME, CK_##ENUM) 61*bdd1243dSDimitry Andric #define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM) 62*bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParserDef.inc" 63*bdd1243dSDimitry Andric .Default(CK_INVALID); 64*bdd1243dSDimitry Andric } 65*bdd1243dSDimitry Andric 66*bdd1243dSDimitry Andric StringRef getMArchFromMcpu(StringRef CPU) { 67*bdd1243dSDimitry Andric CPUKind Kind = parseCPUKind(CPU); 68*bdd1243dSDimitry Andric return RISCVCPUInfo[static_cast<unsigned>(Kind)].DefaultMarch; 69*bdd1243dSDimitry Andric } 70*bdd1243dSDimitry Andric 71*bdd1243dSDimitry Andric void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) { 72*bdd1243dSDimitry Andric for (const auto &C : RISCVCPUInfo) { 73*bdd1243dSDimitry Andric if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) 74*bdd1243dSDimitry Andric Values.emplace_back(C.Name); 75*bdd1243dSDimitry Andric } 76*bdd1243dSDimitry Andric } 77*bdd1243dSDimitry Andric 78*bdd1243dSDimitry Andric void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) { 79*bdd1243dSDimitry Andric for (const auto &C : RISCVCPUInfo) { 80*bdd1243dSDimitry Andric if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit()) 81*bdd1243dSDimitry Andric Values.emplace_back(C.Name); 82*bdd1243dSDimitry Andric } 83*bdd1243dSDimitry Andric #define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME)); 84*bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParserDef.inc" 85*bdd1243dSDimitry Andric } 86*bdd1243dSDimitry Andric 87*bdd1243dSDimitry Andric // Get all features except standard extension feature 88*bdd1243dSDimitry Andric bool getCPUFeaturesExceptStdExt(CPUKind Kind, 89*bdd1243dSDimitry Andric std::vector<StringRef> &Features) { 90*bdd1243dSDimitry Andric const CPUInfo &Info = RISCVCPUInfo[static_cast<unsigned>(Kind)]; 91*bdd1243dSDimitry Andric 92*bdd1243dSDimitry Andric if (Info.isInvalid()) 93*bdd1243dSDimitry Andric return false; 94*bdd1243dSDimitry Andric 95*bdd1243dSDimitry Andric if (Info.is64Bit()) 96*bdd1243dSDimitry Andric Features.push_back("+64bit"); 97*bdd1243dSDimitry Andric else 98*bdd1243dSDimitry Andric Features.push_back("-64bit"); 99*bdd1243dSDimitry Andric 100*bdd1243dSDimitry Andric return true; 101*bdd1243dSDimitry Andric } 102*bdd1243dSDimitry Andric 103*bdd1243dSDimitry Andric } // namespace RISCV 104*bdd1243dSDimitry Andric } // namespace llvm 105