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