1*0fca6ea1SDimitry Andric //===-- RISCVISAInfo.h - RISC-V ISA Information -----------------*- C++ -*-===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric 9*0fca6ea1SDimitry Andric #ifndef LLVM_SUPPORT_RISCVISAINFO_H 10*0fca6ea1SDimitry Andric #define LLVM_SUPPORT_RISCVISAINFO_H 11*0fca6ea1SDimitry Andric 12*0fca6ea1SDimitry Andric #include "llvm/ADT/StringMap.h" 13*0fca6ea1SDimitry Andric #include "llvm/ADT/StringRef.h" 14*0fca6ea1SDimitry Andric #include "llvm/Support/Error.h" 15*0fca6ea1SDimitry Andric #include "llvm/Support/RISCVISAUtils.h" 16*0fca6ea1SDimitry Andric 17*0fca6ea1SDimitry Andric #include <map> 18*0fca6ea1SDimitry Andric #include <set> 19*0fca6ea1SDimitry Andric #include <string> 20*0fca6ea1SDimitry Andric #include <vector> 21*0fca6ea1SDimitry Andric 22*0fca6ea1SDimitry Andric namespace llvm { 23*0fca6ea1SDimitry Andric 24*0fca6ea1SDimitry Andric class RISCVISAInfo { 25*0fca6ea1SDimitry Andric public: 26*0fca6ea1SDimitry Andric RISCVISAInfo(const RISCVISAInfo &) = delete; 27*0fca6ea1SDimitry Andric RISCVISAInfo &operator=(const RISCVISAInfo &) = delete; 28*0fca6ea1SDimitry Andric 29*0fca6ea1SDimitry Andric /// Parse RISC-V ISA info from arch string. 30*0fca6ea1SDimitry Andric /// If IgnoreUnknown is set, any unrecognised extension names or 31*0fca6ea1SDimitry Andric /// extensions with unrecognised versions will be silently dropped, except 32*0fca6ea1SDimitry Andric /// for the special case of the base 'i' and 'e' extensions, where the 33*0fca6ea1SDimitry Andric /// default version will be used (as ignoring the base is not possible). 34*0fca6ea1SDimitry Andric static llvm::Expected<std::unique_ptr<RISCVISAInfo>> 35*0fca6ea1SDimitry Andric parseArchString(StringRef Arch, bool EnableExperimentalExtension, 36*0fca6ea1SDimitry Andric bool ExperimentalExtensionVersionCheck = true); 37*0fca6ea1SDimitry Andric 38*0fca6ea1SDimitry Andric /// Parse RISC-V ISA info from an arch string that is already in normalized 39*0fca6ea1SDimitry Andric /// form (as defined in the psABI). Unlike parseArchString, this function 40*0fca6ea1SDimitry Andric /// will not error for unrecognized extension names or extension versions. 41*0fca6ea1SDimitry Andric static llvm::Expected<std::unique_ptr<RISCVISAInfo>> 42*0fca6ea1SDimitry Andric parseNormalizedArchString(StringRef Arch); 43*0fca6ea1SDimitry Andric 44*0fca6ea1SDimitry Andric /// Parse RISC-V ISA info from feature vector. 45*0fca6ea1SDimitry Andric static llvm::Expected<std::unique_ptr<RISCVISAInfo>> 46*0fca6ea1SDimitry Andric parseFeatures(unsigned XLen, const std::vector<std::string> &Features); 47*0fca6ea1SDimitry Andric 48*0fca6ea1SDimitry Andric static llvm::Expected<std::unique_ptr<RISCVISAInfo>> 49*0fca6ea1SDimitry Andric createFromExtMap(unsigned XLen, 50*0fca6ea1SDimitry Andric const RISCVISAUtils::OrderedExtensionMap &Exts); 51*0fca6ea1SDimitry Andric 52*0fca6ea1SDimitry Andric /// Convert RISC-V ISA info to a feature vector. 53*0fca6ea1SDimitry Andric std::vector<std::string> toFeatures(bool AddAllExtensions = false, 54*0fca6ea1SDimitry Andric bool IgnoreUnknown = true) const; 55*0fca6ea1SDimitry Andric getExtensions()56*0fca6ea1SDimitry Andric const RISCVISAUtils::OrderedExtensionMap &getExtensions() const { 57*0fca6ea1SDimitry Andric return Exts; 58*0fca6ea1SDimitry Andric } 59*0fca6ea1SDimitry Andric getXLen()60*0fca6ea1SDimitry Andric unsigned getXLen() const { return XLen; } getFLen()61*0fca6ea1SDimitry Andric unsigned getFLen() const { return FLen; } getMinVLen()62*0fca6ea1SDimitry Andric unsigned getMinVLen() const { return MinVLen; } getMaxVLen()63*0fca6ea1SDimitry Andric unsigned getMaxVLen() const { return 65536; } getMaxELen()64*0fca6ea1SDimitry Andric unsigned getMaxELen() const { return MaxELen; } getMaxELenFp()65*0fca6ea1SDimitry Andric unsigned getMaxELenFp() const { return MaxELenFp; } 66*0fca6ea1SDimitry Andric 67*0fca6ea1SDimitry Andric bool hasExtension(StringRef Ext) const; 68*0fca6ea1SDimitry Andric std::string toString() const; 69*0fca6ea1SDimitry Andric StringRef computeDefaultABI() const; 70*0fca6ea1SDimitry Andric 71*0fca6ea1SDimitry Andric static bool isSupportedExtensionFeature(StringRef Ext); 72*0fca6ea1SDimitry Andric static bool isSupportedExtension(StringRef Ext); 73*0fca6ea1SDimitry Andric static bool isSupportedExtensionWithVersion(StringRef Ext); 74*0fca6ea1SDimitry Andric static bool isSupportedExtension(StringRef Ext, unsigned MajorVersion, 75*0fca6ea1SDimitry Andric unsigned MinorVersion); 76*0fca6ea1SDimitry Andric static std::string getTargetFeatureForExtension(StringRef Ext); 77*0fca6ea1SDimitry Andric 78*0fca6ea1SDimitry Andric static void printSupportedExtensions(StringMap<StringRef> &DescMap); 79*0fca6ea1SDimitry Andric static void printEnabledExtensions(bool IsRV64, 80*0fca6ea1SDimitry Andric std::set<StringRef> &EnabledFeatureNames, 81*0fca6ea1SDimitry Andric StringMap<StringRef> &DescMap); 82*0fca6ea1SDimitry Andric 83*0fca6ea1SDimitry Andric private: RISCVISAInfo(unsigned XLen)84*0fca6ea1SDimitry Andric RISCVISAInfo(unsigned XLen) : XLen(XLen) {} 85*0fca6ea1SDimitry Andric 86*0fca6ea1SDimitry Andric unsigned XLen; 87*0fca6ea1SDimitry Andric unsigned FLen = 0; 88*0fca6ea1SDimitry Andric unsigned MinVLen = 0; 89*0fca6ea1SDimitry Andric unsigned MaxELen = 0, MaxELenFp = 0; 90*0fca6ea1SDimitry Andric 91*0fca6ea1SDimitry Andric RISCVISAUtils::OrderedExtensionMap Exts; 92*0fca6ea1SDimitry Andric 93*0fca6ea1SDimitry Andric Error checkDependency(); 94*0fca6ea1SDimitry Andric 95*0fca6ea1SDimitry Andric void updateImplication(); 96*0fca6ea1SDimitry Andric void updateCombination(); 97*0fca6ea1SDimitry Andric 98*0fca6ea1SDimitry Andric /// Update FLen, MinVLen, MaxELen, and MaxELenFp. 99*0fca6ea1SDimitry Andric void updateImpliedLengths(); 100*0fca6ea1SDimitry Andric 101*0fca6ea1SDimitry Andric static llvm::Expected<std::unique_ptr<RISCVISAInfo>> 102*0fca6ea1SDimitry Andric postProcessAndChecking(std::unique_ptr<RISCVISAInfo> &&ISAInfo); 103*0fca6ea1SDimitry Andric }; 104*0fca6ea1SDimitry Andric 105*0fca6ea1SDimitry Andric } // namespace llvm 106*0fca6ea1SDimitry Andric 107*0fca6ea1SDimitry Andric #endif 108