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