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 | |
26 | namespace llvm { |
27 | |
28 | // RISCVII - This namespace holds all of the target specific flags that |
29 | // instruction info tracks. All definitions must match RISCVInstrFormats.td. |
30 | namespace RISCVII { |
31 | enum { |
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 | ConstraintShift = InstFormatShift + 5, |
66 | VS2Constraint = 0b001 << ConstraintShift, |
67 | VS1Constraint = 0b010 << ConstraintShift, |
68 | VMConstraint = 0b100 << ConstraintShift, |
69 | ConstraintMask = 0b111 << ConstraintShift, |
70 | |
71 | VLMulShift = ConstraintShift + 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 | |
144 | // Helper functions to read TSFlags. |
145 | /// \returns the format of the instruction. |
146 | static inline unsigned getFormat(uint64_t TSFlags) { |
147 | return (TSFlags & InstFormatMask) >> InstFormatShift; |
148 | } |
149 | /// \returns the LMUL for the instruction. |
150 | static inline RISCVVType::VLMUL getLMul(uint64_t TSFlags) { |
151 | return static_cast<RISCVVType::VLMUL>((TSFlags & VLMulMask) >> VLMulShift); |
152 | } |
153 | /// \returns true if this a _TIED pseudo. |
154 | static inline bool isTiedPseudo(uint64_t TSFlags) { |
155 | return TSFlags & IsTiedPseudoMask; |
156 | } |
157 | /// \returns true if there is a SEW operand for the instruction. |
158 | static inline bool hasSEWOp(uint64_t TSFlags) { |
159 | return TSFlags & HasSEWOpMask; |
160 | } |
161 | /// \returns true if there is a VL operand for the instruction. |
162 | static inline bool hasVLOp(uint64_t TSFlags) { |
163 | return TSFlags & HasVLOpMask; |
164 | } |
165 | /// \returns true if there is a vector policy operand for this instruction. |
166 | static inline bool hasVecPolicyOp(uint64_t TSFlags) { |
167 | return TSFlags & HasVecPolicyOpMask; |
168 | } |
169 | /// \returns true if it is a vector widening reduction instruction. |
170 | static inline bool isRVVWideningReduction(uint64_t TSFlags) { |
171 | return TSFlags & IsRVVWideningReductionMask; |
172 | } |
173 | /// \returns true if mask policy is valid for the instruction. |
174 | static inline bool usesMaskPolicy(uint64_t TSFlags) { |
175 | return TSFlags & UsesMaskPolicyMask; |
176 | } |
177 | |
178 | /// \returns true if there is a rounding mode operand for this instruction |
179 | static inline bool hasRoundModeOp(uint64_t TSFlags) { |
180 | return TSFlags & HasRoundModeOpMask; |
181 | } |
182 | |
183 | /// \returns true if this instruction uses vxrm |
184 | static inline bool usesVXRM(uint64_t TSFlags) { return TSFlags & UsesVXRMMask; } |
185 | |
186 | /// \returns true if the elements in the body are affected by VL, |
187 | /// e.g. vslide1down.vx/vredsum.vs/viota.m |
188 | static inline bool elementsDependOnVL(uint64_t TSFlags) { |
189 | return TSFlags & ElementsDependOnVLMask; |
190 | } |
191 | |
192 | /// \returns true if the elements in the body are affected by the mask, |
193 | /// e.g. vredsum.vs/viota.m |
194 | static inline bool elementsDependOnMask(uint64_t TSFlags) { |
195 | return TSFlags & ElementsDependOnMaskMask; |
196 | } |
197 | |
198 | static inline unsigned getVLOpNum(const MCInstrDesc &Desc) { |
199 | const uint64_t TSFlags = Desc.TSFlags; |
200 | // This method is only called if we expect to have a VL operand, and all |
201 | // instructions with VL also have SEW. |
202 | assert(hasSEWOp(TSFlags) && hasVLOp(TSFlags)); |
203 | unsigned Offset = 2; |
204 | if (hasVecPolicyOp(TSFlags)) |
205 | Offset = 3; |
206 | return Desc.getNumOperands() - Offset; |
207 | } |
208 | |
209 | static inline MCRegister |
210 | getTailExpandUseRegNo(const FeatureBitset &FeatureBits) { |
211 | // For Zicfilp, PseudoTAIL should be expanded to a software guarded branch. |
212 | // It means to use t2(x7) as rs1 of JALR to expand PseudoTAIL. |
213 | return FeatureBits[RISCV::FeatureStdExtZicfilp] ? RISCV::X7 : RISCV::X6; |
214 | } |
215 | |
216 | static inline unsigned getSEWOpNum(const MCInstrDesc &Desc) { |
217 | const uint64_t TSFlags = Desc.TSFlags; |
218 | assert(hasSEWOp(TSFlags)); |
219 | unsigned Offset = 1; |
220 | if (hasVecPolicyOp(TSFlags)) |
221 | Offset = 2; |
222 | return Desc.getNumOperands() - Offset; |
223 | } |
224 | |
225 | static inline unsigned getVecPolicyOpNum(const MCInstrDesc &Desc) { |
226 | assert(hasVecPolicyOp(Desc.TSFlags)); |
227 | return Desc.getNumOperands() - 1; |
228 | } |
229 | |
230 | /// \returns the index to the rounding mode immediate value if any, otherwise |
231 | /// returns -1. |
232 | static inline int getFRMOpNum(const MCInstrDesc &Desc) { |
233 | const uint64_t TSFlags = Desc.TSFlags; |
234 | if (!hasRoundModeOp(TSFlags) || usesVXRM(TSFlags)) |
235 | return -1; |
236 | |
237 | // The operand order |
238 | // -------------------------------------- |
239 | // | n-1 (if any) | n-2 | n-3 | n-4 | |
240 | // | policy | sew | vl | frm | |
241 | // -------------------------------------- |
242 | return getVLOpNum(Desc) - 1; |
243 | } |
244 | |
245 | /// \returns the index to the rounding mode immediate value if any, otherwise |
246 | /// returns -1. |
247 | static inline int getVXRMOpNum(const MCInstrDesc &Desc) { |
248 | const uint64_t TSFlags = Desc.TSFlags; |
249 | if (!hasRoundModeOp(TSFlags) || !usesVXRM(TSFlags)) |
250 | return -1; |
251 | // The operand order |
252 | // -------------------------------------- |
253 | // | n-1 (if any) | n-2 | n-3 | n-4 | |
254 | // | policy | sew | vl | vxrm | |
255 | // -------------------------------------- |
256 | return getVLOpNum(Desc) - 1; |
257 | } |
258 | |
259 | // Is the first def operand tied to the first use operand. This is true for |
260 | // vector pseudo instructions that have a merge operand for tail/mask |
261 | // undisturbed. It's also true for vector FMA instructions where one of the |
262 | // operands is also the destination register. |
263 | static inline bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc) { |
264 | return Desc.getNumDefs() < Desc.getNumOperands() && |
265 | Desc.getOperandConstraint(OpNum: Desc.getNumDefs(), Constraint: MCOI::TIED_TO) == 0; |
266 | } |
267 | |
268 | // RISC-V Specific Machine Operand Flags |
269 | enum { |
270 | MO_None = 0, |
271 | MO_CALL = 1, |
272 | MO_LO = 3, |
273 | MO_HI = 4, |
274 | MO_PCREL_LO = 5, |
275 | MO_PCREL_HI = 6, |
276 | MO_GOT_HI = 7, |
277 | MO_TPREL_LO = 8, |
278 | MO_TPREL_HI = 9, |
279 | MO_TPREL_ADD = 10, |
280 | MO_TLS_GOT_HI = 11, |
281 | MO_TLS_GD_HI = 12, |
282 | MO_TLSDESC_HI = 13, |
283 | MO_TLSDESC_LOAD_LO = 14, |
284 | MO_TLSDESC_ADD_LO = 15, |
285 | MO_TLSDESC_CALL = 16, |
286 | |
287 | // Used to differentiate between target-specific "direct" flags and "bitmask" |
288 | // flags. A machine operand can only have one "direct" flag, but can have |
289 | // multiple "bitmask" flags. |
290 | MO_DIRECT_FLAG_MASK = 31 |
291 | }; |
292 | } // namespace RISCVII |
293 | |
294 | namespace RISCVOp { |
295 | enum OperandType : unsigned { |
296 | OPERAND_FIRST_RISCV_IMM = MCOI::OPERAND_FIRST_TARGET, |
297 | OPERAND_UIMM1 = OPERAND_FIRST_RISCV_IMM, |
298 | OPERAND_UIMM2, |
299 | OPERAND_UIMM2_LSB0, |
300 | OPERAND_UIMM3, |
301 | OPERAND_UIMM4, |
302 | OPERAND_UIMM5, |
303 | OPERAND_UIMM5_NONZERO, |
304 | OPERAND_UIMM5_GT3, |
305 | OPERAND_UIMM5_PLUS1, |
306 | OPERAND_UIMM5_GE6_PLUS1, |
307 | OPERAND_UIMM5_LSB0, |
308 | OPERAND_UIMM5_SLIST, |
309 | OPERAND_UIMM6, |
310 | OPERAND_UIMM6_LSB0, |
311 | OPERAND_UIMM7, |
312 | OPERAND_UIMM7_LSB00, |
313 | OPERAND_UIMM7_LSB000, |
314 | OPERAND_UIMM8_LSB00, |
315 | OPERAND_UIMM8, |
316 | OPERAND_UIMM8_LSB000, |
317 | OPERAND_UIMM8_GE32, |
318 | OPERAND_UIMM9_LSB000, |
319 | OPERAND_UIMM9, |
320 | OPERAND_UIMM10, |
321 | OPERAND_UIMM10_LSB00_NONZERO, |
322 | OPERAND_UIMM11, |
323 | OPERAND_UIMM12, |
324 | OPERAND_UIMM14_LSB00, |
325 | OPERAND_UIMM16, |
326 | OPERAND_UIMM16_NONZERO, |
327 | OPERAND_UIMM20, |
328 | OPERAND_UIMMLOG2XLEN, |
329 | OPERAND_UIMMLOG2XLEN_NONZERO, |
330 | OPERAND_UIMM32, |
331 | OPERAND_UIMM48, |
332 | OPERAND_UIMM64, |
333 | OPERAND_ZERO, |
334 | OPERAND_THREE, |
335 | OPERAND_FOUR, |
336 | OPERAND_SIMM5, |
337 | OPERAND_SIMM5_NONZERO, |
338 | OPERAND_SIMM5_PLUS1, |
339 | OPERAND_SIMM6, |
340 | OPERAND_SIMM6_NONZERO, |
341 | OPERAND_SIMM10, |
342 | OPERAND_SIMM10_UNSIGNED, |
343 | OPERAND_SIMM10_LSB0000_NONZERO, |
344 | OPERAND_SIMM11, |
345 | OPERAND_SIMM12, |
346 | OPERAND_SIMM12_LSB00000, |
347 | OPERAND_SIMM16, |
348 | OPERAND_SIMM16_NONZERO, |
349 | OPERAND_SIMM20_LI, |
350 | OPERAND_SIMM26, |
351 | OPERAND_BARE_SIMM32, |
352 | OPERAND_CLUI_IMM, |
353 | OPERAND_VTYPEI10, |
354 | OPERAND_VTYPEI11, |
355 | OPERAND_RVKRNUM, |
356 | OPERAND_RVKRNUM_0_7, |
357 | OPERAND_RVKRNUM_1_10, |
358 | OPERAND_RVKRNUM_2_14, |
359 | OPERAND_RLIST, |
360 | OPERAND_RLIST_S0, |
361 | OPERAND_STACKADJ, |
362 | // Operand is a 3-bit rounding mode, '111' indicates FRM register. |
363 | // Represents 'frm' argument passing to floating-point operations. |
364 | OPERAND_FRMARG, |
365 | // Operand is a 3-bit rounding mode where only RTZ is valid. |
366 | OPERAND_RTZARG, |
367 | // Condition code used by select and short forward branch pseudos. |
368 | OPERAND_COND_CODE, |
369 | // Vector policy operand. |
370 | OPERAND_VEC_POLICY, |
371 | // Vector SEW operand. Stores in log2(SEW). |
372 | OPERAND_SEW, |
373 | // Special SEW for mask only instructions. Always 0. |
374 | OPERAND_SEW_MASK, |
375 | // Vector rounding mode for VXRM or FRM. |
376 | OPERAND_VEC_RM, |
377 | OPERAND_LAST_RISCV_IMM = OPERAND_VEC_RM, |
378 | // Operand is either a register or uimm5, this is used by V extension pseudo |
379 | // instructions to represent a value that be passed as AVL to either vsetvli |
380 | // or vsetivli. |
381 | OPERAND_AVL, |
382 | }; |
383 | } // namespace RISCVOp |
384 | |
385 | // Describes the predecessor/successor bits used in the FENCE instruction. |
386 | namespace RISCVFenceField { |
387 | enum FenceField { |
388 | I = 8, |
389 | O = 4, |
390 | R = 2, |
391 | W = 1 |
392 | }; |
393 | } |
394 | |
395 | // Describes the supported floating point rounding mode encodings. |
396 | namespace RISCVFPRndMode { |
397 | enum RoundingMode { |
398 | RNE = 0, |
399 | RTZ = 1, |
400 | RDN = 2, |
401 | RUP = 3, |
402 | RMM = 4, |
403 | DYN = 7, |
404 | Invalid |
405 | }; |
406 | |
407 | inline static StringRef roundingModeToString(RoundingMode RndMode) { |
408 | switch (RndMode) { |
409 | default: |
410 | llvm_unreachable("Unknown floating point rounding mode" ); |
411 | case RISCVFPRndMode::RNE: |
412 | return "rne" ; |
413 | case RISCVFPRndMode::RTZ: |
414 | return "rtz" ; |
415 | case RISCVFPRndMode::RDN: |
416 | return "rdn" ; |
417 | case RISCVFPRndMode::RUP: |
418 | return "rup" ; |
419 | case RISCVFPRndMode::RMM: |
420 | return "rmm" ; |
421 | case RISCVFPRndMode::DYN: |
422 | return "dyn" ; |
423 | } |
424 | } |
425 | |
426 | inline static RoundingMode stringToRoundingMode(StringRef Str) { |
427 | return StringSwitch<RoundingMode>(Str) |
428 | .Case(S: "rne" , Value: RISCVFPRndMode::RNE) |
429 | .Case(S: "rtz" , Value: RISCVFPRndMode::RTZ) |
430 | .Case(S: "rdn" , Value: RISCVFPRndMode::RDN) |
431 | .Case(S: "rup" , Value: RISCVFPRndMode::RUP) |
432 | .Case(S: "rmm" , Value: RISCVFPRndMode::RMM) |
433 | .Case(S: "dyn" , Value: RISCVFPRndMode::DYN) |
434 | .Default(Value: RISCVFPRndMode::Invalid); |
435 | } |
436 | |
437 | inline static bool isValidRoundingMode(unsigned Mode) { |
438 | switch (Mode) { |
439 | default: |
440 | return false; |
441 | case RISCVFPRndMode::RNE: |
442 | case RISCVFPRndMode::RTZ: |
443 | case RISCVFPRndMode::RDN: |
444 | case RISCVFPRndMode::RUP: |
445 | case RISCVFPRndMode::RMM: |
446 | case RISCVFPRndMode::DYN: |
447 | return true; |
448 | } |
449 | } |
450 | } // namespace RISCVFPRndMode |
451 | |
452 | namespace RISCVVXRndMode { |
453 | enum RoundingMode { |
454 | RNU = 0, |
455 | RNE = 1, |
456 | RDN = 2, |
457 | ROD = 3, |
458 | Invalid |
459 | }; |
460 | |
461 | inline static StringRef roundingModeToString(RoundingMode RndMode) { |
462 | switch (RndMode) { |
463 | default: |
464 | llvm_unreachable("Unknown vector fixed-point rounding mode" ); |
465 | case RISCVVXRndMode::RNU: |
466 | return "rnu" ; |
467 | case RISCVVXRndMode::RNE: |
468 | return "rne" ; |
469 | case RISCVVXRndMode::RDN: |
470 | return "rdn" ; |
471 | case RISCVVXRndMode::ROD: |
472 | return "rod" ; |
473 | } |
474 | } |
475 | |
476 | inline static RoundingMode stringToRoundingMode(StringRef Str) { |
477 | return StringSwitch<RoundingMode>(Str) |
478 | .Case(S: "rnu" , Value: RISCVVXRndMode::RNU) |
479 | .Case(S: "rne" , Value: RISCVVXRndMode::RNE) |
480 | .Case(S: "rdn" , Value: RISCVVXRndMode::RDN) |
481 | .Case(S: "rod" , Value: RISCVVXRndMode::ROD) |
482 | .Default(Value: RISCVVXRndMode::Invalid); |
483 | } |
484 | |
485 | inline static bool isValidRoundingMode(unsigned Mode) { |
486 | switch (Mode) { |
487 | default: |
488 | return false; |
489 | case RISCVVXRndMode::RNU: |
490 | case RISCVVXRndMode::RNE: |
491 | case RISCVVXRndMode::RDN: |
492 | case RISCVVXRndMode::ROD: |
493 | return true; |
494 | } |
495 | } |
496 | } // namespace RISCVVXRndMode |
497 | |
498 | //===----------------------------------------------------------------------===// |
499 | // Floating-point Immediates |
500 | // |
501 | |
502 | namespace RISCVLoadFPImm { |
503 | float getFPImm(unsigned Imm); |
504 | |
505 | /// getLoadFPImm - Return a 5-bit binary encoding of the floating-point |
506 | /// immediate value. If the value cannot be represented as a 5-bit binary |
507 | /// encoding, then return -1. |
508 | int getLoadFPImm(APFloat FPImm); |
509 | } // namespace RISCVLoadFPImm |
510 | |
511 | namespace RISCVSysReg { |
512 | struct SysReg { |
513 | const char Name[32]; |
514 | unsigned Encoding; |
515 | // FIXME: add these additional fields when needed. |
516 | // Privilege Access: Read, Write, Read-Only. |
517 | // unsigned ReadWrite; |
518 | // Privilege Mode: User, System or Machine. |
519 | // unsigned Mode; |
520 | // Check field name. |
521 | // unsigned Extra; |
522 | // Register number without the privilege bits. |
523 | // unsigned Number; |
524 | FeatureBitset FeaturesRequired; |
525 | bool IsRV32Only; |
526 | bool IsAltName; |
527 | bool IsDeprecatedName; |
528 | |
529 | bool haveRequiredFeatures(const FeatureBitset &ActiveFeatures) const { |
530 | // Not in 32-bit mode. |
531 | if (IsRV32Only && ActiveFeatures[RISCV::Feature64Bit]) |
532 | return false; |
533 | // No required feature associated with the system register. |
534 | if (FeaturesRequired.none()) |
535 | return true; |
536 | return (FeaturesRequired & ActiveFeatures) == FeaturesRequired; |
537 | } |
538 | }; |
539 | |
540 | #define GET_SysRegEncodings_DECL |
541 | #define GET_SysRegsList_DECL |
542 | #include "RISCVGenSearchableTables.inc" |
543 | } // end namespace RISCVSysReg |
544 | |
545 | namespace RISCVInsnOpcode { |
546 | struct RISCVOpcode { |
547 | char Name[10]; |
548 | uint8_t Value; |
549 | }; |
550 | |
551 | #define GET_RISCVOpcodesList_DECL |
552 | #include "RISCVGenSearchableTables.inc" |
553 | } // end namespace RISCVInsnOpcode |
554 | |
555 | namespace RISCVABI { |
556 | |
557 | enum ABI { |
558 | ABI_ILP32, |
559 | ABI_ILP32F, |
560 | ABI_ILP32D, |
561 | ABI_ILP32E, |
562 | ABI_LP64, |
563 | ABI_LP64F, |
564 | ABI_LP64D, |
565 | ABI_LP64E, |
566 | ABI_Unknown |
567 | }; |
568 | |
569 | // Returns the target ABI, or else a StringError if the requested ABIName is |
570 | // not supported for the given TT and FeatureBits combination. |
571 | ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, |
572 | StringRef ABIName); |
573 | |
574 | ABI getTargetABI(StringRef ABIName); |
575 | |
576 | // Returns the register used to hold the stack pointer after realignment. |
577 | MCRegister getBPReg(); |
578 | |
579 | // Returns the register holding shadow call stack pointer. |
580 | MCRegister getSCSPReg(); |
581 | |
582 | } // namespace RISCVABI |
583 | |
584 | namespace RISCVFeatures { |
585 | |
586 | // Validates if the given combination of features are valid for the target |
587 | // triple. Exits with report_fatal_error if not. |
588 | void validate(const Triple &TT, const FeatureBitset &FeatureBits); |
589 | |
590 | llvm::Expected<std::unique_ptr<RISCVISAInfo>> |
591 | parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits); |
592 | |
593 | } // namespace RISCVFeatures |
594 | |
595 | namespace RISCVRVC { |
596 | bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI); |
597 | bool uncompress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI); |
598 | } // namespace RISCVRVC |
599 | |
600 | namespace RISCVZC { |
601 | enum RLISTENCODE { |
602 | RA = 4, |
603 | RA_S0, |
604 | RA_S0_S1, |
605 | RA_S0_S2, |
606 | RA_S0_S3, |
607 | RA_S0_S4, |
608 | RA_S0_S5, |
609 | RA_S0_S6, |
610 | RA_S0_S7, |
611 | RA_S0_S8, |
612 | RA_S0_S9, |
613 | // note - to include s10, s11 must also be included |
614 | RA_S0_S11, |
615 | INVALID_RLIST, |
616 | }; |
617 | |
618 | inline unsigned encodeRegList(MCRegister EndReg, bool IsRVE = false) { |
619 | assert((!IsRVE || EndReg <= RISCV::X9) && "Invalid Rlist for RV32E" ); |
620 | switch (EndReg) { |
621 | case RISCV::X1: |
622 | return RLISTENCODE::RA; |
623 | case RISCV::X8: |
624 | return RLISTENCODE::RA_S0; |
625 | case RISCV::X9: |
626 | return RLISTENCODE::RA_S0_S1; |
627 | case RISCV::X18: |
628 | return RLISTENCODE::RA_S0_S2; |
629 | case RISCV::X19: |
630 | return RLISTENCODE::RA_S0_S3; |
631 | case RISCV::X20: |
632 | return RLISTENCODE::RA_S0_S4; |
633 | case RISCV::X21: |
634 | return RLISTENCODE::RA_S0_S5; |
635 | case RISCV::X22: |
636 | return RLISTENCODE::RA_S0_S6; |
637 | case RISCV::X23: |
638 | return RLISTENCODE::RA_S0_S7; |
639 | case RISCV::X24: |
640 | return RLISTENCODE::RA_S0_S8; |
641 | case RISCV::X25: |
642 | return RLISTENCODE::RA_S0_S9; |
643 | case RISCV::X27: |
644 | return RLISTENCODE::RA_S0_S11; |
645 | default: |
646 | llvm_unreachable("Undefined input." ); |
647 | } |
648 | } |
649 | |
650 | inline static unsigned encodeRegListNumRegs(unsigned NumRegs) { |
651 | assert(NumRegs > 0 && NumRegs < 14 && NumRegs != 12 && |
652 | "Unexpected number of registers" ); |
653 | if (NumRegs == 13) |
654 | return RLISTENCODE::RA_S0_S11; |
655 | |
656 | return RLISTENCODE::RA + (NumRegs - 1); |
657 | } |
658 | |
659 | inline static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64) { |
660 | assert(RlistVal >= RLISTENCODE::RA && RlistVal <= RLISTENCODE::RA_S0_S11 && |
661 | "Invalid Rlist" ); |
662 | unsigned NumRegs = (RlistVal - RLISTENCODE::RA) + 1; |
663 | // s10 and s11 are saved together. |
664 | if (RlistVal == RLISTENCODE::RA_S0_S11) |
665 | ++NumRegs; |
666 | |
667 | unsigned RegSize = IsRV64 ? 8 : 4; |
668 | return alignTo(Value: NumRegs * RegSize, Align: 16); |
669 | } |
670 | |
671 | void printRegList(unsigned RlistEncode, raw_ostream &OS); |
672 | } // namespace RISCVZC |
673 | |
674 | namespace RISCVVInversePseudosTable { |
675 | struct PseudoInfo { |
676 | uint16_t Pseudo; |
677 | uint16_t BaseInstr; |
678 | uint8_t VLMul; |
679 | uint8_t SEW; |
680 | }; |
681 | |
682 | #define GET_RISCVVInversePseudosTable_DECL |
683 | #include "RISCVGenSearchableTables.inc" |
684 | } // namespace RISCVVInversePseudosTable |
685 | |
686 | namespace RISCV { |
687 | struct VLSEGPseudo { |
688 | uint16_t NF : 4; |
689 | uint16_t Masked : 1; |
690 | uint16_t Strided : 1; |
691 | uint16_t FF : 1; |
692 | uint16_t Log2SEW : 3; |
693 | uint16_t LMUL : 3; |
694 | uint16_t Pseudo; |
695 | }; |
696 | |
697 | struct VLXSEGPseudo { |
698 | uint16_t NF : 4; |
699 | uint16_t Masked : 1; |
700 | uint16_t Ordered : 1; |
701 | uint16_t Log2SEW : 3; |
702 | uint16_t LMUL : 3; |
703 | uint16_t IndexLMUL : 3; |
704 | uint16_t Pseudo; |
705 | }; |
706 | |
707 | struct VSSEGPseudo { |
708 | uint16_t NF : 4; |
709 | uint16_t Masked : 1; |
710 | uint16_t Strided : 1; |
711 | uint16_t Log2SEW : 3; |
712 | uint16_t LMUL : 3; |
713 | uint16_t Pseudo; |
714 | }; |
715 | |
716 | struct VSXSEGPseudo { |
717 | uint16_t NF : 4; |
718 | uint16_t Masked : 1; |
719 | uint16_t Ordered : 1; |
720 | uint16_t Log2SEW : 3; |
721 | uint16_t LMUL : 3; |
722 | uint16_t IndexLMUL : 3; |
723 | uint16_t Pseudo; |
724 | }; |
725 | |
726 | struct VLEPseudo { |
727 | uint16_t Masked : 1; |
728 | uint16_t Strided : 1; |
729 | uint16_t FF : 1; |
730 | uint16_t Log2SEW : 3; |
731 | uint16_t LMUL : 3; |
732 | uint16_t Pseudo; |
733 | }; |
734 | |
735 | struct VSEPseudo { |
736 | uint16_t Masked : 1; |
737 | uint16_t Strided : 1; |
738 | uint16_t Log2SEW : 3; |
739 | uint16_t LMUL : 3; |
740 | uint16_t Pseudo; |
741 | }; |
742 | |
743 | struct VLX_VSXPseudo { |
744 | uint16_t Masked : 1; |
745 | uint16_t Ordered : 1; |
746 | uint16_t Log2SEW : 3; |
747 | uint16_t LMUL : 3; |
748 | uint16_t IndexLMUL : 3; |
749 | uint16_t Pseudo; |
750 | }; |
751 | |
752 | #define GET_RISCVVSSEGTable_DECL |
753 | #define GET_RISCVVLSEGTable_DECL |
754 | #define GET_RISCVVLXSEGTable_DECL |
755 | #define GET_RISCVVSXSEGTable_DECL |
756 | #define GET_RISCVVLETable_DECL |
757 | #define GET_RISCVVSETable_DECL |
758 | #define GET_RISCVVLXTable_DECL |
759 | #define GET_RISCVVSXTable_DECL |
760 | #include "RISCVGenSearchableTables.inc" |
761 | } // namespace RISCV |
762 | |
763 | } // namespace llvm |
764 | |
765 | #endif |
766 | |