test_macros.h (29581B)
1 // See LICENSE for license details. 2 3 #ifndef __TEST_MACROS_SCALAR_H 4 #define __TEST_MACROS_SCALAR_H 5 6 7 #----------------------------------------------------------------------- 8 # Helper macros 9 #----------------------------------------------------------------------- 10 11 #define MASK_XLEN(x) ((x) & ((1 << (__riscv_xlen - 1) << 1) - 1)) 12 13 #define TEST_CASE( testnum, testreg, correctval, code... ) \ 14 test_ ## testnum: \ 15 li TESTNUM, testnum; \ 16 code; \ 17 li x7, MASK_XLEN(correctval); \ 18 bne testreg, x7, fail; 19 20 # We use a macro hack to simpify code generation for various numbers 21 # of bubble cycles. 22 23 #define TEST_INSERT_NOPS_0 24 #define TEST_INSERT_NOPS_1 nop; TEST_INSERT_NOPS_0 25 #define TEST_INSERT_NOPS_2 nop; TEST_INSERT_NOPS_1 26 #define TEST_INSERT_NOPS_3 nop; TEST_INSERT_NOPS_2 27 #define TEST_INSERT_NOPS_4 nop; TEST_INSERT_NOPS_3 28 #define TEST_INSERT_NOPS_5 nop; TEST_INSERT_NOPS_4 29 #define TEST_INSERT_NOPS_6 nop; TEST_INSERT_NOPS_5 30 #define TEST_INSERT_NOPS_7 nop; TEST_INSERT_NOPS_6 31 #define TEST_INSERT_NOPS_8 nop; TEST_INSERT_NOPS_7 32 #define TEST_INSERT_NOPS_9 nop; TEST_INSERT_NOPS_8 33 #define TEST_INSERT_NOPS_10 nop; TEST_INSERT_NOPS_9 34 35 #if __riscv_xlen == 64 36 #define LOAD_PTR ld 37 #define STORE_PTR sd 38 #else 39 #define LOAD_PTR lw 40 #define STORE_PTR sw 41 #endif 42 43 #----------------------------------------------------------------------- 44 # RV64UI MACROS 45 #----------------------------------------------------------------------- 46 47 #----------------------------------------------------------------------- 48 # Tests for instructions with immediate operand 49 #----------------------------------------------------------------------- 50 51 #define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11)) 52 53 #define TEST_IMM_OP( testnum, inst, result, val1, imm ) \ 54 TEST_CASE( testnum, x14, result, \ 55 li x13, MASK_XLEN(val1); \ 56 inst x14, x13, SEXT_IMM(imm); \ 57 ) 58 59 #define TEST_IMM_OP_VXSAT( testnum, inst, result, val1, imm, expected_vxsat ) \ 60 TEST_CASE( testnum, x14, result, \ 61 TEST_VXSAT_CLEAR; \ 62 li x13, MASK_XLEN(val1); \ 63 inst x14, x13, SEXT_IMM(imm); \ 64 ) \ 65 TEST_VXSAT_CHECK( expected_vxsat ) 66 67 # RV32 P-extension register-pair immediate-op tests. 68 # rs1 pair = {x13, x12} (even base), rd pair = {x15, x14}. 69 # Both halves of result are checked; on mismatch we jump to the same fail 70 # label as TEST_CASE, so the reported testnum matches. 71 #define TEST_IMM_OP_PAIR( testnum, inst, result, val1, imm ) \ 72 TEST_CASE( testnum, x14, ((result) & 0xFFFFFFFF), \ 73 li x12, ((val1) & 0xFFFFFFFF); \ 74 li x13, (((val1) >> 32) & 0xFFFFFFFF); \ 75 inst x14, x12, SEXT_IMM(imm); \ 76 ) \ 77 li x7, (((result) >> 32) & 0xFFFFFFFF); \ 78 bne x15, x7, fail; 79 80 #define TEST_IMM_SRC1_EQ_DEST( testnum, inst, result, val1, imm ) \ 81 TEST_CASE( testnum, x11, result, \ 82 li x11, MASK_XLEN(val1); \ 83 inst x11, x11, SEXT_IMM(imm); \ 84 ) 85 86 #define TEST_IMM_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \ 87 TEST_CASE( testnum, x6, result, \ 88 li x4, 0; \ 89 1: li x1, MASK_XLEN(val1); \ 90 inst x14, x1, SEXT_IMM(imm); \ 91 TEST_INSERT_NOPS_ ## nop_cycles \ 92 addi x6, x14, 0; \ 93 addi x4, x4, 1; \ 94 li x5, 2; \ 95 bne x4, x5, 1b \ 96 ) 97 98 #define TEST_IMM_SRC1_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \ 99 TEST_CASE( testnum, x14, result, \ 100 li x4, 0; \ 101 1: li x1, MASK_XLEN(val1); \ 102 TEST_INSERT_NOPS_ ## nop_cycles \ 103 inst x14, x1, SEXT_IMM(imm); \ 104 addi x4, x4, 1; \ 105 li x5, 2; \ 106 bne x4, x5, 1b \ 107 ) 108 109 #define TEST_IMM_ZEROSRC1( testnum, inst, result, imm ) \ 110 TEST_CASE( testnum, x1, result, \ 111 inst x1, x0, SEXT_IMM(imm); \ 112 ) 113 114 #define TEST_IMM_ZERODEST( testnum, inst, val1, imm ) \ 115 TEST_CASE( testnum, x0, 0, \ 116 li x1, MASK_XLEN(val1); \ 117 inst x0, x1, SEXT_IMM(imm); \ 118 ) 119 120 #----------------------------------------------------------------------- 121 # Tests for an instruction with register operands 122 #----------------------------------------------------------------------- 123 124 #define TEST_R_OP( testnum, inst, result, val1 ) \ 125 TEST_CASE( testnum, x14, result, \ 126 li x1, val1; \ 127 inst x14, x1; \ 128 ) 129 130 # P-extension vxsat helpers. 131 # vxsat is a sticky CSR (0x009): set to 1 whenever an instruction saturates, 132 # never auto-cleared. To verify it deterministically per test we clear it 133 # before the instruction and check the expected post-value after. 134 # Using the literal CSR address keeps these macros toolchain-independent. 135 #define VXSAT_CSR 0x009 136 #define TEST_VXSAT_CLEAR csrwi VXSAT_CSR, 0 137 #define TEST_VXSAT_CHECK( expected_vxsat ) \ 138 csrr x6, VXSAT_CSR; \ 139 li x7, (expected_vxsat); \ 140 bne x6, x7, fail; 141 142 #define TEST_R_OP_VXSAT( testnum, inst, result, val1, expected_vxsat ) \ 143 TEST_CASE( testnum, x14, result, \ 144 TEST_VXSAT_CLEAR; \ 145 li x1, val1; \ 146 inst x14, x1; \ 147 ) \ 148 TEST_VXSAT_CHECK( expected_vxsat ) 149 150 #define TEST_R_SRC1_EQ_DEST( testnum, inst, result, val1 ) \ 151 TEST_CASE( testnum, x1, result, \ 152 li x1, val1; \ 153 inst x1, x1; \ 154 ) 155 156 #define TEST_R_DEST_BYPASS( testnum, nop_cycles, inst, result, val1 ) \ 157 TEST_CASE( testnum, x6, result, \ 158 li x4, 0; \ 159 1: li x1, val1; \ 160 inst x14, x1; \ 161 TEST_INSERT_NOPS_ ## nop_cycles \ 162 addi x6, x14, 0; \ 163 addi x4, x4, 1; \ 164 li x5, 2; \ 165 bne x4, x5, 1b \ 166 ) 167 168 #----------------------------------------------------------------------- 169 # Tests for an instruction with register-register operands 170 #----------------------------------------------------------------------- 171 172 #define TEST_RR_OP( testnum, inst, result, val1, val2 ) \ 173 TEST_CASE( testnum, x14, result, \ 174 li x11, MASK_XLEN(val1); \ 175 li x12, MASK_XLEN(val2); \ 176 inst x14, x11, x12; \ 177 ) 178 179 #define TEST_RR_OP_VXSAT( testnum, inst, result, val1, val2, expected_vxsat ) \ 180 TEST_CASE( testnum, x14, result, \ 181 TEST_VXSAT_CLEAR; \ 182 li x11, MASK_XLEN(val1); \ 183 li x12, MASK_XLEN(val2); \ 184 inst x14, x11, x12; \ 185 ) \ 186 TEST_VXSAT_CHECK( expected_vxsat ) 187 188 # RV32 P-extension register-pair register-register tests. 189 # rs1 pair = {x13, x12} (even base), rd pair = {x15, x14}, rs2 = x11. 190 # Both halves of result are checked; on mismatch we jump to the same fail 191 # label as TEST_CASE, so the reported testnum matches. 192 #define TEST_RR_OP_PAIR( testnum, inst, result, val1, val2 ) \ 193 TEST_CASE( testnum, x14, ((result) & 0xFFFFFFFF), \ 194 li x12, ((val1) & 0xFFFFFFFF); \ 195 li x13, (((val1) >> 32) & 0xFFFFFFFF); \ 196 li x11, MASK_XLEN(val2); \ 197 inst x14, x12, x11; \ 198 ) \ 199 li x7, (((result) >> 32) & 0xFFFFFFFF); \ 200 bne x15, x7, fail; 201 202 #define TEST_RR_SRC1_EQ_DEST( testnum, inst, result, val1, val2 ) \ 203 TEST_CASE( testnum, x11, result, \ 204 li x11, MASK_XLEN(val1); \ 205 li x12, MASK_XLEN(val2); \ 206 inst x11, x11, x12; \ 207 ) 208 209 #define TEST_RR_SRC2_EQ_DEST( testnum, inst, result, val1, val2 ) \ 210 TEST_CASE( testnum, x12, result, \ 211 li x11, MASK_XLEN(val1); \ 212 li x12, MASK_XLEN(val2); \ 213 inst x12, x11, x12; \ 214 ) 215 216 #define TEST_RR_SRC12_EQ_DEST( testnum, inst, result, val1 ) \ 217 TEST_CASE( testnum, x11, result, \ 218 li x11, MASK_XLEN(val1); \ 219 inst x11, x11, x11; \ 220 ) 221 222 #define TEST_RR_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, val2 ) \ 223 TEST_CASE( testnum, x6, result, \ 224 li x4, 0; \ 225 1: li x1, MASK_XLEN(val1); \ 226 li x2, MASK_XLEN(val2); \ 227 inst x14, x1, x2; \ 228 TEST_INSERT_NOPS_ ## nop_cycles \ 229 addi x6, x14, 0; \ 230 addi x4, x4, 1; \ 231 li x5, 2; \ 232 bne x4, x5, 1b \ 233 ) 234 235 #define TEST_RR_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \ 236 TEST_CASE( testnum, x14, result, \ 237 li x4, 0; \ 238 1: li x1, MASK_XLEN(val1); \ 239 TEST_INSERT_NOPS_ ## src1_nops \ 240 li x2, MASK_XLEN(val2); \ 241 TEST_INSERT_NOPS_ ## src2_nops \ 242 inst x14, x1, x2; \ 243 addi x4, x4, 1; \ 244 li x5, 2; \ 245 bne x4, x5, 1b \ 246 ) 247 248 #define TEST_RR_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \ 249 TEST_CASE( testnum, x14, result, \ 250 li x4, 0; \ 251 1: li x2, MASK_XLEN(val2); \ 252 TEST_INSERT_NOPS_ ## src1_nops \ 253 li x1, MASK_XLEN(val1); \ 254 TEST_INSERT_NOPS_ ## src2_nops \ 255 inst x14, x1, x2; \ 256 addi x4, x4, 1; \ 257 li x5, 2; \ 258 bne x4, x5, 1b \ 259 ) 260 261 #define TEST_RR_ZEROSRC1( testnum, inst, result, val ) \ 262 TEST_CASE( testnum, x2, result, \ 263 li x1, MASK_XLEN(val); \ 264 inst x2, x0, x1; \ 265 ) 266 267 #define TEST_RR_ZEROSRC2( testnum, inst, result, val ) \ 268 TEST_CASE( testnum, x2, result, \ 269 li x1, MASK_XLEN(val); \ 270 inst x2, x1, x0; \ 271 ) 272 273 #define TEST_RR_ZEROSRC12( testnum, inst, result ) \ 274 TEST_CASE( testnum, x1, result, \ 275 inst x1, x0, x0; \ 276 ) 277 278 #define TEST_RR_ZERODEST( testnum, inst, val1, val2 ) \ 279 TEST_CASE( testnum, x0, 0, \ 280 li x1, MASK_XLEN(val1); \ 281 li x2, MASK_XLEN(val2); \ 282 inst x0, x1, x2; \ 283 ) 284 285 #----------------------------------------------------------------------- 286 # Test memory instructions 287 #----------------------------------------------------------------------- 288 289 #define TEST_LD_OP( testnum, inst, result, offset, base ) \ 290 TEST_CASE( testnum, x14, result, \ 291 li x15, result; /* Tell the exception handler the expected result. */ \ 292 la x2, base; \ 293 inst x14, offset(x2); \ 294 ) 295 296 #define TEST_ST_OP( testnum, load_inst, store_inst, result, offset, base ) \ 297 TEST_CASE( testnum, x14, result, \ 298 la x2, base; \ 299 li x1, result; \ 300 la x15, 7f; /* Tell the exception handler how to skip this test. */ \ 301 store_inst x1, offset(x2); \ 302 load_inst x14, offset(x2); \ 303 j 8f; \ 304 7: \ 305 /* Set up the correct result for TEST_CASE(). */ \ 306 mv x14, x1; \ 307 8: \ 308 ) 309 310 #define TEST_LD_DEST_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \ 311 test_ ## testnum: \ 312 li TESTNUM, testnum; \ 313 li x4, 0; \ 314 1: la x13, base; \ 315 inst x14, offset(x13); \ 316 TEST_INSERT_NOPS_ ## nop_cycles \ 317 addi x6, x14, 0; \ 318 li x7, result; \ 319 bne x6, x7, fail; \ 320 addi x4, x4, 1; \ 321 li x5, 2; \ 322 bne x4, x5, 1b; \ 323 324 #define TEST_LD_SRC1_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \ 325 test_ ## testnum: \ 326 li TESTNUM, testnum; \ 327 li x4, 0; \ 328 1: la x13, base; \ 329 TEST_INSERT_NOPS_ ## nop_cycles \ 330 inst x14, offset(x13); \ 331 li x7, result; \ 332 bne x14, x7, fail; \ 333 addi x4, x4, 1; \ 334 li x5, 2; \ 335 bne x4, x5, 1b \ 336 337 #define TEST_ST_SRC12_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \ 338 test_ ## testnum: \ 339 li TESTNUM, testnum; \ 340 li x4, 0; \ 341 1: li x13, result; \ 342 TEST_INSERT_NOPS_ ## src1_nops \ 343 la x12, base; \ 344 TEST_INSERT_NOPS_ ## src2_nops \ 345 store_inst x13, offset(x12); \ 346 load_inst x14, offset(x12); \ 347 li x7, result; \ 348 bne x14, x7, fail; \ 349 addi x4, x4, 1; \ 350 li x5, 2; \ 351 bne x4, x5, 1b \ 352 353 #define TEST_ST_SRC21_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \ 354 test_ ## testnum: \ 355 li TESTNUM, testnum; \ 356 li x4, 0; \ 357 1: la x2, base; \ 358 TEST_INSERT_NOPS_ ## src1_nops \ 359 li x1, result; \ 360 TEST_INSERT_NOPS_ ## src2_nops \ 361 store_inst x1, offset(x2); \ 362 load_inst x14, offset(x2); \ 363 li x7, result; \ 364 bne x14, x7, fail; \ 365 addi x4, x4, 1; \ 366 li x5, 2; \ 367 bne x4, x5, 1b \ 368 369 #define TEST_LD_ST_BYPASS(testnum, load_inst, store_inst, result, offset, base) \ 370 test_ ## testnum: \ 371 li TESTNUM, testnum; \ 372 la x2, base; \ 373 li x1, result; \ 374 store_inst x1, offset(x2); \ 375 load_inst x14, offset(x2); \ 376 store_inst x14, offset(x2); \ 377 load_inst x2, offset(x2); \ 378 li x7, result; \ 379 bne x2, x7, fail; \ 380 la x2, base; \ 381 STORE_PTR x2,8(x2); \ 382 LOAD_PTR x4,8(x2); \ 383 store_inst x1, offset(x4); \ 384 bne x4, x2, fail; \ 385 load_inst x14, offset(x4); \ 386 bne x14, x7, fail; \ 387 388 #define TEST_ST_LD_BYPASS(testnum, load_inst, store_inst, result, offset, base) \ 389 test_ ## testnum: \ 390 li TESTNUM, testnum; \ 391 la x2, base; \ 392 li x1, result; \ 393 store_inst x1, offset(x2); \ 394 load_inst x14, offset(x2); \ 395 li x7, result; \ 396 bne x14, x7, fail; \ 397 398 #define TEST_BR2_OP_TAKEN(testnum, inst, val1, val2 ) \ 399 test_ ## testnum: \ 400 li TESTNUM, testnum; \ 401 li x1, val1; \ 402 li x2, val2; \ 403 inst x1, x2, 2f; \ 404 bne x0, TESTNUM, fail; \ 405 1: bne x0, TESTNUM, 3f; \ 406 2: inst x1, x2, 1b; \ 407 bne x0, TESTNUM, fail; \ 408 3: 409 410 #define TEST_BR2_OP_NOTTAKEN( testnum, inst, val1, val2 ) \ 411 test_ ## testnum: \ 412 li TESTNUM, testnum; \ 413 li x1, val1; \ 414 li x2, val2; \ 415 inst x1, x2, 1f; \ 416 bne x0, TESTNUM, 2f; \ 417 1: bne x0, TESTNUM, fail; \ 418 2: inst x1, x2, 1b; \ 419 3: 420 421 #define TEST_BR2_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \ 422 test_ ## testnum: \ 423 li TESTNUM, testnum; \ 424 li x4, 0; \ 425 1: li x1, val1; \ 426 TEST_INSERT_NOPS_ ## src1_nops \ 427 li x2, val2; \ 428 TEST_INSERT_NOPS_ ## src2_nops \ 429 inst x1, x2, fail; \ 430 addi x4, x4, 1; \ 431 li x5, 2; \ 432 bne x4, x5, 1b \ 433 434 #define TEST_BR2_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \ 435 test_ ## testnum: \ 436 li TESTNUM, testnum; \ 437 li x4, 0; \ 438 1: li x2, val2; \ 439 TEST_INSERT_NOPS_ ## src1_nops \ 440 li x1, val1; \ 441 TEST_INSERT_NOPS_ ## src2_nops \ 442 inst x1, x2, fail; \ 443 addi x4, x4, 1; \ 444 li x5, 2; \ 445 bne x4, x5, 1b \ 446 447 #----------------------------------------------------------------------- 448 # Test jump instructions 449 #----------------------------------------------------------------------- 450 451 #define TEST_JR_SRC1_BYPASS( testnum, nop_cycles, inst ) \ 452 test_ ## testnum: \ 453 li TESTNUM, testnum; \ 454 li x4, 0; \ 455 1: la x6, 2f; \ 456 TEST_INSERT_NOPS_ ## nop_cycles \ 457 inst x6; \ 458 bne x0, TESTNUM, fail; \ 459 2: addi x4, x4, 1; \ 460 li x5, 2; \ 461 bne x4, x5, 1b \ 462 463 #define TEST_JALR_SRC1_BYPASS( testnum, nop_cycles, inst ) \ 464 test_ ## testnum: \ 465 li TESTNUM, testnum; \ 466 li x4, 0; \ 467 1: la x6, 2f; \ 468 TEST_INSERT_NOPS_ ## nop_cycles \ 469 inst x13, x6, 0; \ 470 bne x0, TESTNUM, fail; \ 471 2: addi x4, x4, 1; \ 472 li x5, 2; \ 473 bne x4, x5, 1b \ 474 475 476 #----------------------------------------------------------------------- 477 # RV64UF MACROS 478 #----------------------------------------------------------------------- 479 480 #----------------------------------------------------------------------- 481 # Tests floating-point instructions 482 #----------------------------------------------------------------------- 483 484 # 16-bit half precision (float16) 485 #define qNaNh 0x7e00 486 #define sNaNh 0x7c01 487 #define Infh 0x7c00 488 #define nInfh 0xfc00 489 490 # 32-bit single precision (float) 491 #define qNaNf 0x7fc00000 492 #define sNaNf 0x7f800001 493 #define Inff 0x7f800000 494 #define nInff 0xff800000 495 496 # 64-bit double precision (double) 497 #define qNaNd 0x7ff8000000000000 498 #define sNaNd 0x7ff0000000000001 499 #define Infd 0x7ff0000000000000 500 #define nInfd 0xfff0000000000000 501 502 #define TEST_FP_OP_H_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \ 503 test_ ## testnum: \ 504 li TESTNUM, testnum; \ 505 la a0, test_ ## testnum ## _data ;\ 506 flh f10, 0(a0); \ 507 flh f11, 2(a0); \ 508 flh f12, 4(a0); \ 509 lh a3, 6(a0); \ 510 code; \ 511 fsflags a1, x0; \ 512 li a2, flags; \ 513 bne a0, a3, fail; \ 514 bne a1, a2, fail; \ 515 .pushsection .data; \ 516 .align 1; \ 517 test_ ## testnum ## _data: \ 518 .val1; \ 519 .val2; \ 520 .val3; \ 521 .result; \ 522 .popsection 523 524 #define TEST_FP_OP_S_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \ 525 test_ ## testnum: \ 526 li TESTNUM, testnum; \ 527 la a0, test_ ## testnum ## _data ;\ 528 flw f10, 0(a0); \ 529 flw f11, 4(a0); \ 530 flw f12, 8(a0); \ 531 lw a3, 12(a0); \ 532 code; \ 533 fsflags a1, x0; \ 534 li a2, flags; \ 535 bne a0, a3, fail; \ 536 bne a1, a2, fail; \ 537 .pushsection .data; \ 538 .align 2; \ 539 test_ ## testnum ## _data: \ 540 .val1; \ 541 .val2; \ 542 .val3; \ 543 .result; \ 544 .popsection 545 546 #define TEST_FP_OP_D_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \ 547 test_ ## testnum: \ 548 li TESTNUM, testnum; \ 549 la a0, test_ ## testnum ## _data ;\ 550 fld f10, 0(a0); \ 551 fld f11, 8(a0); \ 552 fld f12, 16(a0); \ 553 ld a3, 24(a0); \ 554 code; \ 555 fsflags a1, x0; \ 556 li a2, flags; \ 557 bne a0, a3, fail; \ 558 bne a1, a2, fail; \ 559 .pushsection .data; \ 560 .align 3; \ 561 test_ ## testnum ## _data: \ 562 .val1; \ 563 .val2; \ 564 .val3; \ 565 .result; \ 566 .popsection 567 568 // TODO: assign a separate mem location for the comparison address? 569 #define TEST_FP_OP_D32_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \ 570 test_ ## testnum: \ 571 li TESTNUM, testnum; \ 572 la a0, test_ ## testnum ## _data ;\ 573 fld f10, 0(a0); \ 574 fld f11, 8(a0); \ 575 fld f12, 16(a0); \ 576 lw a3, 24(a0); \ 577 lw t1, 28(a0); \ 578 code; \ 579 fsflags a1, x0; \ 580 li a2, flags; \ 581 bne a0, a3, fail; \ 582 bne t1, t2, fail; \ 583 bne a1, a2, fail; \ 584 .pushsection .data; \ 585 .align 3; \ 586 test_ ## testnum ## _data: \ 587 .val1; \ 588 .val2; \ 589 .val3; \ 590 .result; \ 591 .popsection 592 593 #define TEST_FCVT_S_D32( testnum, result, val1 ) \ 594 TEST_FP_OP_D32_INTERNAL( testnum, 0, double result, double val1, double 0, double 0, \ 595 fcvt.s.d f13, f10; fcvt.d.s f13, f13; fsd f13, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 596 597 #define TEST_FCVT_S_D( testnum, result, val1 ) \ 598 TEST_FP_OP_D_INTERNAL( testnum, 0, double result, double val1, double 0, double 0, \ 599 fcvt.s.d f13, f10; fcvt.d.s f13, f13; fmv.x.d a0, f13) 600 601 #define TEST_FCVT_D_S( testnum, result, val1 ) \ 602 TEST_FP_OP_S_INTERNAL( testnum, 0, float result, float val1, float 0, float 0, \ 603 fcvt.d.s f13, f10; fcvt.s.d f13, f13; fmv.x.s a0, f13) 604 605 #define TEST_FCVT_H_S( testnum, result, val1 ) \ 606 TEST_FP_OP_H_INTERNAL( testnum, 0, float16 result, float16 val1, float16 0, float16 0, \ 607 fcvt.s.h f13, f10; fcvt.h.s f13, f13; fmv.x.h a0, f13) 608 609 #define TEST_FCVT_H_D( testnum, result, val1 ) \ 610 TEST_FP_OP_H_INTERNAL( testnum, 0, float16 result, float16 val1, float16 0, float16 0, \ 611 fcvt.d.h f13, f10; fcvt.h.d f13, f13; fmv.x.h a0, f13) 612 613 614 #define TEST_FP_OP1_H( testnum, inst, flags, result, val1 ) \ 615 TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, float16 val1, float16 0, float16 0, \ 616 inst f13, f10; fmv.x.h a0, f13;) 617 618 #define TEST_FP_OP1_S( testnum, inst, flags, result, val1 ) \ 619 TEST_FP_OP_S_INTERNAL( testnum, flags, float result, float val1, float 0, float 0, \ 620 inst f13, f10; fmv.x.s a0, f13) 621 622 #define TEST_FP_OP1_D32( testnum, inst, flags, result, val1 ) \ 623 TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, double val1, double 0, double 0, \ 624 inst f13, f10; fsd f13, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 625 // ^: store computation result in address from a0, load high-word into t2 626 627 #define TEST_FP_OP1_D( testnum, inst, flags, result, val1 ) \ 628 TEST_FP_OP_D_INTERNAL( testnum, flags, double result, double val1, double 0, double 0, \ 629 inst f13, f10; fmv.x.d a0, f13) 630 631 #define TEST_FP_OP1_S_DWORD_RESULT( testnum, inst, flags, result, val1 ) \ 632 TEST_FP_OP_S_INTERNAL( testnum, flags, dword result, float val1, float 0, float 0, \ 633 inst f13, f10; fmv.x.s a0, f13) 634 635 #define TEST_FP_OP1_H_DWORD_RESULT( testnum, inst, flags, result, val1 ) \ 636 TEST_FP_OP_H_INTERNAL( testnum, flags, word result, float16 val1, float16 0, float16 0, \ 637 inst f13, f10; fmv.x.h a0, f13) 638 639 #define TEST_FP_OP1_D32_DWORD_RESULT( testnum, inst, flags, result, val1 ) \ 640 TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, double val1, double 0, double 0, \ 641 inst f13, f10; fsd f13, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 642 // ^: store computation result in address from a0, load high-word into t2 643 644 #define TEST_FP_OP1_D_DWORD_RESULT( testnum, inst, flags, result, val1 ) \ 645 TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, double val1, double 0, double 0, \ 646 inst f13, f10; fmv.x.d a0, f13) 647 648 #define TEST_FP_OP2_S( testnum, inst, flags, result, val1, val2 ) \ 649 TEST_FP_OP_S_INTERNAL( testnum, flags, float result, float val1, float val2, float 0, \ 650 inst f13, f10, f11; fmv.x.s a0, f13) 651 652 #define TEST_FP_OP2_S_HEX( testnum, inst, flags, result, val1, val2 ) \ 653 TEST_FP_OP_S_INTERNAL( testnum, flags, word result, word val1, word val2, float 0, \ 654 inst f13, f10, f11; fmv.x.s a0, f13) 655 656 #define TEST_FP_OP2_H( testnum, inst, flags, result, val1, val2 ) \ 657 TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, float16 val1, float16 val2, float16 0, \ 658 inst f13, f10, f11; fmv.x.h a0, f13) 659 660 #define TEST_FP_OP2_H_HEX( testnum, inst, flags, result, val1, val2 ) \ 661 TEST_FP_OP_H_INTERNAL( testnum, flags, half result, half val1, half val2, float16 0, \ 662 inst f13, f10, f11; fmv.x.h a0, f13) 663 664 #define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \ 665 TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, double val1, double val2, double 0, \ 666 inst f13, f10, f11; fsd f13, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 667 // ^: store computation result in address from a0, load high-word into t2 668 669 #define TEST_FP_OP2_D32_HEX( testnum, inst, flags, result, val1, val2 ) \ 670 TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, dword val1, dword val2, double 0, \ 671 inst f13, f10, f11; fsd f13, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 672 673 #define TEST_FP_OP2_D( testnum, inst, flags, result, val1, val2 ) \ 674 TEST_FP_OP_D_INTERNAL( testnum, flags, double result, double val1, double val2, double 0, \ 675 inst f13, f10, f11; fmv.x.d a0, f13) 676 677 #define TEST_FP_OP2_D_HEX( testnum, inst, flags, result, val1, val2 ) \ 678 TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, dword val1, dword val2, double 0, \ 679 inst f13, f10, f11; fmv.x.d a0, f13) 680 681 #define TEST_FP_OP3_S( testnum, inst, flags, result, val1, val2, val3 ) \ 682 TEST_FP_OP_S_INTERNAL( testnum, flags, float result, float val1, float val2, float val3, \ 683 inst f13, f10, f11, f12; fmv.x.s a0, f13) 684 685 #define TEST_FP_OP3_H( testnum, inst, flags, result, val1, val2, val3 ) \ 686 TEST_FP_OP_H_INTERNAL( testnum, flags, float16 result, float16 val1, float16 val2, float16 val3, \ 687 inst f13, f10, f11, f12; fmv.x.h a0, f13) 688 689 #define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \ 690 TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, double val1, double val2, double val3, \ 691 inst f13, f10, f11, f12; fsd f13, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 692 // ^: store computation result in address from a0, load high-word into t2 693 694 #define TEST_FP_OP3_D( testnum, inst, flags, result, val1, val2, val3 ) \ 695 TEST_FP_OP_D_INTERNAL( testnum, flags, double result, double val1, double val2, double val3, \ 696 inst f13, f10, f11, f12; fmv.x.d a0, f13) 697 698 #define TEST_FP_INT_OP_S( testnum, inst, flags, result, val1, rm ) \ 699 TEST_FP_OP_S_INTERNAL( testnum, flags, word result, float val1, float 0, float 0, \ 700 inst a0, f10, rm) 701 702 #define TEST_FP_INT_OP_H( testnum, inst, flags, result, val1, rm ) \ 703 TEST_FP_OP_H_INTERNAL( testnum, flags, word result, float16 val1, float16 0, float16 0, \ 704 inst a0, f10, rm) 705 706 #define TEST_FP_INT_OP_D32( testnum, inst, flags, result, val1, rm ) \ 707 TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, double val1, double 0, double 0, \ 708 inst a0, f10, rm; li t2, ((result) << 32 >> 63) * -1) 709 710 /* #define TEST_FP_INT_OP_D( testnum, inst, flags, result, val1, rm ) \ 711 TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, double val1, double 0, double 0, \ 712 inst a0, f10, rm) */ 713 714 #define TEST_FP_CMP_OP_S( testnum, inst, flags, result, val1, val2 ) \ 715 TEST_FP_OP_S_INTERNAL( testnum, flags, word result, float val1, float val2, float 0, \ 716 inst a0, f10, f11) 717 718 #define TEST_FP_CMP_OP_S_HEX( testnum, inst, flags, result, val1, val2 ) \ 719 TEST_FP_OP_S_INTERNAL( testnum, flags, word result, word val1, word val2, float 0, \ 720 inst a0, f10, f11) 721 722 #define TEST_FP_CMP_OP_H( testnum, inst, flags, result, val1, val2 ) \ 723 TEST_FP_OP_H_INTERNAL( testnum, flags, hword result, float16 val1, float16 val2, float16 0, \ 724 inst a0, f10, f11) 725 726 #define TEST_FP_CMP_OP_H_HEX( testnum, inst, flags, result, val1, val2 ) \ 727 TEST_FP_OP_H_INTERNAL( testnum, flags, hword result, half val1, half val2, float16 0, \ 728 inst a0, f10, f11) 729 730 #define TEST_FP_CMP_OP_D32( testnum, inst, flags, result, val1, val2 ) \ 731 TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, double val1, double val2, double 0, \ 732 inst a0, f10, f11; li t2, 0) 733 734 #define TEST_FP_CMP_OP_D32_HEX( testnum, inst, flags, result, val1, val2 ) \ 735 TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, dword val1, dword val2, double 0, \ 736 inst a0, f10, f11; li t2, 0) 737 738 #define TEST_FP_CMP_OP_D( testnum, inst, flags, result, val1, val2 ) \ 739 TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, double val1, double val2, double 0, \ 740 inst a0, f10, f11) 741 742 #define TEST_FP_CMP_OP_D_HEX( testnum, inst, flags, result, val1, val2 ) \ 743 TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, dword val1, dword val2, double 0, \ 744 inst a0, f10, f11) 745 746 #define TEST_FCLASS_S(testnum, correct, input) \ 747 TEST_CASE(testnum, a0, correct, li a0, input; fmv.s.x f10, a0; \ 748 fclass.s a0, f10) 749 750 #define TEST_FCLASS_D32(testnum, correct, input) \ 751 TEST_CASE(testnum, a0, correct, \ 752 la a0, test_ ## testnum ## _data ;\ 753 fld f10, 0(a0); \ 754 fclass.d a0, f10) \ 755 .pushsection .data; \ 756 .align 3; \ 757 test_ ## testnum ## _data: \ 758 .dword input; \ 759 .popsection 760 761 #define TEST_FCLASS_D(testnum, correct, input) \ 762 TEST_CASE(testnum, a0, correct, li a0, input; fmv.d.x f10, a0; \ 763 fclass.d a0, f10) 764 765 #define TEST_INT_FP_OP_S( testnum, inst, result, val1 ) \ 766 test_ ## testnum: \ 767 li TESTNUM, testnum; \ 768 la a0, test_ ## testnum ## _data ;\ 769 lw a3, 0(a0); \ 770 li a0, val1; \ 771 inst f10, a0; \ 772 fsflags x0; \ 773 fmv.x.s a0, f10; \ 774 bne a0, a3, fail; \ 775 .pushsection .data; \ 776 .align 2; \ 777 test_ ## testnum ## _data: \ 778 .float result; \ 779 .popsection 780 781 #define TEST_INT_FP_OP_H( testnum, inst, result, val1 ) \ 782 test_ ## testnum: \ 783 li TESTNUM, testnum; \ 784 la a0, test_ ## testnum ## _data ;\ 785 lh a3, 0(a0); \ 786 li a0, val1; \ 787 inst f10, a0; \ 788 fsflags x0; \ 789 fmv.x.h a0, f10; \ 790 bne a0, a3, fail; \ 791 .pushsection .data; \ 792 .align 1; \ 793 test_ ## testnum ## _data: \ 794 .float16 result; \ 795 .popsection 796 797 #define TEST_INT_FP_OP_D32( testnum, inst, result, val1 ) \ 798 test_ ## testnum: \ 799 li TESTNUM, testnum; \ 800 la a0, test_ ## testnum ## _data ;\ 801 lw a3, 0(a0); \ 802 lw a4, 4(a0); \ 803 li a1, val1; \ 804 inst f10, a1; \ 805 \ 806 fsd f10, 0(a0); \ 807 lw a1, 4(a0); \ 808 lw a0, 0(a0); \ 809 \ 810 fsflags x0; \ 811 bne a0, a3, fail; \ 812 bne a1, a4, fail; \ 813 .pushsection .data; \ 814 .align 3; \ 815 test_ ## testnum ## _data: \ 816 .double result; \ 817 .popsection 818 819 #define TEST_INT_FP_OP_D( testnum, inst, result, val1 ) \ 820 test_ ## testnum: \ 821 li TESTNUM, testnum; \ 822 la a0, test_ ## testnum ## _data ;\ 823 ld a3, 0(a0); \ 824 li a0, val1; \ 825 inst f10, a0; \ 826 fsflags x0; \ 827 fmv.x.d a0, f10; \ 828 bne a0, a3, fail; \ 829 .pushsection .data; \ 830 .align 3; \ 831 test_ ## testnum ## _data: \ 832 .double result; \ 833 .popsection 834 835 // We need some special handling here to allow 64-bit comparison in 32-bit arch 836 // TODO: find a better name and clean up when intended for general usage? 837 #define TEST_CASE_D32( testnum, testreg1, testreg2, correctval, code... ) \ 838 test_ ## testnum: \ 839 code; \ 840 la x15, test_ ## testnum ## _data ; \ 841 lw x7, 0(x15); \ 842 lw x15, 4(x15); \ 843 li TESTNUM, testnum; \ 844 bne testreg1, x7, fail;\ 845 bne testreg2, x15, fail;\ 846 .pushsection .data; \ 847 .align 3; \ 848 test_ ## testnum ## _data: \ 849 .dword correctval; \ 850 .popsection 851 852 // ^ x14 is used in some other macros, to avoid issues we use x15 for upper word 853 854 #define MISALIGNED_LOAD_HANDLER \ 855 li t0, CAUSE_MISALIGNED_LOAD; \ 856 csrr t1, mcause; \ 857 bne t0, t1, fail; \ 858 \ 859 /* We got a misaligned exception. Pretend we handled it in software */ \ 860 /* by loading the correct result here. */ \ 861 mv a4, a5; \ 862 \ 863 /* And skip this instruction */ \ 864 csrr t0, mepc; \ 865 addi t0, t0, 4; \ 866 csrw mepc, t0; \ 867 mret 868 869 #define MISALIGNED_STORE_HANDLER \ 870 li t0, CAUSE_MISALIGNED_STORE; \ 871 csrr t1, mcause; \ 872 bne t0, t1, fail; \ 873 \ 874 /* We got a misaligned exception. Skip this test. */ \ 875 csrw mepc, x15; \ 876 mret 877 878 #----------------------------------------------------------------------- 879 # Pass and fail code (assumes test num is in TESTNUM) 880 #----------------------------------------------------------------------- 881 882 #define TEST_PASSFAIL \ 883 bne x0, TESTNUM, pass; \ 884 fail: \ 885 RVTEST_FAIL; \ 886 pass: \ 887 RVTEST_PASS \ 888 889 890 #----------------------------------------------------------------------- 891 # Test data section 892 #----------------------------------------------------------------------- 893 894 #define TEST_DATA 895 896 #endif