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 ConstraintOffset = 5,
51 ConstraintMask = 0b1111
52 };
53
54 // Match with the definitions in RISCVInstrFormatsV.td
55 enum RVVConstraintType {
56 NoConstraint = 0,
57 VS2Constraint = 0b0001,
58 VS1Constraint = 0b0010,
59 VMConstraint = 0b0100,
60 OneInput = 0b1000,
61
62 // Illegal instructions:
63 //
64 // * The destination vector register group for a masked vector instruction
65 // cannot overlap the source mask register (v0), unless the destination vector
66 // register is being written with a mask value (e.g., comparisons) or the
67 // scalar result of a reduction.
68 //
69 // * Widening: The destination vector register group cannot overlap a source
70 // vector register group of a different EEW
71 //
72 // * Narrowing: The destination vector register group cannot overlap the
73 // first source vector register group
74 //
75 // * For vadc and vsbc, an illegal instruction exception is raised if the
76 // destination vector register is v0.
77 //
78 // * For vmadc and vmsbc, an illegal instruction exception is raised if the
79 // destination vector register overlaps a source vector register group.
80 //
81 // * viota: An illegal instruction exception is raised if the destination
82 // vector register group overlaps the source vector mask register. If the
83 // instruction is masked, an illegal instruction exception is issued if the
84 // destination vector register group overlaps v0.
85 //
86 // * v[f]slide[1]up: The destination vector register group for vslideup cannot
87 // overlap the source vector register group.
88 //
89 // * vrgather: The destination vector register group cannot overlap with the
90 // source vector register groups.
91 //
92 // * vcompress: The destination vector register group cannot overlap the
93 // source vector register group or the source mask register
94 WidenV = VS2Constraint | VS1Constraint | VMConstraint,
95 WidenW = VS1Constraint | VMConstraint,
96 WidenCvt = VS2Constraint | VMConstraint | OneInput,
97 Narrow = VS2Constraint | VMConstraint,
98 NarrowCvt = VS2Constraint | VMConstraint | OneInput,
99 Vmadc = VS2Constraint | VS1Constraint,
100 Iota = VS2Constraint | VMConstraint | OneInput,
101 SlideUp = VS2Constraint | VMConstraint,
102 Vrgather = VS2Constraint | VS1Constraint | VMConstraint,
103 Vcompress = VS2Constraint | VS1Constraint,
104 };
105
106 // RISC-V Specific Machine Operand Flags
107 enum {
108 MO_None = 0,
109 MO_CALL = 1,
110 MO_PLT = 2,
111 MO_LO = 3,
112 MO_HI = 4,
113 MO_PCREL_LO = 5,
114 MO_PCREL_HI = 6,
115 MO_GOT_HI = 7,
116 MO_TPREL_LO = 8,
117 MO_TPREL_HI = 9,
118 MO_TPREL_ADD = 10,
119 MO_TLS_GOT_HI = 11,
120 MO_TLS_GD_HI = 12,
121
122 // Used to differentiate between target-specific "direct" flags and "bitmask"
123 // flags. A machine operand can only have one "direct" flag, but can have
124 // multiple "bitmask" flags.
125 MO_DIRECT_FLAG_MASK = 15
126 };
127 } // namespace RISCVII
128
129 namespace RISCVOp {
130 enum OperandType : unsigned {
131 OPERAND_FIRST_RISCV_IMM = MCOI::OPERAND_FIRST_TARGET,
132 OPERAND_UIMM4 = OPERAND_FIRST_RISCV_IMM,
133 OPERAND_UIMM5,
134 OPERAND_UIMM12,
135 OPERAND_SIMM12,
136 OPERAND_UIMM20,
137 OPERAND_UIMMLOG2XLEN,
138 OPERAND_LAST_RISCV_IMM = OPERAND_UIMMLOG2XLEN
139 };
140 } // namespace RISCVOp
141
142 // Describes the predecessor/successor bits used in the FENCE instruction.
143 namespace RISCVFenceField {
144 enum FenceField {
145 I = 8,
146 O = 4,
147 R = 2,
148 W = 1
149 };
150 }
151
152 // Describes the supported floating point rounding mode encodings.
153 namespace RISCVFPRndMode {
154 enum RoundingMode {
155 RNE = 0,
156 RTZ = 1,
157 RDN = 2,
158 RUP = 3,
159 RMM = 4,
160 DYN = 7,
161 Invalid
162 };
163
roundingModeToString(RoundingMode RndMode)164 inline static StringRef roundingModeToString(RoundingMode RndMode) {
165 switch (RndMode) {
166 default:
167 llvm_unreachable("Unknown floating point rounding mode");
168 case RISCVFPRndMode::RNE:
169 return "rne";
170 case RISCVFPRndMode::RTZ:
171 return "rtz";
172 case RISCVFPRndMode::RDN:
173 return "rdn";
174 case RISCVFPRndMode::RUP:
175 return "rup";
176 case RISCVFPRndMode::RMM:
177 return "rmm";
178 case RISCVFPRndMode::DYN:
179 return "dyn";
180 }
181 }
182
stringToRoundingMode(StringRef Str)183 inline static RoundingMode stringToRoundingMode(StringRef Str) {
184 return StringSwitch<RoundingMode>(Str)
185 .Case("rne", RISCVFPRndMode::RNE)
186 .Case("rtz", RISCVFPRndMode::RTZ)
187 .Case("rdn", RISCVFPRndMode::RDN)
188 .Case("rup", RISCVFPRndMode::RUP)
189 .Case("rmm", RISCVFPRndMode::RMM)
190 .Case("dyn", RISCVFPRndMode::DYN)
191 .Default(RISCVFPRndMode::Invalid);
192 }
193
isValidRoundingMode(unsigned Mode)194 inline static bool isValidRoundingMode(unsigned Mode) {
195 switch (Mode) {
196 default:
197 return false;
198 case RISCVFPRndMode::RNE:
199 case RISCVFPRndMode::RTZ:
200 case RISCVFPRndMode::RDN:
201 case RISCVFPRndMode::RUP:
202 case RISCVFPRndMode::RMM:
203 case RISCVFPRndMode::DYN:
204 return true;
205 }
206 }
207 } // namespace RISCVFPRndMode
208
209 namespace RISCVSysReg {
210 struct SysReg {
211 const char *Name;
212 unsigned Encoding;
213 const char *AltName;
214 // FIXME: add these additional fields when needed.
215 // Privilege Access: Read, Write, Read-Only.
216 // unsigned ReadWrite;
217 // Privilege Mode: User, System or Machine.
218 // unsigned Mode;
219 // Check field name.
220 // unsigned Extra;
221 // Register number without the privilege bits.
222 // unsigned Number;
223 FeatureBitset FeaturesRequired;
224 bool isRV32Only;
225
haveRequiredFeaturesSysReg226 bool haveRequiredFeatures(FeatureBitset ActiveFeatures) const {
227 // Not in 32-bit mode.
228 if (isRV32Only && ActiveFeatures[RISCV::Feature64Bit])
229 return false;
230 // No required feature associated with the system register.
231 if (FeaturesRequired.none())
232 return true;
233 return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
234 }
235 };
236
237 #define GET_SysRegsList_DECL
238 #include "RISCVGenSearchableTables.inc"
239 } // end namespace RISCVSysReg
240
241 namespace RISCVABI {
242
243 enum ABI {
244 ABI_ILP32,
245 ABI_ILP32F,
246 ABI_ILP32D,
247 ABI_ILP32E,
248 ABI_LP64,
249 ABI_LP64F,
250 ABI_LP64D,
251 ABI_Unknown
252 };
253
254 // Returns the target ABI, or else a StringError if the requested ABIName is
255 // not supported for the given TT and FeatureBits combination.
256 ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits,
257 StringRef ABIName);
258
259 ABI getTargetABI(StringRef ABIName);
260
261 // Returns the register used to hold the stack pointer after realignment.
262 MCRegister getBPReg();
263
264 // Returns the register holding shadow call stack pointer.
265 MCRegister getSCSPReg();
266
267 } // namespace RISCVABI
268
269 namespace RISCVFeatures {
270
271 // Validates if the given combination of features are valid for the target
272 // triple. Exits with report_fatal_error if not.
273 void validate(const Triple &TT, const FeatureBitset &FeatureBits);
274
275 } // namespace RISCVFeatures
276
277 namespace RISCVVMVTs {
278
279 constexpr MVT vint8mf8_t = MVT::nxv1i8;
280 constexpr MVT vint8mf4_t = MVT::nxv2i8;
281 constexpr MVT vint8mf2_t = MVT::nxv4i8;
282 constexpr MVT vint8m1_t = MVT::nxv8i8;
283 constexpr MVT vint8m2_t = MVT::nxv16i8;
284 constexpr MVT vint8m4_t = MVT::nxv32i8;
285 constexpr MVT vint8m8_t = MVT::nxv64i8;
286
287 constexpr MVT vint16mf4_t = MVT::nxv1i16;
288 constexpr MVT vint16mf2_t = MVT::nxv2i16;
289 constexpr MVT vint16m1_t = MVT::nxv4i16;
290 constexpr MVT vint16m2_t = MVT::nxv8i16;
291 constexpr MVT vint16m4_t = MVT::nxv16i16;
292 constexpr MVT vint16m8_t = MVT::nxv32i16;
293
294 constexpr MVT vint32mf2_t = MVT::nxv1i32;
295 constexpr MVT vint32m1_t = MVT::nxv2i32;
296 constexpr MVT vint32m2_t = MVT::nxv4i32;
297 constexpr MVT vint32m4_t = MVT::nxv8i32;
298 constexpr MVT vint32m8_t = MVT::nxv16i32;
299
300 constexpr MVT vint64m1_t = MVT::nxv1i64;
301 constexpr MVT vint64m2_t = MVT::nxv2i64;
302 constexpr MVT vint64m4_t = MVT::nxv4i64;
303 constexpr MVT vint64m8_t = MVT::nxv8i64;
304
305 constexpr MVT vfloat16mf4_t = MVT::nxv1f16;
306 constexpr MVT vfloat16mf2_t = MVT::nxv2f16;
307 constexpr MVT vfloat16m1_t = MVT::nxv4f16;
308 constexpr MVT vfloat16m2_t = MVT::nxv8f16;
309 constexpr MVT vfloat16m4_t = MVT::nxv16f16;
310 constexpr MVT vfloat16m8_t = MVT::nxv32f16;
311
312 constexpr MVT vfloat32mf2_t = MVT::nxv1f32;
313 constexpr MVT vfloat32m1_t = MVT::nxv2f32;
314 constexpr MVT vfloat32m2_t = MVT::nxv4f32;
315 constexpr MVT vfloat32m4_t = MVT::nxv8f32;
316 constexpr MVT vfloat32m8_t = MVT::nxv16f32;
317
318 constexpr MVT vfloat64m1_t = MVT::nxv1f64;
319 constexpr MVT vfloat64m2_t = MVT::nxv2f64;
320 constexpr MVT vfloat64m4_t = MVT::nxv4f64;
321 constexpr MVT vfloat64m8_t = MVT::nxv8f64;
322
323 constexpr MVT vbool1_t = MVT::nxv64i1;
324 constexpr MVT vbool2_t = MVT::nxv32i1;
325 constexpr MVT vbool4_t = MVT::nxv16i1;
326 constexpr MVT vbool8_t = MVT::nxv8i1;
327 constexpr MVT vbool16_t = MVT::nxv4i1;
328 constexpr MVT vbool32_t = MVT::nxv2i1;
329 constexpr MVT vbool64_t = MVT::nxv1i1;
330
331 } // namespace RISCVVMVTs
332
333 enum class RISCVVSEW {
334 SEW_8 = 0,
335 SEW_16,
336 SEW_32,
337 SEW_64,
338 SEW_128,
339 SEW_256,
340 SEW_512,
341 SEW_1024,
342 };
343
344 enum class RISCVVLMUL {
345 LMUL_1 = 0,
346 LMUL_2,
347 LMUL_4,
348 LMUL_8,
349 LMUL_F8 = 5,
350 LMUL_F4,
351 LMUL_F2
352 };
353
354 namespace RISCVVType {
355 // Is this a SEW value that can be encoded into the VTYPE format.
isValidSEW(unsigned SEW)356 inline static bool isValidSEW(unsigned SEW) {
357 return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 1024;
358 }
359
360 // Is this a LMUL value that can be encoded into the VTYPE format.
isValidLMUL(unsigned LMUL,bool Fractional)361 inline static bool isValidLMUL(unsigned LMUL, bool Fractional) {
362 return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1);
363 }
364
365 // Encode VTYPE into the binary format used by the the VSETVLI instruction which
366 // is used by our MC layer representation.
367 //
368 // Bits | Name | Description
369 // -----+------------+------------------------------------------------
370 // 7 | vma | Vector mask agnostic
371 // 6 | vta | Vector tail agnostic
372 // 5 | vlmul[2] | Fractional lmul?
373 // 4:2 | vsew[2:0] | Standard element width (SEW) setting
374 // 1:0 | vlmul[1:0] | Vector register group multiplier (LMUL) setting
375 //
376 // TODO: This format will change for the V extensions spec v1.0.
encodeVTYPE(RISCVVLMUL VLMUL,RISCVVSEW VSEW,bool TailAgnostic,bool MaskAgnostic)377 inline static unsigned encodeVTYPE(RISCVVLMUL VLMUL, RISCVVSEW VSEW,
378 bool TailAgnostic, bool MaskAgnostic) {
379 unsigned VLMULBits = static_cast<unsigned>(VLMUL);
380 unsigned VSEWBits = static_cast<unsigned>(VSEW);
381 unsigned VTypeI =
382 ((VLMULBits & 0x4) << 3) | (VSEWBits << 2) | (VLMULBits & 0x3);
383 if (TailAgnostic)
384 VTypeI |= 0x40;
385 if (MaskAgnostic)
386 VTypeI |= 0x80;
387
388 return VTypeI;
389 }
390 } // namespace RISCVVType
391
392 namespace RISCVVPseudosTable {
393
394 struct PseudoInfo {
395 unsigned int Pseudo;
396 unsigned int BaseInstr;
397 uint8_t VLIndex;
398 uint8_t SEWIndex;
399 uint8_t MergeOpIndex;
400 uint8_t VLMul;
401
getVLIndexPseudoInfo402 int getVLIndex() const { return static_cast<int8_t>(VLIndex); }
403
getSEWIndexPseudoInfo404 int getSEWIndex() const { return static_cast<int8_t>(SEWIndex); }
405
getMergeOpIndexPseudoInfo406 int getMergeOpIndex() const { return static_cast<int8_t>(MergeOpIndex); }
407 };
408
409 using namespace RISCV;
410
411 #define GET_RISCVVPseudosTable_DECL
412 #include "RISCVGenSearchableTables.inc"
413
414 } // end namespace RISCVVPseudosTable
415
416 } // namespace llvm
417
418 #endif
419