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. |
72 | inline static bool isValidSEW(unsigned SEW) { |
73 | return isPowerOf2_32(Value: SEW) && SEW >= 8 && SEW <= 64; |
74 | } |
75 | |
76 | // Is this a LMUL value that can be encoded into the VTYPE format. |
77 | inline static bool isValidLMUL(unsigned LMUL, bool Fractional) { |
78 | return isPowerOf2_32(Value: LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1); |
79 | } |
80 | |
81 | unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic, |
82 | bool MaskAgnostic); |
83 | |
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 | |
92 | inline static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional) { |
93 | assert(isValidLMUL(LMUL, Fractional) && "Unsupported LMUL" ); |
94 | unsigned LmulLog2 = Log2_32(Value: LMUL); |
95 | return static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2); |
96 | } |
97 | |
98 | inline static unsigned decodeVSEW(unsigned VSEW) { |
99 | assert(VSEW < 8 && "Unexpected VSEW value" ); |
100 | return 1 << (VSEW + 3); |
101 | } |
102 | |
103 | inline static unsigned encodeSEW(unsigned SEW) { |
104 | assert(isValidSEW(SEW) && "Unexpected SEW value" ); |
105 | return Log2_32(Value: SEW) - 3; |
106 | } |
107 | |
108 | inline static unsigned getSEW(unsigned VType) { |
109 | unsigned VSEW = (VType >> 3) & 0x7; |
110 | return decodeVSEW(VSEW); |
111 | } |
112 | |
113 | inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; } |
114 | |
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 | |