xref: /freebsd-src/contrib/llvm-project/llvm/lib/TargetParser/RISCVTargetParser.cpp (revision 1ac55f4cb0001fed92329746c730aa9a947c09a5)
1bdd1243dSDimitry Andric //===-- RISCVTargetParser.cpp - Parser for target features ------*- C++ -*-===//
2bdd1243dSDimitry Andric //
3bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bdd1243dSDimitry Andric //
7bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
8bdd1243dSDimitry Andric //
9bdd1243dSDimitry Andric // This file implements a target parser to recognise hardware features
10bdd1243dSDimitry Andric // FOR RISC-V CPUS.
11bdd1243dSDimitry Andric //
12bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
13bdd1243dSDimitry Andric 
14bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParser.h"
15bdd1243dSDimitry Andric #include "llvm/ADT/SmallVector.h"
16bdd1243dSDimitry Andric #include "llvm/ADT/StringSwitch.h"
17*1ac55f4cSDimitry Andric #include "llvm/TargetParser/Triple.h"
18bdd1243dSDimitry Andric 
19bdd1243dSDimitry Andric namespace llvm {
20bdd1243dSDimitry Andric namespace RISCV {
21bdd1243dSDimitry Andric 
22bdd1243dSDimitry Andric struct CPUInfo {
23bdd1243dSDimitry Andric   StringLiteral Name;
24bdd1243dSDimitry Andric   CPUKind Kind;
25bdd1243dSDimitry Andric   StringLiteral DefaultMarch;
26bdd1243dSDimitry Andric   bool isInvalid() const { return DefaultMarch.empty(); }
27bdd1243dSDimitry Andric   bool is64Bit() const { return DefaultMarch.starts_with("rv64"); }
28bdd1243dSDimitry Andric };
29bdd1243dSDimitry Andric 
30bdd1243dSDimitry Andric constexpr CPUInfo RISCVCPUInfo[] = {
31bdd1243dSDimitry Andric #define PROC(ENUM, NAME, DEFAULT_MARCH)                              \
32bdd1243dSDimitry Andric   {NAME, CK_##ENUM, DEFAULT_MARCH},
33bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParserDef.inc"
34bdd1243dSDimitry Andric };
35bdd1243dSDimitry Andric 
36bdd1243dSDimitry Andric bool checkCPUKind(CPUKind Kind, bool IsRV64) {
37bdd1243dSDimitry Andric   if (Kind == CK_INVALID)
38bdd1243dSDimitry Andric     return false;
39bdd1243dSDimitry Andric   return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64;
40bdd1243dSDimitry Andric }
41bdd1243dSDimitry Andric 
42bdd1243dSDimitry Andric bool checkTuneCPUKind(CPUKind Kind, bool IsRV64) {
43bdd1243dSDimitry Andric   if (Kind == CK_INVALID)
44bdd1243dSDimitry Andric     return false;
45bdd1243dSDimitry Andric #define TUNE_PROC(ENUM, NAME)                                                  \
46bdd1243dSDimitry Andric   if (Kind == CK_##ENUM)                                                       \
47bdd1243dSDimitry Andric     return true;
48bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParserDef.inc"
49bdd1243dSDimitry Andric   return RISCVCPUInfo[static_cast<unsigned>(Kind)].is64Bit() == IsRV64;
50bdd1243dSDimitry Andric }
51bdd1243dSDimitry Andric 
52bdd1243dSDimitry Andric CPUKind parseCPUKind(StringRef CPU) {
53bdd1243dSDimitry Andric   return llvm::StringSwitch<CPUKind>(CPU)
54bdd1243dSDimitry Andric #define PROC(ENUM, NAME, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
55bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParserDef.inc"
56bdd1243dSDimitry Andric       .Default(CK_INVALID);
57bdd1243dSDimitry Andric }
58bdd1243dSDimitry Andric 
59bdd1243dSDimitry Andric CPUKind parseTuneCPUKind(StringRef TuneCPU, bool IsRV64) {
60bdd1243dSDimitry Andric   return llvm::StringSwitch<CPUKind>(TuneCPU)
61bdd1243dSDimitry Andric #define PROC(ENUM, NAME, DEFAULT_MARCH) .Case(NAME, CK_##ENUM)
62bdd1243dSDimitry Andric #define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM)
63bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParserDef.inc"
64bdd1243dSDimitry Andric       .Default(CK_INVALID);
65bdd1243dSDimitry Andric }
66bdd1243dSDimitry Andric 
67bdd1243dSDimitry Andric StringRef getMArchFromMcpu(StringRef CPU) {
68bdd1243dSDimitry Andric   CPUKind Kind = parseCPUKind(CPU);
69bdd1243dSDimitry Andric   return RISCVCPUInfo[static_cast<unsigned>(Kind)].DefaultMarch;
70bdd1243dSDimitry Andric }
71bdd1243dSDimitry Andric 
72bdd1243dSDimitry Andric void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) {
73bdd1243dSDimitry Andric   for (const auto &C : RISCVCPUInfo) {
74bdd1243dSDimitry Andric     if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit())
75bdd1243dSDimitry Andric       Values.emplace_back(C.Name);
76bdd1243dSDimitry Andric   }
77bdd1243dSDimitry Andric }
78bdd1243dSDimitry Andric 
79bdd1243dSDimitry Andric void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) {
80bdd1243dSDimitry Andric   for (const auto &C : RISCVCPUInfo) {
81bdd1243dSDimitry Andric     if (C.Kind != CK_INVALID && IsRV64 == C.is64Bit())
82bdd1243dSDimitry Andric       Values.emplace_back(C.Name);
83bdd1243dSDimitry Andric   }
84bdd1243dSDimitry Andric #define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME));
85bdd1243dSDimitry Andric #include "llvm/TargetParser/RISCVTargetParserDef.inc"
86bdd1243dSDimitry Andric }
87bdd1243dSDimitry Andric 
88bdd1243dSDimitry Andric // Get all features except standard extension feature
89bdd1243dSDimitry Andric bool getCPUFeaturesExceptStdExt(CPUKind Kind,
90bdd1243dSDimitry Andric                                 std::vector<StringRef> &Features) {
91bdd1243dSDimitry Andric   const CPUInfo &Info = RISCVCPUInfo[static_cast<unsigned>(Kind)];
92bdd1243dSDimitry Andric 
93bdd1243dSDimitry Andric   if (Info.isInvalid())
94bdd1243dSDimitry Andric     return false;
95bdd1243dSDimitry Andric 
96bdd1243dSDimitry Andric   if (Info.is64Bit())
97bdd1243dSDimitry Andric     Features.push_back("+64bit");
98bdd1243dSDimitry Andric   else
99bdd1243dSDimitry Andric     Features.push_back("-64bit");
100bdd1243dSDimitry Andric 
101bdd1243dSDimitry Andric   return true;
102bdd1243dSDimitry Andric }
103bdd1243dSDimitry Andric 
104*1ac55f4cSDimitry Andric bool isX18ReservedByDefault(const Triple &TT) {
105*1ac55f4cSDimitry Andric   // X18 is reserved for the ShadowCallStack ABI (even when not enabled).
106*1ac55f4cSDimitry Andric   return TT.isOSFuchsia();
107*1ac55f4cSDimitry Andric }
108*1ac55f4cSDimitry Andric 
109bdd1243dSDimitry Andric } // namespace RISCV
110bdd1243dSDimitry Andric } // namespace llvm
111