xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
1*e8d8bef9SDimitry Andric //===-- RISCVBaseInfo.h - Top level definitions for RISCV MC ----*- C++ -*-===//
2*e8d8bef9SDimitry Andric //
3*e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e8d8bef9SDimitry Andric //
7*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8*e8d8bef9SDimitry Andric //
9*e8d8bef9SDimitry Andric // This file contains small standalone enum definitions for the RISCV target
10*e8d8bef9SDimitry Andric // useful for the compiler back-end and the MC libraries.
11*e8d8bef9SDimitry Andric //
12*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
13*e8d8bef9SDimitry Andric #ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVBASEINFO_H
14*e8d8bef9SDimitry Andric #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVBASEINFO_H
15*e8d8bef9SDimitry Andric 
16*e8d8bef9SDimitry Andric #include "MCTargetDesc/RISCVMCTargetDesc.h"
17*e8d8bef9SDimitry Andric #include "llvm/ADT/StringRef.h"
18*e8d8bef9SDimitry Andric #include "llvm/ADT/StringSwitch.h"
19*e8d8bef9SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
20*e8d8bef9SDimitry Andric #include "llvm/MC/SubtargetFeature.h"
21*e8d8bef9SDimitry Andric #include "llvm/Support/MachineValueType.h"
22*e8d8bef9SDimitry Andric 
23*e8d8bef9SDimitry Andric namespace llvm {
24*e8d8bef9SDimitry Andric 
25*e8d8bef9SDimitry Andric // RISCVII - This namespace holds all of the target specific flags that
26*e8d8bef9SDimitry Andric // instruction info tracks. All definitions must match RISCVInstrFormats.td.
27*e8d8bef9SDimitry Andric namespace RISCVII {
28*e8d8bef9SDimitry Andric enum {
29*e8d8bef9SDimitry Andric   InstFormatPseudo = 0,
30*e8d8bef9SDimitry Andric   InstFormatR = 1,
31*e8d8bef9SDimitry Andric   InstFormatR4 = 2,
32*e8d8bef9SDimitry Andric   InstFormatI = 3,
33*e8d8bef9SDimitry Andric   InstFormatS = 4,
34*e8d8bef9SDimitry Andric   InstFormatB = 5,
35*e8d8bef9SDimitry Andric   InstFormatU = 6,
36*e8d8bef9SDimitry Andric   InstFormatJ = 7,
37*e8d8bef9SDimitry Andric   InstFormatCR = 8,
38*e8d8bef9SDimitry Andric   InstFormatCI = 9,
39*e8d8bef9SDimitry Andric   InstFormatCSS = 10,
40*e8d8bef9SDimitry Andric   InstFormatCIW = 11,
41*e8d8bef9SDimitry Andric   InstFormatCL = 12,
42*e8d8bef9SDimitry Andric   InstFormatCS = 13,
43*e8d8bef9SDimitry Andric   InstFormatCA = 14,
44*e8d8bef9SDimitry Andric   InstFormatCB = 15,
45*e8d8bef9SDimitry Andric   InstFormatCJ = 16,
46*e8d8bef9SDimitry Andric   InstFormatOther = 17,
47*e8d8bef9SDimitry Andric 
48*e8d8bef9SDimitry Andric   InstFormatMask = 31,
49*e8d8bef9SDimitry Andric 
50*e8d8bef9SDimitry Andric   ConstraintShift = 5,
51*e8d8bef9SDimitry Andric   ConstraintMask = 0b111 << ConstraintShift,
52*e8d8bef9SDimitry Andric 
53*e8d8bef9SDimitry Andric   VLMulShift = ConstraintShift + 3,
54*e8d8bef9SDimitry Andric   VLMulMask = 0b111 << VLMulShift,
55*e8d8bef9SDimitry Andric 
56*e8d8bef9SDimitry Andric   // Do we need to add a dummy mask op when converting RVV Pseudo to MCInst.
57*e8d8bef9SDimitry Andric   HasDummyMaskOpShift = VLMulShift + 3,
58*e8d8bef9SDimitry Andric   HasDummyMaskOpMask = 1 << HasDummyMaskOpShift,
59*e8d8bef9SDimitry Andric 
60*e8d8bef9SDimitry Andric   // Does this instruction only update element 0 the destination register.
61*e8d8bef9SDimitry Andric   WritesElement0Shift = HasDummyMaskOpShift + 1,
62*e8d8bef9SDimitry Andric   WritesElement0Mask = 1 << WritesElement0Shift,
63*e8d8bef9SDimitry Andric 
64*e8d8bef9SDimitry Andric   // Does this instruction have a merge operand that must be removed when
65*e8d8bef9SDimitry Andric   // converting to MCInst. It will be the first explicit use operand. Used by
66*e8d8bef9SDimitry Andric   // RVV Pseudos.
67*e8d8bef9SDimitry Andric   HasMergeOpShift = WritesElement0Shift + 1,
68*e8d8bef9SDimitry Andric   HasMergeOpMask = 1 << HasMergeOpShift,
69*e8d8bef9SDimitry Andric 
70*e8d8bef9SDimitry Andric   // Does this instruction have a SEW operand. It will be the last explicit
71*e8d8bef9SDimitry Andric   // operand. Used by RVV Pseudos.
72*e8d8bef9SDimitry Andric   HasSEWOpShift = HasMergeOpShift + 1,
73*e8d8bef9SDimitry Andric   HasSEWOpMask = 1 << HasSEWOpShift,
74*e8d8bef9SDimitry Andric 
75*e8d8bef9SDimitry Andric   // Does this instruction have a VL operand. It will be the second to last
76*e8d8bef9SDimitry Andric   // explicit operand. Used by RVV Pseudos.
77*e8d8bef9SDimitry Andric   HasVLOpShift = HasSEWOpShift + 1,
78*e8d8bef9SDimitry Andric   HasVLOpMask = 1 << HasVLOpShift,
79*e8d8bef9SDimitry Andric };
80*e8d8bef9SDimitry Andric 
81*e8d8bef9SDimitry Andric // Match with the definitions in RISCVInstrFormatsV.td
82*e8d8bef9SDimitry Andric enum RVVConstraintType {
83*e8d8bef9SDimitry Andric   NoConstraint = 0,
84*e8d8bef9SDimitry Andric   VS2Constraint = 0b001,
85*e8d8bef9SDimitry Andric   VS1Constraint = 0b010,
86*e8d8bef9SDimitry Andric   VMConstraint = 0b100,
87*e8d8bef9SDimitry Andric };
88*e8d8bef9SDimitry Andric 
89*e8d8bef9SDimitry Andric // RISC-V Specific Machine Operand Flags
90*e8d8bef9SDimitry Andric enum {
91*e8d8bef9SDimitry Andric   MO_None = 0,
92*e8d8bef9SDimitry Andric   MO_CALL = 1,
93*e8d8bef9SDimitry Andric   MO_PLT = 2,
94*e8d8bef9SDimitry Andric   MO_LO = 3,
95*e8d8bef9SDimitry Andric   MO_HI = 4,
96*e8d8bef9SDimitry Andric   MO_PCREL_LO = 5,
97*e8d8bef9SDimitry Andric   MO_PCREL_HI = 6,
98*e8d8bef9SDimitry Andric   MO_GOT_HI = 7,
99*e8d8bef9SDimitry Andric   MO_TPREL_LO = 8,
100*e8d8bef9SDimitry Andric   MO_TPREL_HI = 9,
101*e8d8bef9SDimitry Andric   MO_TPREL_ADD = 10,
102*e8d8bef9SDimitry Andric   MO_TLS_GOT_HI = 11,
103*e8d8bef9SDimitry Andric   MO_TLS_GD_HI = 12,
104*e8d8bef9SDimitry Andric 
105*e8d8bef9SDimitry Andric   // Used to differentiate between target-specific "direct" flags and "bitmask"
106*e8d8bef9SDimitry Andric   // flags. A machine operand can only have one "direct" flag, but can have
107*e8d8bef9SDimitry Andric   // multiple "bitmask" flags.
108*e8d8bef9SDimitry Andric   MO_DIRECT_FLAG_MASK = 15
109*e8d8bef9SDimitry Andric };
110*e8d8bef9SDimitry Andric } // namespace RISCVII
111*e8d8bef9SDimitry Andric 
112*e8d8bef9SDimitry Andric namespace RISCVOp {
113*e8d8bef9SDimitry Andric enum OperandType : unsigned {
114*e8d8bef9SDimitry Andric   OPERAND_FIRST_RISCV_IMM = MCOI::OPERAND_FIRST_TARGET,
115*e8d8bef9SDimitry Andric   OPERAND_UIMM4 = OPERAND_FIRST_RISCV_IMM,
116*e8d8bef9SDimitry Andric   OPERAND_UIMM5,
117*e8d8bef9SDimitry Andric   OPERAND_UIMM12,
118*e8d8bef9SDimitry Andric   OPERAND_SIMM12,
119*e8d8bef9SDimitry Andric   OPERAND_UIMM20,
120*e8d8bef9SDimitry Andric   OPERAND_UIMMLOG2XLEN,
121*e8d8bef9SDimitry Andric   OPERAND_LAST_RISCV_IMM = OPERAND_UIMMLOG2XLEN
122*e8d8bef9SDimitry Andric };
123*e8d8bef9SDimitry Andric } // namespace RISCVOp
124*e8d8bef9SDimitry Andric 
125*e8d8bef9SDimitry Andric // Describes the predecessor/successor bits used in the FENCE instruction.
126*e8d8bef9SDimitry Andric namespace RISCVFenceField {
127*e8d8bef9SDimitry Andric enum FenceField {
128*e8d8bef9SDimitry Andric   I = 8,
129*e8d8bef9SDimitry Andric   O = 4,
130*e8d8bef9SDimitry Andric   R = 2,
131*e8d8bef9SDimitry Andric   W = 1
132*e8d8bef9SDimitry Andric };
133*e8d8bef9SDimitry Andric }
134*e8d8bef9SDimitry Andric 
135*e8d8bef9SDimitry Andric // Describes the supported floating point rounding mode encodings.
136*e8d8bef9SDimitry Andric namespace RISCVFPRndMode {
137*e8d8bef9SDimitry Andric enum RoundingMode {
138*e8d8bef9SDimitry Andric   RNE = 0,
139*e8d8bef9SDimitry Andric   RTZ = 1,
140*e8d8bef9SDimitry Andric   RDN = 2,
141*e8d8bef9SDimitry Andric   RUP = 3,
142*e8d8bef9SDimitry Andric   RMM = 4,
143*e8d8bef9SDimitry Andric   DYN = 7,
144*e8d8bef9SDimitry Andric   Invalid
145*e8d8bef9SDimitry Andric };
146*e8d8bef9SDimitry Andric 
147*e8d8bef9SDimitry Andric inline static StringRef roundingModeToString(RoundingMode RndMode) {
148*e8d8bef9SDimitry Andric   switch (RndMode) {
149*e8d8bef9SDimitry Andric   default:
150*e8d8bef9SDimitry Andric     llvm_unreachable("Unknown floating point rounding mode");
151*e8d8bef9SDimitry Andric   case RISCVFPRndMode::RNE:
152*e8d8bef9SDimitry Andric     return "rne";
153*e8d8bef9SDimitry Andric   case RISCVFPRndMode::RTZ:
154*e8d8bef9SDimitry Andric     return "rtz";
155*e8d8bef9SDimitry Andric   case RISCVFPRndMode::RDN:
156*e8d8bef9SDimitry Andric     return "rdn";
157*e8d8bef9SDimitry Andric   case RISCVFPRndMode::RUP:
158*e8d8bef9SDimitry Andric     return "rup";
159*e8d8bef9SDimitry Andric   case RISCVFPRndMode::RMM:
160*e8d8bef9SDimitry Andric     return "rmm";
161*e8d8bef9SDimitry Andric   case RISCVFPRndMode::DYN:
162*e8d8bef9SDimitry Andric     return "dyn";
163*e8d8bef9SDimitry Andric   }
164*e8d8bef9SDimitry Andric }
165*e8d8bef9SDimitry Andric 
166*e8d8bef9SDimitry Andric inline static RoundingMode stringToRoundingMode(StringRef Str) {
167*e8d8bef9SDimitry Andric   return StringSwitch<RoundingMode>(Str)
168*e8d8bef9SDimitry Andric       .Case("rne", RISCVFPRndMode::RNE)
169*e8d8bef9SDimitry Andric       .Case("rtz", RISCVFPRndMode::RTZ)
170*e8d8bef9SDimitry Andric       .Case("rdn", RISCVFPRndMode::RDN)
171*e8d8bef9SDimitry Andric       .Case("rup", RISCVFPRndMode::RUP)
172*e8d8bef9SDimitry Andric       .Case("rmm", RISCVFPRndMode::RMM)
173*e8d8bef9SDimitry Andric       .Case("dyn", RISCVFPRndMode::DYN)
174*e8d8bef9SDimitry Andric       .Default(RISCVFPRndMode::Invalid);
175*e8d8bef9SDimitry Andric }
176*e8d8bef9SDimitry Andric 
177*e8d8bef9SDimitry Andric inline static bool isValidRoundingMode(unsigned Mode) {
178*e8d8bef9SDimitry Andric   switch (Mode) {
179*e8d8bef9SDimitry Andric   default:
180*e8d8bef9SDimitry Andric     return false;
181*e8d8bef9SDimitry Andric   case RISCVFPRndMode::RNE:
182*e8d8bef9SDimitry Andric   case RISCVFPRndMode::RTZ:
183*e8d8bef9SDimitry Andric   case RISCVFPRndMode::RDN:
184*e8d8bef9SDimitry Andric   case RISCVFPRndMode::RUP:
185*e8d8bef9SDimitry Andric   case RISCVFPRndMode::RMM:
186*e8d8bef9SDimitry Andric   case RISCVFPRndMode::DYN:
187*e8d8bef9SDimitry Andric     return true;
188*e8d8bef9SDimitry Andric   }
189*e8d8bef9SDimitry Andric }
190*e8d8bef9SDimitry Andric } // namespace RISCVFPRndMode
191*e8d8bef9SDimitry Andric 
192*e8d8bef9SDimitry Andric namespace RISCVSysReg {
193*e8d8bef9SDimitry Andric struct SysReg {
194*e8d8bef9SDimitry Andric   const char *Name;
195*e8d8bef9SDimitry Andric   unsigned Encoding;
196*e8d8bef9SDimitry Andric   const char *AltName;
197*e8d8bef9SDimitry Andric   // FIXME: add these additional fields when needed.
198*e8d8bef9SDimitry Andric   // Privilege Access: Read, Write, Read-Only.
199*e8d8bef9SDimitry Andric   // unsigned ReadWrite;
200*e8d8bef9SDimitry Andric   // Privilege Mode: User, System or Machine.
201*e8d8bef9SDimitry Andric   // unsigned Mode;
202*e8d8bef9SDimitry Andric   // Check field name.
203*e8d8bef9SDimitry Andric   // unsigned Extra;
204*e8d8bef9SDimitry Andric   // Register number without the privilege bits.
205*e8d8bef9SDimitry Andric   // unsigned Number;
206*e8d8bef9SDimitry Andric   FeatureBitset FeaturesRequired;
207*e8d8bef9SDimitry Andric   bool isRV32Only;
208*e8d8bef9SDimitry Andric 
209*e8d8bef9SDimitry Andric   bool haveRequiredFeatures(FeatureBitset ActiveFeatures) const {
210*e8d8bef9SDimitry Andric     // Not in 32-bit mode.
211*e8d8bef9SDimitry Andric     if (isRV32Only && ActiveFeatures[RISCV::Feature64Bit])
212*e8d8bef9SDimitry Andric       return false;
213*e8d8bef9SDimitry Andric     // No required feature associated with the system register.
214*e8d8bef9SDimitry Andric     if (FeaturesRequired.none())
215*e8d8bef9SDimitry Andric       return true;
216*e8d8bef9SDimitry Andric     return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
217*e8d8bef9SDimitry Andric   }
218*e8d8bef9SDimitry Andric };
219*e8d8bef9SDimitry Andric 
220*e8d8bef9SDimitry Andric #define GET_SysRegsList_DECL
221*e8d8bef9SDimitry Andric #include "RISCVGenSearchableTables.inc"
222*e8d8bef9SDimitry Andric } // end namespace RISCVSysReg
223*e8d8bef9SDimitry Andric 
224*e8d8bef9SDimitry Andric namespace RISCVABI {
225*e8d8bef9SDimitry Andric 
226*e8d8bef9SDimitry Andric enum ABI {
227*e8d8bef9SDimitry Andric   ABI_ILP32,
228*e8d8bef9SDimitry Andric   ABI_ILP32F,
229*e8d8bef9SDimitry Andric   ABI_ILP32D,
230*e8d8bef9SDimitry Andric   ABI_ILP32E,
231*e8d8bef9SDimitry Andric   ABI_LP64,
232*e8d8bef9SDimitry Andric   ABI_LP64F,
233*e8d8bef9SDimitry Andric   ABI_LP64D,
234*e8d8bef9SDimitry Andric   ABI_Unknown
235*e8d8bef9SDimitry Andric };
236*e8d8bef9SDimitry Andric 
237*e8d8bef9SDimitry Andric // Returns the target ABI, or else a StringError if the requested ABIName is
238*e8d8bef9SDimitry Andric // not supported for the given TT and FeatureBits combination.
239*e8d8bef9SDimitry Andric ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits,
240*e8d8bef9SDimitry Andric                      StringRef ABIName);
241*e8d8bef9SDimitry Andric 
242*e8d8bef9SDimitry Andric ABI getTargetABI(StringRef ABIName);
243*e8d8bef9SDimitry Andric 
244*e8d8bef9SDimitry Andric // Returns the register used to hold the stack pointer after realignment.
245*e8d8bef9SDimitry Andric MCRegister getBPReg();
246*e8d8bef9SDimitry Andric 
247*e8d8bef9SDimitry Andric // Returns the register holding shadow call stack pointer.
248*e8d8bef9SDimitry Andric MCRegister getSCSPReg();
249*e8d8bef9SDimitry Andric 
250*e8d8bef9SDimitry Andric } // namespace RISCVABI
251*e8d8bef9SDimitry Andric 
252*e8d8bef9SDimitry Andric namespace RISCVFeatures {
253*e8d8bef9SDimitry Andric 
254*e8d8bef9SDimitry Andric // Validates if the given combination of features are valid for the target
255*e8d8bef9SDimitry Andric // triple. Exits with report_fatal_error if not.
256*e8d8bef9SDimitry Andric void validate(const Triple &TT, const FeatureBitset &FeatureBits);
257*e8d8bef9SDimitry Andric 
258*e8d8bef9SDimitry Andric } // namespace RISCVFeatures
259*e8d8bef9SDimitry Andric 
260*e8d8bef9SDimitry Andric namespace RISCVVMVTs {
261*e8d8bef9SDimitry Andric 
262*e8d8bef9SDimitry Andric constexpr MVT vint8mf8_t = MVT::nxv1i8;
263*e8d8bef9SDimitry Andric constexpr MVT vint8mf4_t = MVT::nxv2i8;
264*e8d8bef9SDimitry Andric constexpr MVT vint8mf2_t = MVT::nxv4i8;
265*e8d8bef9SDimitry Andric constexpr MVT vint8m1_t = MVT::nxv8i8;
266*e8d8bef9SDimitry Andric constexpr MVT vint8m2_t = MVT::nxv16i8;
267*e8d8bef9SDimitry Andric constexpr MVT vint8m4_t = MVT::nxv32i8;
268*e8d8bef9SDimitry Andric constexpr MVT vint8m8_t = MVT::nxv64i8;
269*e8d8bef9SDimitry Andric 
270*e8d8bef9SDimitry Andric constexpr MVT vint16mf4_t = MVT::nxv1i16;
271*e8d8bef9SDimitry Andric constexpr MVT vint16mf2_t = MVT::nxv2i16;
272*e8d8bef9SDimitry Andric constexpr MVT vint16m1_t = MVT::nxv4i16;
273*e8d8bef9SDimitry Andric constexpr MVT vint16m2_t = MVT::nxv8i16;
274*e8d8bef9SDimitry Andric constexpr MVT vint16m4_t = MVT::nxv16i16;
275*e8d8bef9SDimitry Andric constexpr MVT vint16m8_t = MVT::nxv32i16;
276*e8d8bef9SDimitry Andric 
277*e8d8bef9SDimitry Andric constexpr MVT vint32mf2_t = MVT::nxv1i32;
278*e8d8bef9SDimitry Andric constexpr MVT vint32m1_t = MVT::nxv2i32;
279*e8d8bef9SDimitry Andric constexpr MVT vint32m2_t = MVT::nxv4i32;
280*e8d8bef9SDimitry Andric constexpr MVT vint32m4_t = MVT::nxv8i32;
281*e8d8bef9SDimitry Andric constexpr MVT vint32m8_t = MVT::nxv16i32;
282*e8d8bef9SDimitry Andric 
283*e8d8bef9SDimitry Andric constexpr MVT vint64m1_t = MVT::nxv1i64;
284*e8d8bef9SDimitry Andric constexpr MVT vint64m2_t = MVT::nxv2i64;
285*e8d8bef9SDimitry Andric constexpr MVT vint64m4_t = MVT::nxv4i64;
286*e8d8bef9SDimitry Andric constexpr MVT vint64m8_t = MVT::nxv8i64;
287*e8d8bef9SDimitry Andric 
288*e8d8bef9SDimitry Andric constexpr MVT vfloat16mf4_t = MVT::nxv1f16;
289*e8d8bef9SDimitry Andric constexpr MVT vfloat16mf2_t = MVT::nxv2f16;
290*e8d8bef9SDimitry Andric constexpr MVT vfloat16m1_t = MVT::nxv4f16;
291*e8d8bef9SDimitry Andric constexpr MVT vfloat16m2_t = MVT::nxv8f16;
292*e8d8bef9SDimitry Andric constexpr MVT vfloat16m4_t = MVT::nxv16f16;
293*e8d8bef9SDimitry Andric constexpr MVT vfloat16m8_t = MVT::nxv32f16;
294*e8d8bef9SDimitry Andric 
295*e8d8bef9SDimitry Andric constexpr MVT vfloat32mf2_t = MVT::nxv1f32;
296*e8d8bef9SDimitry Andric constexpr MVT vfloat32m1_t = MVT::nxv2f32;
297*e8d8bef9SDimitry Andric constexpr MVT vfloat32m2_t = MVT::nxv4f32;
298*e8d8bef9SDimitry Andric constexpr MVT vfloat32m4_t = MVT::nxv8f32;
299*e8d8bef9SDimitry Andric constexpr MVT vfloat32m8_t = MVT::nxv16f32;
300*e8d8bef9SDimitry Andric 
301*e8d8bef9SDimitry Andric constexpr MVT vfloat64m1_t = MVT::nxv1f64;
302*e8d8bef9SDimitry Andric constexpr MVT vfloat64m2_t = MVT::nxv2f64;
303*e8d8bef9SDimitry Andric constexpr MVT vfloat64m4_t = MVT::nxv4f64;
304*e8d8bef9SDimitry Andric constexpr MVT vfloat64m8_t = MVT::nxv8f64;
305*e8d8bef9SDimitry Andric 
306*e8d8bef9SDimitry Andric constexpr MVT vbool1_t = MVT::nxv64i1;
307*e8d8bef9SDimitry Andric constexpr MVT vbool2_t = MVT::nxv32i1;
308*e8d8bef9SDimitry Andric constexpr MVT vbool4_t = MVT::nxv16i1;
309*e8d8bef9SDimitry Andric constexpr MVT vbool8_t = MVT::nxv8i1;
310*e8d8bef9SDimitry Andric constexpr MVT vbool16_t = MVT::nxv4i1;
311*e8d8bef9SDimitry Andric constexpr MVT vbool32_t = MVT::nxv2i1;
312*e8d8bef9SDimitry Andric constexpr MVT vbool64_t = MVT::nxv1i1;
313*e8d8bef9SDimitry Andric 
314*e8d8bef9SDimitry Andric } // namespace RISCVVMVTs
315*e8d8bef9SDimitry Andric 
316*e8d8bef9SDimitry Andric enum class RISCVVSEW {
317*e8d8bef9SDimitry Andric   SEW_8 = 0,
318*e8d8bef9SDimitry Andric   SEW_16,
319*e8d8bef9SDimitry Andric   SEW_32,
320*e8d8bef9SDimitry Andric   SEW_64,
321*e8d8bef9SDimitry Andric   SEW_128,
322*e8d8bef9SDimitry Andric   SEW_256,
323*e8d8bef9SDimitry Andric   SEW_512,
324*e8d8bef9SDimitry Andric   SEW_1024,
325*e8d8bef9SDimitry Andric };
326*e8d8bef9SDimitry Andric 
327*e8d8bef9SDimitry Andric enum class RISCVVLMUL {
328*e8d8bef9SDimitry Andric   LMUL_1 = 0,
329*e8d8bef9SDimitry Andric   LMUL_2,
330*e8d8bef9SDimitry Andric   LMUL_4,
331*e8d8bef9SDimitry Andric   LMUL_8,
332*e8d8bef9SDimitry Andric   LMUL_RESERVED,
333*e8d8bef9SDimitry Andric   LMUL_F8,
334*e8d8bef9SDimitry Andric   LMUL_F4,
335*e8d8bef9SDimitry Andric   LMUL_F2
336*e8d8bef9SDimitry Andric };
337*e8d8bef9SDimitry Andric 
338*e8d8bef9SDimitry Andric namespace RISCVVType {
339*e8d8bef9SDimitry Andric // Is this a SEW value that can be encoded into the VTYPE format.
340*e8d8bef9SDimitry Andric inline static bool isValidSEW(unsigned SEW) {
341*e8d8bef9SDimitry Andric   return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 1024;
342*e8d8bef9SDimitry Andric }
343*e8d8bef9SDimitry Andric 
344*e8d8bef9SDimitry Andric // Is this a LMUL value that can be encoded into the VTYPE format.
345*e8d8bef9SDimitry Andric inline static bool isValidLMUL(unsigned LMUL, bool Fractional) {
346*e8d8bef9SDimitry Andric   return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1);
347*e8d8bef9SDimitry Andric }
348*e8d8bef9SDimitry Andric 
349*e8d8bef9SDimitry Andric // Encode VTYPE into the binary format used by the the VSETVLI instruction which
350*e8d8bef9SDimitry Andric // is used by our MC layer representation.
351*e8d8bef9SDimitry Andric //
352*e8d8bef9SDimitry Andric // Bits | Name       | Description
353*e8d8bef9SDimitry Andric // -----+------------+------------------------------------------------
354*e8d8bef9SDimitry Andric // 7    | vma        | Vector mask agnostic
355*e8d8bef9SDimitry Andric // 6    | vta        | Vector tail agnostic
356*e8d8bef9SDimitry Andric // 5:3  | vsew[2:0]  | Standard element width (SEW) setting
357*e8d8bef9SDimitry Andric // 2:0  | vlmul[2:0] | Vector register group multiplier (LMUL) setting
358*e8d8bef9SDimitry Andric inline static unsigned encodeVTYPE(RISCVVLMUL VLMUL, RISCVVSEW VSEW,
359*e8d8bef9SDimitry Andric                                    bool TailAgnostic, bool MaskAgnostic) {
360*e8d8bef9SDimitry Andric   unsigned VLMULBits = static_cast<unsigned>(VLMUL);
361*e8d8bef9SDimitry Andric   unsigned VSEWBits = static_cast<unsigned>(VSEW);
362*e8d8bef9SDimitry Andric   unsigned VTypeI = (VSEWBits << 3) | (VLMULBits & 0x7);
363*e8d8bef9SDimitry Andric   if (TailAgnostic)
364*e8d8bef9SDimitry Andric     VTypeI |= 0x40;
365*e8d8bef9SDimitry Andric   if (MaskAgnostic)
366*e8d8bef9SDimitry Andric     VTypeI |= 0x80;
367*e8d8bef9SDimitry Andric 
368*e8d8bef9SDimitry Andric   return VTypeI;
369*e8d8bef9SDimitry Andric }
370*e8d8bef9SDimitry Andric 
371*e8d8bef9SDimitry Andric inline static RISCVVLMUL getVLMUL(unsigned VType) {
372*e8d8bef9SDimitry Andric   unsigned VLMUL = VType & 0x7;
373*e8d8bef9SDimitry Andric   return static_cast<RISCVVLMUL>(VLMUL);
374*e8d8bef9SDimitry Andric }
375*e8d8bef9SDimitry Andric 
376*e8d8bef9SDimitry Andric inline static RISCVVSEW getVSEW(unsigned VType) {
377*e8d8bef9SDimitry Andric   unsigned VSEW = (VType >> 3) & 0x7;
378*e8d8bef9SDimitry Andric   return static_cast<RISCVVSEW>(VSEW);
379*e8d8bef9SDimitry Andric }
380*e8d8bef9SDimitry Andric 
381*e8d8bef9SDimitry Andric inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; }
382*e8d8bef9SDimitry Andric 
383*e8d8bef9SDimitry Andric inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; }
384*e8d8bef9SDimitry Andric 
385*e8d8bef9SDimitry Andric void printVType(unsigned VType, raw_ostream &OS);
386*e8d8bef9SDimitry Andric 
387*e8d8bef9SDimitry Andric } // namespace RISCVVType
388*e8d8bef9SDimitry Andric 
389*e8d8bef9SDimitry Andric namespace RISCVVPseudosTable {
390*e8d8bef9SDimitry Andric 
391*e8d8bef9SDimitry Andric struct PseudoInfo {
392*e8d8bef9SDimitry Andric #include "MCTargetDesc/RISCVBaseInfo.h"
393*e8d8bef9SDimitry Andric   uint16_t Pseudo;
394*e8d8bef9SDimitry Andric   uint16_t BaseInstr;
395*e8d8bef9SDimitry Andric };
396*e8d8bef9SDimitry Andric 
397*e8d8bef9SDimitry Andric using namespace RISCV;
398*e8d8bef9SDimitry Andric 
399*e8d8bef9SDimitry Andric #define GET_RISCVVPseudosTable_DECL
400*e8d8bef9SDimitry Andric #include "RISCVGenSearchableTables.inc"
401*e8d8bef9SDimitry Andric 
402*e8d8bef9SDimitry Andric } // end namespace RISCVVPseudosTable
403*e8d8bef9SDimitry Andric 
404*e8d8bef9SDimitry Andric } // namespace llvm
405*e8d8bef9SDimitry Andric 
406*e8d8bef9SDimitry Andric #endif
407