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