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, FAST_UNALIGN) 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 StringLiteral DefaultMarch; 31 bool FastUnalignedAccess; 32 bool is64Bit() const { return DefaultMarch.starts_with("rv64"); } 33 }; 34 35 constexpr CPUInfo RISCVCPUInfo[] = { 36 #define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGN) \ 37 {NAME, DEFAULT_MARCH, FAST_UNALIGN}, 38 #include "llvm/TargetParser/RISCVTargetParserDef.inc" 39 }; 40 41 static const CPUInfo *getCPUInfoByName(StringRef CPU) { 42 for (auto &C : RISCVCPUInfo) 43 if (C.Name == CPU) 44 return &C; 45 return nullptr; 46 } 47 48 bool hasFastUnalignedAccess(StringRef CPU) { 49 const CPUInfo *Info = getCPUInfoByName(CPU); 50 return Info && Info->FastUnalignedAccess; 51 } 52 53 bool parseCPU(StringRef CPU, bool IsRV64) { 54 const CPUInfo *Info = getCPUInfoByName(CPU); 55 56 if (!Info) 57 return false; 58 return Info->is64Bit() == IsRV64; 59 } 60 61 bool parseTuneCPU(StringRef TuneCPU, bool IsRV64) { 62 std::optional<CPUKind> Kind = 63 llvm::StringSwitch<std::optional<CPUKind>>(TuneCPU) 64 #define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM) 65 #include "llvm/TargetParser/RISCVTargetParserDef.inc" 66 .Default(std::nullopt); 67 68 if (Kind.has_value()) 69 return true; 70 71 // Fallback to parsing as a CPU. 72 return parseCPU(TuneCPU, IsRV64); 73 } 74 75 StringRef getMArchFromMcpu(StringRef CPU) { 76 const CPUInfo *Info = getCPUInfoByName(CPU); 77 if (!Info) 78 return ""; 79 return Info->DefaultMarch; 80 } 81 82 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) { 83 for (const auto &C : RISCVCPUInfo) { 84 if (IsRV64 == C.is64Bit()) 85 Values.emplace_back(C.Name); 86 } 87 } 88 89 void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64) { 90 for (const auto &C : RISCVCPUInfo) { 91 if (IsRV64 == C.is64Bit()) 92 Values.emplace_back(C.Name); 93 } 94 #define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME)); 95 #include "llvm/TargetParser/RISCVTargetParserDef.inc" 96 } 97 98 } // namespace RISCV 99 } // namespace llvm 100