Home | History | Annotate | Line # | Download | only in MCTargetDesc
      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 
     22 namespace llvm {
     23 
     24 // RISCVII - This namespace holds all of the target specific flags that
     25 // instruction info tracks. All definitions must match RISCVInstrFormats.td.
     26 namespace RISCVII {
     27 enum {
     28   InstFormatPseudo = 0,
     29   InstFormatR = 1,
     30   InstFormatR4 = 2,
     31   InstFormatI = 3,
     32   InstFormatS = 4,
     33   InstFormatB = 5,
     34   InstFormatU = 6,
     35   InstFormatJ = 7,
     36   InstFormatCR = 8,
     37   InstFormatCI = 9,
     38   InstFormatCSS = 10,
     39   InstFormatCIW = 11,
     40   InstFormatCL = 12,
     41   InstFormatCS = 13,
     42   InstFormatCA = 14,
     43   InstFormatCB = 15,
     44   InstFormatCJ = 16,
     45   InstFormatOther = 17,
     46 
     47   InstFormatMask = 31,
     48   InstFormatShift = 0,
     49 
     50   ConstraintShift = InstFormatShift + 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   // Force a tail agnostic policy even this instruction has a tied destination.
     61   ForceTailAgnosticShift = HasDummyMaskOpShift + 1,
     62   ForceTailAgnosticMask = 1 << ForceTailAgnosticShift,
     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 = ForceTailAgnosticShift + 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 VConstraintType {
     83   NoConstraint = 0,
     84   VS2Constraint = 0b001,
     85   VS1Constraint = 0b010,
     86   VMConstraint = 0b100,
     87 };
     88 
     89 enum VLMUL {
     90   LMUL_1 = 0,
     91   LMUL_2,
     92   LMUL_4,
     93   LMUL_8,
     94   LMUL_RESERVED,
     95   LMUL_F8,
     96   LMUL_F4,
     97   LMUL_F2
     98 };
     99 
    100 // Helper functions to read TSFlags.
    101 /// \returns the format of the instruction.
    102 static inline unsigned getFormat(uint64_t TSFlags) {
    103   return (TSFlags & InstFormatMask) >> InstFormatShift;
    104 }
    105 /// \returns the constraint for the instruction.
    106 static inline VConstraintType getConstraint(uint64_t TSFlags) {
    107   return static_cast<VConstraintType>
    108              ((TSFlags & ConstraintMask) >> ConstraintShift);
    109 }
    110 /// \returns the LMUL for the instruction.
    111 static inline VLMUL getLMul(uint64_t TSFlags) {
    112   return static_cast<VLMUL>((TSFlags & VLMulMask) >> VLMulShift);
    113 }
    114 /// \returns true if there is a dummy mask operand for the instruction.
    115 static inline bool hasDummyMaskOp(uint64_t TSFlags) {
    116   return TSFlags & HasDummyMaskOpMask;
    117 }
    118 /// \returns true if tail agnostic is enforced for the instruction.
    119 static inline bool doesForceTailAgnostic(uint64_t TSFlags) {
    120   return TSFlags & ForceTailAgnosticMask;
    121 }
    122 /// \returns true if there is a merge operand for the instruction.
    123 static inline bool hasMergeOp(uint64_t TSFlags) {
    124   return TSFlags & HasMergeOpMask;
    125 }
    126 /// \returns true if there is a SEW operand for the instruction.
    127 static inline bool hasSEWOp(uint64_t TSFlags) {
    128   return TSFlags & HasSEWOpMask;
    129 }
    130 /// \returns true if there is a VL operand for the instruction.
    131 static inline bool hasVLOp(uint64_t TSFlags) {
    132   return TSFlags & HasVLOpMask;
    133 }
    134 
    135 // RISC-V Specific Machine Operand Flags
    136 enum {
    137   MO_None = 0,
    138   MO_CALL = 1,
    139   MO_PLT = 2,
    140   MO_LO = 3,
    141   MO_HI = 4,
    142   MO_PCREL_LO = 5,
    143   MO_PCREL_HI = 6,
    144   MO_GOT_HI = 7,
    145   MO_TPREL_LO = 8,
    146   MO_TPREL_HI = 9,
    147   MO_TPREL_ADD = 10,
    148   MO_TLS_GOT_HI = 11,
    149   MO_TLS_GD_HI = 12,
    150 
    151   // Used to differentiate between target-specific "direct" flags and "bitmask"
    152   // flags. A machine operand can only have one "direct" flag, but can have
    153   // multiple "bitmask" flags.
    154   MO_DIRECT_FLAG_MASK = 15
    155 };
    156 } // namespace RISCVII
    157 
    158 namespace RISCVOp {
    159 enum OperandType : unsigned {
    160   OPERAND_FIRST_RISCV_IMM = MCOI::OPERAND_FIRST_TARGET,
    161   OPERAND_UIMM4 = OPERAND_FIRST_RISCV_IMM,
    162   OPERAND_UIMM5,
    163   OPERAND_UIMM12,
    164   OPERAND_SIMM12,
    165   OPERAND_UIMM20,
    166   OPERAND_UIMMLOG2XLEN,
    167   OPERAND_LAST_RISCV_IMM = OPERAND_UIMMLOG2XLEN,
    168   // Operand is either a register or uimm5, this is used by V extension pseudo
    169   // instructions to represent a value that be passed as AVL to either vsetvli
    170   // or vsetivli.
    171   OPERAND_AVL,
    172 };
    173 } // namespace RISCVOp
    174 
    175 // Describes the predecessor/successor bits used in the FENCE instruction.
    176 namespace RISCVFenceField {
    177 enum FenceField {
    178   I = 8,
    179   O = 4,
    180   R = 2,
    181   W = 1
    182 };
    183 }
    184 
    185 // Describes the supported floating point rounding mode encodings.
    186 namespace RISCVFPRndMode {
    187 enum RoundingMode {
    188   RNE = 0,
    189   RTZ = 1,
    190   RDN = 2,
    191   RUP = 3,
    192   RMM = 4,
    193   DYN = 7,
    194   Invalid
    195 };
    196 
    197 inline static StringRef roundingModeToString(RoundingMode RndMode) {
    198   switch (RndMode) {
    199   default:
    200     llvm_unreachable("Unknown floating point rounding mode");
    201   case RISCVFPRndMode::RNE:
    202     return "rne";
    203   case RISCVFPRndMode::RTZ:
    204     return "rtz";
    205   case RISCVFPRndMode::RDN:
    206     return "rdn";
    207   case RISCVFPRndMode::RUP:
    208     return "rup";
    209   case RISCVFPRndMode::RMM:
    210     return "rmm";
    211   case RISCVFPRndMode::DYN:
    212     return "dyn";
    213   }
    214 }
    215 
    216 inline static RoundingMode stringToRoundingMode(StringRef Str) {
    217   return StringSwitch<RoundingMode>(Str)
    218       .Case("rne", RISCVFPRndMode::RNE)
    219       .Case("rtz", RISCVFPRndMode::RTZ)
    220       .Case("rdn", RISCVFPRndMode::RDN)
    221       .Case("rup", RISCVFPRndMode::RUP)
    222       .Case("rmm", RISCVFPRndMode::RMM)
    223       .Case("dyn", RISCVFPRndMode::DYN)
    224       .Default(RISCVFPRndMode::Invalid);
    225 }
    226 
    227 inline static bool isValidRoundingMode(unsigned Mode) {
    228   switch (Mode) {
    229   default:
    230     return false;
    231   case RISCVFPRndMode::RNE:
    232   case RISCVFPRndMode::RTZ:
    233   case RISCVFPRndMode::RDN:
    234   case RISCVFPRndMode::RUP:
    235   case RISCVFPRndMode::RMM:
    236   case RISCVFPRndMode::DYN:
    237     return true;
    238   }
    239 }
    240 } // namespace RISCVFPRndMode
    241 
    242 namespace RISCVSysReg {
    243 struct SysReg {
    244   const char *Name;
    245   const char *AltName;
    246   const char *DeprecatedName;
    247   unsigned Encoding;
    248   // FIXME: add these additional fields when needed.
    249   // Privilege Access: Read, Write, Read-Only.
    250   // unsigned ReadWrite;
    251   // Privilege Mode: User, System or Machine.
    252   // unsigned Mode;
    253   // Check field name.
    254   // unsigned Extra;
    255   // Register number without the privilege bits.
    256   // unsigned Number;
    257   FeatureBitset FeaturesRequired;
    258   bool isRV32Only;
    259 
    260   bool haveRequiredFeatures(FeatureBitset ActiveFeatures) const {
    261     // Not in 32-bit mode.
    262     if (isRV32Only && ActiveFeatures[RISCV::Feature64Bit])
    263       return false;
    264     // No required feature associated with the system register.
    265     if (FeaturesRequired.none())
    266       return true;
    267     return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
    268   }
    269 };
    270 
    271 #define GET_SysRegsList_DECL
    272 #include "RISCVGenSearchableTables.inc"
    273 } // end namespace RISCVSysReg
    274 
    275 namespace RISCVABI {
    276 
    277 enum ABI {
    278   ABI_ILP32,
    279   ABI_ILP32F,
    280   ABI_ILP32D,
    281   ABI_ILP32E,
    282   ABI_LP64,
    283   ABI_LP64F,
    284   ABI_LP64D,
    285   ABI_Unknown
    286 };
    287 
    288 // Returns the target ABI, or else a StringError if the requested ABIName is
    289 // not supported for the given TT and FeatureBits combination.
    290 ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits,
    291                      StringRef ABIName);
    292 
    293 ABI getTargetABI(StringRef ABIName);
    294 
    295 // Returns the register used to hold the stack pointer after realignment.
    296 MCRegister getBPReg();
    297 
    298 // Returns the register holding shadow call stack pointer.
    299 MCRegister getSCSPReg();
    300 
    301 } // namespace RISCVABI
    302 
    303 namespace RISCVFeatures {
    304 
    305 // Validates if the given combination of features are valid for the target
    306 // triple. Exits with report_fatal_error if not.
    307 void validate(const Triple &TT, const FeatureBitset &FeatureBits);
    308 
    309 } // namespace RISCVFeatures
    310 
    311 namespace RISCVVType {
    312 // Is this a SEW value that can be encoded into the VTYPE format.
    313 inline static bool isValidSEW(unsigned SEW) {
    314   return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 1024;
    315 }
    316 
    317 // Is this a LMUL value that can be encoded into the VTYPE format.
    318 inline static bool isValidLMUL(unsigned LMUL, bool Fractional) {
    319   return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1);
    320 }
    321 
    322 unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic,
    323                      bool MaskAgnostic);
    324 
    325 inline static RISCVII::VLMUL getVLMUL(unsigned VType) {
    326   unsigned VLMUL = VType & 0x7;
    327   return static_cast<RISCVII::VLMUL>(VLMUL);
    328 }
    329 
    330 inline static unsigned decodeVSEW(unsigned VSEW) {
    331   assert(VSEW < 8 && "Unexpected VSEW value");
    332   return 1 << (VSEW + 3);
    333 }
    334 
    335 inline static unsigned getSEW(unsigned VType) {
    336   unsigned VSEW = (VType >> 3) & 0x7;
    337   return decodeVSEW(VSEW);
    338 }
    339 
    340 inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; }
    341 
    342 inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; }
    343 
    344 void printVType(unsigned VType, raw_ostream &OS);
    345 
    346 } // namespace RISCVVType
    347 
    348 } // namespace llvm
    349 
    350 #endif
    351