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(), 7UL); 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_EQ(InfoRV32G.getXLen(), 32U); 236 EXPECT_EQ(InfoRV32G.getFLen(), 64U); 237 EXPECT_EQ(InfoRV32G.getMinVLen(), 0U); 238 EXPECT_EQ(InfoRV32G.getMaxELen(), 0U); 239 EXPECT_EQ(InfoRV32G.getMaxELenFp(), 0U); 240 241 auto MaybeRV64I = RISCVISAInfo::parseArchString("rv64i", true); 242 ASSERT_THAT_EXPECTED(MaybeRV64I, Succeeded()); 243 RISCVISAInfo &InfoRV64I = **MaybeRV64I; 244 const auto &ExtsRV64I = InfoRV64I.getExtensions(); 245 EXPECT_EQ(ExtsRV64I.size(), 1UL); 246 EXPECT_TRUE(ExtsRV64I.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 247 EXPECT_EQ(InfoRV64I.getXLen(), 64U); 248 EXPECT_EQ(InfoRV64I.getFLen(), 0U); 249 EXPECT_EQ(InfoRV64I.getMinVLen(), 0U); 250 EXPECT_EQ(InfoRV64I.getMaxELen(), 0U); 251 EXPECT_EQ(InfoRV64I.getMaxELenFp(), 0U); 252 253 auto MaybeRV64E = RISCVISAInfo::parseArchString("rv64e", true); 254 ASSERT_THAT_EXPECTED(MaybeRV64E, Succeeded()); 255 RISCVISAInfo &InfoRV64E = **MaybeRV64E; 256 const auto &ExtsRV64E = InfoRV64E.getExtensions(); 257 EXPECT_EQ(ExtsRV64E.size(), 1UL); 258 EXPECT_TRUE(ExtsRV64E.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0})); 259 EXPECT_EQ(InfoRV64E.getXLen(), 64U); 260 EXPECT_EQ(InfoRV64E.getFLen(), 0U); 261 EXPECT_EQ(InfoRV64E.getMinVLen(), 0U); 262 EXPECT_EQ(InfoRV64E.getMaxELen(), 0U); 263 EXPECT_EQ(InfoRV64E.getMaxELenFp(), 0U); 264 265 auto MaybeRV64G = RISCVISAInfo::parseArchString("rv64g", true); 266 ASSERT_THAT_EXPECTED(MaybeRV64G, Succeeded()); 267 RISCVISAInfo &InfoRV64G = **MaybeRV64G; 268 const auto &ExtsRV64G = InfoRV64G.getExtensions(); 269 EXPECT_EQ(ExtsRV64G.size(), 7UL); 270 EXPECT_TRUE(ExtsRV64G.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 271 EXPECT_TRUE(ExtsRV64G.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0})); 272 EXPECT_TRUE(ExtsRV64G.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1})); 273 EXPECT_TRUE(ExtsRV64G.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2})); 274 EXPECT_TRUE(ExtsRV64G.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2})); 275 EXPECT_TRUE(ExtsRV64G.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0})); 276 EXPECT_TRUE(ExtsRV64G.at("zifencei") == 277 (RISCVISAUtils::ExtensionVersion{2, 0})); 278 EXPECT_EQ(InfoRV64G.getXLen(), 64U); 279 EXPECT_EQ(InfoRV64G.getFLen(), 64U); 280 EXPECT_EQ(InfoRV64G.getMinVLen(), 0U); 281 EXPECT_EQ(InfoRV64G.getMaxELen(), 0U); 282 EXPECT_EQ(InfoRV64G.getMaxELenFp(), 0U); 283 284 auto MaybeRV64GCV = RISCVISAInfo::parseArchString("rv64gcv", true); 285 ASSERT_THAT_EXPECTED(MaybeRV64GCV, Succeeded()); 286 RISCVISAInfo &InfoRV64GCV = **MaybeRV64GCV; 287 const auto &ExtsRV64GCV = InfoRV64GCV.getExtensions(); 288 EXPECT_EQ(ExtsRV64GCV.size(), 17UL); 289 EXPECT_TRUE(ExtsRV64GCV.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 290 EXPECT_TRUE(ExtsRV64GCV.at("m") == (RISCVISAUtils::ExtensionVersion{2, 0})); 291 EXPECT_TRUE(ExtsRV64GCV.at("a") == (RISCVISAUtils::ExtensionVersion{2, 1})); 292 EXPECT_TRUE(ExtsRV64GCV.at("f") == (RISCVISAUtils::ExtensionVersion{2, 2})); 293 EXPECT_TRUE(ExtsRV64GCV.at("d") == (RISCVISAUtils::ExtensionVersion{2, 2})); 294 EXPECT_TRUE(ExtsRV64GCV.at("c") == (RISCVISAUtils::ExtensionVersion{2, 0})); 295 EXPECT_TRUE(ExtsRV64GCV.at("zicsr") == (RISCVISAUtils::ExtensionVersion{2, 0})); 296 EXPECT_TRUE(ExtsRV64GCV.at("zifencei") == 297 (RISCVISAUtils::ExtensionVersion{2, 0})); 298 EXPECT_TRUE(ExtsRV64GCV.at("v") == (RISCVISAUtils::ExtensionVersion{1, 0})); 299 EXPECT_TRUE(ExtsRV64GCV.at("zve32x") == (RISCVISAUtils::ExtensionVersion{1, 0})); 300 EXPECT_TRUE(ExtsRV64GCV.at("zve32f") == (RISCVISAUtils::ExtensionVersion{1, 0})); 301 EXPECT_TRUE(ExtsRV64GCV.at("zve64x") == (RISCVISAUtils::ExtensionVersion{1, 0})); 302 EXPECT_TRUE(ExtsRV64GCV.at("zve64f") == (RISCVISAUtils::ExtensionVersion{1, 0})); 303 EXPECT_TRUE(ExtsRV64GCV.at("zve64d") == (RISCVISAUtils::ExtensionVersion{1, 0})); 304 EXPECT_TRUE(ExtsRV64GCV.at("zvl32b") == (RISCVISAUtils::ExtensionVersion{1, 0})); 305 EXPECT_TRUE(ExtsRV64GCV.at("zvl64b") == (RISCVISAUtils::ExtensionVersion{1, 0})); 306 EXPECT_TRUE(ExtsRV64GCV.at("zvl128b") == (RISCVISAUtils::ExtensionVersion{1, 0})); 307 EXPECT_EQ(InfoRV64GCV.getXLen(), 64U); 308 EXPECT_EQ(InfoRV64GCV.getFLen(), 64U); 309 EXPECT_EQ(InfoRV64GCV.getMinVLen(), 128U); 310 EXPECT_EQ(InfoRV64GCV.getMaxELen(), 64U); 311 EXPECT_EQ(InfoRV64GCV.getMaxELenFp(), 64U); 312 } 313 314 TEST(ParseArchString, RejectsUnrecognizedExtensionNamesByDefault) { 315 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64ib", true).takeError()), 316 "unsupported standard user-level extension 'b'"); 317 EXPECT_EQ( 318 toString( 319 RISCVISAInfo::parseArchString("rv32i_zmadeup", true).takeError()), 320 "unsupported standard user-level extension 'zmadeup'"); 321 EXPECT_EQ( 322 toString( 323 RISCVISAInfo::parseArchString("rv64g_smadeup", true).takeError()), 324 "unsupported standard supervisor-level extension 'smadeup'"); 325 EXPECT_EQ( 326 toString( 327 RISCVISAInfo::parseArchString("rv64g_xmadeup", true).takeError()), 328 "unsupported non-standard user-level extension 'xmadeup'"); 329 EXPECT_EQ( 330 toString(RISCVISAInfo::parseArchString("rv64ib1p0", true).takeError()), 331 "unsupported standard user-level extension 'b'"); 332 EXPECT_EQ( 333 toString( 334 RISCVISAInfo::parseArchString("rv32i_zmadeup1p0", true).takeError()), 335 "unsupported standard user-level extension 'zmadeup'"); 336 EXPECT_EQ( 337 toString( 338 RISCVISAInfo::parseArchString("rv64g_smadeup1p0", true).takeError()), 339 "unsupported standard supervisor-level extension 'smadeup'"); 340 EXPECT_EQ( 341 toString( 342 RISCVISAInfo::parseArchString("rv64g_xmadeup1p0", true).takeError()), 343 "unsupported non-standard user-level extension 'xmadeup'"); 344 } 345 346 TEST(ParseArchString, IgnoresUnrecognizedExtensionNamesWithIgnoreUnknown) { 347 for (StringRef Input : {"rv32ib", "rv32i_zmadeup", 348 "rv64i_smadeup", "rv64i_xmadeup"}) { 349 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true, false, true); 350 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 351 RISCVISAInfo &Info = **MaybeISAInfo; 352 const auto &Exts = Info.getExtensions(); 353 EXPECT_EQ(Exts.size(), 1UL); 354 EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 355 } 356 357 // Checks that supported extensions aren't incorrectly ignored when a 358 // version is present (an early version of the patch had this mistake). 359 auto MaybeISAInfo = 360 RISCVISAInfo::parseArchString("rv32i_zbc1p0_xmadeup", true, false, true); 361 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 362 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 363 EXPECT_TRUE(Exts.at("zbc") == (RISCVISAUtils::ExtensionVersion{1, 0})); 364 } 365 366 TEST(ParseArchString, AcceptsVersionInLongOrShortForm) { 367 for (StringRef Input : {"rv64i2p1"}) { 368 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 369 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 370 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 371 EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 372 } 373 for (StringRef Input : {"rv32i_zfinx1", "rv32i_zfinx1p0"}) { 374 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 375 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 376 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 377 EXPECT_TRUE(Exts.at("zfinx") == (RISCVISAUtils::ExtensionVersion{1, 0})); 378 } 379 } 380 381 TEST(ParseArchString, RejectsUnrecognizedExtensionVersionsByDefault) { 382 EXPECT_EQ( 383 toString(RISCVISAInfo::parseArchString("rv64i2p", true).takeError()), 384 "minor version number missing after 'p' for extension 'i'"); 385 EXPECT_EQ( 386 toString(RISCVISAInfo::parseArchString("rv64i1p0", true).takeError()), 387 "unsupported version number 1.0 for extension 'i'"); 388 EXPECT_EQ( 389 toString(RISCVISAInfo::parseArchString("rv64i9p9", true).takeError()), 390 "unsupported version number 9.9 for extension 'i'"); 391 EXPECT_EQ( 392 toString(RISCVISAInfo::parseArchString("rv32im0p1", true).takeError()), 393 "unsupported version number 0.1 for extension 'm'"); 394 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32izifencei10p10", true) 395 .takeError()), 396 "unsupported version number 10.10 for extension 'zifencei'"); 397 } 398 399 TEST(ParseArchString, 400 UsesDefaultVersionForUnrecognisedBaseISAVersionWithIgnoreUnknown) { 401 for (StringRef Input : {"rv32i0p1", "rv32i99p99", "rv64i0p1", "rv64i99p99"}) { 402 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true, false, true); 403 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 404 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 405 EXPECT_EQ(Exts.size(), 1UL); 406 EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 407 } 408 for (StringRef Input : {"rv32e0p1", "rv32e99p99", "rv64e0p1", "rv64e99p99"}) { 409 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true, false, true); 410 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 411 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 412 EXPECT_EQ(Exts.size(), 1UL); 413 EXPECT_TRUE(Exts.at("e") == (RISCVISAUtils::ExtensionVersion{2, 0})); 414 } 415 } 416 417 TEST(ParseArchString, 418 IgnoresExtensionsWithUnrecognizedVersionsWithIgnoreUnknown) { 419 for (StringRef Input : {"rv32im1p1", "rv64i_svnapot10p9", "rv32i_zicsr0p5"}) { 420 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true, false, true); 421 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 422 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 423 EXPECT_EQ(Exts.size(), 1UL); 424 EXPECT_TRUE(Exts.at("i") == (RISCVISAUtils::ExtensionVersion{2, 1})); 425 } 426 } 427 428 TEST(ParseArchString, AcceptsUnderscoreSplittingExtensions) { 429 for (StringRef Input : {"rv32imafdczifencei", "rv32i_m_a_f_d_c_zifencei"}) { 430 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 431 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 432 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 433 EXPECT_EQ(Exts.size(), 8UL); 434 EXPECT_EQ(Exts.count("i"), 1U); 435 EXPECT_EQ(Exts.count("m"), 1U); 436 EXPECT_EQ(Exts.count("a"), 1U); 437 EXPECT_EQ(Exts.count("f"), 1U); 438 EXPECT_EQ(Exts.count("d"), 1U); 439 EXPECT_EQ(Exts.count("c"), 1U); 440 EXPECT_EQ(Exts.count("zicsr"), 1U); 441 EXPECT_EQ(Exts.count("zifencei"), 1U); 442 } 443 } 444 445 TEST(ParseArchString, AcceptsRelaxSingleLetterExtensions) { 446 for (StringRef Input : 447 {"rv32imfad", "rv32im_fa_d", "rv32im2p0fad", "rv32i2p1m2p0fad"}) { 448 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 449 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 450 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 451 EXPECT_EQ(Exts.size(), 6UL); 452 EXPECT_EQ(Exts.count("i"), 1U); 453 EXPECT_EQ(Exts.count("m"), 1U); 454 EXPECT_EQ(Exts.count("f"), 1U); 455 EXPECT_EQ(Exts.count("a"), 1U); 456 EXPECT_EQ(Exts.count("d"), 1U); 457 EXPECT_EQ(Exts.count("zicsr"), 1U); 458 } 459 } 460 461 TEST(ParseArchString, AcceptsRelaxMixedLetterExtensions) { 462 for (StringRef Input : 463 {"rv32i_zihintntl_m_a_f_d_svinval", "rv32izihintntl_mafdsvinval", 464 "rv32i_zihintntl_mafd_svinval"}) { 465 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 466 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 467 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 468 EXPECT_EQ(Exts.size(), 8UL); 469 EXPECT_EQ(Exts.count("i"), 1U); 470 EXPECT_EQ(Exts.count("m"), 1U); 471 EXPECT_EQ(Exts.count("a"), 1U); 472 EXPECT_EQ(Exts.count("f"), 1U); 473 EXPECT_EQ(Exts.count("d"), 1U); 474 EXPECT_EQ(Exts.count("zihintntl"), 1U); 475 EXPECT_EQ(Exts.count("svinval"), 1U); 476 EXPECT_EQ(Exts.count("zicsr"), 1U); 477 } 478 } 479 480 TEST(ParseArchString, AcceptsAmbiguousFromRelaxExtensions) { 481 for (StringRef Input : {"rv32i_zba_m", "rv32izba_m", "rv32izba1p0_m2p0"}) { 482 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 483 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 484 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 485 EXPECT_EQ(Exts.size(), 3UL); 486 EXPECT_EQ(Exts.count("i"), 1U); 487 EXPECT_EQ(Exts.count("zba"), 1U); 488 EXPECT_EQ(Exts.count("m"), 1U); 489 } 490 for (StringRef Input : 491 {"rv32ia_zba_m", "rv32iazba_m", "rv32ia2p1zba1p0_m2p0"}) { 492 auto MaybeISAInfo = RISCVISAInfo::parseArchString(Input, true); 493 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 494 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 495 EXPECT_EQ(Exts.size(), 4UL); 496 EXPECT_EQ(Exts.count("i"), 1U); 497 EXPECT_EQ(Exts.count("zba"), 1U); 498 EXPECT_EQ(Exts.count("m"), 1U); 499 EXPECT_EQ(Exts.count("a"), 1U); 500 } 501 } 502 503 TEST(ParseArchString, RejectsRelaxExtensionsNotStartWithEorIorG) { 504 EXPECT_EQ( 505 toString(RISCVISAInfo::parseArchString("rv32zba_im", true).takeError()), 506 "first letter after 'rv32' should be 'e', 'i' or 'g'"); 507 } 508 509 TEST(ParseArchString, 510 RejectsMultiLetterExtensionFollowBySingleLetterExtensions) { 511 for (StringRef Input : {"rv32izbam", "rv32i_zbam"}) 512 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 513 "unsupported standard user-level extension 'zbam'"); 514 EXPECT_EQ( 515 toString(RISCVISAInfo::parseArchString("rv32izbai_m", true).takeError()), 516 "unsupported standard user-level extension 'zbai'"); 517 EXPECT_EQ( 518 toString(RISCVISAInfo::parseArchString("rv32izbaim", true).takeError()), 519 "unsupported standard user-level extension 'zbaim'"); 520 EXPECT_EQ( 521 toString( 522 RISCVISAInfo::parseArchString("rv32i_zba1p0m", true).takeError()), 523 "unsupported standard user-level extension 'zba1p0m'"); 524 } 525 526 TEST(ParseArchString, RejectsDoubleOrTrailingUnderscore) { 527 EXPECT_EQ( 528 toString(RISCVISAInfo::parseArchString("rv64i__m", true).takeError()), 529 "extension name missing after separator '_'"); 530 531 for (StringRef Input : 532 {"rv32ezicsr__zifencei", "rv32i_", "rv32izicsr_", "rv64im_"}) { 533 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 534 "extension name missing after separator '_'"); 535 } 536 } 537 538 TEST(ParseArchString, RejectsDuplicateExtensionNames) { 539 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv64ii", true).takeError()), 540 "invalid standard user-level extension 'i'"); 541 EXPECT_EQ(toString(RISCVISAInfo::parseArchString("rv32ee", true).takeError()), 542 "invalid standard user-level extension 'e'"); 543 EXPECT_EQ( 544 toString(RISCVISAInfo::parseArchString("rv64imm", true).takeError()), 545 "duplicated standard user-level extension 'm'"); 546 EXPECT_EQ( 547 toString( 548 RISCVISAInfo::parseArchString("rv32i_zicsr_zicsr", true).takeError()), 549 "duplicated standard user-level extension 'zicsr'"); 550 } 551 552 TEST(ParseArchString, 553 RejectsExperimentalExtensionsIfNotEnableExperimentalExtension) { 554 EXPECT_EQ( 555 toString(RISCVISAInfo::parseArchString("rv64iztso", false).takeError()), 556 "requires '-menable-experimental-extensions' for experimental extension " 557 "'ztso'"); 558 } 559 560 TEST(ParseArchString, 561 AcceptsExperimentalExtensionsIfEnableExperimentalExtension) { 562 // Note: If ztso becomes none-experimental, this test will need 563 // updating (and unfortunately, it will still pass). The failure of 564 // RejectsExperimentalExtensionsIfNotEnableExperimentalExtension will 565 // hopefully serve as a reminder to update. 566 auto MaybeISAInfo = RISCVISAInfo::parseArchString("rv64iztso", true, false); 567 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 568 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 569 EXPECT_EQ(Exts.size(), 2UL); 570 EXPECT_EQ(Exts.count("ztso"), 1U); 571 auto MaybeISAInfo2 = RISCVISAInfo::parseArchString("rv64iztso0p1", true); 572 ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded()); 573 const auto &Exts2 = (*MaybeISAInfo2)->getExtensions(); 574 EXPECT_EQ(Exts2.size(), 2UL); 575 EXPECT_EQ(Exts2.count("ztso"), 1U); 576 } 577 578 TEST(ParseArchString, 579 RequiresExplicitVersionNumberForExperimentalExtensionByDefault) { 580 EXPECT_EQ( 581 toString(RISCVISAInfo::parseArchString("rv64iztso", true).takeError()), 582 "experimental extension requires explicit version number `ztso`"); 583 } 584 585 TEST(ParseArchString, 586 AcceptsUnrecognizedVersionIfNotExperimentalExtensionVersionCheck) { 587 auto MaybeISAInfo = 588 RISCVISAInfo::parseArchString("rv64iztso9p9", true, false); 589 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 590 const auto &Exts = (*MaybeISAInfo)->getExtensions(); 591 EXPECT_EQ(Exts.size(), 2UL); 592 EXPECT_TRUE(Exts.at("ztso") == (RISCVISAUtils::ExtensionVersion{9, 9})); 593 } 594 595 TEST(ParseArchString, RejectsUnrecognizedVersionForExperimentalExtension) { 596 EXPECT_EQ( 597 toString(RISCVISAInfo::parseArchString("rv64iztso9p9", true).takeError()), 598 "unsupported version number 9.9 for experimental extension 'ztso' " 599 "(this compiler supports 0.1)"); 600 } 601 602 TEST(ParseArchString, RejectsExtensionVersionForG) { 603 for (StringRef Input : {"rv32g1c", "rv64g2p0"}) { 604 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 605 "version not supported for 'g'"); 606 } 607 } 608 609 TEST(ParseArchString, AddsImpliedExtensions) { 610 // Does not attempt to exhaustively test all implications. 611 auto MaybeRV64ID = RISCVISAInfo::parseArchString("rv64id", true); 612 ASSERT_THAT_EXPECTED(MaybeRV64ID, Succeeded()); 613 const auto &ExtsRV64ID = (*MaybeRV64ID)->getExtensions(); 614 EXPECT_EQ(ExtsRV64ID.size(), 4UL); 615 EXPECT_EQ(ExtsRV64ID.count("i"), 1U); 616 EXPECT_EQ(ExtsRV64ID.count("f"), 1U); 617 EXPECT_EQ(ExtsRV64ID.count("d"), 1U); 618 EXPECT_EQ(ExtsRV64ID.count("zicsr"), 1U); 619 620 auto MaybeRV32IZKN = RISCVISAInfo::parseArchString("rv64izkn", true); 621 ASSERT_THAT_EXPECTED(MaybeRV32IZKN, Succeeded()); 622 const auto &ExtsRV32IZKN = (*MaybeRV32IZKN)->getExtensions(); 623 EXPECT_EQ(ExtsRV32IZKN.size(), 8UL); 624 EXPECT_EQ(ExtsRV32IZKN.count("i"), 1U); 625 EXPECT_EQ(ExtsRV32IZKN.count("zbkb"), 1U); 626 EXPECT_EQ(ExtsRV32IZKN.count("zbkc"), 1U); 627 EXPECT_EQ(ExtsRV32IZKN.count("zbkx"), 1U); 628 EXPECT_EQ(ExtsRV32IZKN.count("zkne"), 1U); 629 EXPECT_EQ(ExtsRV32IZKN.count("zknd"), 1U); 630 EXPECT_EQ(ExtsRV32IZKN.count("zknh"), 1U); 631 EXPECT_EQ(ExtsRV32IZKN.count("zkn"), 1U); 632 } 633 634 TEST(ParseArchString, RejectsConflictingExtensions) { 635 for (StringRef Input : {"rv32ifzfinx", "rv64gzdinx"}) { 636 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 637 "'f' and 'zfinx' extensions are incompatible"); 638 } 639 640 for (StringRef Input : {"rv32idc_zcmp1p0", "rv64idc_zcmp1p0"}) { 641 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 642 "'zcmp' extension is incompatible with 'c' extension when 'd' " 643 "extension is enabled"); 644 } 645 646 for (StringRef Input : {"rv32id_zcd1p0_zcmp1p0", "rv64id_zcd1p0_zcmp1p0"}) { 647 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 648 "'zcmp' extension is incompatible with 'zcd' extension when 'd' " 649 "extension is enabled"); 650 } 651 652 for (StringRef Input : {"rv32idc_zcmt1p0", "rv64idc_zcmt1p0"}) { 653 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 654 "'zcmt' extension is incompatible with 'c' extension when 'd' " 655 "extension is enabled"); 656 } 657 658 for (StringRef Input : {"rv32id_zcd1p0_zcmt1p0", "rv64id_zcd1p0_zcmt1p0"}) { 659 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 660 "'zcmt' extension is incompatible with 'zcd' extension when 'd' " 661 "extension is enabled"); 662 } 663 664 for (StringRef Input : {"rv64if_zcf"}) { 665 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 666 "'zcf' is only supported for 'rv32'"); 667 } 668 } 669 670 TEST(ParseArchString, RejectsUnrecognizedProfileNames) { 671 for (StringRef Input : {"rvi23u99", "rvz23u64", "rva99u32"}) { 672 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 673 "string must begin with rv32{i,e,g}, rv64{i,e,g}, or a supported " 674 "profile name"); 675 } 676 } 677 678 TEST(ParseArchString, RejectsProfilesWithUnseparatedExtraExtensions) { 679 for (StringRef Input : {"rvi20u32m", "rvi20u64c"}) { 680 EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()), 681 "additional extensions must be after separator '_'"); 682 } 683 } 684 685 TEST(ParseArchString, AcceptsBareProfileNames) { 686 auto MaybeRVA20U64 = RISCVISAInfo::parseArchString("rva20u64", true); 687 ASSERT_THAT_EXPECTED(MaybeRVA20U64, Succeeded()); 688 const auto &Exts = (*MaybeRVA20U64)->getExtensions(); 689 EXPECT_EQ(Exts.size(), 13UL); 690 EXPECT_EQ(Exts.count("i"), 1U); 691 EXPECT_EQ(Exts.count("m"), 1U); 692 EXPECT_EQ(Exts.count("f"), 1U); 693 EXPECT_EQ(Exts.count("a"), 1U); 694 EXPECT_EQ(Exts.count("d"), 1U); 695 EXPECT_EQ(Exts.count("c"), 1U); 696 EXPECT_EQ(Exts.count("za128rs"), 1U); 697 EXPECT_EQ(Exts.count("zicntr"), 1U); 698 EXPECT_EQ(Exts.count("ziccif"), 1U); 699 EXPECT_EQ(Exts.count("zicsr"), 1U); 700 EXPECT_EQ(Exts.count("ziccrse"), 1U); 701 EXPECT_EQ(Exts.count("ziccamoa"), 1U); 702 EXPECT_EQ(Exts.count("zicclsm"), 1U); 703 704 auto MaybeRVA23U64 = RISCVISAInfo::parseArchString("rva23u64", true); 705 ASSERT_THAT_EXPECTED(MaybeRVA23U64, Succeeded()); 706 EXPECT_GT((*MaybeRVA23U64)->getExtensions().size(), 13UL); 707 } 708 709 TEST(ParseArchSTring, AcceptsProfileNamesWithSeparatedAdditionalExtensions) { 710 auto MaybeRVI20U64 = RISCVISAInfo::parseArchString("rvi20u64_m_zba", true); 711 ASSERT_THAT_EXPECTED(MaybeRVI20U64, Succeeded()); 712 const auto &Exts = (*MaybeRVI20U64)->getExtensions(); 713 EXPECT_EQ(Exts.size(), 3UL); 714 EXPECT_EQ(Exts.count("i"), 1U); 715 EXPECT_EQ(Exts.count("m"), 1U); 716 EXPECT_EQ(Exts.count("zba"), 1U); 717 } 718 719 TEST(ParseArchString, 720 RejectsProfilesWithAdditionalExtensionsGivenAlreadyInProfile) { 721 // This test was added to document the current behaviour. Discussion isn't 722 // believed to have taken place about if this is desirable or not. 723 EXPECT_EQ( 724 toString( 725 RISCVISAInfo::parseArchString("rva20u64_zicntr", true).takeError()), 726 "duplicated standard user-level extension 'zicntr'"); 727 } 728 729 TEST(ParseArchString, 730 RejectsExperimentalProfilesIfEnableExperimentalExtensionsNotSet) { 731 EXPECT_EQ( 732 toString(RISCVISAInfo::parseArchString("rva23u64", false).takeError()), 733 "requires '-menable-experimental-extensions' for profile 'rva23u64'"); 734 } 735 736 TEST(ToFeatures, IIsDroppedAndExperimentalExtensionsArePrefixed) { 737 auto MaybeISAInfo1 = 738 RISCVISAInfo::parseArchString("rv64im_ztso", true, false); 739 ASSERT_THAT_EXPECTED(MaybeISAInfo1, Succeeded()); 740 EXPECT_THAT((*MaybeISAInfo1)->toFeatures(), 741 ElementsAre("+m", "+experimental-ztso")); 742 743 auto MaybeISAInfo2 = 744 RISCVISAInfo::parseArchString("rv32e_ztso_xventanacondops", true, false); 745 ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded()); 746 EXPECT_THAT((*MaybeISAInfo2)->toFeatures(), 747 ElementsAre("+e", "+experimental-ztso", "+xventanacondops")); 748 } 749 750 TEST(ToFeatures, UnsupportedExtensionsAreDropped) { 751 auto MaybeISAInfo = 752 RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0"); 753 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 754 EXPECT_THAT((*MaybeISAInfo)->toFeatures(), ElementsAre("+m")); 755 } 756 757 TEST(ToFeatures, UnsupportedExtensionsAreKeptIfIgnoreUnknownIsFalse) { 758 auto MaybeISAInfo = 759 RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0"); 760 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 761 EXPECT_THAT((*MaybeISAInfo)->toFeatures(false, false), 762 ElementsAre("+m", "+xmadeup")); 763 } 764 765 TEST(ToFeatures, AddAllExtensionsAddsNegativeExtensions) { 766 auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0"); 767 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 768 769 auto Features = (*MaybeISAInfo)->toFeatures(true); 770 EXPECT_GT(Features.size(), 1UL); 771 EXPECT_EQ(Features.front(), "+m"); 772 // Every feature after should be a negative feature 773 for (auto &NegativeExt : llvm::drop_begin(Features)) 774 EXPECT_TRUE(NegativeExt.substr(0, 1) == "-"); 775 } 776 777 TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) { 778 RISCVISAUtils::OrderedExtensionMap Exts; 779 for (auto ExtName : {"y", "l", "m", "c", "i", "xfoo", "xbar", "sfoo", "sbar", 780 "zmfoo", "zzfoo", "zfinx", "zicsr"}) 781 Exts[ExtName] = {1, 0}; 782 783 std::vector<std::string> ExtNames; 784 for (const auto &Ext : Exts) 785 ExtNames.push_back(Ext.first); 786 787 // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'. 788 EXPECT_THAT(ExtNames, 789 ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx", 790 "zzfoo", "sbar", "sfoo", "xbar", "xfoo")); 791 } 792 793 TEST(ParseArchString, ZceImplication) { 794 auto MaybeRV32IZce = RISCVISAInfo::parseArchString("rv32izce", true); 795 ASSERT_THAT_EXPECTED(MaybeRV32IZce, Succeeded()); 796 const auto &ExtsRV32IZce = (*MaybeRV32IZce)->getExtensions(); 797 EXPECT_EQ(ExtsRV32IZce.size(), 7UL); 798 EXPECT_EQ(ExtsRV32IZce.count("i"), 1U); 799 EXPECT_EQ(ExtsRV32IZce.count("zicsr"), 1U); 800 EXPECT_EQ(ExtsRV32IZce.count("zca"), 1U); 801 EXPECT_EQ(ExtsRV32IZce.count("zcb"), 1U); 802 EXPECT_EQ(ExtsRV32IZce.count("zce"), 1U); 803 EXPECT_EQ(ExtsRV32IZce.count("zcmp"), 1U); 804 EXPECT_EQ(ExtsRV32IZce.count("zcmt"), 1U); 805 806 auto MaybeRV32IFZce = RISCVISAInfo::parseArchString("rv32ifzce", true); 807 ASSERT_THAT_EXPECTED(MaybeRV32IFZce, Succeeded()); 808 const auto &ExtsRV32IFZce = (*MaybeRV32IFZce)->getExtensions(); 809 EXPECT_EQ(ExtsRV32IFZce.size(), 9UL); 810 EXPECT_EQ(ExtsRV32IFZce.count("i"), 1U); 811 EXPECT_EQ(ExtsRV32IFZce.count("zicsr"), 1U); 812 EXPECT_EQ(ExtsRV32IFZce.count("f"), 1U); 813 EXPECT_EQ(ExtsRV32IFZce.count("zca"), 1U); 814 EXPECT_EQ(ExtsRV32IFZce.count("zcb"), 1U); 815 EXPECT_EQ(ExtsRV32IFZce.count("zce"), 1U); 816 EXPECT_EQ(ExtsRV32IFZce.count("zcf"), 1U); 817 EXPECT_EQ(ExtsRV32IFZce.count("zcmp"), 1U); 818 EXPECT_EQ(ExtsRV32IFZce.count("zcmt"), 1U); 819 820 auto MaybeRV32IDZce = RISCVISAInfo::parseArchString("rv32idzce", true); 821 ASSERT_THAT_EXPECTED(MaybeRV32IDZce, Succeeded()); 822 const auto &ExtsRV32IDZce = (*MaybeRV32IDZce)->getExtensions(); 823 EXPECT_EQ(ExtsRV32IDZce.size(), 10UL); 824 EXPECT_EQ(ExtsRV32IDZce.count("i"), 1U); 825 EXPECT_EQ(ExtsRV32IDZce.count("zicsr"), 1U); 826 EXPECT_EQ(ExtsRV32IDZce.count("f"), 1U); 827 EXPECT_EQ(ExtsRV32IDZce.count("d"), 1U); 828 EXPECT_EQ(ExtsRV32IDZce.count("zca"), 1U); 829 EXPECT_EQ(ExtsRV32IDZce.count("zcb"), 1U); 830 EXPECT_EQ(ExtsRV32IDZce.count("zce"), 1U); 831 EXPECT_EQ(ExtsRV32IDZce.count("zcf"), 1U); 832 EXPECT_EQ(ExtsRV32IDZce.count("zcmp"), 1U); 833 EXPECT_EQ(ExtsRV32IDZce.count("zcmt"), 1U); 834 835 auto MaybeRV64IZce = RISCVISAInfo::parseArchString("rv64izce", true); 836 ASSERT_THAT_EXPECTED(MaybeRV64IZce, Succeeded()); 837 const auto &ExtsRV64IZce = (*MaybeRV64IZce)->getExtensions(); 838 EXPECT_EQ(ExtsRV64IZce.size(), 7UL); 839 EXPECT_EQ(ExtsRV64IZce.count("i"), 1U); 840 EXPECT_EQ(ExtsRV64IZce.count("zicsr"), 1U); 841 EXPECT_EQ(ExtsRV64IZce.count("zca"), 1U); 842 EXPECT_EQ(ExtsRV64IZce.count("zcb"), 1U); 843 EXPECT_EQ(ExtsRV64IZce.count("zce"), 1U); 844 EXPECT_EQ(ExtsRV64IZce.count("zcmp"), 1U); 845 EXPECT_EQ(ExtsRV64IZce.count("zcmt"), 1U); 846 847 auto MaybeRV64IFZce = RISCVISAInfo::parseArchString("rv64ifzce", true); 848 ASSERT_THAT_EXPECTED(MaybeRV64IFZce, Succeeded()); 849 const auto &ExtsRV64IFZce = (*MaybeRV64IFZce)->getExtensions(); 850 EXPECT_EQ(ExtsRV64IFZce.size(), 8UL); 851 EXPECT_EQ(ExtsRV64IFZce.count("i"), 1U); 852 EXPECT_EQ(ExtsRV64IFZce.count("zicsr"), 1U); 853 EXPECT_EQ(ExtsRV64IFZce.count("f"), 1U); 854 EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U); 855 EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U); 856 EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U); 857 EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U); 858 EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U); 859 860 EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U); 861 EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U); 862 EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U); 863 EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U); 864 EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U); 865 866 auto MaybeRV64IDZce = RISCVISAInfo::parseArchString("rv64idzce", true); 867 ASSERT_THAT_EXPECTED(MaybeRV64IDZce, Succeeded()); 868 const auto &ExtsRV64IDZce = (*MaybeRV64IDZce)->getExtensions(); 869 EXPECT_EQ(ExtsRV64IDZce.size(), 9UL); 870 EXPECT_EQ(ExtsRV64IDZce.count("i"), 1U); 871 EXPECT_EQ(ExtsRV64IDZce.count("zicsr"), 1U); 872 EXPECT_EQ(ExtsRV64IDZce.count("f"), 1U); 873 EXPECT_EQ(ExtsRV64IDZce.count("d"), 1U); 874 EXPECT_EQ(ExtsRV64IDZce.count("zca"), 1U); 875 EXPECT_EQ(ExtsRV64IDZce.count("zcb"), 1U); 876 EXPECT_EQ(ExtsRV64IDZce.count("zce"), 1U); 877 EXPECT_EQ(ExtsRV64IDZce.count("zcmp"), 1U); 878 EXPECT_EQ(ExtsRV64IDZce.count("zcmt"), 1U); 879 } 880 881 TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) { 882 EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0")); 883 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb")); 884 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0")); 885 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo")); 886 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("")); 887 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0")); 888 } 889 890 TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) { 891 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb"), "zbb"); 892 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso0p1"), 893 "experimental-ztso"); 894 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso"), 895 "experimental-ztso"); 896 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321"), 897 ""); 898 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo"), ""); 899 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), ""); 900 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), ""); 901 } 902 903 TEST(RiscvExtensionsHelp, CheckExtensions) { 904 // clang-format off 905 std::string ExpectedOutput = 906 R"(All available -march extensions for RISC-V 907 908 Name Version Description 909 i 2.1 This is a long dummy description 910 e 2.0 911 m 2.0 912 a 2.1 913 f 2.2 914 d 2.2 915 c 2.0 916 v 1.0 917 h 1.0 918 zic64b 1.0 919 zicbom 1.0 920 zicbop 1.0 921 zicboz 1.0 922 ziccamoa 1.0 923 ziccif 1.0 924 zicclsm 1.0 925 ziccrse 1.0 926 zicntr 2.0 927 zicond 1.0 928 zicsr 2.0 929 zifencei 2.0 930 zihintntl 1.0 931 zihintpause 2.0 932 zihpm 2.0 933 zimop 1.0 934 zmmul 1.0 935 za128rs 1.0 936 za64rs 1.0 937 zaamo 1.0 938 zacas 1.0 939 zalrsc 1.0 940 zama16b 1.0 941 zawrs 1.0 942 zfa 1.0 943 zfh 1.0 944 zfhmin 1.0 945 zfinx 1.0 946 zdinx 1.0 947 zca 1.0 948 zcb 1.0 949 zcd 1.0 950 zce 1.0 951 zcf 1.0 952 zcmop 1.0 953 zcmp 1.0 954 zcmt 1.0 955 zba 1.0 956 zbb 1.0 957 zbc 1.0 958 zbkb 1.0 959 zbkc 1.0 960 zbkx 1.0 961 zbs 1.0 962 zk 1.0 963 zkn 1.0 964 zknd 1.0 965 zkne 1.0 966 zknh 1.0 967 zkr 1.0 968 zks 1.0 969 zksed 1.0 970 zksh 1.0 971 zkt 1.0 972 zvbb 1.0 973 zvbc 1.0 974 zve32f 1.0 975 zve32x 1.0 976 zve64d 1.0 977 zve64f 1.0 978 zve64x 1.0 979 zvfh 1.0 980 zvfhmin 1.0 981 zvkb 1.0 982 zvkg 1.0 983 zvkn 1.0 984 zvknc 1.0 985 zvkned 1.0 986 zvkng 1.0 987 zvknha 1.0 988 zvknhb 1.0 989 zvks 1.0 990 zvksc 1.0 991 zvksed 1.0 992 zvksg 1.0 993 zvksh 1.0 994 zvkt 1.0 995 zvl1024b 1.0 996 zvl128b 1.0 997 zvl16384b 1.0 998 zvl2048b 1.0 999 zvl256b 1.0 1000 zvl32768b 1.0 1001 zvl32b 1.0 1002 zvl4096b 1.0 1003 zvl512b 1.0 1004 zvl64b 1.0 1005 zvl65536b 1.0 1006 zvl8192b 1.0 1007 zhinx 1.0 1008 zhinxmin 1.0 1009 shcounterenw 1.0 1010 shgatpa 1.0 1011 shtvala 1.0 1012 shvsatpa 1.0 1013 shvstvala 1.0 1014 shvstvecd 1.0 1015 smaia 1.0 1016 smepmp 1.0 1017 smstateen 1.0 1018 ssaia 1.0 1019 ssccptr 1.0 1020 sscofpmf 1.0 1021 sscounterenw 1.0 1022 ssstateen 1.0 1023 ssstrict 1.0 1024 sstc 1.0 1025 sstvala 1.0 1026 sstvecd 1.0 1027 ssu64xl 1.0 1028 svade 1.0 1029 svadu 1.0 1030 svbare 1.0 1031 svinval 1.0 1032 svnapot 1.0 1033 svpbmt 1.0 1034 xcvalu 1.0 1035 xcvbi 1.0 1036 xcvbitmanip 1.0 1037 xcvelw 1.0 1038 xcvmac 1.0 1039 xcvmem 1.0 1040 xcvsimd 1.0 1041 xsfcease 1.0 1042 xsfvcp 1.0 1043 xsfvfnrclipxfqf 1.0 1044 xsfvfwmaccqqq 1.0 1045 xsfvqmaccdod 1.0 1046 xsfvqmaccqoq 1.0 1047 xsifivecdiscarddlone 1.0 1048 xsifivecflushdlone 1.0 1049 xtheadba 1.0 1050 xtheadbb 1.0 1051 xtheadbs 1.0 1052 xtheadcmo 1.0 1053 xtheadcondmov 1.0 1054 xtheadfmemidx 1.0 1055 xtheadmac 1.0 1056 xtheadmemidx 1.0 1057 xtheadmempair 1.0 1058 xtheadsync 1.0 1059 xtheadvdot 1.0 1060 xventanacondops 1.0 1061 1062 Experimental extensions 1063 zicfilp 0.4 This is a long dummy description 1064 zicfiss 0.4 1065 zabha 1.0 1066 zalasr 0.1 1067 zfbfmin 1.0 1068 ztso 0.1 1069 zvfbfmin 1.0 1070 zvfbfwma 1.0 1071 smmpm 0.8 1072 smnpm 0.8 1073 ssnpm 0.8 1074 sspm 0.8 1075 ssqosid 1.0 1076 supm 0.8 1077 1078 Supported Profiles 1079 rva20s64 1080 rva20u64 1081 rva22s64 1082 rva22u64 1083 rvi20u32 1084 rvi20u64 1085 1086 Experimental Profiles 1087 rva23s64 1088 rva23u64 1089 rvb23s64 1090 rvb23u64 1091 rvm23u32 1092 1093 Use -march to specify the target's extension. 1094 For example, clang -march=rv32i_v1p0)"; 1095 // clang-format on 1096 1097 StringMap<StringRef> DummyMap; 1098 DummyMap["i"] = "This is a long dummy description"; 1099 DummyMap["experimental-zicfilp"] = "This is a long dummy description"; 1100 1101 outs().flush(); 1102 testing::internal::CaptureStdout(); 1103 riscvExtensionsHelp(DummyMap); 1104 outs().flush(); 1105 1106 std::string CapturedOutput = testing::internal::GetCapturedStdout(); 1107 EXPECT_TRUE([](std::string &Captured, std::string &Expected) { 1108 return Captured.find(Expected) != std::string::npos; 1109 }(CapturedOutput, ExpectedOutput)); 1110 } 1111