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