1 //===-- unittests/RISCVISAInfoTest.cpp ------------------------------------===// 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 #include "llvm/TargetParser/RISCVISAInfo.h" 10 #include "llvm/ADT/StringMap.h" 11 #include "llvm/Testing/Support/Error.h" 12 #include "gtest/gtest.h" 13 14 using ::testing::ElementsAre; 15 16 using namespace llvm; 17 18 bool operator==(const RISCVISAUtils::ExtensionVersion &A, 19 const RISCVISAUtils::ExtensionVersion &B) { 20 return A.Major == B.Major && A.Minor == B.Minor; 21 } 22 23 TEST(ParseNormalizedArchString, RejectsInvalidChars) { 24 for (StringRef Input : {"RV32", "rV64", "rv32i2P0", "rv64i2p0_A2p0", 25 "rv32e2.0", "rva20u64+zbc"}) { 26 EXPECT_EQ( 27 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), 28 "string may only contain [a-z0-9_]"); 29 } 30 } 31 32 TEST(ParseNormalizedArchString, RejectsInvalidBaseISA) { 33 for (StringRef Input : {"rv32", "rv64", "rv32j", "rv65i"}) { 34 EXPECT_EQ( 35 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), 36 "arch string must begin with valid base ISA"); 37 } 38 } 39 40 TEST(ParseNormalizedArchString, RejectsMalformedInputs) { 41 for (StringRef Input : {"rv64e2p", "rv32i", "rv64ip1"}) { 42 EXPECT_EQ( 43 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), 44 "extension lacks version in expected format"); 45 } 46 47 for (StringRef Input : {"rv64i2p0_", "rv32i2p0__a2p0"}) { 48 EXPECT_EQ( 49 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), 50 "extension name missing after separator '_'"); 51 } 52 } 53 54 TEST(ParseNormalizedArchString, RejectsOnlyVersion) { 55 for (StringRef Input : {"rv64i2p0_1p0", "rv32i2p0_1p0"}) { 56 EXPECT_EQ( 57 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), 58 "missing extension name"); 59 } 60 } 61 62 TEST(ParseNormalizedArchString, RejectsBadZ) { 63 for (StringRef Input : {"rv64i2p0_z1p0", "rv32i2p0_z2a1p0"}) { 64 EXPECT_EQ( 65 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), 66 "'z' must be followed by a letter"); 67 } 68 } 69 70 TEST(ParseNormalizedArchString, RejectsBadS) { 71 for (StringRef Input : {"rv64i2p0_s1p0", "rv32i2p0_s2a1p0"}) { 72 EXPECT_EQ( 73 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), 74 "'s' must be followed by a letter"); 75 } 76 } 77 78 TEST(ParseNormalizedArchString, RejectsBadX) { 79 for (StringRef Input : {"rv64i2p0_x1p0", "rv32i2p0_x2a1p0"}) { 80 EXPECT_EQ( 81 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), 82 "'x' must be followed by a letter"); 83 } 84 } 85 86 TEST(ParseNormalizedArchString, DuplicateExtension) { 87 for (StringRef Input : {"rv64i2p0_a2p0_a1p0"}) { 88 EXPECT_EQ( 89 toString(RISCVISAInfo::parseNormalizedArchString(Input).takeError()), 90 "duplicate extension 'a'"); 91 } 92 } 93 94 TEST(ParseNormalizedArchString, AcceptsValidBaseISAsAndSetsXLen) { 95 auto MaybeRV32I = RISCVISAInfo::parseNormalizedArchString("rv32i2p0"); 96 ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded()); 97 RISCVISAInfo &InfoRV32I = **MaybeRV32I; 98 EXPECT_EQ(InfoRV32I.getExtensions().size(), 1UL); 99 EXPECT_TRUE(InfoRV32I.getExtensions().at("i") == 100 (RISCVISAUtils::ExtensionVersion{2, 0})); 101 EXPECT_EQ(InfoRV32I.getXLen(), 32U); 102 103 auto MaybeRV32E = RISCVISAInfo::parseNormalizedArchString("rv32e2p0"); 104 ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded()); 105 RISCVISAInfo &InfoRV32E = **MaybeRV32E; 106 EXPECT_EQ(InfoRV32E.getExtensions().size(), 1UL); 107 EXPECT_TRUE(InfoRV32E.getExtensions().at("e") == 108 (RISCVISAUtils::ExtensionVersion{2, 0})); 109 EXPECT_EQ(InfoRV32E.getXLen(), 32U); 110 111 auto MaybeRV64I = RISCVISAInfo::parseNormalizedArchString("rv64i2p0"); 112 ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded()); 113 RISCVISAInfo &InfoRV64I = **MaybeRV64I; 114 EXPECT_EQ(InfoRV64I.getExtensions().size(), 1UL); 115 EXPECT_TRUE(InfoRV64I.getExtensions().at("i") == 116 (RISCVISAUtils::ExtensionVersion{2, 0})); 117 EXPECT_EQ(InfoRV64I.getXLen(), 64U); 118 119 auto MaybeRV64E = RISCVISAInfo::parseNormalizedArchString("rv64e2p0"); 120 ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded()); 121 RISCVISAInfo &InfoRV64E = **MaybeRV64E; 122 EXPECT_EQ(InfoRV64E.getExtensions().size(), 1UL); 123 EXPECT_TRUE(InfoRV64E.getExtensions().at("e") == 124 (RISCVISAUtils::ExtensionVersion{2, 0})); 125 EXPECT_EQ(InfoRV64E.getXLen(), 64U); 126 } 127 128 TEST(ParseNormalizedArchString, AcceptsArbitraryExtensionsAndVersions) { 129 auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString( 130 "rv64i5p1_m3p2_zmadeup11p12_sfoo2p0_xbar3p0"); 131 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 132 RISCVISAInfo &Info = **MaybeISAInfo; 133 EXPECT_EQ(Info.getExtensions().size(), 5UL); 134 EXPECT_TRUE(Info.getExtensions().at("i") == 135 (RISCVISAUtils::ExtensionVersion{5, 1})); 136 EXPECT_TRUE(Info.getExtensions().at("m") == 137 (RISCVISAUtils::ExtensionVersion{3, 2})); 138 EXPECT_TRUE(Info.getExtensions().at("zmadeup") == 139 (RISCVISAUtils::ExtensionVersion{11, 12})); 140 EXPECT_TRUE(Info.getExtensions().at("sfoo") == 141 (RISCVISAUtils::ExtensionVersion{2, 0})); 142 EXPECT_TRUE(Info.getExtensions().at("xbar") == 143 (RISCVISAUtils::ExtensionVersion{3, 0})); 144 } 145 146 TEST(ParseNormalizedArchString, UpdatesFLenMinVLenMaxELen) { 147 auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString( 148 "rv64i2p0_d2p0_zvl64b1p0_zve64d1p0"); 149 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 150 RISCVISAInfo &Info = **MaybeISAInfo; 151 EXPECT_EQ(Info.getXLen(), 64U); 152 EXPECT_EQ(Info.getFLen(), 64U); 153 EXPECT_EQ(Info.getMinVLen(), 64U); 154 EXPECT_EQ(Info.getMaxELen(), 64U); 155 EXPECT_EQ(Info.getMaxELenFp(), 64U); 156 } 157 158 TEST(ParseNormalizedArchString, AcceptsUnknownMultiletter) { 159 auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString( 160 "rv64i2p0_f2p0_d2p0_zicsr2p0_ykk1p0"); 161 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 162 RISCVISAInfo &Info = **MaybeISAInfo; 163 EXPECT_EQ(Info.toString(), "rv64i2p0_f2p0_d2p0_zicsr2p0_ykk1p0"); 164 } 165 166 TEST(ParseArchString, RejectsInvalidChars) { 167 for (StringRef Input : {"RV32", "rV64", "rv32i2P0", "rv64i2p0_A2p0"}) { 168 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 169 "string may only contain [a-z0-9_]"); 170 } 171 } 172 173 TEST(ParseArchString, RejectsInvalidBaseISA) { 174 for (StringRef Input : {"rv32", "rv64", "rv65i"}) { 175 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 176 "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported " 177 "profile name"); 178 } 179 180 for (StringRef Input : {"rv32j", "rv32_i"}) { 181 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 182 "first letter after 'rv32' should be 'e', 'i' or 'g'"); 183 } 184 185 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64k", true).takeError()), 186 "first letter after 'rv64' should be 'e', 'i' or 'g'"); 187 } 188 189 TEST(ParseArchString, RejectsUnsupportedBaseISA) { 190 for (StringRef Input : {"rv128i", "rv128g"}) { 191 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 192 "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported " 193 "profile name"); 194 } 195 } 196 197 TEST(ParseArchString, AcceptsSupportedBaseISAsAndSetsXLenAndFLen) { 198 auto MaybeRV32I = RISCVISAInfo::parseArchString("rv32i", true); 199 ASSERT_THAT_EXPECTED(MaybeRV32I, Succeeded()); 200 RISCVISAInfo &InfoRV32I = **MaybeRV32I; 201 const auto &ExtsRV32I = InfoRV32I.getExtensions(); 202 EXPECT_EQ(ExtsRV32I.size(), 1UL); 203 EXPECT_TRUE(ExtsRV32I.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 204 EXPECT_EQ(InfoRV32I.getXLen(), 32U); 205 EXPECT_EQ(InfoRV32I.getFLen(), 0U); 206 EXPECT_EQ(InfoRV32I.getMinVLen(), 0U); 207 EXPECT_EQ(InfoRV32I.getMaxELen(), 0U); 208 EXPECT_EQ(InfoRV32I.getMaxELenFp(), 0U); 209 210 auto MaybeRV32E = RISCVISAInfo::parseArchString("rv32e", true); 211 ASSERT_THAT_EXPECTED(MaybeRV32E, Succeeded()); 212 RISCVISAInfo &InfoRV32E = **MaybeRV32E; 213 const auto &ExtsRV32E = InfoRV32E.getExtensions(); 214 EXPECT_EQ(ExtsRV32E.size(), 1UL); 215 EXPECT_TRUE(ExtsRV32E.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0})); 216 EXPECT_EQ(InfoRV32E.getXLen(), 32U); 217 EXPECT_EQ(InfoRV32E.getFLen(), 0U); 218 EXPECT_EQ(InfoRV32E.getMinVLen(), 0U); 219 EXPECT_EQ(InfoRV32E.getMaxELen(), 0U); 220 EXPECT_EQ(InfoRV32E.getMaxELenFp(), 0U); 221 222 auto MaybeRV32G = RISCVISAInfo::parseArchString("rv32g", true); 223 ASSERT_THAT_EXPECTED(MaybeRV32G, Succeeded()); 224 RISCVISAInfo &InfoRV32G = **MaybeRV32G; 225 const auto &ExtsRV32G = InfoRV32G.getExtensions(); 226 EXPECT_EQ(ExtsRV32G.size(), 10UL); 227 EXPECT_TRUE(ExtsRV32G.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 228 EXPECT_TRUE(ExtsRV32G.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0})); 229 EXPECT_TRUE(ExtsRV32G.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1})); 230 EXPECT_TRUE(ExtsRV32G.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2})); 231 EXPECT_TRUE(ExtsRV32G.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2})); 232 EXPECT_TRUE(ExtsRV32G.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0})); 233 EXPECT_TRUE(ExtsRV32G.at("zifencei") == 234 (RISCVISAUtils::ExtensionVersion{2, 0})); 235 EXPECT_TRUE(ExtsRV32G.at("zmmul") == (RISCVISAUtils::ExtensionVersion{1, 0})); 236 EXPECT_TRUE(ExtsRV32G.at("zaamo") == (RISCVISAUtils::ExtensionVersion{1, 0})); 237 EXPECT_TRUE(ExtsRV32G.at("zalrsc") == 238 (RISCVISAUtils::ExtensionVersion{1, 0})); 239 EXPECT_EQ(InfoRV32G.getXLen(), 32U); 240 EXPECT_EQ(InfoRV32G.getFLen(), 64U); 241 EXPECT_EQ(InfoRV32G.getMinVLen(), 0U); 242 EXPECT_EQ(InfoRV32G.getMaxELen(), 0U); 243 EXPECT_EQ(InfoRV32G.getMaxELenFp(), 0U); 244 245 auto MaybeRV64I = RISCVISAInfo::parseArchString("rv64i", true); 246 ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded()); 247 RISCVISAInfo &InfoRV64I = **MaybeRV64I; 248 const auto &ExtsRV64I = InfoRV64I.getExtensions(); 249 EXPECT_EQ(ExtsRV64I.size(), 1UL); 250 EXPECT_TRUE(ExtsRV64I.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 251 EXPECT_EQ(InfoRV64I.getXLen(), 64U); 252 EXPECT_EQ(InfoRV64I.getFLen(), 0U); 253 EXPECT_EQ(InfoRV64I.getMinVLen(), 0U); 254 EXPECT_EQ(InfoRV64I.getMaxELen(), 0U); 255 EXPECT_EQ(InfoRV64I.getMaxELenFp(), 0U); 256 257 auto MaybeRV64E = RISCVISAInfo::parseArchString("rv64e", true); 258 ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded()); 259 RISCVISAInfo &InfoRV64E = **MaybeRV64E; 260 const auto &ExtsRV64E = InfoRV64E.getExtensions(); 261 EXPECT_EQ(ExtsRV64E.size(), 1UL); 262 EXPECT_TRUE(ExtsRV64E.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0})); 263 EXPECT_EQ(InfoRV64E.getXLen(), 64U); 264 EXPECT_EQ(InfoRV64E.getFLen(), 0U); 265 EXPECT_EQ(InfoRV64E.getMinVLen(), 0U); 266 EXPECT_EQ(InfoRV64E.getMaxELen(), 0U); 267 EXPECT_EQ(InfoRV64E.getMaxELenFp(), 0U); 268 269 auto MaybeRV64G = RISCVISAInfo::parseArchString("rv64g", true); 270 ASSERT_THAT_EXPECTED(MaybeRV64G, Succeeded()); 271 RISCVISAInfo &InfoRV64G = **MaybeRV64G; 272 const auto &ExtsRV64G = InfoRV64G.getExtensions(); 273 EXPECT_EQ(ExtsRV64G.size(), 10UL); 274 EXPECT_TRUE(ExtsRV64G.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 275 EXPECT_TRUE(ExtsRV64G.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0})); 276 EXPECT_TRUE(ExtsRV64G.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1})); 277 EXPECT_TRUE(ExtsRV64G.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2})); 278 EXPECT_TRUE(ExtsRV64G.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2})); 279 EXPECT_TRUE(ExtsRV64G.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0})); 280 EXPECT_TRUE(ExtsRV64G.at("zifencei") == 281 (RISCVISAUtils::ExtensionVersion{2, 0})); 282 EXPECT_TRUE(ExtsRV64G.at("zmmul") == (RISCVISAUtils::ExtensionVersion{1, 0})); 283 EXPECT_TRUE(ExtsRV64G.at("zaamo") == (RISCVISAUtils::ExtensionVersion{1, 0})); 284 EXPECT_TRUE(ExtsRV64G.at("zalrsc") == 285 (RISCVISAUtils::ExtensionVersion{1, 0})); 286 EXPECT_EQ(InfoRV64G.getXLen(), 64U); 287 EXPECT_EQ(InfoRV64G.getFLen(), 64U); 288 EXPECT_EQ(InfoRV64G.getMinVLen(), 0U); 289 EXPECT_EQ(InfoRV64G.getMaxELen(), 0U); 290 EXPECT_EQ(InfoRV64G.getMaxELenFp(), 0U); 291 292 auto MaybeRV64GCV = RISCVISAInfo::parseArchString("rv64gcv", true); 293 ASSERT_THAT_EXPECTED(MaybeRV64GCV, Succeeded()); 294 RISCVISAInfo &InfoRV64GCV = **MaybeRV64GCV; 295 const auto &ExtsRV64GCV = InfoRV64GCV.getExtensions(); 296 EXPECT_EQ(ExtsRV64GCV.size(), 20UL); 297 EXPECT_TRUE(ExtsRV64GCV.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 298 EXPECT_TRUE(ExtsRV64GCV.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0})); 299 EXPECT_TRUE(ExtsRV64GCV.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1})); 300 EXPECT_TRUE(ExtsRV64GCV.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2})); 301 EXPECT_TRUE(ExtsRV64GCV.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2})); 302 EXPECT_TRUE(ExtsRV64GCV.at("c") == (RISCVISAUtils::ExtensionVersion{2, 0})); 303 EXPECT_TRUE(ExtsRV64GCV.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0})); 304 EXPECT_TRUE(ExtsRV64GCV.at("zifencei") == 305 (RISCVISAUtils::ExtensionVersion{2, 0})); 306 EXPECT_TRUE(ExtsRV64G.at("zmmul") == (RISCVISAUtils::ExtensionVersion{1, 0})); 307 EXPECT_TRUE(ExtsRV64G.at("zaamo") == (RISCVISAUtils::ExtensionVersion{1, 0})); 308 EXPECT_TRUE(ExtsRV64G.at("zalrsc") == 309 (RISCVISAUtils::ExtensionVersion{1, 0})); 310 EXPECT_TRUE(ExtsRV64GCV.at("v") == (RISCVISAUtils::ExtensionVersion{1, 0})); 311 EXPECT_TRUE(ExtsRV64GCV.at("zve32x") == (RISCVISAUtils::ExtensionVersion{1, 0})); 312 EXPECT_TRUE(ExtsRV64GCV.at("zve32f") == (RISCVISAUtils::ExtensionVersion{1, 0})); 313 EXPECT_TRUE(ExtsRV64GCV.at("zve64x") == (RISCVISAUtils::ExtensionVersion{1, 0})); 314 EXPECT_TRUE(ExtsRV64GCV.at("zve64f") == (RISCVISAUtils::ExtensionVersion{1, 0})); 315 EXPECT_TRUE(ExtsRV64GCV.at("zve64d") == (RISCVISAUtils::ExtensionVersion{1, 0})); 316 EXPECT_TRUE(ExtsRV64GCV.at("zvl32b") == (RISCVISAUtils::ExtensionVersion{1, 0})); 317 EXPECT_TRUE(ExtsRV64GCV.at("zvl64b") == (RISCVISAUtils::ExtensionVersion{1, 0})); 318 EXPECT_TRUE(ExtsRV64GCV.at("zvl128b") == (RISCVISAUtils::ExtensionVersion{1, 0})); 319 EXPECT_EQ(InfoRV64GCV.getXLen(), 64U); 320 EXPECT_EQ(InfoRV64GCV.getFLen(), 64U); 321 EXPECT_EQ(InfoRV64GCV.getMinVLen(), 128U); 322 EXPECT_EQ(InfoRV64GCV.getMaxELen(), 64U); 323 EXPECT_EQ(InfoRV64GCV.getMaxELenFp(), 64U); 324 } 325 326 TEST(ParseArchString, RejectsUnrecognizedExtensionNamesByDefault) { 327 EXPECT_EQ( 328 toString( 329 RISCVISAInfo::parseArchString("rv32i_zmadeup", true).takeError()), 330 "unsupported standard user-level extension 'zmadeup'"); 331 EXPECT_EQ( 332 toString( 333 RISCVISAInfo::parseArchString("rv64g_smadeup", true).takeError()), 334 "unsupported standard supervisor-level extension 'smadeup'"); 335 EXPECT_EQ( 336 toString( 337 RISCVISAInfo::parseArchString("rv64g_xmadeup", true).takeError()), 338 "unsupported non-standard user-level extension 'xmadeup'"); 339 EXPECT_EQ( 340 toString( 341 RISCVISAInfo::parseArchString("rv32i_zmadeup1p0", true).takeError()), 342 "unsupported standard user-level extension 'zmadeup'"); 343 EXPECT_EQ( 344 toString( 345 RISCVISAInfo::parseArchString("rv64g_smadeup1p0", true).takeError()), 346 "unsupported standard supervisor-level extension 'smadeup'"); 347 EXPECT_EQ( 348 toString( 349 RISCVISAInfo::parseArchString("rv64g_xmadeup1p0", true).takeError()), 350 "unsupported non-standard user-level extension 'xmadeup'"); 351 } 352 353 TEST(ParseArchString, AcceptsVersionInLongOrShortForm) { 354 for (StringRef Input : {"rv64i2p1"}) { 355 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 356 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 357 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 358 EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 359 } 360 for (StringRef Input : {"rv32i_zfinx1", "rv32i_zfinx1p0"}) { 361 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 362 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 363 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 364 EXPECT_TRUE(Exts.at("zfinx") == (RISCVISAUtils::ExtensionVersion{1, 0})); 365 } 366 } 367 368 TEST(ParseArchString, RejectsUnrecognizedExtensionVersionsByDefault) { 369 EXPECT_EQ( 370 toString(RISCVISAInfo::parseArchString("rv64i2p", true).takeError()), 371 "minor version number missing after 'p' for extension 'i'"); 372 EXPECT_EQ( 373 toString(RISCVISAInfo::parseArchString("rv64i1p0", true).takeError()), 374 "unsupported version number 1.0 for extension 'i'"); 375 EXPECT_EQ( 376 toString(RISCVISAInfo::parseArchString("rv64i9p9", true).takeError()), 377 "unsupported version number 9.9 for extension 'i'"); 378 EXPECT_EQ( 379 toString(RISCVISAInfo::parseArchString("rv32im0p1", true).takeError()), 380 "unsupported version number 0.1 for extension 'm'"); 381 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32izifencei10p10", true) 382 .takeError()), 383 "unsupported version number 10.10 for extension 'zifencei'"); 384 } 385 386 TEST(ParseArchString, AcceptsUnderscoreSplittingExtensions) { 387 for (StringRef Input : {"rv32imafdczifencei", "rv32i_m_a_f_d_c_zifencei"}) { 388 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 389 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 390 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 391 EXPECT_EQ(Exts.size(), 11UL); 392 EXPECT_EQ(Exts.count("i"), 1U); 393 EXPECT_EQ(Exts.count("m"), 1U); 394 EXPECT_EQ(Exts.count("a"), 1U); 395 EXPECT_EQ(Exts.count("f"), 1U); 396 EXPECT_EQ(Exts.count("d"), 1U); 397 EXPECT_EQ(Exts.count("c"), 1U); 398 EXPECT_EQ(Exts.count("zicsr"), 1U); 399 EXPECT_EQ(Exts.count("zifencei"), 1U); 400 EXPECT_EQ(Exts.count("zmmul"), 1U); 401 EXPECT_EQ(Exts.count("zaamo"), 1U); 402 EXPECT_EQ(Exts.count("zalrsc"), 1U); 403 } 404 } 405 406 TEST(ParseArchString, AcceptsRelaxSingleLetterExtensions) { 407 for (StringRef Input : 408 {"rv32imfad", "rv32im_fa_d", "rv32im2p0fad", "rv32i2p1m2p0fad"}) { 409 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 410 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 411 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 412 EXPECT_EQ(Exts.size(), 9UL); 413 EXPECT_EQ(Exts.count("i"), 1U); 414 EXPECT_EQ(Exts.count("m"), 1U); 415 EXPECT_EQ(Exts.count("f"), 1U); 416 EXPECT_EQ(Exts.count("a"), 1U); 417 EXPECT_EQ(Exts.count("d"), 1U); 418 EXPECT_EQ(Exts.count("zicsr"), 1U); 419 EXPECT_EQ(Exts.count("zmmul"), 1U); 420 EXPECT_EQ(Exts.count("zaamo"), 1U); 421 EXPECT_EQ(Exts.count("zalrsc"), 1U); 422 } 423 } 424 425 TEST(ParseArchString, AcceptsRelaxMixedLetterExtensions) { 426 for (StringRef Input : 427 {"rv32i_zihintntl_m_a_f_d_svinval", "rv32izihintntl_mafdsvinval", 428 "rv32i_zihintntl_mafd_svinval"}) { 429 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 430 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 431 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 432 EXPECT_EQ(Exts.size(), 11UL); 433 EXPECT_EQ(Exts.count("i"), 1U); 434 EXPECT_EQ(Exts.count("m"), 1U); 435 EXPECT_EQ(Exts.count("a"), 1U); 436 EXPECT_EQ(Exts.count("f"), 1U); 437 EXPECT_EQ(Exts.count("d"), 1U); 438 EXPECT_EQ(Exts.count("zihintntl"), 1U); 439 EXPECT_EQ(Exts.count("svinval"), 1U); 440 EXPECT_EQ(Exts.count("zicsr"), 1U); 441 EXPECT_EQ(Exts.count("zmmul"), 1U); 442 EXPECT_EQ(Exts.count("zaamo"), 1U); 443 EXPECT_EQ(Exts.count("zalrsc"), 1U); 444 } 445 } 446 447 TEST(ParseArchString, AcceptsAmbiguousFromRelaxExtensions) { 448 for (StringRef Input : {"rv32i_zba_m", "rv32izba_m", "rv32izba1p0_m2p0"}) { 449 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 450 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 451 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 452 EXPECT_EQ(Exts.size(), 4UL); 453 EXPECT_EQ(Exts.count("i"), 1U); 454 EXPECT_EQ(Exts.count("zba"), 1U); 455 EXPECT_EQ(Exts.count("m"), 1U); 456 EXPECT_EQ(Exts.count("zmmul"), 1U); 457 } 458 for (StringRef Input : 459 {"rv32ia_zba_m", "rv32iazba_m", "rv32ia2p1zba1p0_m2p0"}) { 460 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 461 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 462 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 463 EXPECT_EQ(Exts.size(), 7UL); 464 EXPECT_EQ(Exts.count("i"), 1U); 465 EXPECT_EQ(Exts.count("zba"), 1U); 466 EXPECT_EQ(Exts.count("m"), 1U); 467 EXPECT_EQ(Exts.count("a"), 1U); 468 EXPECT_EQ(Exts.count("zmmul"), 1U); 469 EXPECT_EQ(Exts.count("zaamo"), 1U); 470 EXPECT_EQ(Exts.count("zalrsc"), 1U); 471 } 472 } 473 474 TEST(ParseArchString, RejectsRelaxExtensionsNotStartWithEorIorG) { 475 EXPECT_EQ( 476 toString(RISCVISAInfo::parseArchString("rv32zba_im", true).takeError()), 477 "first letter after 'rv32' should be 'e', 'i' or 'g'"); 478 } 479 480 TEST(ParseArchString, 481 RejectsMultiLetterExtensionFollowBySingleLetterExtensions) { 482 for (StringRef Input : {"rv32izbam", "rv32i_zbam"}) 483 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 484 "unsupported standard user-level extension 'zbam'"); 485 EXPECT_EQ( 486 toString(RISCVISAInfo::parseArchString("rv32izbai_m", true).takeError()), 487 "unsupported standard user-level extension 'zbai'"); 488 EXPECT_EQ( 489 toString(RISCVISAInfo::parseArchString("rv32izbaim", true).takeError()), 490 "unsupported standard user-level extension 'zbaim'"); 491 EXPECT_EQ( 492 toString( 493 RISCVISAInfo::parseArchString("rv32i_zba1p0m", true).takeError()), 494 "unsupported standard user-level extension 'zba1p0m'"); 495 } 496 497 TEST(ParseArchString, RejectsDoubleOrTrailingUnderscore) { 498 EXPECT_EQ( 499 toString(RISCVISAInfo::parseArchString("rv64i__m", true).takeError()), 500 "extension name missing after separator '_'"); 501 502 for (StringRef Input : 503 {"rv32ezicsr__zifencei", "rv32i_", "rv32izicsr_", "rv64im_"}) { 504 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 505 "extension name missing after separator '_'"); 506 } 507 } 508 509 TEST(ParseArchString, RejectsDuplicateExtensionNames) { 510 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64ii", true).takeError()), 511 "invalid standard user-level extension 'i'"); 512 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32ee", true).takeError()), 513 "invalid standard user-level extension 'e'"); 514 EXPECT_EQ( 515 toString(RISCVISAInfo::parseArchString("rv64imm", true).takeError()), 516 "duplicated standard user-level extension 'm'"); 517 EXPECT_EQ( 518 toString( 519 RISCVISAInfo::parseArchString("rv32i_zicsr_zicsr", true).takeError()), 520 "duplicated standard user-level extension 'zicsr'"); 521 } 522 523 TEST(ParseArchString, 524 RejectsExperimentalExtensionsIfNotEnableExperimentalExtension) { 525 EXPECT_EQ( 526 toString(RISCVISAInfo::parseArchString("rv64izalasr", false).takeError()), 527 "requires '-menable-experimental-extensions' for experimental extension " 528 "'zalasr'"); 529 } 530 531 TEST(ParseArchString, 532 AcceptsExperimentalExtensionsIfEnableExperimentalExtension) { 533 // Note: If zalasr becomes none-experimental, this test will need 534 // updating (and unfortunately, it will still pass). The failure of 535 // RejectsExperimentalExtensionsIfNotEnableExperimentalExtension will 536 // hopefully serve as a reminder to update. 537 auto MaybeISAInfo = RISCVISAInfo::parseArchString("rv64izalasr", true, false); 538 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 539 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 540 EXPECT_EQ(Exts.size(), 2UL); 541 EXPECT_EQ(Exts.count("zalasr"), 1U); 542 auto MaybeISAInfo2 = RISCVISAInfo::parseArchString("rv64izalasr0p1", true); 543 ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded()); 544 const auto &Exts2 = (*MaybeISAInfo2)->getExtensions(); 545 EXPECT_EQ(Exts2.size(), 2UL); 546 EXPECT_EQ(Exts2.count("zalasr"), 1U); 547 } 548 549 TEST(ParseArchString, 550 RequiresExplicitVersionNumberForExperimentalExtensionByDefault) { 551 EXPECT_EQ( 552 toString(RISCVISAInfo::parseArchString("rv64izalasr", true).takeError()), 553 "experimental extension requires explicit version number `zalasr`"); 554 } 555 556 TEST(ParseArchString, 557 AcceptsUnrecognizedVersionIfNotExperimentalExtensionVersionCheck) { 558 auto MaybeISAInfo = 559 RISCVISAInfo::parseArchString("rv64izalasr9p9", true, false); 560 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 561 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 562 EXPECT_EQ(Exts.size(), 2UL); 563 EXPECT_TRUE(Exts.at("zalasr") == (RISCVISAUtils::ExtensionVersion{9, 9})); 564 } 565 566 TEST(ParseArchString, RejectsUnrecognizedVersionForExperimentalExtension) { 567 EXPECT_EQ( 568 toString( 569 RISCVISAInfo::parseArchString("rv64izalasr9p9", true).takeError()), 570 "unsupported version number 9.9 for experimental extension 'zalasr' " 571 "(this compiler supports 0.1)"); 572 } 573 574 TEST(ParseArchString, RejectsExtensionVersionForG) { 575 for (StringRef Input : {"rv32g1c", "rv64g2p0"}) { 576 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 577 "version not supported for 'g'"); 578 } 579 } 580 581 TEST(ParseArchString, AddsImpliedExtensions) { 582 // Does not attempt to exhaustively test all implications. 583 auto MaybeRV64ID = RISCVISAInfo::parseArchString("rv64id", true); 584 ASSERT_THAT_EXPECTED(MaybeRV64ID, Succeeded()); 585 const auto &ExtsRV64ID = (*MaybeRV64ID)->getExtensions(); 586 EXPECT_EQ(ExtsRV64ID.size(), 4UL); 587 EXPECT_EQ(ExtsRV64ID.count("i"), 1U); 588 EXPECT_EQ(ExtsRV64ID.count("f"), 1U); 589 EXPECT_EQ(ExtsRV64ID.count("d"), 1U); 590 EXPECT_EQ(ExtsRV64ID.count("zicsr"), 1U); 591 592 auto MaybeRV32IZKN = RISCVISAInfo::parseArchString("rv64izkn", true); 593 ASSERT_THAT_EXPECTED(MaybeRV32IZKN, Succeeded()); 594 const auto &ExtsRV32IZKN = (*MaybeRV32IZKN)->getExtensions(); 595 EXPECT_EQ(ExtsRV32IZKN.size(), 8UL); 596 EXPECT_EQ(ExtsRV32IZKN.count("i"), 1U); 597 EXPECT_EQ(ExtsRV32IZKN.count("zbkb"), 1U); 598 EXPECT_EQ(ExtsRV32IZKN.count("zbkc"), 1U); 599 EXPECT_EQ(ExtsRV32IZKN.count("zbkx"), 1U); 600 EXPECT_EQ(ExtsRV32IZKN.count("zkne"), 1U); 601 EXPECT_EQ(ExtsRV32IZKN.count("zknd"), 1U); 602 EXPECT_EQ(ExtsRV32IZKN.count("zknh"), 1U); 603 EXPECT_EQ(ExtsRV32IZKN.count("zkn"), 1U); 604 } 605 606 TEST(ParseArchString, RejectsConflictingExtensions) { 607 for (StringRef Input : {"rv32ifzfinx", "rv64gzdinx"}) { 608 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 609 "'f' and 'zfinx' extensions are incompatible"); 610 } 611 612 for (StringRef Input : {"rv32idc_zcmp1p0", "rv64idc_zcmp1p0"}) { 613 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 614 "'zcmp' extension is incompatible with 'c' extension when 'd' " 615 "extension is enabled"); 616 } 617 618 for (StringRef Input : {"rv32id_zcd1p0_zcmp1p0", "rv64id_zcd1p0_zcmp1p0"}) { 619 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 620 "'zcmp' extension is incompatible with 'zcd' extension when 'd' " 621 "extension is enabled"); 622 } 623 624 for (StringRef Input : {"rv32idc_zcmt1p0", "rv64idc_zcmt1p0"}) { 625 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 626 "'zcmt' extension is incompatible with 'c' extension when 'd' " 627 "extension is enabled"); 628 } 629 630 for (StringRef Input : {"rv32id_zcd1p0_zcmt1p0", "rv64id_zcd1p0_zcmt1p0"}) { 631 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 632 "'zcmt' extension is incompatible with 'zcd' extension when 'd' " 633 "extension is enabled"); 634 } 635 636 for (StringRef Input : {"rv64if_zcf"}) { 637 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 638 "'zcf' is only supported for 'rv32'"); 639 } 640 641 for (StringRef Input : {"rv64i_xwchc"}) { 642 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 643 "'xwchc' is only supported for 'rv32'"); 644 } 645 646 for (StringRef Input : {"rv32id_xwchc"}) { 647 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 648 "'d' and 'xwchc' extensions are incompatible"); 649 } 650 651 for (StringRef Input : {"rv32i_zcb_xwchc"}) { 652 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 653 "'xwchc' and 'zcb' extensions are incompatible"); 654 } 655 } 656 657 TEST(ParseArchString, MissingDepency) { 658 for (StringRef Input : {"rv32i_zvl32b", "rv64i_zvl128b"}) { 659 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 660 "'zvl*b' requires 'v' or 'zve*' extension to also be specified"); 661 } 662 663 // These all have an implication relationship, thus should pass 664 for (StringRef Input : { 665 "rv32i_zvbb", 666 "rv32i_zvbc32e0p7", 667 "rv32i_zvbc", 668 "rv32i_zvkb", 669 "rv32i_zvkg", 670 "rv32i_zvkgs0p7", 671 "rv32i_zvkned", 672 "rv32i_zvknha", 673 "rv32i_zvksed", 674 "rv32i_zvksh", 675 "rv32i_zvknhb", 676 }) { 677 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 678 ""); 679 } 680 } 681 682 TEST(ParseArchString, RejectsUnrecognizedProfileNames) { 683 for (StringRef Input : {"rvi23u99", "rvz23u64", "rva99u32"}) { 684 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 685 "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported " 686 "profile name"); 687 } 688 } 689 690 TEST(ParseArchString, RejectsProfilesWithUnseparatedExtraExtensions) { 691 for (StringRef Input : {"rvi20u32m", "rvi20u64c"}) { 692 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 693 "additional extensions must be after separator '_'"); 694 } 695 } 696 697 TEST(ParseArchString, AcceptsBareProfileNames) { 698 auto MaybeRVA20U64 = RISCVISAInfo::parseArchString("rva20u64", true); 699 ASSERT_THAT_EXPECTED(MaybeRVA20U64, Succeeded()); 700 const auto &Exts = (*MaybeRVA20U64)->getExtensions(); 701 EXPECT_EQ(Exts.size(), 16UL); 702 EXPECT_EQ(Exts.count("i"), 1U); 703 EXPECT_EQ(Exts.count("m"), 1U); 704 EXPECT_EQ(Exts.count("f"), 1U); 705 EXPECT_EQ(Exts.count("a"), 1U); 706 EXPECT_EQ(Exts.count("d"), 1U); 707 EXPECT_EQ(Exts.count("c"), 1U); 708 EXPECT_EQ(Exts.count("za128rs"), 1U); 709 EXPECT_EQ(Exts.count("zicntr"), 1U); 710 EXPECT_EQ(Exts.count("ziccif"), 1U); 711 EXPECT_EQ(Exts.count("zicsr"), 1U); 712 EXPECT_EQ(Exts.count("ziccrse"), 1U); 713 EXPECT_EQ(Exts.count("ziccamoa"), 1U); 714 EXPECT_EQ(Exts.count("zicclsm"), 1U); 715 EXPECT_EQ(Exts.count("zmmul"), 1U); 716 EXPECT_EQ(Exts.count("zaamo"), 1U); 717 EXPECT_EQ(Exts.count("zalrsc"), 1U); 718 719 auto MaybeRVA23U64 = RISCVISAInfo::parseArchString("rva23u64", true); 720 ASSERT_THAT_EXPECTED(MaybeRVA23U64, Succeeded()); 721 EXPECT_GT((*MaybeRVA23U64)->getExtensions().size(), 13UL); 722 } 723 724 TEST(ParseArchSTring, AcceptsProfileNamesWithSeparatedAdditionalExtensions) { 725 auto MaybeRVI20U64 = RISCVISAInfo::parseArchString("rvi20u64_m_zba", true); 726 ASSERT_THAT_EXPECTED(MaybeRVI20U64, Succeeded()); 727 const auto &Exts = (*MaybeRVI20U64)->getExtensions(); 728 EXPECT_EQ(Exts.size(), 4UL); 729 EXPECT_EQ(Exts.count("i"), 1U); 730 EXPECT_EQ(Exts.count("m"), 1U); 731 EXPECT_EQ(Exts.count("zba"), 1U); 732 EXPECT_EQ(Exts.count("zmmul"), 1U); 733 } 734 735 TEST(ParseArchString, 736 RejectsProfilesWithAdditionalExtensionsGivenAlreadyInProfile) { 737 // This test was added to document the current behaviour. Discussion isn't 738 // believed to have taken place about if this is desirable or not. 739 EXPECT_EQ( 740 toString( 741 RISCVISAInfo::parseArchString("rva20u64_zicntr", true).takeError()), 742 "duplicated standard user-level extension 'zicntr'"); 743 } 744 745 TEST(ParseArchString, 746 RejectsExperimentalProfilesIfEnableExperimentalExtensionsNotSet) { 747 EXPECT_EQ( 748 toString(RISCVISAInfo::parseArchString("rvm23u32", false).takeError()), 749 "requires '-menable-experimental-extensions' for profile 'rvm23u32'"); 750 } 751 752 TEST(ToFeatures, IIsDroppedAndExperimentalExtensionsArePrefixed) { 753 auto MaybeISAInfo1 = 754 RISCVISAInfo::parseArchString("rv64im_zalasr", true, false); 755 ASSERT_THAT_EXPECTED(MaybeISAInfo1, Succeeded()); 756 EXPECT_THAT((*MaybeISAInfo1)->toFeatures(), 757 ElementsAre("+m", "+zmmul", "+experimental-zalasr")); 758 759 auto MaybeISAInfo2 = RISCVISAInfo::parseArchString( 760 "rv32e_zalasr_xventanacondops", true, false); 761 ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded()); 762 EXPECT_THAT((*MaybeISAInfo2)->toFeatures(), 763 ElementsAre("+e", "+experimental-zalasr", "+xventanacondops")); 764 } 765 766 TEST(ToFeatures, UnsupportedExtensionsAreDropped) { 767 auto MaybeISAInfo = 768 RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0"); 769 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 770 EXPECT_THAT((*MaybeISAInfo)->toFeatures(), ElementsAre("+m")); 771 } 772 773 TEST(ToFeatures, UnsupportedExtensionsAreKeptIfIgnoreUnknownIsFalse) { 774 auto MaybeISAInfo = 775 RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0"); 776 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 777 EXPECT_THAT((*MaybeISAInfo)->toFeatures(false, false), 778 ElementsAre("+m", "+xmadeup")); 779 } 780 781 TEST(ToFeatures, AddAllExtensionsAddsNegativeExtensions) { 782 auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0"); 783 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 784 785 auto Features = (*MaybeISAInfo)->toFeatures(true); 786 EXPECT_GT(Features.size(), 1UL); 787 EXPECT_EQ(Features.front(), "+m"); 788 // Every feature after should be a negative feature 789 for (auto &NegativeExt : llvm::drop_begin(Features)) 790 EXPECT_TRUE(NegativeExt.substr(0, 1) == "-"); 791 } 792 793 TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) { 794 RISCVISAUtils::OrderedExtensionMap Exts; 795 for (auto ExtName : {"y", "l", "m", "c", "i", "xfoo", "xbar", "sfoo", "sbar", 796 "zmfoo", "zzfoo", "zfinx", "zicsr"}) 797 Exts[ExtName] = {1, 0}; 798 799 std::vector<std::string> ExtNames; 800 for (const auto &Ext : Exts) 801 ExtNames.push_back(Ext.first); 802 803 // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'. 804 EXPECT_THAT(ExtNames, 805 ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx", 806 "zzfoo", "sbar", "sfoo", "xbar", "xfoo")); 807 } 808 809 TEST(ParseArchString, ZceImplication) { 810 auto MaybeRV32IZce = RISCVISAInfo::parseArchString("rv32izce", true); 811 ASSERT_THAT_EXPECTED(MaybeRV32IZce, Succeeded()); 812 const auto &ExtsRV32IZce = (*MaybeRV32IZce)->getExtensions(); 813 EXPECT_EQ(ExtsRV32IZce.size(), 7UL); 814 EXPECT_EQ(ExtsRV32IZce.count("i"), 1U); 815 EXPECT_EQ(ExtsRV32IZce.count("zicsr"), 1U); 816 EXPECT_EQ(ExtsRV32IZce.count("zca"), 1U); 817 EXPECT_EQ(ExtsRV32IZce.count("zcb"), 1U); 818 EXPECT_EQ(ExtsRV32IZce.count("zce"), 1U); 819 EXPECT_EQ(ExtsRV32IZce.count("zcmp"), 1U); 820 EXPECT_EQ(ExtsRV32IZce.count("zcmt"), 1U); 821 822 auto MaybeRV32IFZce = RISCVISAInfo::parseArchString("rv32ifzce", true); 823 ASSERT_THAT_EXPECTED(MaybeRV32IFZce, Succeeded()); 824 const auto &ExtsRV32IFZce = (*MaybeRV32IFZce)->getExtensions(); 825 EXPECT_EQ(ExtsRV32IFZce.size(), 9UL); 826 EXPECT_EQ(ExtsRV32IFZce.count("i"), 1U); 827 EXPECT_EQ(ExtsRV32IFZce.count("zicsr"), 1U); 828 EXPECT_EQ(ExtsRV32IFZce.count("f"), 1U); 829 EXPECT_EQ(ExtsRV32IFZce.count("zca"), 1U); 830 EXPECT_EQ(ExtsRV32IFZce.count("zcb"), 1U); 831 EXPECT_EQ(ExtsRV32IFZce.count("zce"), 1U); 832 EXPECT_EQ(ExtsRV32IFZce.count("zcf"), 1U); 833 EXPECT_EQ(ExtsRV32IFZce.count("zcmp"), 1U); 834 EXPECT_EQ(ExtsRV32IFZce.count("zcmt"), 1U); 835 836 auto MaybeRV32IDZce = RISCVISAInfo::parseArchString("rv32idzce", true); 837 ASSERT_THAT_EXPECTED(MaybeRV32IDZce, Succeeded()); 838 const auto &ExtsRV32IDZce = (*MaybeRV32IDZce)->getExtensions(); 839 EXPECT_EQ(ExtsRV32IDZce.size(), 10UL); 840 EXPECT_EQ(ExtsRV32IDZce.count("i"), 1U); 841 EXPECT_EQ(ExtsRV32IDZce.count("zicsr"), 1U); 842 EXPECT_EQ(ExtsRV32IDZce.count("f"), 1U); 843 EXPECT_EQ(ExtsRV32IDZce.count("d"), 1U); 844 EXPECT_EQ(ExtsRV32IDZce.count("zca"), 1U); 845 EXPECT_EQ(ExtsRV32IDZce.count("zcb"), 1U); 846 EXPECT_EQ(ExtsRV32IDZce.count("zce"), 1U); 847 EXPECT_EQ(ExtsRV32IDZce.count("zcf"), 1U); 848 EXPECT_EQ(ExtsRV32IDZce.count("zcmp"), 1U); 849 EXPECT_EQ(ExtsRV32IDZce.count("zcmt"), 1U); 850 851 auto MaybeRV64IZce = RISCVISAInfo::parseArchString("rv64izce", true); 852 ASSERT_THAT_EXPECTED(MaybeRV64IZce, Succeeded()); 853 const auto &ExtsRV64IZce = (*MaybeRV64IZce)->getExtensions(); 854 EXPECT_EQ(ExtsRV64IZce.size(), 7UL); 855 EXPECT_EQ(ExtsRV64IZce.count("i"), 1U); 856 EXPECT_EQ(ExtsRV64IZce.count("zicsr"), 1U); 857 EXPECT_EQ(ExtsRV64IZce.count("zca"), 1U); 858 EXPECT_EQ(ExtsRV64IZce.count("zcb"), 1U); 859 EXPECT_EQ(ExtsRV64IZce.count("zce"), 1U); 860 EXPECT_EQ(ExtsRV64IZce.count("zcmp"), 1U); 861 EXPECT_EQ(ExtsRV64IZce.count("zcmt"), 1U); 862 863 auto MaybeRV64IFZce = RISCVISAInfo::parseArchString("rv64ifzce", true); 864 ASSERT_THAT_EXPECTED(MaybeRV64IFZce, Succeeded()); 865 const auto &ExtsRV64IFZce = (*MaybeRV64IFZce)->getExtensions(); 866 EXPECT_EQ(ExtsRV64IFZce.size(), 8UL); 867 EXPECT_EQ(ExtsRV64IFZce.count("i"), 1U); 868 EXPECT_EQ(ExtsRV64IFZce.count("zicsr"), 1U); 869 EXPECT_EQ(ExtsRV64IFZce.count("f"), 1U); 870 EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U); 871 EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U); 872 EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U); 873 EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U); 874 EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U); 875 876 EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U); 877 EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U); 878 EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U); 879 EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U); 880 EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U); 881 882 auto MaybeRV64IDZce = RISCVISAInfo::parseArchString("rv64idzce", true); 883 ASSERT_THAT_EXPECTED(MaybeRV64IDZce, Succeeded()); 884 const auto &ExtsRV64IDZce = (*MaybeRV64IDZce)->getExtensions(); 885 EXPECT_EQ(ExtsRV64IDZce.size(), 9UL); 886 EXPECT_EQ(ExtsRV64IDZce.count("i"), 1U); 887 EXPECT_EQ(ExtsRV64IDZce.count("zicsr"), 1U); 888 EXPECT_EQ(ExtsRV64IDZce.count("f"), 1U); 889 EXPECT_EQ(ExtsRV64IDZce.count("d"), 1U); 890 EXPECT_EQ(ExtsRV64IDZce.count("zca"), 1U); 891 EXPECT_EQ(ExtsRV64IDZce.count("zcb"), 1U); 892 EXPECT_EQ(ExtsRV64IDZce.count("zce"), 1U); 893 EXPECT_EQ(ExtsRV64IDZce.count("zcmp"), 1U); 894 EXPECT_EQ(ExtsRV64IDZce.count("zcmt"), 1U); 895 } 896 897 TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) { 898 EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0")); 899 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb")); 900 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0")); 901 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo")); 902 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("")); 903 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0")); 904 } 905 906 TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) { 907 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb"), "zbb"); 908 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso1p0"), "ztso"); 909 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso"), "ztso"); 910 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321"), 911 ""); 912 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo"), ""); 913 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), ""); 914 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), ""); 915 } 916 917 TEST(RiscvExtensionsHelp, CheckExtensions) { 918 // clang-format off 919 std::string ExpectedOutput = 920 R"(All available -march extensions for RISC-V 921 922 Name Version Description 923 i 2.1 This is a long dummy description 924 e 2.0 925 m 2.0 926 a 2.1 927 f 2.2 928 d 2.2 929 c 2.0 930 b 1.0 931 v 1.0 932 h 1.0 933 zic64b 1.0 934 zicbom 1.0 935 zicbop 1.0 936 zicboz 1.0 937 ziccamoa 1.0 938 ziccif 1.0 939 zicclsm 1.0 940 ziccrse 1.0 941 zicntr 2.0 942 zicond 1.0 943 zicsr 2.0 944 zifencei 2.0 945 zihintntl 1.0 946 zihintpause 2.0 947 zihpm 2.0 948 zimop 1.0 949 zmmul 1.0 950 za128rs 1.0 951 za64rs 1.0 952 zaamo 1.0 953 zabha 1.0 954 zacas 1.0 955 zalrsc 1.0 956 zama16b 1.0 957 zawrs 1.0 958 zfa 1.0 959 zfbfmin 1.0 960 zfh 1.0 961 zfhmin 1.0 962 zfinx 1.0 963 zdinx 1.0 964 zca 1.0 965 zcb 1.0 966 zcd 1.0 967 zce 1.0 968 zcf 1.0 969 zcmop 1.0 970 zcmp 1.0 971 zcmt 1.0 972 zba 1.0 973 zbb 1.0 974 zbc 1.0 975 zbkb 1.0 976 zbkc 1.0 977 zbkx 1.0 978 zbs 1.0 979 zk 1.0 980 zkn 1.0 981 zknd 1.0 982 zkne 1.0 983 zknh 1.0 984 zkr 1.0 985 zks 1.0 986 zksed 1.0 987 zksh 1.0 988 zkt 1.0 989 ztso 1.0 990 zvbb 1.0 991 zvbc 1.0 992 zve32f 1.0 993 zve32x 1.0 994 zve64d 1.0 995 zve64f 1.0 996 zve64x 1.0 997 zvfbfmin 1.0 998 zvfbfwma 1.0 999 zvfh 1.0 1000 zvfhmin 1.0 1001 zvkb 1.0 1002 zvkg 1.0 1003 zvkn 1.0 1004 zvknc 1.0 1005 zvkned 1.0 1006 zvkng 1.0 1007 zvknha 1.0 1008 zvknhb 1.0 1009 zvks 1.0 1010 zvksc 1.0 1011 zvksed 1.0 1012 zvksg 1.0 1013 zvksh 1.0 1014 zvkt 1.0 1015 zvl1024b 1.0 1016 zvl128b 1.0 1017 zvl16384b 1.0 1018 zvl2048b 1.0 1019 zvl256b 1.0 1020 zvl32768b 1.0 1021 zvl32b 1.0 1022 zvl4096b 1.0 1023 zvl512b 1.0 1024 zvl64b 1.0 1025 zvl65536b 1.0 1026 zvl8192b 1.0 1027 zhinx 1.0 1028 zhinxmin 1.0 1029 sha 1.0 1030 shcounterenw 1.0 1031 shgatpa 1.0 1032 shtvala 1.0 1033 shvsatpa 1.0 1034 shvstvala 1.0 1035 shvstvecd 1.0 1036 smaia 1.0 1037 smcdeleg 1.0 1038 smcsrind 1.0 1039 smdbltrp 1.0 1040 smepmp 1.0 1041 smmpm 1.0 1042 smnpm 1.0 1043 smrnmi 1.0 1044 smstateen 1.0 1045 ssaia 1.0 1046 ssccfg 1.0 1047 ssccptr 1.0 1048 sscofpmf 1.0 1049 sscounterenw 1.0 1050 sscsrind 1.0 1051 ssdbltrp 1.0 1052 ssnpm 1.0 1053 sspm 1.0 1054 ssqosid 1.0 1055 ssstateen 1.0 1056 ssstrict 1.0 1057 sstc 1.0 1058 sstvala 1.0 1059 sstvecd 1.0 1060 ssu64xl 1.0 1061 supm 1.0 1062 svade 1.0 1063 svadu 1.0 1064 svbare 1.0 1065 svinval 1.0 1066 svnapot 1.0 1067 svpbmt 1.0 1068 svvptc 1.0 1069 xcvalu 1.0 1070 xcvbi 1.0 1071 xcvbitmanip 1.0 1072 xcvelw 1.0 1073 xcvmac 1.0 1074 xcvmem 1.0 1075 xcvsimd 1.0 1076 xsfcease 1.0 1077 xsfvcp 1.0 1078 xsfvfnrclipxfqf 1.0 1079 xsfvfwmaccqqq 1.0 1080 xsfvqmaccdod 1.0 1081 xsfvqmaccqoq 1.0 1082 xsifivecdiscarddlone 1.0 1083 xsifivecflushdlone 1.0 1084 xtheadba 1.0 1085 xtheadbb 1.0 1086 xtheadbs 1.0 1087 xtheadcmo 1.0 1088 xtheadcondmov 1.0 1089 xtheadfmemidx 1.0 1090 xtheadmac 1.0 1091 xtheadmemidx 1.0 1092 xtheadmempair 1.0 1093 xtheadsync 1.0 1094 xtheadvdot 1.0 1095 xventanacondops 1.0 1096 xwchc 2.2 1097 1098 Experimental extensions 1099 zicfilp 1.0 This is a long dummy description 1100 zicfiss 1.0 1101 zalasr 0.1 1102 zvbc32e 0.7 1103 zvkgs 0.7 1104 smctr 1.0 1105 ssctr 1.0 1106 svukte 0.3 1107 xqcicsr 0.2 1108 1109 Supported Profiles 1110 rva20s64 1111 rva20u64 1112 rva22s64 1113 rva22u64 1114 rva23s64 1115 rva23u64 1116 rvb23s64 1117 rvb23u64 1118 rvi20u32 1119 rvi20u64 1120 1121 Experimental Profiles 1122 rvm23u32 1123 1124 Use -march to specify the target's extension. 1125 For example, clang -march=rv32i_v1p0)"; 1126 // clang-format on 1127 1128 StringMap<StringRef> DummyMap; 1129 DummyMap["i"] = "This is a long dummy description"; 1130 DummyMap["experimental-zicfilp"] = "This is a long dummy description"; 1131 1132 outs().flush(); 1133 testing::internal::CaptureStdout(); 1134 RISCVISAInfo::printSupportedExtensions(DummyMap); 1135 outs().flush(); 1136 1137 std::string CapturedOutput = testing::internal::GetCapturedStdout(); 1138 EXPECT_TRUE([](std::string &Captured, std::string &Expected) { 1139 return Captured.find(Expected) != std::string::npos; 1140 }(CapturedOutput, ExpectedOutput)); 1141 } 1142 1143 TEST(TargetParserTest, RISCVPrintEnabledExtensions) { 1144 // clang-format off 1145 std::string ExpectedOutput = 1146 R"(Extensions enabled for the given RISC-V target 1147 1148 Name Version Description 1149 i 2.1 'I' (Base Integer Instruction Set) 1150 1151 Experimental extensions 1152 zicfilp 1.0 'Zicfilp' (Landing pad) 1153 1154 ISA String: rv64i2p1_zicfilp1p0_zicsr2p0 1155 )"; 1156 // clang-format on 1157 1158 StringMap<StringRef> DescMap; 1159 DescMap["i"] = "'I' (Base Integer Instruction Set)"; 1160 DescMap["experimental-zicfilp"] = "'Zicfilp' (Landing pad)"; 1161 std::set<StringRef> EnabledExtensions = {"i", "experimental-zicfilp"}; 1162 1163 outs().flush(); 1164 testing::internal::CaptureStdout(); 1165 RISCVISAInfo::printEnabledExtensions(/*IsRV64=*/true, EnabledExtensions, 1166 DescMap); 1167 outs().flush(); 1168 std::string CapturedOutput = testing::internal::GetCapturedStdout(); 1169 1170 EXPECT_EQ(CapturedOutput, ExpectedOutput); 1171 } 1172