• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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