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 // We use 64 bits as the known part in the scalable vector types.
28 static constexpr unsigned RVVBitsPerBlock = 64;
29 
30 void getFeaturesForCPU(StringRef CPU,
31                        SmallVectorImpl<std::string> &EnabledFeatures,
32                        bool NeedPlus = false);
33 bool parseCPU(StringRef CPU, bool IsRV64);
34 bool parseTuneCPU(StringRef CPU, bool IsRV64);
35 StringRef getMArchFromMcpu(StringRef CPU);
36 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
37 void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64);
38 bool hasFastUnalignedAccess(StringRef CPU);
39 
40 } // namespace RISCV
41 
42 namespace RISCVII {
43 enum VLMUL : uint8_t {
44   LMUL_1 = 0,
45   LMUL_2,
46   LMUL_4,
47   LMUL_8,
48   LMUL_RESERVED,
49   LMUL_F8,
50   LMUL_F4,
51   LMUL_F2
52 };
53 
54 enum {
55   TAIL_UNDISTURBED_MASK_UNDISTURBED = 0,
56   TAIL_AGNOSTIC = 1,
57   MASK_AGNOSTIC = 2,
58 };
59 } // namespace RISCVII
60 
61 namespace RISCVVType {
62 // Is this a SEW value that can be encoded into the VTYPE format.
isValidSEW(unsigned SEW)63 inline static bool isValidSEW(unsigned SEW) {
64   return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 1024;
65 }
66 
67 // Is this a LMUL value that can be encoded into the VTYPE format.
isValidLMUL(unsigned LMUL,bool Fractional)68 inline static bool isValidLMUL(unsigned LMUL, bool Fractional) {
69   return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1);
70 }
71 
72 unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic,
73                      bool MaskAgnostic);
74 
getVLMUL(unsigned VType)75 inline static RISCVII::VLMUL getVLMUL(unsigned VType) {
76   unsigned VLMUL = VType & 0x7;
77   return static_cast<RISCVII::VLMUL>(VLMUL);
78 }
79 
80 // Decode VLMUL into 1,2,4,8 and fractional indicator.
81 std::pair<unsigned, bool> decodeVLMUL(RISCVII::VLMUL VLMUL);
82 
encodeLMUL(unsigned LMUL,bool Fractional)83 inline static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional) {
84   assert(isValidLMUL(LMUL, Fractional) && "Unsupported LMUL");
85   unsigned LmulLog2 = Log2_32(LMUL);
86   return static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2);
87 }
88 
decodeVSEW(unsigned VSEW)89 inline static unsigned decodeVSEW(unsigned VSEW) {
90   assert(VSEW < 8 && "Unexpected VSEW value");
91   return 1 << (VSEW + 3);
92 }
93 
encodeSEW(unsigned SEW)94 inline static unsigned encodeSEW(unsigned SEW) {
95   assert(isValidSEW(SEW) && "Unexpected SEW value");
96   return Log2_32(SEW) - 3;
97 }
98 
getSEW(unsigned VType)99 inline static unsigned getSEW(unsigned VType) {
100   unsigned VSEW = (VType >> 3) & 0x7;
101   return decodeVSEW(VSEW);
102 }
103 
isTailAgnostic(unsigned VType)104 inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; }
105 
isMaskAgnostic(unsigned VType)106 inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; }
107 
108 void printVType(unsigned VType, raw_ostream &OS);
109 
110 unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul);
111 
112 std::optional<RISCVII::VLMUL>
113 getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW);
114 } // namespace RISCVVType
115 
116 } // namespace llvm
117 
118 #endif
119