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