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 StringLiteral DefaultMarch; 31 bool is64Bit() const { return DefaultMarch.starts_with("rv64"); } 32 }; 33 34 constexpr CPUInfo RISCVCPUInfo[] = { 35 #define PROC(ENUM, NAME, DEFAULT_MARCH) \ 36 {NAME, DEFAULT_MARCH}, 37 #include "llvm/TargetParser/RISCVTargetParserDef.inc" 38 }; 39 40 static const CPUInfo *getCPUInfoByName(StringRef CPU) { 41 for (auto &C : RISCVCPUInfo) 42 if (C.Name == CPU) 43 return &C; 44 return nullptr; 45 } 46 47 bool parseCPU(StringRef CPU, bool IsRV64) { 48 const CPUInfo *Info = getCPUInfoByName(CPU); 49 50 if (!Info) 51 return false; 52 return Info->is64Bit() == IsRV64; 53 } 54 55 bool parseTuneCPU(StringRef TuneCPU, bool IsRV64) { 56 std::optional<CPUKind> Kind = 57 llvm::StringSwitch<std::optional<CPUKind>>(TuneCPU) 58 #define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM) 59 #include "llvm/TargetParser/RISCVTargetParserDef.inc" 60 .Default(std::nullopt); 61 62 if (Kind.has_value()) 63 return true; 64 65 // Fallback to parsing as a CPU. 66 return parseCPU(TuneCPU, IsRV64); 67 } 68 69 StringRef getMArchFromMcpu(StringRef CPU) { 70 const CPUInfo *Info = getCPUInfoByName(CPU); 71 if (!Info) 72 return ""; 73 return Info->DefaultMarch; 74 } 75 76 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) { 77 for (const auto &C : RISCVCPUInfo) { 78 if (IsRV64 == C.is64Bit()) 79 Values.emplace_back(C.Name); 80 } 81 } 82 83 void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) { 84 for (const auto &C : RISCVCPUInfo) { 85 if (IsRV64 == C.is64Bit()) 86 Values.emplace_back(C.Name); 87 } 88 #define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME)); 89 #include "llvm/TargetParser/RISCVTargetParserDef.inc" 90 } 91 92 } // namespace RISCV 93 } // namespace llvm 94