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