1 //===-- RISCVTargetParser.cpp - Parser for target features ------*- 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 // This file implements a target parser to recognise hardware features 10 // for RISC-V CPUs. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/TargetParser/RISCVTargetParser.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringSwitch.h" 17 #include "llvm/TargetParser/Triple.h" 18 19 namespace llvm { 20 namespace RISCV { 21 22 enum CPUKind : unsigned { 23 #define PROC(ENUM, NAME, DEFAULT_MARCH) CK_##ENUM, 24 #define TUNE_PROC(ENUM, NAME) CK_##ENUM, 25 #include "llvm/TargetParser/RISCVTargetParserDef.inc" 26 }; 27 28 struct CPUInfo { 29 StringLiteral Name; 30 CPUKind Kind; 31 StringLiteral DefaultMarch; 32 bool is64Bit() const { return DefaultMarch.starts_with("rv64"); } 33 }; 34 35 constexpr CPUInfo RISCVCPUInfo[] = { 36 #define PROC(ENUM, NAME, DEFAULT_MARCH) \ 37 {NAME, CK_##ENUM, DEFAULT_MARCH}, 38 #include "llvm/TargetParser/RISCVTargetParserDef.inc" 39 }; 40 41 static const CPUInfo *getCPUInfoByName(StringRef CPU) { 42 for (auto &C : RISCVCPUInfo) 43 if (C.Name == CPU) 44 return &C; 45 return nullptr; 46 } 47 48 bool parseCPU(StringRef CPU, bool IsRV64) { 49 const CPUInfo *Info = getCPUInfoByName(CPU); 50 51 if (!Info) 52 return false; 53 return Info->is64Bit() == IsRV64; 54 } 55 56 bool parseTuneCPU(StringRef TuneCPU, bool IsRV64) { 57 std::optional<CPUKind> Kind = 58 llvm::StringSwitch<std::optional<CPUKind>>(TuneCPU) 59 #define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM) 60 #include "llvm/TargetParser/RISCVTargetParserDef.inc" 61 .Default(std::nullopt); 62 63 if (Kind.has_value()) 64 return true; 65 66 // Fallback to parsing as a CPU. 67 return parseCPU(TuneCPU, IsRV64); 68 } 69 70 StringRef getMArchFromMcpu(StringRef CPU) { 71 const CPUInfo *Info = getCPUInfoByName(CPU); 72 if (!Info) 73 return ""; 74 return Info->DefaultMarch; 75 } 76 77 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) { 78 for (const auto &C : RISCVCPUInfo) { 79 if (IsRV64 == C.is64Bit()) 80 Values.emplace_back(C.Name); 81 } 82 } 83 84 void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) { 85 for (const auto &C : RISCVCPUInfo) { 86 if (IsRV64 == C.is64Bit()) 87 Values.emplace_back(C.Name); 88 } 89 #define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME)); 90 #include "llvm/TargetParser/RISCVTargetParserDef.inc" 91 } 92 93 } // namespace RISCV 94 } // namespace llvm 95