LLVM 19.0.0git
RISCVTargetParser.cpp
Go to the documentation of this file.
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
19
20namespace llvm {
21namespace RISCV {
22
23enum CPUKind : unsigned {
24#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGN) CK_##ENUM,
25#define TUNE_PROC(ENUM, NAME) CK_##ENUM,
26#include "llvm/TargetParser/RISCVTargetParserDef.inc"
27};
28
29struct CPUInfo {
33 bool is64Bit() const { return DefaultMarch.starts_with("rv64"); }
34};
35
36constexpr CPUInfo RISCVCPUInfo[] = {
37#define PROC(ENUM, NAME, DEFAULT_MARCH, FAST_UNALIGN) \
38 {NAME, DEFAULT_MARCH, FAST_UNALIGN},
39#include "llvm/TargetParser/RISCVTargetParserDef.inc"
40};
41
43 for (auto &C : RISCVCPUInfo)
44 if (C.Name == CPU)
45 return &C;
46 return nullptr;
47}
48
50 const CPUInfo *Info = getCPUInfoByName(CPU);
51 return Info && Info->FastUnalignedAccess;
52}
53
54bool parseCPU(StringRef CPU, bool IsRV64) {
55 const CPUInfo *Info = getCPUInfoByName(CPU);
56
57 if (!Info)
58 return false;
59 return Info->is64Bit() == IsRV64;
60}
61
62bool parseTuneCPU(StringRef TuneCPU, bool IsRV64) {
63 std::optional<CPUKind> Kind =
65#define TUNE_PROC(ENUM, NAME) .Case(NAME, CK_##ENUM)
66 #include "llvm/TargetParser/RISCVTargetParserDef.inc"
67 .Default(std::nullopt);
68
69 if (Kind.has_value())
70 return true;
71
72 // Fallback to parsing as a CPU.
73 return parseCPU(TuneCPU, IsRV64);
74}
75
77 const CPUInfo *Info = getCPUInfoByName(CPU);
78 if (!Info)
79 return "";
80 return Info->DefaultMarch;
81}
82
84 for (const auto &C : RISCVCPUInfo) {
85 if (IsRV64 == C.is64Bit())
86 Values.emplace_back(C.Name);
87 }
88}
89
91 for (const auto &C : RISCVCPUInfo) {
92 if (IsRV64 == C.is64Bit())
93 Values.emplace_back(C.Name);
94 }
95#define TUNE_PROC(ENUM, NAME) Values.emplace_back(StringRef(NAME));
96#include "llvm/TargetParser/RISCVTargetParserDef.inc"
97}
98
99// This function is currently used by IREE, so it's not dead code.
101 SmallVectorImpl<std::string> &EnabledFeatures,
102 bool NeedPlus) {
103 StringRef MarchFromCPU = llvm::RISCV::getMArchFromMcpu(CPU);
104 if (MarchFromCPU == "")
105 return;
106
107 EnabledFeatures.clear();
109 MarchFromCPU, /* EnableExperimentalExtension */ true);
110
111 if (llvm::errorToBool(RII.takeError()))
112 return;
113
114 std::vector<std::string> FeatStrings =
115 (*RII)->toFeatures(/* AddAllExtensions */ false);
116 for (const auto &F : FeatStrings)
117 if (NeedPlus)
118 EnabledFeatures.push_back(F);
119 else
120 EnabledFeatures.push_back(F.substr(1));
121}
122} // namespace RISCV
123
124namespace RISCVVType {
125// Encode VTYPE into the binary format used by the the VSETVLI instruction which
126// is used by our MC layer representation.
127//
128// Bits | Name | Description
129// -----+------------+------------------------------------------------
130// 7 | vma | Vector mask agnostic
131// 6 | vta | Vector tail agnostic
132// 5:3 | vsew[2:0] | Standard element width (SEW) setting
133// 2:0 | vlmul[2:0] | Vector register group multiplier (LMUL) setting
134unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic,
135 bool MaskAgnostic) {
136 assert(isValidSEW(SEW) && "Invalid SEW");
137 unsigned VLMULBits = static_cast<unsigned>(VLMUL);
138 unsigned VSEWBits = encodeSEW(SEW);
139 unsigned VTypeI = (VSEWBits << 3) | (VLMULBits & 0x7);
140 if (TailAgnostic)
141 VTypeI |= 0x40;
142 if (MaskAgnostic)
143 VTypeI |= 0x80;
144
145 return VTypeI;
146}
147
148std::pair<unsigned, bool> decodeVLMUL(RISCVII::VLMUL VLMUL) {
149 switch (VLMUL) {
150 default:
151 llvm_unreachable("Unexpected LMUL value!");
156 return std::make_pair(1 << static_cast<unsigned>(VLMUL), false);
160 return std::make_pair(1 << (8 - static_cast<unsigned>(VLMUL)), true);
161 }
162}
163
164void printVType(unsigned VType, raw_ostream &OS) {
165 unsigned Sew = getSEW(VType);
166 OS << "e" << Sew;
167
168 unsigned LMul;
169 bool Fractional;
170 std::tie(LMul, Fractional) = decodeVLMUL(getVLMUL(VType));
171
172 if (Fractional)
173 OS << ", mf";
174 else
175 OS << ", m";
176 OS << LMul;
177
178 if (isTailAgnostic(VType))
179 OS << ", ta";
180 else
181 OS << ", tu";
182
183 if (isMaskAgnostic(VType))
184 OS << ", ma";
185 else
186 OS << ", mu";
187}
188
189unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul) {
190 unsigned LMul;
191 bool Fractional;
192 std::tie(LMul, Fractional) = decodeVLMUL(VLMul);
193
194 // Convert LMul to a fixed point value with 3 fractional bits.
195 LMul = Fractional ? (8 / LMul) : (LMul * 8);
196
197 assert(SEW >= 8 && "Unexpected SEW value");
198 return (SEW * 8) / LMul;
199}
200
201std::optional<RISCVII::VLMUL>
202getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW) {
203 unsigned Ratio = RISCVVType::getSEWLMULRatio(SEW, VLMUL);
204 unsigned EMULFixedPoint = (EEW * 8) / Ratio;
205 bool Fractional = EMULFixedPoint < 8;
206 unsigned EMUL = Fractional ? 8 / EMULFixedPoint : EMULFixedPoint / 8;
207 if (!isValidLMUL(EMUL, Fractional))
208 return std::nullopt;
209 return RISCVVType::encodeLMUL(EMUL, Fractional);
210}
211
212} // namespace RISCVVType
213
214} // namespace llvm
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define ENUM(Name,...)
Definition: ClauseT.h:61
#define F(x, y, z)
Definition: MD5.cpp:55
#define TUNE_PROC(ENUM, NAME)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true, bool IgnoreUnknown=false)
Parse RISC-V ISA info from arch string.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:950
void push_back(const T &Elt)
Definition: SmallVector.h:426
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:849
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:257
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
static bool isTailAgnostic(unsigned VType)
static RISCVII::VLMUL getVLMUL(unsigned VType)
std::pair< unsigned, bool > decodeVLMUL(RISCVII::VLMUL VLMUL)
unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
static bool isMaskAgnostic(unsigned VType)
static unsigned encodeSEW(unsigned SEW)
static bool isValidSEW(unsigned SEW)
void printVType(unsigned VType, raw_ostream &OS)
unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic)
static unsigned getSEW(unsigned VType)
std::optional< RISCVII::VLMUL > getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW)
void getFeaturesForCPU(StringRef CPU, SmallVectorImpl< std::string > &EnabledFeatures, bool NeedPlus=false)
void fillValidTuneCPUArchList(SmallVectorImpl< StringRef > &Values, bool IsRV64)
static const CPUInfo * getCPUInfoByName(StringRef CPU)
constexpr CPUInfo RISCVCPUInfo[]
bool hasFastUnalignedAccess(StringRef CPU)
StringRef getMArchFromMcpu(StringRef CPU)
bool parseCPU(StringRef CPU, bool IsRV64)
bool parseTuneCPU(StringRef CPU, bool IsRV64)
void fillValidCPUArchList(SmallVectorImpl< StringRef > &Values, bool IsRV64)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
Definition: Error.h:1071