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... ) \ 14test_ ## testnum: \ 15 code; \ 16 li x29, MASK_XLEN(correctval); \ 17 li TESTNUM, testnum; \ 18 bne testreg, x29, 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 36#----------------------------------------------------------------------- 37# RV64UI MACROS 38#----------------------------------------------------------------------- 39 40#----------------------------------------------------------------------- 41# Tests for instructions with immediate operand 42#----------------------------------------------------------------------- 43 44#define SEXT_IMM(x) ((x) | (-(((x) >> 11) & 1) << 11)) 45 46#define TEST_IMM_OP( testnum, inst, result, val1, imm ) \ 47 TEST_CASE( testnum, x30, result, \ 48 li x1, MASK_XLEN(val1); \ 49 inst x30, x1, SEXT_IMM(imm); \ 50 ) 51 52#define TEST_IMM_SRC1_EQ_DEST( testnum, inst, result, val1, imm ) \ 53 TEST_CASE( testnum, x1, result, \ 54 li x1, MASK_XLEN(val1); \ 55 inst x1, x1, SEXT_IMM(imm); \ 56 ) 57 58#define TEST_IMM_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \ 59 TEST_CASE( testnum, x6, result, \ 60 li x4, 0; \ 611: li x1, MASK_XLEN(val1); \ 62 inst x30, x1, SEXT_IMM(imm); \ 63 TEST_INSERT_NOPS_ ## nop_cycles \ 64 addi x6, x30, 0; \ 65 addi x4, x4, 1; \ 66 li x5, 2; \ 67 bne x4, x5, 1b \ 68 ) 69 70#define TEST_IMM_SRC1_BYPASS( testnum, nop_cycles, inst, result, val1, imm ) \ 71 TEST_CASE( testnum, x30, result, \ 72 li x4, 0; \ 731: li x1, MASK_XLEN(val1); \ 74 TEST_INSERT_NOPS_ ## nop_cycles \ 75 inst x30, x1, SEXT_IMM(imm); \ 76 addi x4, x4, 1; \ 77 li x5, 2; \ 78 bne x4, x5, 1b \ 79 ) 80 81#define TEST_IMM_ZEROSRC1( testnum, inst, result, imm ) \ 82 TEST_CASE( testnum, x1, result, \ 83 inst x1, x0, SEXT_IMM(imm); \ 84 ) 85 86#define TEST_IMM_ZERODEST( testnum, inst, val1, imm ) \ 87 TEST_CASE( testnum, x0, 0, \ 88 li x1, MASK_XLEN(val1); \ 89 inst x0, x1, SEXT_IMM(imm); \ 90 ) 91 92#----------------------------------------------------------------------- 93# Tests for an instruction with register operands 94#----------------------------------------------------------------------- 95 96#define TEST_R_OP( testnum, inst, result, val1 ) \ 97 TEST_CASE( testnum, x30, result, \ 98 li x1, val1; \ 99 inst x30, x1; \ 100 ) 101 102#define TEST_R_SRC1_EQ_DEST( testnum, inst, result, val1 ) \ 103 TEST_CASE( testnum, x1, result, \ 104 li x1, val1; \ 105 inst x1, x1; \ 106 ) 107 108#define TEST_R_DEST_BYPASS( testnum, nop_cycles, inst, result, val1 ) \ 109 TEST_CASE( testnum, x6, result, \ 110 li x4, 0; \ 1111: li x1, val1; \ 112 inst x30, x1; \ 113 TEST_INSERT_NOPS_ ## nop_cycles \ 114 addi x6, x30, 0; \ 115 addi x4, x4, 1; \ 116 li x5, 2; \ 117 bne x4, x5, 1b \ 118 ) 119 120#----------------------------------------------------------------------- 121# Tests for an instruction with register-register operands 122#----------------------------------------------------------------------- 123 124#define TEST_RR_OP( testnum, inst, result, val1, val2 ) \ 125 TEST_CASE( testnum, x30, result, \ 126 li x1, MASK_XLEN(val1); \ 127 li x2, MASK_XLEN(val2); \ 128 inst x30, x1, x2; \ 129 ) 130 131#define TEST_RR_SRC1_EQ_DEST( testnum, inst, result, val1, val2 ) \ 132 TEST_CASE( testnum, x1, result, \ 133 li x1, MASK_XLEN(val1); \ 134 li x2, MASK_XLEN(val2); \ 135 inst x1, x1, x2; \ 136 ) 137 138#define TEST_RR_SRC2_EQ_DEST( testnum, inst, result, val1, val2 ) \ 139 TEST_CASE( testnum, x2, result, \ 140 li x1, MASK_XLEN(val1); \ 141 li x2, MASK_XLEN(val2); \ 142 inst x2, x1, x2; \ 143 ) 144 145#define TEST_RR_SRC12_EQ_DEST( testnum, inst, result, val1 ) \ 146 TEST_CASE( testnum, x1, result, \ 147 li x1, MASK_XLEN(val1); \ 148 inst x1, x1, x1; \ 149 ) 150 151#define TEST_RR_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, val2 ) \ 152 TEST_CASE( testnum, x6, result, \ 153 li x4, 0; \ 1541: li x1, MASK_XLEN(val1); \ 155 li x2, MASK_XLEN(val2); \ 156 inst x30, x1, x2; \ 157 TEST_INSERT_NOPS_ ## nop_cycles \ 158 addi x6, x30, 0; \ 159 addi x4, x4, 1; \ 160 li x5, 2; \ 161 bne x4, x5, 1b \ 162 ) 163 164#define TEST_RR_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \ 165 TEST_CASE( testnum, x30, result, \ 166 li x4, 0; \ 1671: li x1, MASK_XLEN(val1); \ 168 TEST_INSERT_NOPS_ ## src1_nops \ 169 li x2, MASK_XLEN(val2); \ 170 TEST_INSERT_NOPS_ ## src2_nops \ 171 inst x30, x1, x2; \ 172 addi x4, x4, 1; \ 173 li x5, 2; \ 174 bne x4, x5, 1b \ 175 ) 176 177#define TEST_RR_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \ 178 TEST_CASE( testnum, x30, result, \ 179 li x4, 0; \ 1801: li x2, MASK_XLEN(val2); \ 181 TEST_INSERT_NOPS_ ## src1_nops \ 182 li x1, MASK_XLEN(val1); \ 183 TEST_INSERT_NOPS_ ## src2_nops \ 184 inst x30, x1, x2; \ 185 addi x4, x4, 1; \ 186 li x5, 2; \ 187 bne x4, x5, 1b \ 188 ) 189 190#define TEST_RR_ZEROSRC1( testnum, inst, result, val ) \ 191 TEST_CASE( testnum, x2, result, \ 192 li x1, MASK_XLEN(val); \ 193 inst x2, x0, x1; \ 194 ) 195 196#define TEST_RR_ZEROSRC2( testnum, inst, result, val ) \ 197 TEST_CASE( testnum, x2, result, \ 198 li x1, MASK_XLEN(val); \ 199 inst x2, x1, x0; \ 200 ) 201 202#define TEST_RR_ZEROSRC12( testnum, inst, result ) \ 203 TEST_CASE( testnum, x1, result, \ 204 inst x1, x0, x0; \ 205 ) 206 207#define TEST_RR_ZERODEST( testnum, inst, val1, val2 ) \ 208 TEST_CASE( testnum, x0, 0, \ 209 li x1, MASK_XLEN(val1); \ 210 li x2, MASK_XLEN(val2); \ 211 inst x0, x1, x2; \ 212 ) 213 214#----------------------------------------------------------------------- 215# Test memory instructions 216#----------------------------------------------------------------------- 217 218#define TEST_LD_OP( testnum, inst, result, offset, base ) \ 219 TEST_CASE( testnum, x30, result, \ 220 la x1, base; \ 221 inst x30, offset(x1); \ 222 ) 223 224#define TEST_ST_OP( testnum, load_inst, store_inst, result, offset, base ) \ 225 TEST_CASE( testnum, x30, result, \ 226 la x1, base; \ 227 li x2, result; \ 228 store_inst x2, offset(x1); \ 229 load_inst x30, offset(x1); \ 230 ) 231 232#define TEST_LD_DEST_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \ 233test_ ## testnum: \ 234 li TESTNUM, testnum; \ 235 li x4, 0; \ 2361: la x1, base; \ 237 inst x30, offset(x1); \ 238 TEST_INSERT_NOPS_ ## nop_cycles \ 239 addi x6, x30, 0; \ 240 li x29, result; \ 241 bne x6, x29, fail; \ 242 addi x4, x4, 1; \ 243 li x5, 2; \ 244 bne x4, x5, 1b; \ 245 246#define TEST_LD_SRC1_BYPASS( testnum, nop_cycles, inst, result, offset, base ) \ 247test_ ## testnum: \ 248 li TESTNUM, testnum; \ 249 li x4, 0; \ 2501: la x1, base; \ 251 TEST_INSERT_NOPS_ ## nop_cycles \ 252 inst x30, offset(x1); \ 253 li x29, result; \ 254 bne x30, x29, fail; \ 255 addi x4, x4, 1; \ 256 li x5, 2; \ 257 bne x4, x5, 1b \ 258 259#define TEST_ST_SRC12_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \ 260test_ ## testnum: \ 261 li TESTNUM, testnum; \ 262 li x4, 0; \ 2631: li x1, result; \ 264 TEST_INSERT_NOPS_ ## src1_nops \ 265 la x2, base; \ 266 TEST_INSERT_NOPS_ ## src2_nops \ 267 store_inst x1, offset(x2); \ 268 load_inst x30, offset(x2); \ 269 li x29, result; \ 270 bne x30, x29, fail; \ 271 addi x4, x4, 1; \ 272 li x5, 2; \ 273 bne x4, x5, 1b \ 274 275#define TEST_ST_SRC21_BYPASS( testnum, src1_nops, src2_nops, load_inst, store_inst, result, offset, base ) \ 276test_ ## testnum: \ 277 li TESTNUM, testnum; \ 278 li x4, 0; \ 2791: la x2, base; \ 280 TEST_INSERT_NOPS_ ## src1_nops \ 281 li x1, result; \ 282 TEST_INSERT_NOPS_ ## src2_nops \ 283 store_inst x1, offset(x2); \ 284 load_inst x30, offset(x2); \ 285 li x29, result; \ 286 bne x30, x29, fail; \ 287 addi x4, x4, 1; \ 288 li x5, 2; \ 289 bne x4, x5, 1b \ 290 291#define TEST_BR2_OP_TAKEN( testnum, inst, val1, val2 ) \ 292test_ ## testnum: \ 293 li TESTNUM, testnum; \ 294 li x1, val1; \ 295 li x2, val2; \ 296 inst x1, x2, 2f; \ 297 bne x0, TESTNUM, fail; \ 2981: bne x0, TESTNUM, 3f; \ 2992: inst x1, x2, 1b; \ 300 bne x0, TESTNUM, fail; \ 3013: 302 303#define TEST_BR2_OP_NOTTAKEN( testnum, inst, val1, val2 ) \ 304test_ ## testnum: \ 305 li TESTNUM, testnum; \ 306 li x1, val1; \ 307 li x2, val2; \ 308 inst x1, x2, 1f; \ 309 bne x0, TESTNUM, 2f; \ 3101: bne x0, TESTNUM, fail; \ 3112: inst x1, x2, 1b; \ 3123: 313 314#define TEST_BR2_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \ 315test_ ## testnum: \ 316 li TESTNUM, testnum; \ 317 li x4, 0; \ 3181: li x1, val1; \ 319 TEST_INSERT_NOPS_ ## src1_nops \ 320 li x2, val2; \ 321 TEST_INSERT_NOPS_ ## src2_nops \ 322 inst x1, x2, fail; \ 323 addi x4, x4, 1; \ 324 li x5, 2; \ 325 bne x4, x5, 1b \ 326 327#define TEST_BR2_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, val1, val2 ) \ 328test_ ## testnum: \ 329 li TESTNUM, testnum; \ 330 li x4, 0; \ 3311: li x2, val2; \ 332 TEST_INSERT_NOPS_ ## src1_nops \ 333 li x1, val1; \ 334 TEST_INSERT_NOPS_ ## src2_nops \ 335 inst x1, x2, fail; \ 336 addi x4, x4, 1; \ 337 li x5, 2; \ 338 bne x4, x5, 1b \ 339 340#----------------------------------------------------------------------- 341# Test jump instructions 342#----------------------------------------------------------------------- 343 344#define TEST_JR_SRC1_BYPASS( testnum, nop_cycles, inst ) \ 345test_ ## testnum: \ 346 li TESTNUM, testnum; \ 347 li x4, 0; \ 3481: la x6, 2f; \ 349 TEST_INSERT_NOPS_ ## nop_cycles \ 350 inst x6; \ 351 bne x0, TESTNUM, fail; \ 3522: addi x4, x4, 1; \ 353 li x5, 2; \ 354 bne x4, x5, 1b \ 355 356#define TEST_JALR_SRC1_BYPASS( testnum, nop_cycles, inst ) \ 357test_ ## testnum: \ 358 li TESTNUM, testnum; \ 359 li x4, 0; \ 3601: la x6, 2f; \ 361 TEST_INSERT_NOPS_ ## nop_cycles \ 362 inst x19, x6, 0; \ 363 bne x0, TESTNUM, fail; \ 3642: addi x4, x4, 1; \ 365 li x5, 2; \ 366 bne x4, x5, 1b \ 367 368 369#----------------------------------------------------------------------- 370# RV64UF MACROS 371#----------------------------------------------------------------------- 372 373#----------------------------------------------------------------------- 374# Tests floating-point instructions 375#----------------------------------------------------------------------- 376 377#define qNaNf 0f:7fc00000 378#define sNaNf 0f:7f800001 379#define qNaN 0d:7ff8000000000000 380#define sNaN 0d:7ff0000000000001 381 382#define TEST_FP_OP_S_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \ 383test_ ## testnum: \ 384 li TESTNUM, testnum; \ 385 la a0, test_ ## testnum ## _data ;\ 386 flw f0, 0(a0); \ 387 flw f1, 4(a0); \ 388 flw f2, 8(a0); \ 389 lw a3, 12(a0); \ 390 code; \ 391 fsflags a1, x0; \ 392 li a2, flags; \ 393 bne a0, a3, fail; \ 394 bne a1, a2, fail; \ 395 .pushsection .data; \ 396 .align 2; \ 397 test_ ## testnum ## _data: \ 398 .float val1; \ 399 .float val2; \ 400 .float val3; \ 401 .result; \ 402 .popsection 403 404#define TEST_FP_OP_D_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \ 405test_ ## testnum: \ 406 li TESTNUM, testnum; \ 407 la a0, test_ ## testnum ## _data ;\ 408 fld f0, 0(a0); \ 409 fld f1, 8(a0); \ 410 fld f2, 16(a0); \ 411 ld a3, 24(a0); \ 412 code; \ 413 fsflags a1, x0; \ 414 li a2, flags; \ 415 bne a0, a3, fail; \ 416 bne a1, a2, fail; \ 417 .pushsection .data; \ 418 .align 3; \ 419 test_ ## testnum ## _data: \ 420 .double val1; \ 421 .double val2; \ 422 .double val3; \ 423 .result; \ 424 .popsection 425 426// TODO: assign a separate mem location for the comparison address? 427#define TEST_FP_OP_D32_INTERNAL( testnum, flags, result, val1, val2, val3, code... ) \ 428test_ ## testnum: \ 429 li TESTNUM, testnum; \ 430 la a0, test_ ## testnum ## _data ;\ 431 fld f0, 0(a0); \ 432 fld f1, 8(a0); \ 433 fld f2, 16(a0); \ 434 lw a3, 24(a0); \ 435 lw t1, 28(a0); \ 436 code; \ 437 fsflags a1, x0; \ 438 li a2, flags; \ 439 bne a0, a3, fail; \ 440 bne t1, t2, fail; \ 441 bne a1, a2, fail; \ 442 .pushsection .data; \ 443 .align 3; \ 444 test_ ## testnum ## _data: \ 445 .double val1; \ 446 .double val2; \ 447 .double val3; \ 448 .result; \ 449 .popsection 450 451#define TEST_FCVT_S_D32( testnum, result, val1 ) \ 452 TEST_FP_OP_D32_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \ 453 fcvt.s.d f3, f0; fcvt.d.s f3, f3; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 454 455#define TEST_FCVT_S_D( testnum, result, val1 ) \ 456 TEST_FP_OP_D_INTERNAL( testnum, 0, double result, val1, 0.0, 0.0, \ 457 fcvt.s.d f3, f0; fcvt.d.s f3, f3; fmv.x.d a0, f3) 458 459#define TEST_FCVT_D_S( testnum, result, val1 ) \ 460 TEST_FP_OP_S_INTERNAL( testnum, 0, float result, val1, 0.0, 0.0, \ 461 fcvt.d.s f3, f0; fcvt.s.d f3, f3; fmv.x.s a0, f3) 462 463#define TEST_FP_OP1_S( testnum, inst, flags, result, val1 ) \ 464 TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, 0.0, 0.0, \ 465 inst f3, f0; fmv.x.s a0, f3) 466 467#define TEST_FP_OP1_D32( testnum, inst, flags, result, val1 ) \ 468 TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \ 469 inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 470// ^: store computation result in address from a0, load high-word into t2 471 472#define TEST_FP_OP1_D( testnum, inst, flags, result, val1 ) \ 473 TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, 0.0, 0.0, \ 474 inst f3, f0; fmv.x.d a0, f3) 475 476#define TEST_FP_OP1_S_DWORD_RESULT( testnum, inst, flags, result, val1 ) \ 477 TEST_FP_OP_S_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \ 478 inst f3, f0; fmv.x.s a0, f3) 479 480#define TEST_FP_OP1_D32_DWORD_RESULT( testnum, inst, flags, result, val1 ) \ 481 TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \ 482 inst f3, f0; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 483// ^: store computation result in address from a0, load high-word into t2 484 485#define TEST_FP_OP1_D_DWORD_RESULT( testnum, inst, flags, result, val1 ) \ 486 TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \ 487 inst f3, f0; fmv.x.d a0, f3) 488 489#define TEST_FP_OP2_S( testnum, inst, flags, result, val1, val2 ) \ 490 TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, 0.0, \ 491 inst f3, f0, f1; fmv.x.s a0, f3) 492 493#define TEST_FP_OP2_D32( testnum, inst, flags, result, val1, val2 ) \ 494 TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \ 495 inst f3, f0, f1; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 496// ^: store computation result in address from a0, load high-word into t2 497 498#define TEST_FP_OP2_D( testnum, inst, flags, result, val1, val2 ) \ 499 TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, 0.0, \ 500 inst f3, f0, f1; fmv.x.d a0, f3) 501 502#define TEST_FP_OP3_S( testnum, inst, flags, result, val1, val2, val3 ) \ 503 TEST_FP_OP_S_INTERNAL( testnum, flags, float result, val1, val2, val3, \ 504 inst f3, f0, f1, f2; fmv.x.s a0, f3) 505 506#define TEST_FP_OP3_D32( testnum, inst, flags, result, val1, val2, val3 ) \ 507 TEST_FP_OP_D32_INTERNAL( testnum, flags, double result, val1, val2, val3, \ 508 inst f3, f0, f1, f2; fsd f3, 0(a0); lw t2, 4(a0); lw a0, 0(a0)) 509// ^: store computation result in address from a0, load high-word into t2 510 511#define TEST_FP_OP3_D( testnum, inst, flags, result, val1, val2, val3 ) \ 512 TEST_FP_OP_D_INTERNAL( testnum, flags, double result, val1, val2, val3, \ 513 inst f3, f0, f1, f2; fmv.x.d a0, f3) 514 515#define TEST_FP_INT_OP_S( testnum, inst, flags, result, val1, rm ) \ 516 TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, 0.0, 0.0, \ 517 inst a0, f0, rm) 518 519#define TEST_FP_INT_OP_D32( testnum, inst, flags, result, val1, rm ) \ 520 TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \ 521 inst a0, f0, f1; li t2, 0) 522 523#define TEST_FP_INT_OP_D( testnum, inst, flags, result, val1, rm ) \ 524 TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, 0.0, 0.0, \ 525 inst a0, f0, rm) 526 527#define TEST_FP_CMP_OP_S( testnum, inst, flags, result, val1, val2 ) \ 528 TEST_FP_OP_S_INTERNAL( testnum, flags, word result, val1, val2, 0.0, \ 529 inst a0, f0, f1) 530 531#define TEST_FP_CMP_OP_D32( testnum, inst, flags, result, val1, val2 ) \ 532 TEST_FP_OP_D32_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \ 533 inst a0, f0, f1; li t2, 0) 534 535#define TEST_FP_CMP_OP_D( testnum, inst, flags, result, val1, val2 ) \ 536 TEST_FP_OP_D_INTERNAL( testnum, flags, dword result, val1, val2, 0.0, \ 537 inst a0, f0, f1) 538 539#define TEST_FCLASS_S(testnum, correct, input) \ 540 TEST_CASE(testnum, a0, correct, li a0, input; fmv.s.x fa0, a0; \ 541 fclass.s a0, fa0) 542 543#define TEST_FCLASS_D32(testnum, correct, input) \ 544 TEST_CASE(testnum, a0, correct, \ 545 la a0, test_ ## testnum ## _data ;\ 546 fld fa0, 0(a0); \ 547 fclass.d a0, fa0) \ 548 .pushsection .data; \ 549 .align 3; \ 550 test_ ## testnum ## _data: \ 551 .dword input; \ 552 .popsection 553 554#define TEST_FCLASS_D(testnum, correct, input) \ 555 TEST_CASE(testnum, a0, correct, li a0, input; fmv.d.x fa0, a0; \ 556 fclass.d a0, fa0) 557 558#define TEST_INT_FP_OP_S( testnum, inst, result, val1 ) \ 559test_ ## testnum: \ 560 li TESTNUM, testnum; \ 561 la a0, test_ ## testnum ## _data ;\ 562 lw a3, 0(a0); \ 563 li a0, val1; \ 564 inst f0, a0; \ 565 fsflags x0; \ 566 fmv.x.s a0, f0; \ 567 bne a0, a3, fail; \ 568 .pushsection .data; \ 569 .align 2; \ 570 test_ ## testnum ## _data: \ 571 .float result; \ 572 .popsection 573 574#define TEST_INT_FP_OP_D32( testnum, inst, result, val1 ) \ 575test_ ## testnum: \ 576 li TESTNUM, testnum; \ 577 la a0, test_ ## testnum ## _data ;\ 578 lw a3, 0(a0); \ 579 lw a4, 4(a0); \ 580 li a1, val1; \ 581 inst f0, a1; \ 582 \ 583 fsd f0, 0(a0); \ 584 lw a1, 4(a0); \ 585 lw a0, 0(a0); \ 586 \ 587 fsflags x0; \ 588 bne a0, a3, fail; \ 589 bne a1, a4, fail; \ 590 .pushsection .data; \ 591 .align 3; \ 592 test_ ## testnum ## _data: \ 593 .double result; \ 594 .popsection 595 596#define TEST_INT_FP_OP_D( testnum, inst, result, val1 ) \ 597test_ ## testnum: \ 598 li TESTNUM, testnum; \ 599 la a0, test_ ## testnum ## _data ;\ 600 ld a3, 0(a0); \ 601 li a0, val1; \ 602 inst f0, a0; \ 603 fsflags x0; \ 604 fmv.x.d a0, f0; \ 605 bne a0, a3, fail; \ 606 .pushsection .data; \ 607 .align 3; \ 608 test_ ## testnum ## _data: \ 609 .double result; \ 610 .popsection 611 612// We need some special handling here to allow 64-bit comparison in 32-bit arch 613// TODO: find a better name and clean up when intended for general usage? 614#define TEST_CASE_D32( testnum, testreg1, testreg2, correctval, code... ) \ 615test_ ## testnum: \ 616 code; \ 617 la x31, test_ ## testnum ## _data ; \ 618 lw x29, 0(x31); \ 619 lw x31, 4(x31); \ 620 li TESTNUM, testnum; \ 621 bne testreg1, x29, fail;\ 622 bne testreg2, x31, fail;\ 623 .pushsection .data; \ 624 .align 3; \ 625 test_ ## testnum ## _data: \ 626 .dword correctval; \ 627 .popsection 628 629// ^ x30 is used in some other macros, to avoid issues we use x31 for upper word 630 631#----------------------------------------------------------------------- 632# Pass and fail code (assumes test num is in TESTNUM) 633#----------------------------------------------------------------------- 634 635#define TEST_PASSFAIL \ 636 bne x0, TESTNUM, pass; \ 637fail: \ 638 RVTEST_FAIL; \ 639pass: \ 640 RVTEST_PASS \ 641 642 643#----------------------------------------------------------------------- 644# Test data section 645#----------------------------------------------------------------------- 646 647#define TEST_DATA 648 649#endif 650