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(ToFeatures, IIsDroppedAndExperimentalExtensionsArePrefixed) { 730 auto MaybeISAInfo1 = 731 RISCVISAInfo::parseArchString("rv64im_ztso", true, false); 732 ASSERT_THAT_EXPECTED(MaybeISAInfo1, Succeeded()); 733 EXPECT_THAT((*MaybeISAInfo1)->toFeatures(), 734 ElementsAre("+m", "+experimental-ztso")); 735 736 auto MaybeISAInfo2 = 737 RISCVISAInfo::parseArchString("rv32e_ztso_xventanacondops", true, false); 738 ASSERT_THAT_EXPECTED(MaybeISAInfo2, Succeeded()); 739 EXPECT_THAT((*MaybeISAInfo2)->toFeatures(), 740 ElementsAre("+e", "+experimental-ztso", "+xventanacondops")); 741 } 742 743 TEST(ToFeatures, UnsupportedExtensionsAreDropped) { 744 auto MaybeISAInfo = 745 RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0"); 746 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 747 EXPECT_THAT((*MaybeISAInfo)->toFeatures(), ElementsAre("+m")); 748 } 749 750 TEST(ToFeatures, UnsupportedExtensionsAreKeptIfIgnoreUnknownIsFalse) { 751 auto MaybeISAInfo = 752 RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0_xmadeup1p0"); 753 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 754 EXPECT_THAT((*MaybeISAInfo)->toFeatures(false, false), 755 ElementsAre("+m", "+xmadeup")); 756 } 757 758 TEST(ToFeatures, AddAllExtensionsAddsNegativeExtensions) { 759 auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString("rv64i2p0_m2p0"); 760 ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded()); 761 762 auto Features = (*MaybeISAInfo)->toFeatures(true); 763 EXPECT_GT(Features.size(), 1UL); 764 EXPECT_EQ(Features.front(), "+m"); 765 // Every feature after should be a negative feature 766 for (auto &NegativeExt : llvm::drop_begin(Features)) 767 EXPECT_TRUE(NegativeExt.substr(0, 1) == "-"); 768 } 769 770 TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) { 771 RISCVISAUtils::OrderedExtensionMap Exts; 772 for (auto ExtName : {"y", "l", "m", "c", "i", "xfoo", "xbar", "sfoo", "sbar", 773 "zmfoo", "zzfoo", "zfinx", "zicsr"}) 774 Exts[ExtName] = {1, 0}; 775 776 std::vector<std::string> ExtNames; 777 for (const auto &Ext : Exts) 778 ExtNames.push_back(Ext.first); 779 780 // FIXME: 'l' and 'y' should be ordered after 'i', 'm', 'c'. 781 EXPECT_THAT(ExtNames, 782 ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx", 783 "zzfoo", "sbar", "sfoo", "xbar", "xfoo")); 784 } 785 786 TEST(ParseArchString, ZceImplication) { 787 auto MaybeRV32IZce = RISCVISAInfo::parseArchString("rv32izce", true); 788 ASSERT_THAT_EXPECTED(MaybeRV32IZce, Succeeded()); 789 const auto &ExtsRV32IZce = (*MaybeRV32IZce)->getExtensions(); 790 EXPECT_EQ(ExtsRV32IZce.size(), 7UL); 791 EXPECT_EQ(ExtsRV32IZce.count("i"), 1U); 792 EXPECT_EQ(ExtsRV32IZce.count("zicsr"), 1U); 793 EXPECT_EQ(ExtsRV32IZce.count("zca"), 1U); 794 EXPECT_EQ(ExtsRV32IZce.count("zcb"), 1U); 795 EXPECT_EQ(ExtsRV32IZce.count("zce"), 1U); 796 EXPECT_EQ(ExtsRV32IZce.count("zcmp"), 1U); 797 EXPECT_EQ(ExtsRV32IZce.count("zcmt"), 1U); 798 799 auto MaybeRV32IFZce = RISCVISAInfo::parseArchString("rv32ifzce", true); 800 ASSERT_THAT_EXPECTED(MaybeRV32IFZce, Succeeded()); 801 const auto &ExtsRV32IFZce = (*MaybeRV32IFZce)->getExtensions(); 802 EXPECT_EQ(ExtsRV32IFZce.size(), 9UL); 803 EXPECT_EQ(ExtsRV32IFZce.count("i"), 1U); 804 EXPECT_EQ(ExtsRV32IFZce.count("zicsr"), 1U); 805 EXPECT_EQ(ExtsRV32IFZce.count("f"), 1U); 806 EXPECT_EQ(ExtsRV32IFZce.count("zca"), 1U); 807 EXPECT_EQ(ExtsRV32IFZce.count("zcb"), 1U); 808 EXPECT_EQ(ExtsRV32IFZce.count("zce"), 1U); 809 EXPECT_EQ(ExtsRV32IFZce.count("zcf"), 1U); 810 EXPECT_EQ(ExtsRV32IFZce.count("zcmp"), 1U); 811 EXPECT_EQ(ExtsRV32IFZce.count("zcmt"), 1U); 812 813 auto MaybeRV32IDZce = RISCVISAInfo::parseArchString("rv32idzce", true); 814 ASSERT_THAT_EXPECTED(MaybeRV32IDZce, Succeeded()); 815 const auto &ExtsRV32IDZce = (*MaybeRV32IDZce)->getExtensions(); 816 EXPECT_EQ(ExtsRV32IDZce.size(), 10UL); 817 EXPECT_EQ(ExtsRV32IDZce.count("i"), 1U); 818 EXPECT_EQ(ExtsRV32IDZce.count("zicsr"), 1U); 819 EXPECT_EQ(ExtsRV32IDZce.count("f"), 1U); 820 EXPECT_EQ(ExtsRV32IDZce.count("d"), 1U); 821 EXPECT_EQ(ExtsRV32IDZce.count("zca"), 1U); 822 EXPECT_EQ(ExtsRV32IDZce.count("zcb"), 1U); 823 EXPECT_EQ(ExtsRV32IDZce.count("zce"), 1U); 824 EXPECT_EQ(ExtsRV32IDZce.count("zcf"), 1U); 825 EXPECT_EQ(ExtsRV32IDZce.count("zcmp"), 1U); 826 EXPECT_EQ(ExtsRV32IDZce.count("zcmt"), 1U); 827 828 auto MaybeRV64IZce = RISCVISAInfo::parseArchString("rv64izce", true); 829 ASSERT_THAT_EXPECTED(MaybeRV64IZce, Succeeded()); 830 const auto &ExtsRV64IZce = (*MaybeRV64IZce)->getExtensions(); 831 EXPECT_EQ(ExtsRV64IZce.size(), 7UL); 832 EXPECT_EQ(ExtsRV64IZce.count("i"), 1U); 833 EXPECT_EQ(ExtsRV64IZce.count("zicsr"), 1U); 834 EXPECT_EQ(ExtsRV64IZce.count("zca"), 1U); 835 EXPECT_EQ(ExtsRV64IZce.count("zcb"), 1U); 836 EXPECT_EQ(ExtsRV64IZce.count("zce"), 1U); 837 EXPECT_EQ(ExtsRV64IZce.count("zcmp"), 1U); 838 EXPECT_EQ(ExtsRV64IZce.count("zcmt"), 1U); 839 840 auto MaybeRV64IFZce = RISCVISAInfo::parseArchString("rv64ifzce", true); 841 ASSERT_THAT_EXPECTED(MaybeRV64IFZce, Succeeded()); 842 const auto &ExtsRV64IFZce = (*MaybeRV64IFZce)->getExtensions(); 843 EXPECT_EQ(ExtsRV64IFZce.size(), 8UL); 844 EXPECT_EQ(ExtsRV64IFZce.count("i"), 1U); 845 EXPECT_EQ(ExtsRV64IFZce.count("zicsr"), 1U); 846 EXPECT_EQ(ExtsRV64IFZce.count("f"), 1U); 847 EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U); 848 EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U); 849 EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U); 850 EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U); 851 EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U); 852 853 EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U); 854 EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U); 855 EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U); 856 EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U); 857 EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U); 858 859 auto MaybeRV64IDZce = RISCVISAInfo::parseArchString("rv64idzce", true); 860 ASSERT_THAT_EXPECTED(MaybeRV64IDZce, Succeeded()); 861 const auto &ExtsRV64IDZce = (*MaybeRV64IDZce)->getExtensions(); 862 EXPECT_EQ(ExtsRV64IDZce.size(), 9UL); 863 EXPECT_EQ(ExtsRV64IDZce.count("i"), 1U); 864 EXPECT_EQ(ExtsRV64IDZce.count("zicsr"), 1U); 865 EXPECT_EQ(ExtsRV64IDZce.count("f"), 1U); 866 EXPECT_EQ(ExtsRV64IDZce.count("d"), 1U); 867 EXPECT_EQ(ExtsRV64IDZce.count("zca"), 1U); 868 EXPECT_EQ(ExtsRV64IDZce.count("zcb"), 1U); 869 EXPECT_EQ(ExtsRV64IDZce.count("zce"), 1U); 870 EXPECT_EQ(ExtsRV64IDZce.count("zcmp"), 1U); 871 EXPECT_EQ(ExtsRV64IDZce.count("zcmt"), 1U); 872 } 873 874 TEST(isSupportedExtensionWithVersion, AcceptsSingleExtensionWithVersion) { 875 EXPECT_TRUE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb1p0")); 876 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zbb")); 877 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo1p0")); 878 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("zfoo")); 879 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("")); 880 EXPECT_FALSE(RISCVISAInfo::isSupportedExtensionWithVersion("c2p0zbb1p0")); 881 } 882 883 TEST(getTargetFeatureForExtension, RetrieveTargetFeatureFromOneExt) { 884 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbb"), "zbb"); 885 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso0p1"), 886 "experimental-ztso"); 887 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("ztso"), 888 "experimental-ztso"); 889 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zihintntl1234p4321"), 890 ""); 891 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zfoo"), ""); 892 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension(""), ""); 893 EXPECT_EQ(RISCVISAInfo::getTargetFeatureForExtension("zbbzihintntl"), ""); 894 } 895 896 TEST(RiscvExtensionsHelp, CheckExtensions) { 897 // clang-format off 898 std::string ExpectedOutput = 899 R"(All available -march extensions for RISC-V 900 901 Name Version Description 902 i 2.1 This is a long dummy description 903 e 2.0 904 m 2.0 905 a 2.1 906 f 2.2 907 d 2.2 908 c 2.0 909 v 1.0 910 h 1.0 911 zic64b 1.0 912 zicbom 1.0 913 zicbop 1.0 914 zicboz 1.0 915 ziccamoa 1.0 916 ziccif 1.0 917 zicclsm 1.0 918 ziccrse 1.0 919 zicntr 2.0 920 zicond 1.0 921 zicsr 2.0 922 zifencei 2.0 923 zihintntl 1.0 924 zihintpause 2.0 925 zihpm 2.0 926 zimop 1.0 927 zmmul 1.0 928 za128rs 1.0 929 za64rs 1.0 930 zacas 1.0 931 zama16b 1.0 932 zawrs 1.0 933 zfa 1.0 934 zfh 1.0 935 zfhmin 1.0 936 zfinx 1.0 937 zdinx 1.0 938 zca 1.0 939 zcb 1.0 940 zcd 1.0 941 zce 1.0 942 zcf 1.0 943 zcmop 1.0 944 zcmp 1.0 945 zcmt 1.0 946 zba 1.0 947 zbb 1.0 948 zbc 1.0 949 zbkb 1.0 950 zbkc 1.0 951 zbkx 1.0 952 zbs 1.0 953 zk 1.0 954 zkn 1.0 955 zknd 1.0 956 zkne 1.0 957 zknh 1.0 958 zkr 1.0 959 zks 1.0 960 zksed 1.0 961 zksh 1.0 962 zkt 1.0 963 zvbb 1.0 964 zvbc 1.0 965 zve32f 1.0 966 zve32x 1.0 967 zve64d 1.0 968 zve64f 1.0 969 zve64x 1.0 970 zvfh 1.0 971 zvfhmin 1.0 972 zvkb 1.0 973 zvkg 1.0 974 zvkn 1.0 975 zvknc 1.0 976 zvkned 1.0 977 zvkng 1.0 978 zvknha 1.0 979 zvknhb 1.0 980 zvks 1.0 981 zvksc 1.0 982 zvksed 1.0 983 zvksg 1.0 984 zvksh 1.0 985 zvkt 1.0 986 zvl1024b 1.0 987 zvl128b 1.0 988 zvl16384b 1.0 989 zvl2048b 1.0 990 zvl256b 1.0 991 zvl32768b 1.0 992 zvl32b 1.0 993 zvl4096b 1.0 994 zvl512b 1.0 995 zvl64b 1.0 996 zvl65536b 1.0 997 zvl8192b 1.0 998 zhinx 1.0 999 zhinxmin 1.0 1000 shcounterenw 1.0 1001 shgatpa 1.0 1002 shtvala 1.0 1003 shvsatpa 1.0 1004 shvstvala 1.0 1005 shvstvecd 1.0 1006 smaia 1.0 1007 smepmp 1.0 1008 smstateen 1.0 1009 ssaia 1.0 1010 ssccptr 1.0 1011 sscofpmf 1.0 1012 sscounterenw 1.0 1013 ssstateen 1.0 1014 ssstrict 1.0 1015 sstc 1.0 1016 sstvala 1.0 1017 sstvecd 1.0 1018 ssu64xl 1.0 1019 svade 1.0 1020 svadu 1.0 1021 svbare 1.0 1022 svinval 1.0 1023 svnapot 1.0 1024 svpbmt 1.0 1025 xcvalu 1.0 1026 xcvbi 1.0 1027 xcvbitmanip 1.0 1028 xcvelw 1.0 1029 xcvmac 1.0 1030 xcvmem 1.0 1031 xcvsimd 1.0 1032 xsfcease 1.0 1033 xsfvcp 1.0 1034 xsfvfnrclipxfqf 1.0 1035 xsfvfwmaccqqq 1.0 1036 xsfvqmaccdod 1.0 1037 xsfvqmaccqoq 1.0 1038 xsifivecdiscarddlone 1.0 1039 xsifivecflushdlone 1.0 1040 xtheadba 1.0 1041 xtheadbb 1.0 1042 xtheadbs 1.0 1043 xtheadcmo 1.0 1044 xtheadcondmov 1.0 1045 xtheadfmemidx 1.0 1046 xtheadmac 1.0 1047 xtheadmemidx 1.0 1048 xtheadmempair 1.0 1049 xtheadsync 1.0 1050 xtheadvdot 1.0 1051 xventanacondops 1.0 1052 1053 Experimental extensions 1054 zicfilp 0.4 This is a long dummy description 1055 zicfiss 0.4 1056 zaamo 0.2 1057 zabha 1.0 1058 zalasr 0.1 1059 zalrsc 0.2 1060 zfbfmin 1.0 1061 ztso 0.1 1062 zvfbfmin 1.0 1063 zvfbfwma 1.0 1064 smmpm 0.8 1065 smnpm 0.8 1066 ssnpm 0.8 1067 sspm 0.8 1068 ssqosid 1.0 1069 supm 0.8 1070 1071 Supported Profiles 1072 rva20s64 1073 rva20u64 1074 rva22s64 1075 rva22u64 1076 rva23s64 1077 rva23u64 1078 rvb23s64 1079 rvb23u64 1080 rvi20u32 1081 rvi20u64 1082 rvm23u32 1083 1084 Use -march to specify the target's extension. 1085 For example, clang -march=rv32i_v1p0)"; 1086 // clang-format on 1087 1088 StringMap<StringRef> DummyMap; 1089 DummyMap["i"] = "This is a long dummy description"; 1090 DummyMap["experimental-zicfilp"] = "This is a long dummy description"; 1091 1092 outs().flush(); 1093 testing::internal::CaptureStdout(); 1094 riscvExtensionsHelp(DummyMap); 1095 outs().flush(); 1096 1097 std::string CapturedOutput = testing::internal::GetCapturedStdout(); 1098 EXPECT_TRUE([](std::string &Captured, std::string &Expected) { 1099 return Captured.find(Expected) != std::string::npos; 1100 }(CapturedOutput, ExpectedOutput)); 1101 } 1102