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