1 //===-- RISCVTargetParser - Parser for target features ----------*- 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 implements a target parser to recognise hardware features 10 // for RISC-V CPUs. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_TARGETPARSER_RISCVTARGETPARSER_H 15 #define LLVM_TARGETPARSER_RISCVTARGETPARSER_H 16 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/Support/MathExtras.h" 19 #include "llvm/Support/raw_ostream.h" 20 21 namespace llvm { 22 23 class Triple; 24 25 namespace RISCV { 26 27 namespace RISCVExtensionBitmaskTable { 28 struct RISCVExtensionBitmask { 29 const char *Name; 30 unsigned GroupID; 31 unsigned BitPosition; 32 }; 33 } // namespace RISCVExtensionBitmaskTable 34 35 struct CPUModel { 36 uint32_t MVendorID; 37 uint64_t MArchID; 38 uint64_t MImpID; 39 }; 40 41 struct CPUInfo { 42 StringLiteral Name; 43 StringLiteral DefaultMarch; 44 bool FastScalarUnalignedAccess; 45 bool FastVectorUnalignedAccess; 46 CPUModel Model; 47 bool is64Bit() const { return DefaultMarch.starts_with("rv64"); } 48 }; 49 50 // We use 64 bits as the known part in the scalable vector types. 51 static constexpr unsigned RVVBitsPerBlock = 64; 52 53 void getFeaturesForCPU(StringRef CPU, 54 SmallVectorImpl<std::string> &EnabledFeatures, 55 bool NeedPlus = false); 56 bool parseCPU(StringRef CPU, bool IsRV64); 57 bool parseTuneCPU(StringRef CPU, bool IsRV64); 58 StringRef getMArchFromMcpu(StringRef CPU); 59 void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64); 60 void fillValidTuneCPUArchList(SmallVectorImpl<StringRef> &Values, bool IsRV64); 61 bool hasFastScalarUnalignedAccess(StringRef CPU); 62 bool hasFastVectorUnalignedAccess(StringRef CPU); 63 bool hasValidCPUModel(StringRef CPU); 64 CPUModel getCPUModel(StringRef CPU); 65 66 } // namespace RISCV 67 68 namespace RISCVII { 69 enum VLMUL : uint8_t { 70 LMUL_1 = 0, 71 LMUL_2, 72 LMUL_4, 73 LMUL_8, 74 LMUL_RESERVED, 75 LMUL_F8, 76 LMUL_F4, 77 LMUL_F2 78 }; 79 80 enum { 81 TAIL_UNDISTURBED_MASK_UNDISTURBED = 0, 82 TAIL_AGNOSTIC = 1, 83 MASK_AGNOSTIC = 2, 84 }; 85 } // namespace RISCVII 86 87 namespace RISCVVType { 88 // Is this a SEW value that can be encoded into the VTYPE format. 89 inline static bool isValidSEW(unsigned SEW) { 90 return isPowerOf2_32(SEW) && SEW >= 8 && SEW <= 64; 91 } 92 93 // Is this a LMUL value that can be encoded into the VTYPE format. 94 inline static bool isValidLMUL(unsigned LMUL, bool Fractional) { 95 return isPowerOf2_32(LMUL) && LMUL <= 8 && (!Fractional || LMUL != 1); 96 } 97 98 unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic, 99 bool MaskAgnostic); 100 101 inline static RISCVII::VLMUL getVLMUL(unsigned VType) { 102 unsigned VLMUL = VType & 0x7; 103 return static_cast<RISCVII::VLMUL>(VLMUL); 104 } 105 106 // Decode VLMUL into 1,2,4,8 and fractional indicator. 107 std::pair<unsigned, bool> decodeVLMUL(RISCVII::VLMUL VLMUL); 108 109 inline static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional) { 110 assert(isValidLMUL(LMUL, Fractional) && "Unsupported LMUL"); 111 unsigned LmulLog2 = Log2_32(LMUL); 112 return static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2); 113 } 114 115 inline static unsigned decodeVSEW(unsigned VSEW) { 116 assert(VSEW < 8 && "Unexpected VSEW value"); 117 return 1 << (VSEW + 3); 118 } 119 120 inline static unsigned encodeSEW(unsigned SEW) { 121 assert(isValidSEW(SEW) && "Unexpected SEW value"); 122 return Log2_32(SEW) - 3; 123 } 124 125 inline static unsigned getSEW(unsigned VType) { 126 unsigned VSEW = (VType >> 3) & 0x7; 127 return decodeVSEW(VSEW); 128 } 129 130 inline static bool isTailAgnostic(unsigned VType) { return VType & 0x40; } 131 132 inline static bool isMaskAgnostic(unsigned VType) { return VType & 0x80; } 133 134 void printVType(unsigned VType, raw_ostream &OS); 135 136 unsigned getSEWLMULRatio(unsigned SEW, RISCVII::VLMUL VLMul); 137 138 std::optional<RISCVII::VLMUL> 139 getSameRatioLMUL(unsigned SEW, RISCVII::VLMUL VLMUL, unsigned EEW); 140 } // namespace RISCVVType 141 142 } // namespace llvm 143 144 #endif 145