xref: /llvm-project/llvm/include/llvm/TargetParser/RISCVTargetParser.h (revision 875b10f7d0888ca7e53f527f4c30531bd6b50bfb)
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/MathExtras.h"
19 #include "llvm/Support/raw_ostream.h"
20 
21 namespace llvm {
22 
23 class Triple;
24 
25 namespace RISCV {
26 
27 namespace RISCVExtensionBitmaskTable {
28 struct RISCVExtensionBitmask {
29   const char *Name;
30   unsigned GroupID;
31   unsigned BitPosition;
32 };
33 } // namespace RISCVExtensionBitmaskTable
34 
35 struct CPUModel {
36   uint32_t MVendorID;
37   uint64_t MArchID;
38   uint64_t MImpID;
39 };
40 
41 struct CPUInfo {
42   StringLiteral Name;
43   StringLiteral DefaultMarch;
44   bool FastScalarUnalignedAccess;
45   bool FastVectorUnalignedAccess;
46   CPUModel Model;
47   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 
53 void getFeaturesForCPU(StringRef CPU,
54                        SmallVectorImpl<std::string> &EnabledFeatures,
55                        bool NeedPlus = false);
56 bool parseCPU(StringRef CPU, bool IsRV64);
57 bool parseTuneCPU(StringRef CPU, bool IsRV64);
58 StringRef getMArchFromMcpu(StringRef CPU);
59 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
60 void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
61 bool hasFastScalarUnalignedAccess(StringRef CPU);
62 bool hasFastVectorUnalignedAccess(StringRef CPU);
63 bool hasValidCPUModel(StringRef CPU);
64 CPUModel getCPUModel(StringRef CPU);
65 
66 } // namespace RISCV
67 
68 namespace RISCVII {
69 enum VLMUL : uint8_t {
70   LMUL_1 = 0,
71   LMUL_2,
72   LMUL_4,
73   LMUL_8,
74   LMUL_RESERVED,
75   LMUL_F8,
76   LMUL_F4,
77   LMUL_F2
78 };
79 
80 enum {
81   TAIL_UNDISTURBED_MASK_UNDISTURBED = 0,
82   TAIL_AGNOSTIC = 1,
83   MASK_AGNOSTIC = 2,
84 };
85 } // namespace RISCVII
86 
87 namespace RISCVVType {
88 // Is this a SEW value that can be encoded into the VTYPE format.
89 inline static bool isValidSEW(unsigned SEW) {
90   return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 64;
91 }
92 
93 // Is this a LMUL value that can be encoded into the VTYPE format.
94 inline static bool isValidLMUL(unsigned LMUL, bool Fractional) {
95   return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1);
96 }
97 
98 unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic,
99                      bool MaskAgnostic);
100 
101 inline static RISCVII::VLMUL getVLMUL(unsigned VType) {
102   unsigned VLMUL = VType & 0x7;
103   return static_cast<RISCVII::VLMUL>(VLMUL);
104 }
105 
106 // Decode VLMUL into 1,2,4,8 and fractional indicator.
107 std::pair<unsigned, bool> decodeVLMUL(RISCVII::VLMUL VLMUL);
108 
109 inline static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional) {
110   assert(isValidLMUL(LMUL, Fractional) && "Unsupported LMUL");
111   unsigned LmulLog2 = Log2_32(LMUL);
112   return static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2);
113 }
114 
115 inline static unsigned decodeVSEW(unsigned VSEW) {
116   assert(VSEW < 8 && "Unexpected VSEW value");
117   return 1 << (VSEW + 3);
118 }
119 
120 inline static unsigned encodeSEW(unsigned SEW) {
121   assert(isValidSEW(SEW) && "Unexpected SEW value");
122   return Log2_32(SEW) - 3;
123 }
124 
125 inline static unsigned getSEW(unsigned VType) {
126   unsigned VSEW = (VType >> 3) & 0x7;
127   return decodeVSEW(VSEW);
128 }
129 
130 inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; }
131 
132 inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; }
133 
134 void printVType(unsigned VType, raw_ostream &OS);
135 
136 unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul);
137 
138 std::optional<RISCVII::VLMUL>
139 getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW);
140 } // namespace RISCVVType
141 
142 } // namespace llvm
143 
144 #endif
145