test_macros.h revision 12771:75508af5d8dc
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