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 InstFormatOther = 22, 55 56 InstFormatMask = 31, 57 InstFormatShift = 0, 58 59 ConstraintShift = InstFormatShift + 5, 60 VS2Constraint = 0b001 << ConstraintShift, 61 VS1Constraint = 0b010 << ConstraintShift, 62 VMConstraint = 0b100 << ConstraintShift, 63 ConstraintMask = 0b111 << ConstraintShift, 64 65 VLMulShift = ConstraintShift + 3, 66 VLMulMask = 0b111 << VLMulShift, 67 68 // Force a tail agnostic policy even this instruction has a tied destination. 69 ForceTailAgnosticShift = VLMulShift + 3, 70 ForceTailAgnosticMask = 1 << ForceTailAgnosticShift, 71 72 // Is this a _TIED vector pseudo instruction. For these instructions we 73 // shouldn't skip the tied operand when converting to MC instructions. 74 IsTiedPseudoShift = ForceTailAgnosticShift + 1, 75 IsTiedPseudoMask = 1 << IsTiedPseudoShift, 76 77 // Does this instruction have a SEW operand. It will be the last explicit 78 // operand unless there is a vector policy operand. Used by RVV Pseudos. 79 HasSEWOpShift = IsTiedPseudoShift + 1, 80 HasSEWOpMask = 1 << HasSEWOpShift, 81 82 // Does this instruction have a VL operand. It will be the second to last 83 // explicit operand unless there is a vector policy operand. Used by RVV 84 // Pseudos. 85 HasVLOpShift = HasSEWOpShift + 1, 86 HasVLOpMask = 1 << HasVLOpShift, 87 88 // Does this instruction have a vector policy operand. It will be the last 89 // explicit operand. Used by RVV Pseudos. 90 HasVecPolicyOpShift = HasVLOpShift + 1, 91 HasVecPolicyOpMask = 1 << HasVecPolicyOpShift, 92 93 // Is this instruction a vector widening reduction instruction. Used by RVV 94 // Pseudos. 95 IsRVVWideningReductionShift = HasVecPolicyOpShift + 1, 96 IsRVVWideningReductionMask = 1 << IsRVVWideningReductionShift, 97 98 // Does this instruction care about mask policy. If it is not, the mask policy 99 // could be either agnostic or undisturbed. For example, unmasked, store, and 100 // reduction operations result would not be affected by mask policy, so 101 // compiler has free to select either one. 102 UsesMaskPolicyShift = IsRVVWideningReductionShift + 1, 103 UsesMaskPolicyMask = 1 << UsesMaskPolicyShift, 104 105 // Indicates that the result can be considered sign extended from bit 31. Some 106 // instructions with this flag aren't W instructions, but are either sign 107 // extended from a smaller size, always outputs a small integer, or put zeros 108 // in bits 63:31. Used by the SExtWRemoval pass. 109 IsSignExtendingOpWShift = UsesMaskPolicyShift + 1, 110 IsSignExtendingOpWMask = 1ULL << IsSignExtendingOpWShift, 111 112 HasRoundModeOpShift = IsSignExtendingOpWShift + 1, 113 HasRoundModeOpMask = 1 << HasRoundModeOpShift, 114 115 UsesVXRMShift = HasRoundModeOpShift + 1, 116 UsesVXRMMask = 1 << UsesVXRMShift, 117 118 // Indicates whether these instructions can partially overlap between source 119 // registers and destination registers according to the vector spec. 120 // 0 -> not a vector pseudo 121 // 1 -> default value for vector pseudos. not widening or narrowing. 122 // 2 -> narrowing case 123 // 3 -> widening case 124 TargetOverlapConstraintTypeShift = UsesVXRMShift + 1, 125 TargetOverlapConstraintTypeMask = 3ULL << TargetOverlapConstraintTypeShift, 126 }; 127 128 // Helper functions to read TSFlags. 129 /// \returns the format of the instruction. 130 static inline unsigned getFormat(uint64_t TSFlags) { 131 return (TSFlags & InstFormatMask) >> InstFormatShift; 132 } 133 /// \returns the LMUL for the instruction. 134 static inline VLMUL getLMul(uint64_t TSFlags) { 135 return static_cast<VLMUL>((TSFlags & VLMulMask) >> VLMulShift); 136 } 137 /// \returns true if tail agnostic is enforced for the instruction. 138 static inline bool doesForceTailAgnostic(uint64_t TSFlags) { 139 return TSFlags & ForceTailAgnosticMask; 140 } 141 /// \returns true if this a _TIED pseudo. 142 static inline bool isTiedPseudo(uint64_t TSFlags) { 143 return TSFlags & IsTiedPseudoMask; 144 } 145 /// \returns true if there is a SEW operand for the instruction. 146 static inline bool hasSEWOp(uint64_t TSFlags) { 147 return TSFlags & HasSEWOpMask; 148 } 149 /// \returns true if there is a VL operand for the instruction. 150 static inline bool hasVLOp(uint64_t TSFlags) { 151 return TSFlags & HasVLOpMask; 152 } 153 /// \returns true if there is a vector policy operand for this instruction. 154 static inline bool hasVecPolicyOp(uint64_t TSFlags) { 155 return TSFlags & HasVecPolicyOpMask; 156 } 157 /// \returns true if it is a vector widening reduction instruction. 158 static inline bool isRVVWideningReduction(uint64_t TSFlags) { 159 return TSFlags & IsRVVWideningReductionMask; 160 } 161 /// \returns true if mask policy is valid for the instruction. 162 static inline bool usesMaskPolicy(uint64_t TSFlags) { 163 return TSFlags & UsesMaskPolicyMask; 164 } 165 166 /// \returns true if there is a rounding mode operand for this instruction 167 static inline bool hasRoundModeOp(uint64_t TSFlags) { 168 return TSFlags & HasRoundModeOpMask; 169 } 170 171 /// \returns true if this instruction uses vxrm 172 static inline bool usesVXRM(uint64_t TSFlags) { return TSFlags & UsesVXRMMask; } 173 174 static inline unsigned getVLOpNum(const MCInstrDesc &Desc) { 175 const uint64_t TSFlags = Desc.TSFlags; 176 // This method is only called if we expect to have a VL operand, and all 177 // instructions with VL also have SEW. 178 assert(hasSEWOp(TSFlags) && hasVLOp(TSFlags)); 179 unsigned Offset = 2; 180 if (hasVecPolicyOp(TSFlags)) 181 Offset = 3; 182 return Desc.getNumOperands() - Offset; 183 } 184 185 static inline unsigned getSEWOpNum(const MCInstrDesc &Desc) { 186 const uint64_t TSFlags = Desc.TSFlags; 187 assert(hasSEWOp(TSFlags)); 188 unsigned Offset = 1; 189 if (hasVecPolicyOp(TSFlags)) 190 Offset = 2; 191 return Desc.getNumOperands() - Offset; 192 } 193 194 static inline unsigned getVecPolicyOpNum(const MCInstrDesc &Desc) { 195 assert(hasVecPolicyOp(Desc.TSFlags)); 196 return Desc.getNumOperands() - 1; 197 } 198 199 /// \returns the index to the rounding mode immediate value if any, otherwise 200 /// returns -1. 201 static inline int getFRMOpNum(const MCInstrDesc &Desc) { 202 const uint64_t TSFlags = Desc.TSFlags; 203 if (!hasRoundModeOp(TSFlags) || usesVXRM(TSFlags)) 204 return -1; 205 206 // The operand order 207 // -------------------------------------- 208 // | n-1 (if any) | n-2 | n-3 | n-4 | 209 // | policy | sew | vl | frm | 210 // -------------------------------------- 211 return getVLOpNum(Desc) - 1; 212 } 213 214 /// \returns the index to the rounding mode immediate value if any, otherwise 215 /// returns -1. 216 static inline int getVXRMOpNum(const MCInstrDesc &Desc) { 217 const uint64_t TSFlags = Desc.TSFlags; 218 if (!hasRoundModeOp(TSFlags) || !usesVXRM(TSFlags)) 219 return -1; 220 // The operand order 221 // -------------------------------------- 222 // | n-1 (if any) | n-2 | n-3 | n-4 | 223 // | policy | sew | vl | vxrm | 224 // -------------------------------------- 225 return getVLOpNum(Desc) - 1; 226 } 227 228 // Is the first def operand tied to the first use operand. This is true for 229 // vector pseudo instructions that have a merge operand for tail/mask 230 // undisturbed. It's also true for vector FMA instructions where one of the 231 // operands is also the destination register. 232 static inline bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc) { 233 return Desc.getNumDefs() < Desc.getNumOperands() && 234 Desc.getOperandConstraint(Desc.getNumDefs(), MCOI::TIED_TO) == 0; 235 } 236 237 // RISC-V Specific Machine Operand Flags 238 enum { 239 MO_None = 0, 240 MO_CALL = 1, 241 MO_LO = 3, 242 MO_HI = 4, 243 MO_PCREL_LO = 5, 244 MO_PCREL_HI = 6, 245 MO_GOT_HI = 7, 246 MO_TPREL_LO = 8, 247 MO_TPREL_HI = 9, 248 MO_TPREL_ADD = 10, 249 MO_TLS_GOT_HI = 11, 250 MO_TLS_GD_HI = 12, 251 MO_TLSDESC_HI = 13, 252 MO_TLSDESC_LOAD_LO = 14, 253 MO_TLSDESC_ADD_LO = 15, 254 MO_TLSDESC_CALL = 16, 255 256 // Used to differentiate between target-specific "direct" flags and "bitmask" 257 // flags. A machine operand can only have one "direct" flag, but can have 258 // multiple "bitmask" flags. 259 MO_DIRECT_FLAG_MASK = 31 260 }; 261 } // namespace RISCVII 262 263 namespace RISCVOp { 264 enum OperandType : unsigned { 265 OPERAND_FIRST_RISCV_IMM = MCOI::OPERAND_FIRST_TARGET, 266 OPERAND_UIMM1 = OPERAND_FIRST_RISCV_IMM, 267 OPERAND_UIMM2, 268 OPERAND_UIMM2_LSB0, 269 OPERAND_UIMM3, 270 OPERAND_UIMM4, 271 OPERAND_UIMM5, 272 OPERAND_UIMM5_LSB0, 273 OPERAND_UIMM6, 274 OPERAND_UIMM6_LSB0, 275 OPERAND_UIMM7, 276 OPERAND_UIMM7_LSB00, 277 OPERAND_UIMM8_LSB00, 278 OPERAND_UIMM8, 279 OPERAND_UIMM8_LSB000, 280 OPERAND_UIMM8_GE32, 281 OPERAND_UIMM9_LSB000, 282 OPERAND_UIMM10_LSB00_NONZERO, 283 OPERAND_UIMM12, 284 OPERAND_UIMM16, 285 OPERAND_UIMM32, 286 OPERAND_ZERO, 287 OPERAND_SIMM5, 288 OPERAND_SIMM5_PLUS1, 289 OPERAND_SIMM6, 290 OPERAND_SIMM6_NONZERO, 291 OPERAND_SIMM10_LSB0000_NONZERO, 292 OPERAND_SIMM12, 293 OPERAND_SIMM12_LSB00000, 294 OPERAND_UIMM20, 295 OPERAND_UIMMLOG2XLEN, 296 OPERAND_UIMMLOG2XLEN_NONZERO, 297 OPERAND_CLUI_IMM, 298 OPERAND_VTYPEI10, 299 OPERAND_VTYPEI11, 300 OPERAND_RVKRNUM, 301 OPERAND_RVKRNUM_0_7, 302 OPERAND_RVKRNUM_1_10, 303 OPERAND_RVKRNUM_2_14, 304 OPERAND_SPIMM, 305 OPERAND_LAST_RISCV_IMM = OPERAND_SPIMM, 306 // Operand is either a register or uimm5, this is used by V extension pseudo 307 // instructions to represent a value that be passed as AVL to either vsetvli 308 // or vsetivli. 309 OPERAND_AVL, 310 }; 311 } // namespace RISCVOp 312 313 // Describes the predecessor/successor bits used in the FENCE instruction. 314 namespace RISCVFenceField { 315 enum FenceField { 316 I = 8, 317 O = 4, 318 R = 2, 319 W = 1 320 }; 321 } 322 323 // Describes the supported floating point rounding mode encodings. 324 namespace RISCVFPRndMode { 325 enum RoundingMode { 326 RNE = 0, 327 RTZ = 1, 328 RDN = 2, 329 RUP = 3, 330 RMM = 4, 331 DYN = 7, 332 Invalid 333 }; 334 335 inline static StringRef roundingModeToString(RoundingMode RndMode) { 336 switch (RndMode) { 337 default: 338 llvm_unreachable("Unknown floating point rounding mode"); 339 case RISCVFPRndMode::RNE: 340 return "rne"; 341 case RISCVFPRndMode::RTZ: 342 return "rtz"; 343 case RISCVFPRndMode::RDN: 344 return "rdn"; 345 case RISCVFPRndMode::RUP: 346 return "rup"; 347 case RISCVFPRndMode::RMM: 348 return "rmm"; 349 case RISCVFPRndMode::DYN: 350 return "dyn"; 351 } 352 } 353 354 inline static RoundingMode stringToRoundingMode(StringRef Str) { 355 return StringSwitch<RoundingMode>(Str) 356 .Case("rne", RISCVFPRndMode::RNE) 357 .Case("rtz", RISCVFPRndMode::RTZ) 358 .Case("rdn", RISCVFPRndMode::RDN) 359 .Case("rup", RISCVFPRndMode::RUP) 360 .Case("rmm", RISCVFPRndMode::RMM) 361 .Case("dyn", RISCVFPRndMode::DYN) 362 .Default(RISCVFPRndMode::Invalid); 363 } 364 365 inline static bool isValidRoundingMode(unsigned Mode) { 366 switch (Mode) { 367 default: 368 return false; 369 case RISCVFPRndMode::RNE: 370 case RISCVFPRndMode::RTZ: 371 case RISCVFPRndMode::RDN: 372 case RISCVFPRndMode::RUP: 373 case RISCVFPRndMode::RMM: 374 case RISCVFPRndMode::DYN: 375 return true; 376 } 377 } 378 } // namespace RISCVFPRndMode 379 380 namespace RISCVVXRndMode { 381 enum RoundingMode { 382 RNU = 0, 383 RNE = 1, 384 RDN = 2, 385 ROD = 3, 386 }; 387 } // namespace RISCVVXRndMode 388 389 //===----------------------------------------------------------------------===// 390 // Floating-point Immediates 391 // 392 393 namespace RISCVLoadFPImm { 394 float getFPImm(unsigned Imm); 395 396 /// getLoadFPImm - Return a 5-bit binary encoding of the floating-point 397 /// immediate value. If the value cannot be represented as a 5-bit binary 398 /// encoding, then return -1. 399 int getLoadFPImm(APFloat FPImm); 400 } // namespace RISCVLoadFPImm 401 402 namespace RISCVSysReg { 403 struct SysReg { 404 const char *Name; 405 const char *AltName; 406 const char *DeprecatedName; 407 unsigned Encoding; 408 // FIXME: add these additional fields when needed. 409 // Privilege Access: Read, Write, Read-Only. 410 // unsigned ReadWrite; 411 // Privilege Mode: User, System or Machine. 412 // unsigned Mode; 413 // Check field name. 414 // unsigned Extra; 415 // Register number without the privilege bits. 416 // unsigned Number; 417 FeatureBitset FeaturesRequired; 418 bool isRV32Only; 419 420 bool haveRequiredFeatures(const FeatureBitset &ActiveFeatures) const { 421 // Not in 32-bit mode. 422 if (isRV32Only && ActiveFeatures[RISCV::Feature64Bit]) 423 return false; 424 // No required feature associated with the system register. 425 if (FeaturesRequired.none()) 426 return true; 427 return (FeaturesRequired & ActiveFeatures) == FeaturesRequired; 428 } 429 }; 430 431 #define GET_SysRegsList_DECL 432 #include "RISCVGenSearchableTables.inc" 433 } // end namespace RISCVSysReg 434 435 namespace RISCVInsnOpcode { 436 struct RISCVOpcode { 437 const char *Name; 438 unsigned Value; 439 }; 440 441 #define GET_RISCVOpcodesList_DECL 442 #include "RISCVGenSearchableTables.inc" 443 } // end namespace RISCVInsnOpcode 444 445 namespace RISCVABI { 446 447 enum ABI { 448 ABI_ILP32, 449 ABI_ILP32F, 450 ABI_ILP32D, 451 ABI_ILP32E, 452 ABI_LP64, 453 ABI_LP64F, 454 ABI_LP64D, 455 ABI_LP64E, 456 ABI_Unknown 457 }; 458 459 // Returns the target ABI, or else a StringError if the requested ABIName is 460 // not supported for the given TT and FeatureBits combination. 461 ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, 462 StringRef ABIName); 463 464 ABI getTargetABI(StringRef ABIName); 465 466 // Returns the register used to hold the stack pointer after realignment. 467 MCRegister getBPReg(); 468 469 // Returns the register holding shadow call stack pointer. 470 MCRegister getSCSPReg(); 471 472 } // namespace RISCVABI 473 474 namespace RISCVFeatures { 475 476 // Validates if the given combination of features are valid for the target 477 // triple. Exits with report_fatal_error if not. 478 void validate(const Triple &TT, const FeatureBitset &FeatureBits); 479 480 llvm::Expected<std::unique_ptr<RISCVISAInfo>> 481 parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits); 482 483 } // namespace RISCVFeatures 484 485 namespace RISCVRVC { 486 bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI); 487 bool uncompress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI); 488 } // namespace RISCVRVC 489 490 namespace RISCVZC { 491 enum RLISTENCODE { 492 RA = 4, 493 RA_S0, 494 RA_S0_S1, 495 RA_S0_S2, 496 RA_S0_S3, 497 RA_S0_S4, 498 RA_S0_S5, 499 RA_S0_S6, 500 RA_S0_S7, 501 RA_S0_S8, 502 RA_S0_S9, 503 // note - to include s10, s11 must also be included 504 RA_S0_S11, 505 INVALID_RLIST, 506 }; 507 508 inline unsigned encodeRlist(MCRegister EndReg, bool IsRV32E = false) { 509 assert((!IsRV32E || EndReg <= RISCV::X9) && "Invalid Rlist for RV32E"); 510 switch (EndReg) { 511 case RISCV::X1: 512 return RLISTENCODE::RA; 513 case RISCV::X8: 514 return RLISTENCODE::RA_S0; 515 case RISCV::X9: 516 return RLISTENCODE::RA_S0_S1; 517 case RISCV::X18: 518 return RLISTENCODE::RA_S0_S2; 519 case RISCV::X19: 520 return RLISTENCODE::RA_S0_S3; 521 case RISCV::X20: 522 return RLISTENCODE::RA_S0_S4; 523 case RISCV::X21: 524 return RLISTENCODE::RA_S0_S5; 525 case RISCV::X22: 526 return RLISTENCODE::RA_S0_S6; 527 case RISCV::X23: 528 return RLISTENCODE::RA_S0_S7; 529 case RISCV::X24: 530 return RLISTENCODE::RA_S0_S8; 531 case RISCV::X25: 532 return RLISTENCODE::RA_S0_S9; 533 case RISCV::X26: 534 return RLISTENCODE::INVALID_RLIST; 535 case RISCV::X27: 536 return RLISTENCODE::RA_S0_S11; 537 default: 538 llvm_unreachable("Undefined input."); 539 } 540 } 541 542 inline static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64) { 543 assert(RlistVal != RLISTENCODE::INVALID_RLIST && 544 "{ra, s0-s10} is not supported, s11 must be included."); 545 if (!IsRV64) { 546 switch (RlistVal) { 547 case RLISTENCODE::RA: 548 case RLISTENCODE::RA_S0: 549 case RLISTENCODE::RA_S0_S1: 550 case RLISTENCODE::RA_S0_S2: 551 return 16; 552 case RLISTENCODE::RA_S0_S3: 553 case RLISTENCODE::RA_S0_S4: 554 case RLISTENCODE::RA_S0_S5: 555 case RLISTENCODE::RA_S0_S6: 556 return 32; 557 case RLISTENCODE::RA_S0_S7: 558 case RLISTENCODE::RA_S0_S8: 559 case RLISTENCODE::RA_S0_S9: 560 return 48; 561 case RLISTENCODE::RA_S0_S11: 562 return 64; 563 } 564 } else { 565 switch (RlistVal) { 566 case RLISTENCODE::RA: 567 case RLISTENCODE::RA_S0: 568 return 16; 569 case RLISTENCODE::RA_S0_S1: 570 case RLISTENCODE::RA_S0_S2: 571 return 32; 572 case RLISTENCODE::RA_S0_S3: 573 case RLISTENCODE::RA_S0_S4: 574 return 48; 575 case RLISTENCODE::RA_S0_S5: 576 case RLISTENCODE::RA_S0_S6: 577 return 64; 578 case RLISTENCODE::RA_S0_S7: 579 case RLISTENCODE::RA_S0_S8: 580 return 80; 581 case RLISTENCODE::RA_S0_S9: 582 return 96; 583 case RLISTENCODE::RA_S0_S11: 584 return 112; 585 } 586 } 587 llvm_unreachable("Unexpected RlistVal"); 588 } 589 590 inline static bool getSpimm(unsigned RlistVal, unsigned &SpimmVal, 591 int64_t StackAdjustment, bool IsRV64) { 592 if (RlistVal == RLISTENCODE::INVALID_RLIST) 593 return false; 594 unsigned StackAdjBase = getStackAdjBase(RlistVal, IsRV64); 595 StackAdjustment -= StackAdjBase; 596 if (StackAdjustment % 16 != 0) 597 return false; 598 SpimmVal = StackAdjustment / 16; 599 if (SpimmVal > 3) 600 return false; 601 return true; 602 } 603 604 void printRlist(unsigned SlistEncode, raw_ostream &OS); 605 } // namespace RISCVZC 606 607 } // namespace llvm 608 609 #endif 610