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