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