xref: /llvm-project/llvm/lib/TargetParser/RISCVTargetParser.cpp (revision 09f6bdda24d57c40cd4bd27c598d875c226cd5f2)
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