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