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;
is64Bitllvm::RISCV::CPUInfo32 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
getCPUInfoByName(StringRef CPU)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
hasFastUnalignedAccess(StringRef CPU)48 bool hasFastUnalignedAccess(StringRef CPU) {
49 const CPUInfo *Info = getCPUInfoByName(CPU);
50 return Info && Info->FastUnalignedAccess;
51 }
52
parseCPU(StringRef CPU,bool IsRV64)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
parseTuneCPU(StringRef TuneCPU,bool IsRV64)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
getMArchFromMcpu(StringRef CPU)75 StringRef getMArchFromMcpu(StringRef CPU) {
76 const CPUInfo *Info = getCPUInfoByName(CPU);
77 if (!Info)
78 return "";
79 return Info->DefaultMarch;
80 }
81
fillValidCPUArchList(SmallVectorImpl<StringRef> & Values,bool IsRV64)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
fillValidTuneCPUArchList(SmallVectorImpl<StringRef> & Values,bool IsRV64)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