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