1//===-- RISCVBaseInfo.h - Top level definitions for RISC-V 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 RISC-V 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/APFloat.h"
18#include "llvm/ADT/APInt.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/MC/MCInstrDesc.h"
22#include "llvm/TargetParser/RISCVISAInfo.h"
23#include "llvm/TargetParser/RISCVTargetParser.h"
24#include "llvm/TargetParser/SubtargetFeature.h"
25
26namespace llvm {
27
28// RISCVII - This namespace holds all of the target specific flags that
29// instruction info tracks. All definitions must match RISCVInstrFormats.td.
30namespace RISCVII {
31enum {
32 InstFormatPseudo = 0,
33 InstFormatR = 1,
34 InstFormatR4 = 2,
35 InstFormatI = 3,
36 InstFormatS = 4,
37 InstFormatB = 5,
38 InstFormatU = 6,
39 InstFormatJ = 7,
40 InstFormatCR = 8,
41 InstFormatCI = 9,
42 InstFormatCSS = 10,
43 InstFormatCIW = 11,
44 InstFormatCL = 12,
45 InstFormatCS = 13,
46 InstFormatCA = 14,
47 InstFormatCB = 15,
48 InstFormatCJ = 16,
49 InstFormatCU = 17,
50 InstFormatCLB = 18,
51 InstFormatCLH = 19,
52 InstFormatCSB = 20,
53 InstFormatCSH = 21,
54 InstFormatQC_EAI = 22,
55 InstFormatQC_EI = 23,
56 InstFormatQC_EB = 24,
57 InstFormatQC_EJ = 25,
58 InstFormatQC_ES = 26,
59 InstFormatNDS_BRANCH_10 = 27,
60 InstFormatOther = 31,
61
62 InstFormatMask = 31,
63 InstFormatShift = 0,
64
65 RVVConstraintShift = InstFormatShift + 5,
66 VS2Constraint = 0b001 << RVVConstraintShift,
67 VS1Constraint = 0b010 << RVVConstraintShift,
68 VMConstraint = 0b100 << RVVConstraintShift,
69 RVVConstraintMask = 0b111 << RVVConstraintShift,
70
71 VLMulShift = RVVConstraintShift + 3,
72 VLMulMask = 0b111 << VLMulShift,
73
74 // Is this a _TIED vector pseudo instruction. For these instructions we
75 // shouldn't skip the tied operand when converting to MC instructions.
76 IsTiedPseudoShift = VLMulShift + 3,
77 IsTiedPseudoMask = 1 << IsTiedPseudoShift,
78
79 // Does this instruction have a SEW operand. It will be the last explicit
80 // operand unless there is a vector policy operand. Used by RVV Pseudos.
81 HasSEWOpShift = IsTiedPseudoShift + 1,
82 HasSEWOpMask = 1 << HasSEWOpShift,
83
84 // Does this instruction have a VL operand. It will be the second to last
85 // explicit operand unless there is a vector policy operand. Used by RVV
86 // Pseudos.
87 HasVLOpShift = HasSEWOpShift + 1,
88 HasVLOpMask = 1 << HasVLOpShift,
89
90 // Does this instruction have a vector policy operand. It will be the last
91 // explicit operand. Used by RVV Pseudos.
92 HasVecPolicyOpShift = HasVLOpShift + 1,
93 HasVecPolicyOpMask = 1 << HasVecPolicyOpShift,
94
95 // Is this instruction a vector widening reduction instruction. Used by RVV
96 // Pseudos.
97 IsRVVWideningReductionShift = HasVecPolicyOpShift + 1,
98 IsRVVWideningReductionMask = 1 << IsRVVWideningReductionShift,
99
100 // Does this instruction care about mask policy. If it is not, the mask policy
101 // could be either agnostic or undisturbed. For example, unmasked, store, and
102 // reduction operations result would not be affected by mask policy, so
103 // compiler has free to select either one.
104 UsesMaskPolicyShift = IsRVVWideningReductionShift + 1,
105 UsesMaskPolicyMask = 1 << UsesMaskPolicyShift,
106
107 // Indicates that the result can be considered sign extended from bit 31. Some
108 // instructions with this flag aren't W instructions, but are either sign
109 // extended from a smaller size, always outputs a small integer, or put zeros
110 // in bits 63:31. Used by the SExtWRemoval pass.
111 IsSignExtendingOpWShift = UsesMaskPolicyShift + 1,
112 IsSignExtendingOpWMask = 1ULL << IsSignExtendingOpWShift,
113
114 HasRoundModeOpShift = IsSignExtendingOpWShift + 1,
115 HasRoundModeOpMask = 1 << HasRoundModeOpShift,
116
117 UsesVXRMShift = HasRoundModeOpShift + 1,
118 UsesVXRMMask = 1 << UsesVXRMShift,
119
120 // Indicates whether these instructions can partially overlap between source
121 // registers and destination registers according to the vector spec.
122 // 0 -> not a vector pseudo
123 // 1 -> default value for vector pseudos. not widening or narrowing.
124 // 2 -> narrowing case
125 // 3 -> widening case
126 TargetOverlapConstraintTypeShift = UsesVXRMShift + 1,
127 TargetOverlapConstraintTypeMask = 3ULL << TargetOverlapConstraintTypeShift,
128
129 ElementsDependOnVLShift = TargetOverlapConstraintTypeShift + 2,
130 ElementsDependOnVLMask = 1ULL << ElementsDependOnVLShift,
131
132 ElementsDependOnMaskShift = ElementsDependOnVLShift + 1,
133 ElementsDependOnMaskMask = 1ULL << ElementsDependOnMaskShift,
134
135 // Indicates the EEW of a vector instruction's destination operand.
136 // 0 -> 1
137 // 1 -> SEW
138 // 2 -> SEW * 2
139 // 3 -> SEW * 4
140 DestEEWShift = ElementsDependOnMaskShift + 1,
141 DestEEWMask = 3ULL << DestEEWShift,
142
143 ReadsPastVLShift = DestEEWShift + 2,
144 ReadsPastVLMask = 1ULL << ReadsPastVLShift,
145
146 // 0 -> Don't care about altfmt bit in VTYPE.
147 // 1 -> Is not altfmt.
148 // 2 -> Is altfmt(BF16).
149 AltFmtTypeShift = ReadsPastVLShift + 1,
150 AltFmtTypeMask = 3ULL << AltFmtTypeShift,
151
152 // XSfmmbase
153 HasTWidenOpShift = AltFmtTypeShift + 2,
154 HasTWidenOpMask = 1ULL << HasTWidenOpShift,
155
156 HasTMOpShift = HasTWidenOpShift + 1,
157 HasTMOpMask = 1ULL << HasTMOpShift,
158
159 HasTKOpShift = HasTMOpShift + 1,
160 HasTKOpMask = 1ULL << HasTKOpShift,
161};
162
163// Helper functions to read TSFlags.
164/// \returns the format of the instruction.
165static inline unsigned getFormat(uint64_t TSFlags) {
166 return (TSFlags & InstFormatMask) >> InstFormatShift;
167}
168/// \returns the LMUL for the instruction.
169static inline RISCVVType::VLMUL getLMul(uint64_t TSFlags) {
170 return static_cast<RISCVVType::VLMUL>((TSFlags & VLMulMask) >> VLMulShift);
171}
172/// \returns true if this a _TIED pseudo.
173static inline bool isTiedPseudo(uint64_t TSFlags) {
174 return TSFlags & IsTiedPseudoMask;
175}
176/// \returns true if there is a SEW operand for the instruction.
177static inline bool hasSEWOp(uint64_t TSFlags) {
178 return TSFlags & HasSEWOpMask;
179}
180/// \returns true if there is a VL operand for the instruction.
181static inline bool hasVLOp(uint64_t TSFlags) {
182 return TSFlags & HasVLOpMask;
183}
184/// \returns true if there is a vector policy operand for this instruction.
185static inline bool hasVecPolicyOp(uint64_t TSFlags) {
186 return TSFlags & HasVecPolicyOpMask;
187}
188/// \returns true if it is a vector widening reduction instruction.
189static inline bool isRVVWideningReduction(uint64_t TSFlags) {
190 return TSFlags & IsRVVWideningReductionMask;
191}
192/// \returns true if mask policy is valid for the instruction.
193static inline bool usesMaskPolicy(uint64_t TSFlags) {
194 return TSFlags & UsesMaskPolicyMask;
195}
196
197/// \returns true if there is a rounding mode operand for this instruction
198static inline bool hasRoundModeOp(uint64_t TSFlags) {
199 return TSFlags & HasRoundModeOpMask;
200}
201
202enum class AltFmtType { DontCare, NotAltFmt, AltFmt };
203static inline AltFmtType getAltFmtType(uint64_t TSFlags) {
204 return static_cast<AltFmtType>((TSFlags & AltFmtTypeMask) >> AltFmtTypeShift);
205}
206
207/// \returns true if this instruction uses vxrm
208static inline bool usesVXRM(uint64_t TSFlags) { return TSFlags & UsesVXRMMask; }
209
210/// \returns true if the elements in the body are affected by VL,
211/// e.g. vslide1down.vx/vredsum.vs/viota.m
212static inline bool elementsDependOnVL(uint64_t TSFlags) {
213 return TSFlags & ElementsDependOnVLMask;
214}
215
216/// \returns true if the elements in the body are affected by the mask,
217/// e.g. vredsum.vs/viota.m
218static inline bool elementsDependOnMask(uint64_t TSFlags) {
219 return TSFlags & ElementsDependOnMaskMask;
220}
221
222/// \returns true if the instruction may read elements past VL, e.g.
223/// vslidedown/vrgather
224static inline bool readsPastVL(uint64_t TSFlags) {
225 return TSFlags & ReadsPastVLMask;
226}
227
228// XSfmmbase
229static inline bool hasTWidenOp(uint64_t TSFlags) {
230 return TSFlags & HasTWidenOpMask;
231}
232
233static inline bool hasTMOp(uint64_t TSFlags) { return TSFlags & HasTMOpMask; }
234
235static inline bool hasTKOp(uint64_t TSFlags) { return TSFlags & HasTKOpMask; }
236
237static inline unsigned getTNOpNum(const MCInstrDesc &Desc) {
238 const uint64_t TSFlags = Desc.TSFlags;
239 assert(hasTWidenOp(TSFlags) && hasVLOp(TSFlags));
240 unsigned Offset = 3;
241 if (hasTKOp(TSFlags))
242 Offset = 4;
243 return Desc.getNumOperands() - Offset;
244}
245
246static inline unsigned getTMOpNum(const MCInstrDesc &Desc) {
247 const uint64_t TSFlags = Desc.TSFlags;
248 assert(hasTWidenOp(TSFlags) && hasTMOp(TSFlags));
249 if (hasTKOp(TSFlags))
250 return Desc.getNumOperands() - 5;
251 // vtzero.t
252 return Desc.getNumOperands() - 4;
253}
254
255static inline unsigned getTKOpNum(const MCInstrDesc &Desc) {
256 [[maybe_unused]] const uint64_t TSFlags = Desc.TSFlags;
257 assert(hasTWidenOp(TSFlags) && hasTKOp(TSFlags));
258 return Desc.getNumOperands() - 3;
259}
260
261static inline unsigned getVLOpNum(const MCInstrDesc &Desc) {
262 const uint64_t TSFlags = Desc.TSFlags;
263 // This method is only called if we expect to have a VL operand, and all
264 // instructions with VL also have SEW.
265 assert(hasSEWOp(TSFlags) && hasVLOp(TSFlags));
266 // In Xsfmmbase, TN is an alias for VL, so here we use the same TSFlags bit.
267 if (hasTWidenOp(TSFlags))
268 return getTNOpNum(Desc);
269 unsigned Offset = 2;
270 if (hasVecPolicyOp(TSFlags))
271 Offset = 3;
272 return Desc.getNumOperands() - Offset;
273}
274
275static inline MCRegister
276getTailExpandUseRegNo(const FeatureBitset &FeatureBits) {
277 // For Zicfilp, PseudoTAIL should be expanded to a software guarded branch.
278 // It means to use t2(x7) as rs1 of JALR to expand PseudoTAIL.
279 return FeatureBits[RISCV::FeatureStdExtZicfilp] ? RISCV::X7 : RISCV::X6;
280}
281
282static inline unsigned getSEWOpNum(const MCInstrDesc &Desc) {
283 const uint64_t TSFlags = Desc.TSFlags;
284 assert(hasSEWOp(TSFlags));
285 unsigned Offset = 1;
286 if (hasVecPolicyOp(TSFlags) || hasTWidenOp(TSFlags))
287 Offset = 2;
288 return Desc.getNumOperands() - Offset;
289}
290
291static inline unsigned getVecPolicyOpNum(const MCInstrDesc &Desc) {
292 assert(hasVecPolicyOp(Desc.TSFlags));
293 return Desc.getNumOperands() - 1;
294}
295
296/// \returns the index to the rounding mode immediate value if any, otherwise
297/// returns -1.
298static inline int getFRMOpNum(const MCInstrDesc &Desc) {
299 const uint64_t TSFlags = Desc.TSFlags;
300 if (!hasRoundModeOp(TSFlags) || usesVXRM(TSFlags))
301 return -1;
302
303 if (hasTWidenOp(TSFlags) && hasTMOp(TSFlags))
304 return getTMOpNum(Desc) - 1;
305
306 // The operand order
307 // --------------------------------------
308 // | n-1 (if any) | n-2 | n-3 | n-4 |
309 // | policy | sew | vl | frm |
310 // --------------------------------------
311 return getVLOpNum(Desc) - 1;
312}
313
314/// \returns the index to the rounding mode immediate value if any, otherwise
315/// returns -1.
316static inline int getVXRMOpNum(const MCInstrDesc &Desc) {
317 const uint64_t TSFlags = Desc.TSFlags;
318 if (!hasRoundModeOp(TSFlags) || !usesVXRM(TSFlags))
319 return -1;
320 // The operand order
321 // --------------------------------------
322 // | n-1 (if any) | n-2 | n-3 | n-4 |
323 // | policy | sew | vl | vxrm |
324 // --------------------------------------
325 return getVLOpNum(Desc) - 1;
326}
327
328// Is the first def operand tied to the first use operand. This is true for
329// vector pseudo instructions that have a merge operand for tail/mask
330// undisturbed. It's also true for vector FMA instructions where one of the
331// operands is also the destination register.
332static inline bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc) {
333 return Desc.getNumDefs() < Desc.getNumOperands() &&
334 Desc.getOperandConstraint(OpNum: Desc.getNumDefs(), Constraint: MCOI::TIED_TO) == 0;
335}
336
337// RISC-V Specific Machine Operand Flags
338enum {
339 MO_None = 0,
340 MO_CALL = 1,
341 MO_LO = 3,
342 MO_HI = 4,
343 MO_PCREL_LO = 5,
344 MO_PCREL_HI = 6,
345 MO_GOT_HI = 7,
346 MO_TPREL_LO = 8,
347 MO_TPREL_HI = 9,
348 MO_TPREL_ADD = 10,
349 MO_TLS_GOT_HI = 11,
350 MO_TLS_GD_HI = 12,
351 MO_TLSDESC_HI = 13,
352 MO_TLSDESC_LOAD_LO = 14,
353 MO_TLSDESC_ADD_LO = 15,
354 MO_TLSDESC_CALL = 16,
355
356 // Used to differentiate between target-specific "direct" flags and "bitmask"
357 // flags. A machine operand can only have one "direct" flag, but can have
358 // multiple "bitmask" flags.
359 MO_DIRECT_FLAG_MASK = 31
360};
361} // namespace RISCVII
362
363namespace RISCVOp {
364enum OperandType : unsigned {
365 OPERAND_FIRST_RISCV_IMM = MCOI::OPERAND_FIRST_TARGET,
366 OPERAND_UIMM1 = OPERAND_FIRST_RISCV_IMM,
367 OPERAND_UIMM2,
368 OPERAND_UIMM2_LSB0,
369 OPERAND_UIMM3,
370 OPERAND_UIMM4,
371 OPERAND_UIMM5,
372 OPERAND_UIMM5_NONZERO,
373 OPERAND_UIMM5_GT3,
374 OPERAND_UIMM5_PLUS1,
375 OPERAND_UIMM5_GE6_PLUS1,
376 OPERAND_UIMM5_LSB0,
377 OPERAND_UIMM5_SLIST,
378 OPERAND_UIMM6,
379 OPERAND_UIMM6_LSB0,
380 OPERAND_UIMM7,
381 OPERAND_UIMM7_LSB00,
382 OPERAND_UIMM7_LSB000,
383 OPERAND_UIMM8_LSB00,
384 OPERAND_UIMM8,
385 OPERAND_UIMM8_LSB000,
386 OPERAND_UIMM8_GE32,
387 OPERAND_UIMM9_LSB000,
388 OPERAND_UIMM9,
389 OPERAND_UIMM10,
390 OPERAND_UIMM10_LSB00_NONZERO,
391 OPERAND_UIMM11,
392 OPERAND_UIMM12,
393 OPERAND_UIMM14_LSB00,
394 OPERAND_UIMM16,
395 OPERAND_UIMM16_NONZERO,
396 OPERAND_UIMMLOG2XLEN,
397 OPERAND_UIMMLOG2XLEN_NONZERO,
398 OPERAND_UIMM32,
399 OPERAND_UIMM48,
400 OPERAND_UIMM64,
401 OPERAND_THREE,
402 OPERAND_FOUR,
403 OPERAND_IMM5_ZIBI,
404 OPERAND_SIMM5,
405 OPERAND_SIMM5_NONZERO,
406 OPERAND_SIMM5_PLUS1,
407 OPERAND_SIMM6,
408 OPERAND_SIMM6_NONZERO,
409 OPERAND_SIMM8_UNSIGNED,
410 OPERAND_SIMM10,
411 OPERAND_SIMM10_LSB0000_NONZERO,
412 OPERAND_SIMM10_UNSIGNED,
413 OPERAND_SIMM11,
414 OPERAND_SIMM12_LSB00000,
415 OPERAND_SIMM16,
416 OPERAND_SIMM16_NONZERO,
417 OPERAND_SIMM20,
418 OPERAND_SIMM20_LI,
419 OPERAND_SIMM26,
420 OPERAND_CLUI_IMM,
421 OPERAND_VTYPEI10,
422 OPERAND_VTYPEI11,
423 OPERAND_RVKRNUM,
424 OPERAND_RVKRNUM_0_7,
425 OPERAND_RVKRNUM_1_10,
426 OPERAND_RVKRNUM_2_14,
427 OPERAND_RLIST,
428 OPERAND_RLIST_S0,
429 OPERAND_STACKADJ,
430 // Operand is a 3-bit rounding mode, '111' indicates FRM register.
431 // Represents 'frm' argument passing to floating-point operations.
432 OPERAND_FRMARG,
433 // Operand is a 3-bit rounding mode where only RTZ is valid.
434 OPERAND_RTZARG,
435 // Condition code used by select and short forward branch pseudos.
436 OPERAND_COND_CODE,
437 // Ordering for atomic pseudos.
438 OPERAND_ATOMIC_ORDERING,
439 // Vector policy operand.
440 OPERAND_VEC_POLICY,
441 // Vector SEW operand. Stores in log2(SEW).
442 OPERAND_SEW,
443 // Special SEW for mask only instructions. Always 0.
444 OPERAND_SEW_MASK,
445 // Vector rounding mode for VXRM or FRM.
446 OPERAND_VEC_RM,
447 // Vtype operand for XSfmm extension.
448 OPERAND_XSFMM_VTYPE,
449 // XSfmm twiden operand.
450 OPERAND_XSFMM_TWIDEN,
451 OPERAND_LAST_RISCV_IMM = OPERAND_XSFMM_TWIDEN,
452
453 OPERAND_UIMM20_LUI,
454 OPERAND_UIMM20_AUIPC,
455
456 // Simm12 or constant pool, global, basicblock, etc.
457 OPERAND_SIMM12_LO,
458
459 OPERAND_BARE_SIMM32,
460
461 // Operand is either a register or uimm5, this is used by V extension pseudo
462 // instructions to represent a value that be passed as AVL to either vsetvli
463 // or vsetivli.
464 OPERAND_AVL,
465
466 OPERAND_VMASK,
467};
468} // namespace RISCVOp
469
470// Describes the predecessor/successor bits used in the FENCE instruction.
471namespace RISCVFenceField {
472enum FenceField {
473 I = 8,
474 O = 4,
475 R = 2,
476 W = 1
477};
478}
479
480// Describes the supported floating point rounding mode encodings.
481namespace RISCVFPRndMode {
482enum RoundingMode {
483 RNE = 0,
484 RTZ = 1,
485 RDN = 2,
486 RUP = 3,
487 RMM = 4,
488 DYN = 7,
489 Invalid
490};
491
492inline static StringRef roundingModeToString(RoundingMode RndMode) {
493 switch (RndMode) {
494 default:
495 llvm_unreachable("Unknown floating point rounding mode");
496 case RISCVFPRndMode::RNE:
497 return "rne";
498 case RISCVFPRndMode::RTZ:
499 return "rtz";
500 case RISCVFPRndMode::RDN:
501 return "rdn";
502 case RISCVFPRndMode::RUP:
503 return "rup";
504 case RISCVFPRndMode::RMM:
505 return "rmm";
506 case RISCVFPRndMode::DYN:
507 return "dyn";
508 }
509}
510
511inline static RoundingMode stringToRoundingMode(StringRef Str) {
512 return StringSwitch<RoundingMode>(Str)
513 .Case(S: "rne", Value: RISCVFPRndMode::RNE)
514 .Case(S: "rtz", Value: RISCVFPRndMode::RTZ)
515 .Case(S: "rdn", Value: RISCVFPRndMode::RDN)
516 .Case(S: "rup", Value: RISCVFPRndMode::RUP)
517 .Case(S: "rmm", Value: RISCVFPRndMode::RMM)
518 .Case(S: "dyn", Value: RISCVFPRndMode::DYN)
519 .Default(Value: RISCVFPRndMode::Invalid);
520}
521
522inline static bool isValidRoundingMode(unsigned Mode) {
523 switch (Mode) {
524 default:
525 return false;
526 case RISCVFPRndMode::RNE:
527 case RISCVFPRndMode::RTZ:
528 case RISCVFPRndMode::RDN:
529 case RISCVFPRndMode::RUP:
530 case RISCVFPRndMode::RMM:
531 case RISCVFPRndMode::DYN:
532 return true;
533 }
534}
535} // namespace RISCVFPRndMode
536
537namespace RISCVVXRndMode {
538enum RoundingMode {
539 RNU = 0,
540 RNE = 1,
541 RDN = 2,
542 ROD = 3,
543 Invalid
544};
545
546inline static StringRef roundingModeToString(RoundingMode RndMode) {
547 switch (RndMode) {
548 default:
549 llvm_unreachable("Unknown vector fixed-point rounding mode");
550 case RISCVVXRndMode::RNU:
551 return "rnu";
552 case RISCVVXRndMode::RNE:
553 return "rne";
554 case RISCVVXRndMode::RDN:
555 return "rdn";
556 case RISCVVXRndMode::ROD:
557 return "rod";
558 }
559}
560
561inline static RoundingMode stringToRoundingMode(StringRef Str) {
562 return StringSwitch<RoundingMode>(Str)
563 .Case(S: "rnu", Value: RISCVVXRndMode::RNU)
564 .Case(S: "rne", Value: RISCVVXRndMode::RNE)
565 .Case(S: "rdn", Value: RISCVVXRndMode::RDN)
566 .Case(S: "rod", Value: RISCVVXRndMode::ROD)
567 .Default(Value: RISCVVXRndMode::Invalid);
568}
569
570inline static bool isValidRoundingMode(unsigned Mode) {
571 switch (Mode) {
572 default:
573 return false;
574 case RISCVVXRndMode::RNU:
575 case RISCVVXRndMode::RNE:
576 case RISCVVXRndMode::RDN:
577 case RISCVVXRndMode::ROD:
578 return true;
579 }
580}
581} // namespace RISCVVXRndMode
582
583namespace RISCVExceptFlags {
584enum ExceptionFlag {
585 NX = 0x01, // Inexact
586 UF = 0x02, // Underflow
587 OF = 0x04, // Overflow
588 DZ = 0x08, // Divide by zero
589 NV = 0x10, // Invalid operation
590 ALL = 0x1F // Mask for all accrued exception flags
591};
592}
593
594//===----------------------------------------------------------------------===//
595// Floating-point Immediates
596//
597
598namespace RISCVLoadFPImm {
599float getFPImm(unsigned Imm);
600
601/// getLoadFPImm - Return a 5-bit binary encoding of the floating-point
602/// immediate value. If the value cannot be represented as a 5-bit binary
603/// encoding, then return -1.
604int getLoadFPImm(APFloat FPImm);
605} // namespace RISCVLoadFPImm
606
607namespace RISCVSysReg {
608struct SysReg {
609 const char Name[32];
610 unsigned Encoding;
611 // FIXME: add these additional fields when needed.
612 // Privilege Access: Read, Write, Read-Only.
613 // unsigned ReadWrite;
614 // Privilege Mode: User, System or Machine.
615 // unsigned Mode;
616 // Check field name.
617 // unsigned Extra;
618 // Register number without the privilege bits.
619 // unsigned Number;
620 FeatureBitset FeaturesRequired;
621 bool IsRV32Only;
622 bool IsAltName;
623 bool IsDeprecatedName;
624
625 bool haveRequiredFeatures(const FeatureBitset &ActiveFeatures) const {
626 // Not in 32-bit mode.
627 if (IsRV32Only && ActiveFeatures[RISCV::Feature64Bit])
628 return false;
629 // No required feature associated with the system register.
630 if (FeaturesRequired.none())
631 return true;
632 return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
633 }
634};
635
636#define GET_SysRegEncodings_DECL
637#define GET_SysRegsList_DECL
638#include "RISCVGenSearchableTables.inc"
639} // end namespace RISCVSysReg
640
641namespace RISCVInsnOpcode {
642struct RISCVOpcode {
643 char Name[10];
644 uint8_t Value;
645};
646
647#define GET_RISCVOpcodesList_DECL
648#include "RISCVGenSearchableTables.inc"
649} // end namespace RISCVInsnOpcode
650
651namespace RISCVABI {
652
653enum ABI {
654 ABI_ILP32,
655 ABI_ILP32F,
656 ABI_ILP32D,
657 ABI_ILP32E,
658 ABI_LP64,
659 ABI_LP64F,
660 ABI_LP64D,
661 ABI_LP64E,
662 ABI_Unknown
663};
664
665// Returns the target ABI, or else a StringError if the requested ABIName is
666// not supported for the given TT and FeatureBits combination.
667ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits,
668 StringRef ABIName);
669
670ABI getTargetABI(StringRef ABIName);
671
672// Returns the register used to hold the stack pointer after realignment.
673MCRegister getBPReg();
674
675// Returns the register holding shadow call stack pointer.
676MCRegister getSCSPReg();
677
678} // namespace RISCVABI
679
680namespace RISCVFeatures {
681
682// Validates if the given combination of features are valid for the target
683// triple. Exits with report_fatal_error if not.
684void validate(const Triple &TT, const FeatureBitset &FeatureBits);
685
686llvm::Expected<std::unique_ptr<RISCVISAInfo>>
687parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits);
688
689} // namespace RISCVFeatures
690
691namespace RISCVRVC {
692bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI);
693bool uncompress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI);
694} // namespace RISCVRVC
695
696namespace RISCVZC {
697enum RLISTENCODE {
698 RA = 4,
699 RA_S0,
700 RA_S0_S1,
701 RA_S0_S2,
702 RA_S0_S3,
703 RA_S0_S4,
704 RA_S0_S5,
705 RA_S0_S6,
706 RA_S0_S7,
707 RA_S0_S8,
708 RA_S0_S9,
709 // note - to include s10, s11 must also be included
710 RA_S0_S11,
711 INVALID_RLIST,
712};
713
714inline unsigned encodeRegList(MCRegister EndReg, bool IsRVE = false) {
715 assert((!IsRVE || EndReg <= RISCV::X9) && "Invalid Rlist for RV32E");
716 switch (EndReg.id()) {
717 case RISCV::X1:
718 return RLISTENCODE::RA;
719 case RISCV::X8:
720 return RLISTENCODE::RA_S0;
721 case RISCV::X9:
722 return RLISTENCODE::RA_S0_S1;
723 case RISCV::X18:
724 return RLISTENCODE::RA_S0_S2;
725 case RISCV::X19:
726 return RLISTENCODE::RA_S0_S3;
727 case RISCV::X20:
728 return RLISTENCODE::RA_S0_S4;
729 case RISCV::X21:
730 return RLISTENCODE::RA_S0_S5;
731 case RISCV::X22:
732 return RLISTENCODE::RA_S0_S6;
733 case RISCV::X23:
734 return RLISTENCODE::RA_S0_S7;
735 case RISCV::X24:
736 return RLISTENCODE::RA_S0_S8;
737 case RISCV::X25:
738 return RLISTENCODE::RA_S0_S9;
739 case RISCV::X27:
740 return RLISTENCODE::RA_S0_S11;
741 default:
742 llvm_unreachable("Undefined input.");
743 }
744}
745
746inline static unsigned encodeRegListNumRegs(unsigned NumRegs) {
747 assert(NumRegs > 0 && NumRegs < 14 && NumRegs != 12 &&
748 "Unexpected number of registers");
749 if (NumRegs == 13)
750 return RLISTENCODE::RA_S0_S11;
751
752 return RLISTENCODE::RA + (NumRegs - 1);
753}
754
755inline static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64) {
756 assert(RlistVal >= RLISTENCODE::RA && RlistVal <= RLISTENCODE::RA_S0_S11 &&
757 "Invalid Rlist");
758 unsigned NumRegs = (RlistVal - RLISTENCODE::RA) + 1;
759 // s10 and s11 are saved together.
760 if (RlistVal == RLISTENCODE::RA_S0_S11)
761 ++NumRegs;
762
763 unsigned RegSize = IsRV64 ? 8 : 4;
764 return alignTo(Value: NumRegs * RegSize, Align: 16);
765}
766
767void printRegList(unsigned RlistEncode, raw_ostream &OS);
768} // namespace RISCVZC
769
770namespace RISCVVInversePseudosTable {
771struct PseudoInfo {
772 uint16_t Pseudo;
773 uint16_t BaseInstr;
774 uint16_t VLMul : 3;
775 uint16_t SEW : 8;
776 uint16_t IsAltFmt : 1;
777};
778
779#define GET_RISCVVInversePseudosTable_DECL
780#include "RISCVGenSearchableTables.inc"
781
782inline const PseudoInfo *getBaseInfo(unsigned BaseInstr, uint8_t VLMul,
783 uint8_t SEW, bool IsAltFmt = false) {
784 return getBaseInfoImpl(BaseInstr, VLMul, SEW, IsAltFmt);
785}
786} // namespace RISCVVInversePseudosTable
787
788namespace RISCV {
789struct VLSEGPseudo {
790 uint16_t NF : 4;
791 uint16_t Masked : 1;
792 uint16_t Strided : 1;
793 uint16_t FF : 1;
794 uint16_t Log2SEW : 3;
795 uint16_t LMUL : 3;
796 uint16_t Pseudo;
797};
798
799struct VLXSEGPseudo {
800 uint16_t NF : 4;
801 uint16_t Masked : 1;
802 uint16_t Ordered : 1;
803 uint16_t Log2SEW : 3;
804 uint16_t LMUL : 3;
805 uint16_t IndexLMUL : 3;
806 uint16_t Pseudo;
807};
808
809struct VSSEGPseudo {
810 uint16_t NF : 4;
811 uint16_t Masked : 1;
812 uint16_t Strided : 1;
813 uint16_t Log2SEW : 3;
814 uint16_t LMUL : 3;
815 uint16_t Pseudo;
816};
817
818struct VSXSEGPseudo {
819 uint16_t NF : 4;
820 uint16_t Masked : 1;
821 uint16_t Ordered : 1;
822 uint16_t Log2SEW : 3;
823 uint16_t LMUL : 3;
824 uint16_t IndexLMUL : 3;
825 uint16_t Pseudo;
826};
827
828struct VLEPseudo {
829 uint16_t Masked : 1;
830 uint16_t Strided : 1;
831 uint16_t FF : 1;
832 uint16_t Log2SEW : 3;
833 uint16_t LMUL : 3;
834 uint16_t Pseudo;
835};
836
837struct VSEPseudo {
838 uint16_t Masked : 1;
839 uint16_t Strided : 1;
840 uint16_t Log2SEW : 3;
841 uint16_t LMUL : 3;
842 uint16_t Pseudo;
843};
844
845struct VLX_VSXPseudo {
846 uint16_t Masked : 1;
847 uint16_t Ordered : 1;
848 uint16_t Log2SEW : 3;
849 uint16_t LMUL : 3;
850 uint16_t IndexLMUL : 3;
851 uint16_t Pseudo;
852};
853
854struct NDSVLNPseudo {
855 uint16_t Masked : 1;
856 uint16_t Unsigned : 1;
857 uint16_t Log2SEW : 3;
858 uint16_t LMUL : 3;
859 uint16_t Pseudo;
860};
861
862#define GET_RISCVVSSEGTable_DECL
863#define GET_RISCVVLSEGTable_DECL
864#define GET_RISCVVLXSEGTable_DECL
865#define GET_RISCVVSXSEGTable_DECL
866#define GET_RISCVVLETable_DECL
867#define GET_RISCVVSETable_DECL
868#define GET_RISCVVLXTable_DECL
869#define GET_RISCVVSXTable_DECL
870#define GET_RISCVNDSVLNTable_DECL
871#include "RISCVGenSearchableTables.inc"
872} // namespace RISCV
873
874} // namespace llvm
875
876#endif
877