xref: /freebsd/contrib/llvm-project/llvm/include/llvm/TargetParser/RISCVTargetParser.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- RISCVTargetParser - 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 #ifndef LLVM_TARGETPARSER_RISCVTARGETPARSER_H
15 #define LLVM_TARGETPARSER_RISCVTARGETPARSER_H
16 
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/Support/MathExtras.h"
20 #include "llvm/Support/raw_ostream.h"
21 
22 namespace llvm {
23 
24 class Triple;
25 
26 namespace RISCV {
27 
28 struct CPUModel {
29   uint32_t MVendorID;
30   uint64_t MArchID;
31   uint64_t MImpID;
32 
isValidCPUModel33   bool isValid() const { return MVendorID != 0 && MArchID != 0 && MImpID != 0; }
34 
35   bool operator==(const CPUModel &Other) const {
36     return MVendorID == Other.MVendorID && MArchID == Other.MArchID &&
37            MImpID == Other.MImpID;
38   }
39 };
40 
41 struct CPUInfo {
42   StringLiteral Name;
43   StringLiteral DefaultMarch;
44   bool FastScalarUnalignedAccess;
45   bool FastVectorUnalignedAccess;
46   CPUModel Model;
is64BitCPUInfo47   bool is64Bit() const { return DefaultMarch.starts_with("rv64"); }
48 };
49 
50 // We use 64 bits as the known part in the scalable vector types.
51 static constexpr unsigned RVVBitsPerBlock = 64;
52 static constexpr unsigned RVVBytesPerBlock = RVVBitsPerBlock / 8;
53 
54 LLVM_ABI void getFeaturesForCPU(StringRef CPU,
55                                 SmallVectorImpl<std::string> &EnabledFeatures,
56                                 bool NeedPlus = false);
57 LLVM_ABI bool parseCPU(StringRef CPU, bool IsRV64);
58 LLVM_ABI bool parseTuneCPU(StringRef CPU, bool IsRV64);
59 LLVM_ABI StringRef getMArchFromMcpu(StringRef CPU);
60 LLVM_ABI void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values,
61                                    bool IsRV64);
62 LLVM_ABI void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values,
63                                        bool IsRV64);
64 LLVM_ABI bool hasFastScalarUnalignedAccess(StringRef CPU);
65 LLVM_ABI bool hasFastVectorUnalignedAccess(StringRef CPU);
66 LLVM_ABI bool hasValidCPUModel(StringRef CPU);
67 LLVM_ABI CPUModel getCPUModel(StringRef CPU);
68 LLVM_ABI StringRef getCPUNameFromCPUModel(const CPUModel &Model);
69 
70 } // namespace RISCV
71 
72 namespace RISCVVType {
73 enum VLMUL : uint8_t {
74   LMUL_1 = 0,
75   LMUL_2,
76   LMUL_4,
77   LMUL_8,
78   LMUL_RESERVED,
79   LMUL_F8,
80   LMUL_F4,
81   LMUL_F2
82 };
83 
84 enum {
85   TAIL_UNDISTURBED_MASK_UNDISTURBED = 0,
86   TAIL_AGNOSTIC = 1,
87   MASK_AGNOSTIC = 2,
88 };
89 
90 // Is this a SEW value that can be encoded into the VTYPE format.
isValidSEW(unsigned SEW)91 inline static bool isValidSEW(unsigned SEW) {
92   return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 64;
93 }
94 
95 // Is this a LMUL value that can be encoded into the VTYPE format.
isValidLMUL(unsigned LMUL,bool Fractional)96 inline static bool isValidLMUL(unsigned LMUL, bool Fractional) {
97   return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1);
98 }
99 
100 LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic,
101                               bool MaskAgnostic);
102 
103 LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt);
104 
getVLMUL(unsigned VType)105 inline static VLMUL getVLMUL(unsigned VType) {
106   unsigned VLMul = VType & 0x7;
107   return static_cast<VLMUL>(VLMul);
108 }
109 
110 // Decode VLMUL into 1,2,4,8 and fractional indicator.
111 LLVM_ABI std::pair<unsigned, bool> decodeVLMUL(VLMUL VLMul);
112 
encodeLMUL(unsigned LMUL,bool Fractional)113 inline static VLMUL encodeLMUL(unsigned LMUL, bool Fractional) {
114   assert(isValidLMUL(LMUL, Fractional) && "Unsupported LMUL");
115   unsigned LmulLog2 = Log2_32(LMUL);
116   return static_cast<VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2);
117 }
118 
decodeVSEW(unsigned VSEW)119 inline static unsigned decodeVSEW(unsigned VSEW) {
120   assert(VSEW < 8 && "Unexpected VSEW value");
121   return 1 << (VSEW + 3);
122 }
123 
encodeSEW(unsigned SEW)124 inline static unsigned encodeSEW(unsigned SEW) {
125   assert(isValidSEW(SEW) && "Unexpected SEW value");
126   return Log2_32(SEW) - 3;
127 }
128 
getSEW(unsigned VType)129 inline static unsigned getSEW(unsigned VType) {
130   unsigned VSEW = (VType >> 3) & 0x7;
131   return decodeVSEW(VSEW);
132 }
133 
decodeTWiden(unsigned TWiden)134 inline static unsigned decodeTWiden(unsigned TWiden) {
135   assert((TWiden == 1 || TWiden == 2 || TWiden == 3) &&
136          "Unexpected TWiden value");
137   return 1 << (TWiden - 1);
138 }
139 
hasXSfmmWiden(unsigned VType)140 inline static bool hasXSfmmWiden(unsigned VType) {
141   unsigned TWiden = (VType >> 9) & 0x3;
142   return TWiden != 0;
143 }
144 
getXSfmmWiden(unsigned VType)145 inline static unsigned getXSfmmWiden(unsigned VType) {
146   unsigned TWiden = (VType >> 9) & 0x3;
147   assert(TWiden != 0 && "Invalid widen value");
148   return 1 << (TWiden - 1);
149 }
150 
isValidXSfmmVType(unsigned VTypeI)151 static inline bool isValidXSfmmVType(unsigned VTypeI) {
152   return (VTypeI & ~0x738) == 0 && RISCVVType::hasXSfmmWiden(VTypeI) &&
153          RISCVVType::getSEW(VTypeI) * RISCVVType::getXSfmmWiden(VTypeI) <= 64;
154 }
155 
isTailAgnostic(unsigned VType)156 inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; }
157 
isMaskAgnostic(unsigned VType)158 inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; }
159 
isAltFmt(unsigned VType)160 inline static bool isAltFmt(unsigned VType) { return VType & 0x100; }
161 
162 LLVM_ABI void printVType(unsigned VType, raw_ostream &OS);
163 
164 LLVM_ABI unsigned getSEWLMULRatio(unsigned SEW, VLMUL VLMul);
165 
166 LLVM_ABI std::optional<VLMUL> getSameRatioLMUL(unsigned SEW, VLMUL VLMUL,
167                                                unsigned EEW);
168 } // namespace RISCVVType
169 
170 } // namespace llvm
171 
172 #endif
173