xref: /freebsd/contrib/llvm-project/llvm/lib/TargetParser/RISCVTargetParser.cpp (revision 7ef62cebc2f965b0f640263e179276928885e33d)
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 struct CPUInfo {
23   StringLiteral Name;
24   CPUKind Kind;
25   StringLiteral DefaultMarch;
26   bool isInvalid() const { return DefaultMarch.empty(); }
27   bool is64Bit() const { return DefaultMarch.starts_with("rv64"); }
28 };
29 
30 constexpr CPUInfo RISCVCPUInfo[] = {
31 #define PROC(ENUM, NAME, DEFAULT_MARCH)                              \
32   {NAME, CK_##ENUM, DEFAULT_MARCH},
33 #include "llvm/TargetParser/RISCVTargetParserDef.inc"
34 };
35 
36 bool checkCPUKind(CPUKind Kind, bool IsRV64) {
37   if (Kind == CK_INVALID)
38     return false;
39   return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64;
40 }
41 
42 bool checkTuneCPUKind(CPUKind Kind, bool IsRV64) {
43   if (Kind == CK_INVALID)
44     return false;
45 #define TUNE_PROC(ENUM, NAME)                                                  \
46   if (Kind == CK_##ENUM)                                                       \
47     return true;
48 #include "llvm/TargetParser/RISCVTargetParserDef.inc"
49   return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64;
50 }
51 
52 CPUKind parseCPUKind(StringRef CPU) {
53   return llvm::StringSwitch<CPUKind>(CPU)
54 #define PROC(ENUM, NAME, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
55 #include "llvm/TargetParser/RISCVTargetParserDef.inc"
56       .Default(CK_INVALID);
57 }
58 
59 CPUKind parseTuneCPUKind(StringRef TuneCPU, bool IsRV64) {
60   return llvm::StringSwitch<CPUKind>(TuneCPU)
61 #define PROC(ENUM, NAME, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
62 #define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM)
63 #include "llvm/TargetParser/RISCVTargetParserDef.inc"
64       .Default(CK_INVALID);
65 }
66 
67 StringRef getMArchFromMcpu(StringRef CPU) {
68   CPUKind Kind = parseCPUKind(CPU);
69   return RISCVCPUInfo[static_cast<unsigned>(Kind)].DefaultMarch;
70 }
71 
72 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) {
73   for (const auto &C : RISCVCPUInfo) {
74     if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit())
75       Values.emplace_back(C.Name);
76   }
77 }
78 
79 void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) {
80   for (const auto &C : RISCVCPUInfo) {
81     if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit())
82       Values.emplace_back(C.Name);
83   }
84 #define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME));
85 #include "llvm/TargetParser/RISCVTargetParserDef.inc"
86 }
87 
88 // Get all features except standard extension feature
89 bool getCPUFeaturesExceptStdExt(CPUKind Kind,
90                                 std::vector<StringRef> &Features) {
91   const CPUInfo &Info = RISCVCPUInfo[static_cast<unsigned>(Kind)];
92 
93   if (Info.isInvalid())
94     return false;
95 
96   if (Info.is64Bit())
97     Features.push_back("+64bit");
98   else
99     Features.push_back("-64bit");
100 
101   return true;
102 }
103 
104 bool isX18ReservedByDefault(const Triple &TT) {
105   // X18 is reserved for the ShadowCallStack ABI (even when not enabled).
106   return TT.isOSFuchsia();
107 }
108 
109 } // namespace RISCV
110 } // namespace llvm
111