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