assembler_rv64i_tests.cpp
1 #include <catch/catch.hpp> 2 3 #include <array> 4 #include <biscuit/assembler.hpp> 5 6 #include "assembler_test_utils.hpp" 7 8 using namespace biscuit; 9 10 TEST_CASE("ADDIW", "[rv64i]") { 11 uint32_t value = 0; 12 auto as = MakeAssembler64(value); 13 14 as.ADDIW(x31, x15, 1024); 15 REQUIRE(value == 0x40078F9B); 16 17 as.RewindBuffer(); 18 19 as.ADDIW(x31, x15, 2048); 20 REQUIRE(value == 0x80078F9B); 21 22 as.RewindBuffer(); 23 24 as.ADDIW(x31, x15, 4095); 25 REQUIRE(value == 0xFFF78F9B); 26 } 27 28 TEST_CASE("ADDW", "[rv64i]") { 29 uint32_t value = 0; 30 auto as = MakeAssembler64(value); 31 32 as.ADDW(x7, x15, x31); 33 REQUIRE(value == 0x01F783BB); 34 35 as.RewindBuffer(); 36 37 as.ADDW(x31, x31, x31); 38 REQUIRE(value == 0x01FF8FBB); 39 40 as.RewindBuffer(); 41 42 as.ADDW(x0, x0, x0); 43 REQUIRE(value == 0x0000003B); 44 } 45 46 TEST_CASE("LWU", "[rv64i]") { 47 uint32_t value = 0; 48 auto as = MakeAssembler64(value); 49 50 as.LWU(x15, 1024, x31); 51 REQUIRE(value == 0x400FE783); 52 53 as.RewindBuffer(); 54 55 as.LWU(x15, 1536, x31); 56 REQUIRE(value == 0x600FE783); 57 58 as.RewindBuffer(); 59 60 as.LWU(x15, -1, x31); 61 REQUIRE(value == 0xFFFFE783); 62 } 63 64 TEST_CASE("LD", "[rv64i]") { 65 uint32_t value = 0; 66 auto as = MakeAssembler64(value); 67 68 as.LD(x15, 1024, x31); 69 REQUIRE(value == 0x400FB783); 70 71 as.RewindBuffer(); 72 73 as.LD(x15, 1536, x31); 74 REQUIRE(value == 0x600FB783); 75 76 as.RewindBuffer(); 77 78 as.LD(x15, -1, x31); 79 REQUIRE(value == 0xFFFFB783); 80 } 81 82 TEST_CASE("LI (RV64)", "[rv64i]") { 83 // Up to 8 instructions can be generated 84 std::array<uint32_t, 8> vals{}; 85 auto as = MakeAssembler64(vals); 86 87 const auto compare_vals = [&vals]<typename... Args>(const Args&... args) { 88 static_assert(sizeof...(args) <= vals.size()); 89 90 size_t i = 0; 91 for (const auto arg : {args...}) { 92 REQUIRE(vals[i] == arg); 93 i++; 94 } 95 }; 96 97 ///////// Single ADDIW cases 98 99 as.LI(x1, 0); 100 // addiw x1, x0, 0 101 compare_vals(0x0000009BU, 0x00000000U); 102 as.RewindBuffer(); 103 vals = {}; 104 105 as.LI(x1, -1); 106 // addiw x1, x0, -1 107 compare_vals(0xFFF0009BU, 0x00000000U); 108 as.RewindBuffer(); 109 vals = {}; 110 111 as.LI(x1, 42); 112 // addiw x1, x0, 42 113 compare_vals(0x02A0009BU, 0x000000000U); 114 as.RewindBuffer(); 115 vals = {}; 116 117 as.LI(x1, 0x7ff); 118 // addiw x1, x0, 2047 119 compare_vals(0x7FF0009BU, 0x00000000U); 120 as.RewindBuffer(); 121 vals = {}; 122 123 ///////// Single LUI cases 124 125 as.LI(x1, 0x2A000); 126 // lui x1, 42 127 compare_vals(0x0002A0B7U, 0x00000000U); 128 as.RewindBuffer(); 129 vals = {}; 130 131 as.LI(x1, ~0xFFF); 132 // lui x1, -1 133 compare_vals(0xFFFFF0B7U, 0x00000000U); 134 as.RewindBuffer(); 135 vals = {}; 136 137 as.LI(x1, INT32_MIN); 138 // lui x1, -524288 139 compare_vals(0x800000B7U, 0x00000000U); 140 as.RewindBuffer(); 141 vals = {}; 142 143 ///////// LUI+ADDIW cases 144 145 as.LI(x1, 0x11111111); 146 // lui x1, 69905 147 // addiw x1, x1, 273 148 compare_vals(0x111110B7U, 0x1110809BU, 0x00000000U); 149 as.RewindBuffer(); 150 vals = {}; 151 152 as.LI(x1, INT32_MAX); 153 // lui x1, -524288 154 // addiw x1, x1, -1 155 compare_vals(0x800000B7U, 0xFFF0809BU, 0x00000000U); 156 as.RewindBuffer(); 157 vals = {}; 158 159 ///////// ADDIW+SLLI cases 160 161 as.LI(x1, 0x7FF0000000ULL); 162 // addiw x1, x0, 2047 163 // slli x1, x1, 28 164 compare_vals(0x7FF0009BU, 0x01C09093U, 0x000000000U); 165 as.RewindBuffer(); 166 vals = {}; 167 168 as.LI(x1, 0xABC00000ULL); 169 // addiw x1, x0, 687 170 // slli x1, x1, 22 171 compare_vals(0x2AF0009BU, 0x01609093U, 0x000000000U); 172 as.RewindBuffer(); 173 vals = {}; 174 175 ///////// LUI+ADDIW+SLLI cases 176 177 as.LI(x1, 0x7FFFFFFF0000ULL); 178 // lui x1, -524288 179 // addiw x1, x1, -1 180 // slli x1, x1, 16 181 compare_vals(0x800000B7U, 0xFFF0809BU, 0x01009093U, 0x000000000U); 182 as.RewindBuffer(); 183 vals = {}; 184 185 ///////// LUI+ADDIW+SLLI+ADDI cases 186 187 as.LI(x1, 0x7FFFFFFF0123); 188 // lui x1, -524288 189 // addiw x1, x1, -1 190 // slli x1, x1, 16 191 // addi x1, x1, 291 192 compare_vals(0x800000B7U, 0xfff0809BU, 0x01009093U, 0x12308093U, 193 0x000000000U); 194 as.RewindBuffer(); 195 vals = {}; 196 197 ///////// ADDIW+SLLI+ADDI+SLLI+ADDI cases 198 199 as.LI(x1, 0x8000000080000001ULL); 200 // addiw x1, x0, -1 201 // slli x1, x1, 32 202 // addi x1, x1, 1 203 // slli x1, x1, 31 204 // addi x1, x1, 1 205 compare_vals(0xFFF0009BU, 0x02009093U, 0x00108093U, 0x01F09093U, 206 0x00108093U, 0x000000000U); 207 as.RewindBuffer(); 208 vals = {}; 209 210 ///////// Full LUI+ADDIW+SLLI+ADDI+SLLI+ADDI+SLLI+ADDI cases 211 212 as.LI(x1, 0x80808000808080F1ULL); 213 // lui x1, -16 214 // addiw x1, x1, 257 215 // slli x1, x1, 16 216 // addi x1, x1, 1 217 // slli x1, x1, 16 218 // addi x1, x1, 257 219 // slli x1, x1, 15 220 // addi x1, x1, 241 221 compare_vals(0xFFFF00B7U, 0x1010809BU, 0x01009093U, 0x00108093U, 222 0x01009093U, 0x10108093U, 0x00F09093U, 0x0F108093U); 223 } 224 225 TEST_CASE("SD", "[rv64i]") { 226 uint32_t value = 0; 227 auto as = MakeAssembler64(value); 228 229 as.SD(x15, 1024, x31); 230 REQUIRE(value == 0x40FFB023); 231 232 as.RewindBuffer(); 233 234 as.SD(x15, 1536, x31); 235 REQUIRE(value == 0x60FFB023); 236 237 as.RewindBuffer(); 238 239 as.SD(x15, -1, x31); 240 REQUIRE(value == 0xFEFFBFA3); 241 } 242 243 TEST_CASE("SLLI (RV64)", "[rv64i]") { 244 uint32_t value = 0; 245 auto as = MakeAssembler64(value); 246 247 as.SLLI(x31, x15, 10); 248 REQUIRE(value == 0x00A79F93); 249 250 as.RewindBuffer(); 251 252 as.SLLI(x31, x15, 20); 253 REQUIRE(value == 0x01479F93); 254 255 as.RewindBuffer(); 256 257 as.SLLI(x31, x15, 31); 258 REQUIRE(value == 0x01F79F93); 259 260 as.RewindBuffer(); 261 262 as.SLLI(x31, x15, 63); 263 REQUIRE(value == 0x03F79F93); 264 } 265 266 TEST_CASE("SLLIW", "[rv64i]") { 267 uint32_t value = 0; 268 auto as = MakeAssembler64(value); 269 270 as.SLLIW(x31, x15, 10); 271 REQUIRE(value == 0x00A79F9B); 272 273 as.RewindBuffer(); 274 275 as.SLLIW(x31, x15, 20); 276 REQUIRE(value == 0x01479F9B); 277 278 as.RewindBuffer(); 279 280 as.SLLIW(x31, x15, 31); 281 REQUIRE(value == 0x01F79F9B); 282 } 283 284 TEST_CASE("SLLW", "[rv64i]") { 285 uint32_t value = 0; 286 auto as = MakeAssembler64(value); 287 288 as.SLLW(x7, x15, x31); 289 REQUIRE(value == 0x01F793BB); 290 291 as.RewindBuffer(); 292 293 as.SLLW(x31, x31, x31); 294 REQUIRE(value == 0x01FF9FBB); 295 296 as.RewindBuffer(); 297 298 as.SLLW(x0, x0, x0); 299 REQUIRE(value == 0x0000103B); 300 } 301 302 TEST_CASE("SRAI (RV64)", "[rv64i]") { 303 uint32_t value = 0; 304 auto as = MakeAssembler64(value); 305 306 as.SRAI(x31, x15, 10); 307 REQUIRE(value == 0x40A7DF93); 308 309 as.RewindBuffer(); 310 311 as.SRAI(x31, x15, 20); 312 REQUIRE(value == 0x4147DF93); 313 314 as.RewindBuffer(); 315 316 as.SRAI(x31, x15, 31); 317 REQUIRE(value == 0x41F7DF93); 318 319 as.RewindBuffer(); 320 321 as.SRAI(x31, x15, 63); 322 REQUIRE(value == 0x43F7DF93); 323 } 324 325 TEST_CASE("SRAIW", "[rv64i]") { 326 uint32_t value = 0; 327 auto as = MakeAssembler64(value); 328 329 as.SRAIW(x31, x15, 10); 330 REQUIRE(value == 0x40A7DF9B); 331 332 as.RewindBuffer(); 333 334 as.SRAIW(x31, x15, 20); 335 REQUIRE(value == 0x4147DF9B); 336 337 as.RewindBuffer(); 338 339 as.SRAIW(x31, x15, 31); 340 REQUIRE(value == 0x41F7DF9B); 341 } 342 343 TEST_CASE("SRAW", "[rv64i]") { 344 uint32_t value = 0; 345 auto as = MakeAssembler64(value); 346 347 as.SRAW(x7, x15, x31); 348 REQUIRE(value == 0x41F7D3BB); 349 350 as.RewindBuffer(); 351 352 as.SRAW(x31, x31, x31); 353 REQUIRE(value == 0x41FFDFBB); 354 355 as.RewindBuffer(); 356 357 as.SRAW(x0, x0, x0); 358 REQUIRE(value == 0x4000503B); 359 } 360 361 TEST_CASE("SRLI (RV64)", "[rv64i]") { 362 uint32_t value = 0; 363 auto as = MakeAssembler64(value); 364 365 as.SRLI(x31, x15, 10); 366 REQUIRE(value == 0x00A7DF93); 367 368 as.RewindBuffer(); 369 370 as.SRLI(x31, x15, 20); 371 REQUIRE(value == 0x0147DF93); 372 373 as.RewindBuffer(); 374 375 as.SRLI(x31, x15, 31); 376 REQUIRE(value == 0x01F7DF93); 377 378 as.RewindBuffer(); 379 380 as.SRLI(x31, x15, 63); 381 REQUIRE(value == 0x03F7DF93); 382 } 383 384 TEST_CASE("SRLIW", "[rv64i]") { 385 uint32_t value = 0; 386 auto as = MakeAssembler64(value); 387 388 as.SRLIW(x31, x15, 10); 389 REQUIRE(value == 0x00A7DF9B); 390 391 as.RewindBuffer(); 392 393 as.SRLIW(x31, x15, 20); 394 REQUIRE(value == 0x0147DF9B); 395 396 as.RewindBuffer(); 397 398 as.SRLIW(x31, x15, 31); 399 REQUIRE(value == 0x01F7DF9B); 400 } 401 402 TEST_CASE("SRLW", "[rv64i]") { 403 uint32_t value = 0; 404 auto as = MakeAssembler64(value); 405 406 as.SRLW(x7, x15, x31); 407 REQUIRE(value == 0x01F7D3BB); 408 409 as.RewindBuffer(); 410 411 as.SRLW(x31, x31, x31); 412 REQUIRE(value == 0x01FFDFBB); 413 414 as.RewindBuffer(); 415 416 as.SRLW(x0, x0, x0); 417 REQUIRE(value == 0x0000503B); 418 } 419 420 TEST_CASE("SUBW", "[rv64i]") { 421 uint32_t value = 0; 422 auto as = MakeAssembler64(value); 423 424 as.SUBW(x7, x15, x31); 425 REQUIRE(value == 0x41F783BB); 426 427 as.RewindBuffer(); 428 429 as.SUBW(x31, x31, x31); 430 REQUIRE(value == 0x41FF8FBB); 431 432 as.RewindBuffer(); 433 434 as.SUBW(x0, x0, x0); 435 REQUIRE(value == 0x4000003B); 436 }