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