1 //===-- RISCVBaseInfo.h - Top level definitions for RISCV MC ----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains small standalone enum definitions for the RISCV target 10 // useful for the compiler back-end and the MC libraries. 11 // 12 //===----------------------------------------------------------------------===// 13 #ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVBASEINFO_H 14 #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVBASEINFO_H 15 16 #include "MCTargetDesc/RISCVMCTargetDesc.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/ADT/StringSwitch.h" 19 #include "llvm/MC/MCInstrDesc.h" 20 #include "llvm/MC/SubtargetFeature.h" 21 #include "llvm/Support/MachineValueType.h" 22 23 namespace llvm { 24 25 // RISCVII - This namespace holds all of the target specific flags that 26 // instruction info tracks. All definitions must match RISCVInstrFormats.td. 27 namespace RISCVII { 28 enum { 29 InstFormatPseudo = 0, 30 InstFormatR = 1, 31 InstFormatR4 = 2, 32 InstFormatI = 3, 33 InstFormatS = 4, 34 InstFormatB = 5, 35 InstFormatU = 6, 36 InstFormatJ = 7, 37 InstFormatCR = 8, 38 InstFormatCI = 9, 39 InstFormatCSS = 10, 40 InstFormatCIW = 11, 41 InstFormatCL = 12, 42 InstFormatCS = 13, 43 InstFormatCA = 14, 44 InstFormatCB = 15, 45 InstFormatCJ = 16, 46 InstFormatOther = 17, 47 48 InstFormatMask = 31, 49 50 ConstraintShift = 5, 51 ConstraintMask = 0b111 << ConstraintShift, 52 53 VLMulShift = ConstraintShift + 3, 54 VLMulMask = 0b111 << VLMulShift, 55 56 // Do we need to add a dummy mask op when converting RVV Pseudo to MCInst. 57 HasDummyMaskOpShift = VLMulShift + 3, 58 HasDummyMaskOpMask = 1 << HasDummyMaskOpShift, 59 60 // Does this instruction only update element 0 the destination register. 61 WritesElement0Shift = HasDummyMaskOpShift + 1, 62 WritesElement0Mask = 1 << WritesElement0Shift, 63 64 // Does this instruction have a merge operand that must be removed when 65 // converting to MCInst. It will be the first explicit use operand. Used by 66 // RVV Pseudos. 67 HasMergeOpShift = WritesElement0Shift + 1, 68 HasMergeOpMask = 1 << HasMergeOpShift, 69 70 // Does this instruction have a SEW operand. It will be the last explicit 71 // operand. Used by RVV Pseudos. 72 HasSEWOpShift = HasMergeOpShift + 1, 73 HasSEWOpMask = 1 << HasSEWOpShift, 74 75 // Does this instruction have a VL operand. It will be the second to last 76 // explicit operand. Used by RVV Pseudos. 77 HasVLOpShift = HasSEWOpShift + 1, 78 HasVLOpMask = 1 << HasVLOpShift, 79 }; 80 81 // Match with the definitions in RISCVInstrFormatsV.td 82 enum RVVConstraintType { 83 NoConstraint = 0, 84 VS2Constraint = 0b001, 85 VS1Constraint = 0b010, 86 VMConstraint = 0b100, 87 }; 88 89 // RISC-V Specific Machine Operand Flags 90 enum { 91 MO_None = 0, 92 MO_CALL = 1, 93 MO_PLT = 2, 94 MO_LO = 3, 95 MO_HI = 4, 96 MO_PCREL_LO = 5, 97 MO_PCREL_HI = 6, 98 MO_GOT_HI = 7, 99 MO_TPREL_LO = 8, 100 MO_TPREL_HI = 9, 101 MO_TPREL_ADD = 10, 102 MO_TLS_GOT_HI = 11, 103 MO_TLS_GD_HI = 12, 104 105 // Used to differentiate between target-specific "direct" flags and "bitmask" 106 // flags. A machine operand can only have one "direct" flag, but can have 107 // multiple "bitmask" flags. 108 MO_DIRECT_FLAG_MASK = 15 109 }; 110 } // namespace RISCVII 111 112 namespace RISCVOp { 113 enum OperandType : unsigned { 114 OPERAND_FIRST_RISCV_IMM = MCOI::OPERAND_FIRST_TARGET, 115 OPERAND_UIMM4 = OPERAND_FIRST_RISCV_IMM, 116 OPERAND_UIMM5, 117 OPERAND_UIMM12, 118 OPERAND_SIMM12, 119 OPERAND_UIMM20, 120 OPERAND_UIMMLOG2XLEN, 121 OPERAND_LAST_RISCV_IMM = OPERAND_UIMMLOG2XLEN 122 }; 123 } // namespace RISCVOp 124 125 // Describes the predecessor/successor bits used in the FENCE instruction. 126 namespace RISCVFenceField { 127 enum FenceField { 128 I = 8, 129 O = 4, 130 R = 2, 131 W = 1 132 }; 133 } 134 135 // Describes the supported floating point rounding mode encodings. 136 namespace RISCVFPRndMode { 137 enum RoundingMode { 138 RNE = 0, 139 RTZ = 1, 140 RDN = 2, 141 RUP = 3, 142 RMM = 4, 143 DYN = 7, 144 Invalid 145 }; 146 147 inline static StringRef roundingModeToString(RoundingMode RndMode) { 148 switch (RndMode) { 149 default: 150 llvm_unreachable("Unknown floating point rounding mode"); 151 case RISCVFPRndMode::RNE: 152 return "rne"; 153 case RISCVFPRndMode::RTZ: 154 return "rtz"; 155 case RISCVFPRndMode::RDN: 156 return "rdn"; 157 case RISCVFPRndMode::RUP: 158 return "rup"; 159 case RISCVFPRndMode::RMM: 160 return "rmm"; 161 case RISCVFPRndMode::DYN: 162 return "dyn"; 163 } 164 } 165 166 inline static RoundingMode stringToRoundingMode(StringRef Str) { 167 return StringSwitch<RoundingMode>(Str) 168 .Case("rne", RISCVFPRndMode::RNE) 169 .Case("rtz", RISCVFPRndMode::RTZ) 170 .Case("rdn", RISCVFPRndMode::RDN) 171 .Case("rup", RISCVFPRndMode::RUP) 172 .Case("rmm", RISCVFPRndMode::RMM) 173 .Case("dyn", RISCVFPRndMode::DYN) 174 .Default(RISCVFPRndMode::Invalid); 175 } 176 177 inline static bool isValidRoundingMode(unsigned Mode) { 178 switch (Mode) { 179 default: 180 return false; 181 case RISCVFPRndMode::RNE: 182 case RISCVFPRndMode::RTZ: 183 case RISCVFPRndMode::RDN: 184 case RISCVFPRndMode::RUP: 185 case RISCVFPRndMode::RMM: 186 case RISCVFPRndMode::DYN: 187 return true; 188 } 189 } 190 } // namespace RISCVFPRndMode 191 192 namespace RISCVSysReg { 193 struct SysReg { 194 const char *Name; 195 unsigned Encoding; 196 const char *AltName; 197 // FIXME: add these additional fields when needed. 198 // Privilege Access: Read, Write, Read-Only. 199 // unsigned ReadWrite; 200 // Privilege Mode: User, System or Machine. 201 // unsigned Mode; 202 // Check field name. 203 // unsigned Extra; 204 // Register number without the privilege bits. 205 // unsigned Number; 206 FeatureBitset FeaturesRequired; 207 bool isRV32Only; 208 209 bool haveRequiredFeatures(FeatureBitset ActiveFeatures) const { 210 // Not in 32-bit mode. 211 if (isRV32Only && ActiveFeatures[RISCV::Feature64Bit]) 212 return false; 213 // No required feature associated with the system register. 214 if (FeaturesRequired.none()) 215 return true; 216 return (FeaturesRequired & ActiveFeatures) == FeaturesRequired; 217 } 218 }; 219 220 #define GET_SysRegsList_DECL 221 #include "RISCVGenSearchableTables.inc" 222 } // end namespace RISCVSysReg 223 224 namespace RISCVABI { 225 226 enum ABI { 227 ABI_ILP32, 228 ABI_ILP32F, 229 ABI_ILP32D, 230 ABI_ILP32E, 231 ABI_LP64, 232 ABI_LP64F, 233 ABI_LP64D, 234 ABI_Unknown 235 }; 236 237 // Returns the target ABI, or else a StringError if the requested ABIName is 238 // not supported for the given TT and FeatureBits combination. 239 ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits, 240 StringRef ABIName); 241 242 ABI getTargetABI(StringRef ABIName); 243 244 // Returns the register used to hold the stack pointer after realignment. 245 MCRegister getBPReg(); 246 247 // Returns the register holding shadow call stack pointer. 248 MCRegister getSCSPReg(); 249 250 } // namespace RISCVABI 251 252 namespace RISCVFeatures { 253 254 // Validates if the given combination of features are valid for the target 255 // triple. Exits with report_fatal_error if not. 256 void validate(const Triple &TT, const FeatureBitset &FeatureBits); 257 258 } // namespace RISCVFeatures 259 260 namespace RISCVVMVTs { 261 262 constexpr MVT vint8mf8_t = MVT::nxv1i8; 263 constexpr MVT vint8mf4_t = MVT::nxv2i8; 264 constexpr MVT vint8mf2_t = MVT::nxv4i8; 265 constexpr MVT vint8m1_t = MVT::nxv8i8; 266 constexpr MVT vint8m2_t = MVT::nxv16i8; 267 constexpr MVT vint8m4_t = MVT::nxv32i8; 268 constexpr MVT vint8m8_t = MVT::nxv64i8; 269 270 constexpr MVT vint16mf4_t = MVT::nxv1i16; 271 constexpr MVT vint16mf2_t = MVT::nxv2i16; 272 constexpr MVT vint16m1_t = MVT::nxv4i16; 273 constexpr MVT vint16m2_t = MVT::nxv8i16; 274 constexpr MVT vint16m4_t = MVT::nxv16i16; 275 constexpr MVT vint16m8_t = MVT::nxv32i16; 276 277 constexpr MVT vint32mf2_t = MVT::nxv1i32; 278 constexpr MVT vint32m1_t = MVT::nxv2i32; 279 constexpr MVT vint32m2_t = MVT::nxv4i32; 280 constexpr MVT vint32m4_t = MVT::nxv8i32; 281 constexpr MVT vint32m8_t = MVT::nxv16i32; 282 283 constexpr MVT vint64m1_t = MVT::nxv1i64; 284 constexpr MVT vint64m2_t = MVT::nxv2i64; 285 constexpr MVT vint64m4_t = MVT::nxv4i64; 286 constexpr MVT vint64m8_t = MVT::nxv8i64; 287 288 constexpr MVT vfloat16mf4_t = MVT::nxv1f16; 289 constexpr MVT vfloat16mf2_t = MVT::nxv2f16; 290 constexpr MVT vfloat16m1_t = MVT::nxv4f16; 291 constexpr MVT vfloat16m2_t = MVT::nxv8f16; 292 constexpr MVT vfloat16m4_t = MVT::nxv16f16; 293 constexpr MVT vfloat16m8_t = MVT::nxv32f16; 294 295 constexpr MVT vfloat32mf2_t = MVT::nxv1f32; 296 constexpr MVT vfloat32m1_t = MVT::nxv2f32; 297 constexpr MVT vfloat32m2_t = MVT::nxv4f32; 298 constexpr MVT vfloat32m4_t = MVT::nxv8f32; 299 constexpr MVT vfloat32m8_t = MVT::nxv16f32; 300 301 constexpr MVT vfloat64m1_t = MVT::nxv1f64; 302 constexpr MVT vfloat64m2_t = MVT::nxv2f64; 303 constexpr MVT vfloat64m4_t = MVT::nxv4f64; 304 constexpr MVT vfloat64m8_t = MVT::nxv8f64; 305 306 constexpr MVT vbool1_t = MVT::nxv64i1; 307 constexpr MVT vbool2_t = MVT::nxv32i1; 308 constexpr MVT vbool4_t = MVT::nxv16i1; 309 constexpr MVT vbool8_t = MVT::nxv8i1; 310 constexpr MVT vbool16_t = MVT::nxv4i1; 311 constexpr MVT vbool32_t = MVT::nxv2i1; 312 constexpr MVT vbool64_t = MVT::nxv1i1; 313 314 } // namespace RISCVVMVTs 315 316 enum class RISCVVSEW { 317 SEW_8 = 0, 318 SEW_16, 319 SEW_32, 320 SEW_64, 321 SEW_128, 322 SEW_256, 323 SEW_512, 324 SEW_1024, 325 }; 326 327 enum class RISCVVLMUL { 328 LMUL_1 = 0, 329 LMUL_2, 330 LMUL_4, 331 LMUL_8, 332 LMUL_RESERVED, 333 LMUL_F8, 334 LMUL_F4, 335 LMUL_F2 336 }; 337 338 namespace RISCVVType { 339 // Is this a SEW value that can be encoded into the VTYPE format. 340 inline static bool isValidSEW(unsigned SEW) { 341 return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 1024; 342 } 343 344 // Is this a LMUL value that can be encoded into the VTYPE format. 345 inline static bool isValidLMUL(unsigned LMUL, bool Fractional) { 346 return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1); 347 } 348 349 // Encode VTYPE into the binary format used by the the VSETVLI instruction which 350 // is used by our MC layer representation. 351 // 352 // Bits | Name | Description 353 // -----+------------+------------------------------------------------ 354 // 7 | vma | Vector mask agnostic 355 // 6 | vta | Vector tail agnostic 356 // 5:3 | vsew[2:0] | Standard element width (SEW) setting 357 // 2:0 | vlmul[2:0] | Vector register group multiplier (LMUL) setting 358 inline static unsigned encodeVTYPE(RISCVVLMUL VLMUL, RISCVVSEW VSEW, 359 bool TailAgnostic, bool MaskAgnostic) { 360 unsigned VLMULBits = static_cast<unsigned>(VLMUL); 361 unsigned VSEWBits = static_cast<unsigned>(VSEW); 362 unsigned VTypeI = (VSEWBits << 3) | (VLMULBits & 0x7); 363 if (TailAgnostic) 364 VTypeI |= 0x40; 365 if (MaskAgnostic) 366 VTypeI |= 0x80; 367 368 return VTypeI; 369 } 370 371 inline static RISCVVLMUL getVLMUL(unsigned VType) { 372 unsigned VLMUL = VType & 0x7; 373 return static_cast<RISCVVLMUL>(VLMUL); 374 } 375 376 inline static RISCVVSEW getVSEW(unsigned VType) { 377 unsigned VSEW = (VType >> 3) & 0x7; 378 return static_cast<RISCVVSEW>(VSEW); 379 } 380 381 inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; } 382 383 inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; } 384 385 void printVType(unsigned VType, raw_ostream &OS); 386 387 } // namespace RISCVVType 388 389 namespace RISCVVPseudosTable { 390 391 struct PseudoInfo { 392 #include "MCTargetDesc/RISCVBaseInfo.h" 393 uint16_t Pseudo; 394 uint16_t BaseInstr; 395 }; 396 397 using namespace RISCV; 398 399 #define GET_RISCVVPseudosTable_DECL 400 #include "RISCVGenSearchableTables.inc" 401 402 } // end namespace RISCVVPseudosTable 403 404 } // namespace llvm 405 406 #endif 407