1 //===-- RISCVBaseInfo.cpp - Top level definitions for RISCV MC ------------===//
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
14 #include "RISCVBaseInfo.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/Triple.h"
17 #include "llvm/MC/MCSubtargetInfo.h"
18 #include "llvm/Support/RISCVISAInfo.h"
19 #include "llvm/Support/TargetParser.h"
20 #include "llvm/Support/raw_ostream.h"
21
22 namespace llvm {
23
24 extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
25
26 namespace RISCVSysReg {
27 #define GET_SysRegsList_IMPL
28 #include "RISCVGenSearchableTables.inc"
29 } // namespace RISCVSysReg
30
31 namespace RISCVInsnOpcode {
32 #define GET_RISCVOpcodesList_IMPL
33 #include "RISCVGenSearchableTables.inc"
34 } // namespace RISCVInsnOpcode
35
36 namespace RISCVABI {
computeTargetABI(const Triple & TT,FeatureBitset FeatureBits,StringRef ABIName)37 ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits,
38 StringRef ABIName) {
39 auto TargetABI = getTargetABI(ABIName);
40 bool IsRV64 = TT.isArch64Bit();
41 bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
42
43 if (!ABIName.empty() && TargetABI == ABI_Unknown) {
44 errs()
45 << "'" << ABIName
46 << "' is not a recognized ABI for this target (ignoring target-abi)\n";
47 } else if (ABIName.startswith("ilp32") && IsRV64) {
48 errs() << "32-bit ABIs are not supported for 64-bit targets (ignoring "
49 "target-abi)\n";
50 TargetABI = ABI_Unknown;
51 } else if (ABIName.startswith("lp64") && !IsRV64) {
52 errs() << "64-bit ABIs are not supported for 32-bit targets (ignoring "
53 "target-abi)\n";
54 TargetABI = ABI_Unknown;
55 } else if (IsRV32E && TargetABI != ABI_ILP32E && TargetABI != ABI_Unknown) {
56 // TODO: move this checking to RISCVTargetLowering and RISCVAsmParser
57 errs()
58 << "Only the ilp32e ABI is supported for RV32E (ignoring target-abi)\n";
59 TargetABI = ABI_Unknown;
60 }
61
62 if (TargetABI != ABI_Unknown)
63 return TargetABI;
64
65 // If no explicit ABI is given, try to compute the default ABI.
66 auto ISAInfo = RISCVFeatures::parseFeatureBits(IsRV64, FeatureBits);
67 if (!ISAInfo)
68 report_fatal_error(ISAInfo.takeError());
69 return getTargetABI((*ISAInfo)->computeDefaultABI());
70 }
71
getTargetABI(StringRef ABIName)72 ABI getTargetABI(StringRef ABIName) {
73 auto TargetABI = StringSwitch<ABI>(ABIName)
74 .Case("ilp32", ABI_ILP32)
75 .Case("ilp32f", ABI_ILP32F)
76 .Case("ilp32d", ABI_ILP32D)
77 .Case("ilp32e", ABI_ILP32E)
78 .Case("lp64", ABI_LP64)
79 .Case("lp64f", ABI_LP64F)
80 .Case("lp64d", ABI_LP64D)
81 .Default(ABI_Unknown);
82 return TargetABI;
83 }
84
85 // To avoid the BP value clobbered by a function call, we need to choose a
86 // callee saved register to save the value. RV32E only has X8 and X9 as callee
87 // saved registers and X8 will be used as fp. So we choose X9 as bp.
getBPReg()88 MCRegister getBPReg() { return RISCV::X9; }
89
90 // Returns the register holding shadow call stack pointer.
getSCSPReg()91 MCRegister getSCSPReg() { return RISCV::X18; }
92
93 } // namespace RISCVABI
94
95 namespace RISCVFeatures {
96
validate(const Triple & TT,const FeatureBitset & FeatureBits)97 void validate(const Triple &TT, const FeatureBitset &FeatureBits) {
98 if (TT.isArch64Bit() && !FeatureBits[RISCV::Feature64Bit])
99 report_fatal_error("RV64 target requires an RV64 CPU");
100 if (!TT.isArch64Bit() && FeatureBits[RISCV::Feature64Bit])
101 report_fatal_error("RV32 target requires an RV32 CPU");
102 if (TT.isArch64Bit() && FeatureBits[RISCV::FeatureRV32E])
103 report_fatal_error("RV32E can't be enabled for an RV64 target");
104 }
105
106 llvm::Expected<std::unique_ptr<RISCVISAInfo>>
parseFeatureBits(bool IsRV64,const FeatureBitset & FeatureBits)107 parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits) {
108 unsigned XLen = IsRV64 ? 64 : 32;
109 std::vector<std::string> FeatureVector;
110 // Convert FeatureBitset to FeatureVector.
111 for (auto Feature : RISCVFeatureKV) {
112 if (FeatureBits[Feature.Value] &&
113 llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key))
114 FeatureVector.push_back(std::string("+") + Feature.Key);
115 }
116 return llvm::RISCVISAInfo::parseFeatures(XLen, FeatureVector);
117 }
118
119 } // namespace RISCVFeatures
120
121 // Encode VTYPE into the binary format used by the the VSETVLI instruction which
122 // is used by our MC layer representation.
123 //
124 // Bits | Name | Description
125 // -----+------------+------------------------------------------------
126 // 7 | vma | Vector mask agnostic
127 // 6 | vta | Vector tail agnostic
128 // 5:3 | vsew[2:0] | Standard element width (SEW) setting
129 // 2:0 | vlmul[2:0] | Vector register group multiplier (LMUL) setting
encodeVTYPE(RISCVII::VLMUL VLMUL,unsigned SEW,bool TailAgnostic,bool MaskAgnostic)130 unsigned RISCVVType::encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW,
131 bool TailAgnostic, bool MaskAgnostic) {
132 assert(isValidSEW(SEW) && "Invalid SEW");
133 unsigned VLMULBits = static_cast<unsigned>(VLMUL);
134 unsigned VSEWBits = encodeSEW(SEW);
135 unsigned VTypeI = (VSEWBits << 3) | (VLMULBits & 0x7);
136 if (TailAgnostic)
137 VTypeI |= 0x40;
138 if (MaskAgnostic)
139 VTypeI |= 0x80;
140
141 return VTypeI;
142 }
143
decodeVLMUL(RISCVII::VLMUL VLMUL)144 std::pair<unsigned, bool> RISCVVType::decodeVLMUL(RISCVII::VLMUL VLMUL) {
145 switch (VLMUL) {
146 default:
147 llvm_unreachable("Unexpected LMUL value!");
148 case RISCVII::VLMUL::LMUL_1:
149 case RISCVII::VLMUL::LMUL_2:
150 case RISCVII::VLMUL::LMUL_4:
151 case RISCVII::VLMUL::LMUL_8:
152 return std::make_pair(1 << static_cast<unsigned>(VLMUL), false);
153 case RISCVII::VLMUL::LMUL_F2:
154 case RISCVII::VLMUL::LMUL_F4:
155 case RISCVII::VLMUL::LMUL_F8:
156 return std::make_pair(1 << (8 - static_cast<unsigned>(VLMUL)), true);
157 }
158 }
159
printVType(unsigned VType,raw_ostream & OS)160 void RISCVVType::printVType(unsigned VType, raw_ostream &OS) {
161 unsigned Sew = getSEW(VType);
162 OS << "e" << Sew;
163
164 unsigned LMul;
165 bool Fractional;
166 std::tie(LMul, Fractional) = decodeVLMUL(getVLMUL(VType));
167
168 if (Fractional)
169 OS << ", mf";
170 else
171 OS << ", m";
172 OS << LMul;
173
174 if (isTailAgnostic(VType))
175 OS << ", ta";
176 else
177 OS << ", tu";
178
179 if (isMaskAgnostic(VType))
180 OS << ", ma";
181 else
182 OS << ", mu";
183 }
184
185 } // namespace llvm
186