1 /* Copyright (C) 2012 IBM
3 Author: Maynard Johnson <maynardj@us.ibm.com>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 The GNU General Public License is contained in the file COPYING.
28 register double f14
__asm__ ("fr14");
29 register double f15
__asm__ ("fr15");
30 register double f16
__asm__ ("fr16");
31 register double f17
__asm__ ("fr17");
32 register double f18
__asm__ ("fr18");
33 register double f19
__asm__ ("fr19");
36 typedef unsigned char Bool
;
41 #define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
43 #define SET_CR(_arg) \
44 __asm__ __volatile__ ("mtcr %0" : : "b"(_arg) : ALLCR );
46 #define SET_XER(_arg) \
47 __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" );
49 #define GET_CR(_lval) \
50 __asm__ __volatile__ ("mfcr %0" : "=b"(_lval) )
52 #define GET_XER(_lval) \
53 __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
55 #define GET_CR_XER(_lval_cr,_lval_xer) \
56 do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0)
61 #define SET_XER_ZERO \
64 #define SET_CR_XER_ZERO \
65 do { SET_CR_ZERO; SET_XER_ZERO; } while (0)
67 #define SET_FPSCR_ZERO \
68 do { double _d = 0.0; \
69 __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \
72 #define GET_FPSCR(_arg) \
73 __asm__ __volatile__ ("mffs %0" : "=f"(_arg) )
75 #define SET_FPSCR_DRN \
76 __asm__ __volatile__ ("mtfsf 1, %0, 0, 1" : : "f"(f14) )
79 // The assembly-level instructions being tested
80 static void _test_drintx(int R
, int RMC
)
82 if (RMC
< 0 || RMC
> 3 || R
< 0 || R
> 1) {
83 fprintf(stderr
, "Invalid inputs to asm test: a=%d, b=%d\n", R
, RMC
);
89 __asm__
__volatile__ ("drintx 1, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
91 __asm__
__volatile__ ("drintx 0, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
95 __asm__
__volatile__ ("drintx 1, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
97 __asm__
__volatile__ ("drintx 0, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
101 __asm__
__volatile__ ("drintx 1, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
103 __asm__
__volatile__ ("drintx 0, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
107 __asm__
__volatile__ ("drintx 1, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
109 __asm__
__volatile__ ("drintx 0, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
116 static void _test_drintn(int R
, int RMC
)
118 if (RMC
< 0 || RMC
> 3 || R
< 0 || R
> 1) {
119 fprintf(stderr
, "Invalid inputs to asm test: a=%d, b=%d\n", R
, RMC
);
125 __asm__
__volatile__ ("drintn 1, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
127 __asm__
__volatile__ ("drintn 0, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
131 __asm__
__volatile__ ("drintn 1, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
133 __asm__
__volatile__ ("drintn 0, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
137 __asm__
__volatile__ ("drintn 1, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
139 __asm__
__volatile__ ("drintn 0, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
143 __asm__
__volatile__ ("drintn 1, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
145 __asm__
__volatile__ ("drintn 0, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
153 static void _test_diex(int a
__attribute__((unused
)), int b
__attribute__((unused
)))
155 __asm__
__volatile__ ("diex %0, %1, %2" : "=f" (f18
) : "f" (f14
),"f" (f16
));
158 static void _test_dxex(int a
__attribute__((unused
)), int b
__attribute__((unused
)))
160 __asm__
__volatile__ ("dxex %0, %1" : "=f" (f18
) : "f" (f16
));
163 static void _test_dcmpo(int BF
, int x
__attribute__((unused
)))
165 if (BF
< 0 || BF
> 7) {
166 fprintf(stderr
, "Invalid input to asm test: a=%d\n", BF
);
171 __asm__
__volatile__ ("dcmpo 0, %0, %1" : : "f" (f14
),"f" (f16
));
174 __asm__
__volatile__ ("dcmpo 1, %0, %1" : : "f" (f14
),"f" (f16
));
177 __asm__
__volatile__ ("dcmpo 2, %0, %1" : : "f" (f14
),"f" (f16
));
180 __asm__
__volatile__ ("dcmpo 3, %0, %1" : : "f" (f14
),"f" (f16
));
183 __asm__
__volatile__ ("dcmpo 4, %0, %1" : : "f" (f14
),"f" (f16
));
186 __asm__
__volatile__ ("dcmpo 5, %0, %1" : : "f" (f14
),"f" (f16
));
189 __asm__
__volatile__ ("dcmpo 6, %0, %1" : : "f" (f14
),"f" (f16
));
192 __asm__
__volatile__ ("dcmpo 7, %0, %1" : : "f" (f14
),"f" (f16
));
199 static void _test_dcmpu(int BF
, int x
__attribute__((unused
)))
201 if (BF
< 0 || BF
> 7) {
202 fprintf(stderr
, "Invalid input to asm test: a=%d\n", BF
);
207 __asm__
__volatile__ ("dcmpu 0, %0, %1" : : "f" (f14
),"f" (f16
));
210 __asm__
__volatile__ ("dcmpu 1, %0, %1" : : "f" (f14
),"f" (f16
));
213 __asm__
__volatile__ ("dcmpu 2, %0, %1" : : "f" (f14
),"f" (f16
));
216 __asm__
__volatile__ ("dcmpu 3, %0, %1" : : "f" (f14
),"f" (f16
));
219 __asm__
__volatile__ ("dcmpu 4, %0, %1" : : "f" (f14
),"f" (f16
));
222 __asm__
__volatile__ ("dcmpu 5, %0, %1" : : "f" (f14
),"f" (f16
));
225 __asm__
__volatile__ ("dcmpu 6, %0, %1" : : "f" (f14
),"f" (f16
));
228 __asm__
__volatile__ ("dcmpu 7, %0, %1" : : "f" (f14
),"f" (f16
));
235 // Quad instruction testing
236 static void _test_drintxq(int R
, int RMC
)
238 if (RMC
< 0 || RMC
> 3 || R
< 0 || R
> 1) {
239 fprintf(stderr
, "Invalid inputs to asm test: a=%d, b=%d\n", R
, RMC
);
245 __asm__
__volatile__ ("drintxq 1, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
247 __asm__
__volatile__ ("drintxq 0, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
251 __asm__
__volatile__ ("drintxq 1, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
253 __asm__
__volatile__ ("drintxq 0, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
257 __asm__
__volatile__ ("drintxq 1, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
259 __asm__
__volatile__ ("drintxq 0, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
263 __asm__
__volatile__ ("drintxq 1, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
265 __asm__
__volatile__ ("drintxq 0, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
272 static void _test_drintnq(int R
, int RMC
)
274 if (RMC
< 0 || RMC
> 3 || R
< 0 || R
> 1) {
275 fprintf(stderr
, "Invalid inputs to asm test: a=%d, b=%d\n", R
, RMC
);
281 __asm__
__volatile__ ("drintnq 1, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
283 __asm__
__volatile__ ("drintnq 0, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
287 __asm__
__volatile__ ("drintnq 1, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
289 __asm__
__volatile__ ("drintnq 0, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
293 __asm__
__volatile__ ("drintnq 1, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
295 __asm__
__volatile__ ("drintnq 0, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
299 __asm__
__volatile__ ("drintnq 1, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
301 __asm__
__volatile__ ("drintnq 0, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
308 static void _test_diexq(int a
__attribute__((unused
)), int b
__attribute__((unused
)))
310 __asm__
__volatile__ ("diexq %0, %1, %2" : "=f" (f18
) : "f" (f14
),"f" (f16
));
313 static void _test_dxexq(int a
__attribute__((unused
)), int b
__attribute__((unused
)))
315 __asm__
__volatile__ ("dxexq %0, %1" : "=f" (f18
) : "f" (f16
));
318 static void _test_dcmpoq(int BF
, int x
__attribute__((unused
)))
320 if (BF
< 0 || BF
> 7) {
321 fprintf(stderr
, "Invalid input to asm test: a=%d\n", BF
);
326 __asm__
__volatile__ ("dcmpoq 0, %0, %1" : : "f" (f14
),"f" (f16
));
329 __asm__
__volatile__ ("dcmpoq 1, %0, %1" : : "f" (f14
),"f" (f16
));
332 __asm__
__volatile__ ("dcmpoq 2, %0, %1" : : "f" (f14
),"f" (f16
));
335 __asm__
__volatile__ ("dcmpoq 3, %0, %1" : : "f" (f14
),"f" (f16
));
338 __asm__
__volatile__ ("dcmpoq 4, %0, %1" : : "f" (f14
),"f" (f16
));
341 __asm__
__volatile__ ("dcmpoq 5, %0, %1" : : "f" (f14
),"f" (f16
));
344 __asm__
__volatile__ ("dcmpoq 6, %0, %1" : : "f" (f14
),"f" (f16
));
347 __asm__
__volatile__ ("dcmpoq 7, %0, %1" : : "f" (f14
),"f" (f16
));
354 static void _test_dcmpuq(int BF
, int x
__attribute__((unused
)))
356 if (BF
< 0 || BF
> 7) {
357 fprintf(stderr
, "Invalid input to asm test: a=%d\n", BF
);
362 __asm__
__volatile__ ("dcmpuq 0, %0, %1" : : "f" (f14
),"f" (f16
));
365 __asm__
__volatile__ ("dcmpuq 1, %0, %1" : : "f" (f14
),"f" (f16
));
368 __asm__
__volatile__ ("dcmpuq 2, %0, %1" : : "f" (f14
),"f" (f16
));
371 __asm__
__volatile__ ("dcmpuq 3, %0, %1" : : "f" (f14
),"f" (f16
));
374 __asm__
__volatile__ ("dcmpuq 4, %0, %1" : : "f" (f14
),"f" (f16
));
377 __asm__
__volatile__ ("dcmpuq 5, %0, %1" : : "f" (f14
),"f" (f16
));
380 __asm__
__volatile__ ("dcmpuq 6, %0, %1" : : "f" (f14
),"f" (f16
));
383 __asm__
__volatile__ ("dcmpuq 7, %0, %1" : : "f" (f14
),"f" (f16
));
390 static void _test_drrnd(int x
__attribute__((unused
)), int RMC
)
392 if (RMC
< 0 || RMC
> 31) {
393 fprintf(stderr
, "Invalid input to asm test: a=%d\n", RMC
);
398 __asm__
__volatile__ ("drrnd %0, %1, %2, 0" : "=f" (f18
) : "f" (f14
), "f" (f16
));
401 __asm__
__volatile__ ("drrnd %0, %1, %2, 1" : "=f" (f18
) : "f" (f14
), "f" (f16
));
404 __asm__
__volatile__ ("drrnd %0, %1, %2, 2" : "=f" (f18
) : "f" (f14
), "f" (f16
));
407 __asm__
__volatile__ ("drrnd %0, %1, %2, 3" : "=f" (f18
) : "f" (f14
), "f" (f16
));
414 static void _test_drrndq(int x
__attribute__((unused
)), int RMC
)
416 if (RMC
< 0 || RMC
> 3) {
417 fprintf(stderr
, "Invalid input to asm test: a=%dn", RMC
);
422 __asm__
__volatile__ ("drrndq %0, %1, %2, 0" : "=f" (f18
) : "f" (f14
), "f" (f16
));
425 __asm__
__volatile__ ("drrndq %0, %1, %2, 1" : "=f" (f18
) : "f" (f14
), "f" (f16
));
428 __asm__
__volatile__ ("drrndq %0, %1, %2, 2" : "=f" (f18
) : "f" (f14
), "f" (f16
));
431 __asm__
__volatile__ ("drrndq %0, %1, %2, 3" : "=f" (f18
) : "f" (f14
), "f" (f16
));
438 static void _test_dqua(int x
__attribute__((unused
)), int RMC
)
440 if (RMC
< 0 || RMC
> 3) {
441 fprintf(stderr
, "Invalid input to asm test: a=%d\n", RMC
);
446 __asm__
__volatile__ ("dqua %0, %1, %2, 0" : "=f" (f18
) : "f" (f14
), "f" (f16
));
449 __asm__
__volatile__ ("dqua %0, %1, %2, 1" : "=f" (f18
) : "f" (f14
), "f" (f16
));
452 __asm__
__volatile__ ("dqua %0, %1, %2, 2" : "=f" (f18
) : "f" (f14
), "f" (f16
));
455 __asm__
__volatile__ ("dqua %0, %1, %2, 3" : "=f" (f18
) : "f" (f14
), "f" (f16
));
462 static void _test_dquaq(int x
__attribute__((unused
)), int RMC
)
464 if (RMC
< 0 || RMC
> 3) {
465 fprintf(stderr
, "Invalid input to asm test: a=%d\n", RMC
);
470 __asm__
__volatile__ ("dquaq %0, %1, %2, 0" : "=f" (f18
) : "f" (f14
), "f" (f16
));
473 __asm__
__volatile__ ("dquaq %0, %1, %2, 1" : "=f" (f18
) : "f" (f14
), "f" (f16
));
476 __asm__
__volatile__ ("dquaq %0, %1, %2, 2" : "=f" (f18
) : "f" (f14
), "f" (f16
));
479 __asm__
__volatile__ ("dquaq %0, %1, %2, 3" : "=f" (f18
) : "f" (f14
), "f" (f16
));
486 static int TE_vals
[] = { -16, -2, 0, 5};
487 #define TE_VAL_LEN sizeof(TE_vals)/sizeof(int)
488 static Bool
__is_TE_val(int x
)
491 for (i
= 0; i
< TE_VAL_LEN
; i
++) {
498 static void _test_dquai(int TE
, int RMC
)
500 if (RMC
< 0 || RMC
> 3 || !__is_TE_val(TE
)) {
501 fprintf(stderr
, "Invalid inputs to asm test: a=%d, b=%d\n", TE
, RMC
);
508 __asm__
__volatile__ ("dquai -16, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
511 __asm__
__volatile__ ("dquai -2, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
514 __asm__
__volatile__ ("dquai 0, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
517 __asm__
__volatile__ ("dquai 5, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
526 __asm__
__volatile__ ("dquai -16, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
529 __asm__
__volatile__ ("dquai -2, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
532 __asm__
__volatile__ ("dquai 0, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
535 __asm__
__volatile__ ("dquai 5, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
544 __asm__
__volatile__ ("dquai -16, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
547 __asm__
__volatile__ ("dquai -2, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
550 __asm__
__volatile__ ("dquai 0, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
553 __asm__
__volatile__ ("dquai 5, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
562 __asm__
__volatile__ ("dquai -16, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
565 __asm__
__volatile__ ("dquai -2, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
568 __asm__
__volatile__ ("dquai 0, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
571 __asm__
__volatile__ ("dquai 5, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
582 static void _test_dquaiq(int TE
, int RMC
)
584 if (RMC
< 0 || RMC
> 3 || !__is_TE_val(TE
)) {
585 fprintf(stderr
, "Invalid inputs to asm test: a=%d, b=%d\n", TE
, RMC
);
592 __asm__
__volatile__ ("dquaiq -16, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
595 __asm__
__volatile__ ("dquaiq -2, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
598 __asm__
__volatile__ ("dquaiq 0, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
601 __asm__
__volatile__ ("dquaiq 5, %0, %1, 0" : "=f" (f18
) : "f" (f16
));
610 __asm__
__volatile__ ("dquaiq -16, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
613 __asm__
__volatile__ ("dquaiq -2, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
616 __asm__
__volatile__ ("dquaiq 0, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
619 __asm__
__volatile__ ("dquaiq 5, %0, %1, 1" : "=f" (f18
) : "f" (f16
));
628 __asm__
__volatile__ ("dquaiq -16, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
631 __asm__
__volatile__ ("dquaiq -2, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
634 __asm__
__volatile__ ("dquaiq 0, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
637 __asm__
__volatile__ ("dquaiq 5, %0, %1, 2" : "=f" (f18
) : "f" (f16
));
646 __asm__
__volatile__ ("dquaiq -16, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
649 __asm__
__volatile__ ("dquaiq -2, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
652 __asm__
__volatile__ ("dquaiq 0, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
655 __asm__
__volatile__ ("dquaiq 5, %0, %1, 3" : "=f" (f18
) : "f" (f16
));
667 typedef void (*test_func_t
)(int a
, int b
);
668 typedef void (*test_driver_func_t
)(void);
669 typedef struct test_table
671 test_driver_func_t test_category
;
676 * 345.0DD (0x2207c00000000000 0xe50)
677 * 1.2300e+5DD (0x2207c00000000000 0x14c000)
678 * -16.0DD (0xa207c00000000000 0xe0)
679 * 0.00189DD (0x2206c00000000000 0xcf)
680 * -4.1235DD (0xa205c00000000000 0x10a395bcf)
681 * 9.8399e+20DD (0x2209400000000000 0x253f1f534acdd4)
682 * 0DD (0x2208000000000000 0x0)
683 * 0DD (0x2208000000000000 0x0)
684 * infDD (0x7800000000000000 0x0)
685 * nanDD (0x7c00000000000000 0x0
687 static unsigned long long dfp128_vals
[] = {
688 // Some finite numbers
689 0x2207c00000000000ULL
, 0x0000000000000e50ULL
,
690 0x2207c00000000000ULL
, 0x000000000014c000ULL
,
691 0xa207c00000000000ULL
, 0x00000000000000e0ULL
,
692 0x2206c00000000000ULL
, 0x00000000000000cfULL
,
693 0xa205c00000000000ULL
, 0x000000010a395bcfULL
,
694 0x6209400000fd0000ULL
, 0x00253f1f534acdd4ULL
, // huge number
695 0x000400000089b000ULL
, 0x0a6000d000000049ULL
, // very small number
697 0x2208000000000000ULL
, 0x0000000000000000ULL
,
698 0xa208000000000000ULL
, 0x0000000000000000ULL
, // negative
699 0xa248000000000000ULL
, 0x0000000000000000ULL
,
701 0x7c00000000000000ULL
, 0x0000000000000000ULL
, // quiet
702 0xfc00000000000000ULL
, 0xc00100035b007700ULL
,
703 0x7e00000000000000ULL
, 0xfe000000d0e0a0d0ULL
, // signaling
704 // flavors of Infinity
705 0x7800000000000000ULL
, 0x0000000000000000ULL
,
706 0xf800000000000000ULL
, 0x0000000000000000ULL
, // negative
707 0xf900000000000000ULL
, 0x0000000000000000ULL
710 static unsigned long long dfp64_vals
[] = {
711 // various finite numbers
712 0x2234000000000e50ULL
,
713 0x223400000014c000ULL
,
714 0xa2340000000000e0ULL
,// negative
715 0x22240000000000cfULL
,
716 0xa21400010a395bcfULL
,// negative
717 0x6e4d3f1f534acdd4ULL
,// huge number
718 0x000400000089b000ULL
,// very small number
720 0x2238000000000000ULL
,
721 0xa238000000000000ULL
,
722 0x4248000000000000ULL
,
724 0x7e34000000000111ULL
,
725 0xfe000000d0e0a0d0ULL
,//signaling
726 0xfc00000000000000ULL
,//quiet
727 // flavors of Infinity
728 0x7800000000000000ULL
,
729 0xf800000000000000ULL
,//negative
730 0x7a34000000000000ULL
,
733 // Both Long and Quad arrays of DFP values should have the same length.
734 // If that length is changed, t
735 #define NUM_DFP_VALS (sizeof(dfp64_vals)/8)
737 typedef struct dfp_test_args
{
743 // Index pairs from dfp64_vals array to be used with dfp_two_arg_tests
744 static dfp_test_args_t dfp_2args_x1
[] = {
777 typedef struct dfp_test
779 test_func_t test_func
;
781 dfp_test_args_t
* targs
;
783 precision_type_t precision
;
787 typedef struct dfp_one_arg_test
789 test_func_t test_func
;
791 precision_type_t precision
;
793 } dfp_one_arg_test_t
;
796 static dfp_one_arg_test_t
798 { &_test_dquai
, "dquai", LONG_TEST
, "[QI]"},
799 { &_test_dquaiq
, "dquaiq", QUAD_TEST
, "[QI]"},
800 { NULL
, NULL
, 0, NULL
}
803 static void test_dfp_quai_ops(void)
806 unsigned long long u0
, u0x
;
807 double res
, d0
, *d0p
, d0x
, *d0xp
;
814 while ((func
= dfp_quai_tests
[k
].test_func
)) {
816 dfp_one_arg_test_t test_def
= dfp_quai_tests
[k
];
818 for (i
= 0; i
< NUM_DFP_VALS
; i
++) {
821 if (test_def
.precision
== LONG_TEST
) {
824 u0
= dfp128_vals
[i
* 2];
825 u0x
= dfp128_vals
[(i
* 2) + 1];
827 *(unsigned long long *)d0p
= u0
;
829 if (test_def
.precision
== QUAD_TEST
) {
830 *(unsigned long long *)d0xp
= u0x
;
834 for (TE
= 0; TE
< TE_VAL_LEN
; TE
++) {
835 for (RMC
= 0; RMC
< 4; RMC
++) {
836 (*func
)(TE_vals
[TE
], RMC
);
838 printf("%s (RMC=%2d, TE=%3d) %s %016llx", test_def
.name
, RMC
,
839 TE_vals
[TE
], test_def
.op
, u0
);
840 if (test_def
.precision
== LONG_TEST
) {
841 printf(" => %016llx\n",
842 *((unsigned long long *)(&res
)));
845 printf(" %016llx ==> %016llx %016llx\n",
846 u0x
, *((unsigned long long *)(&res
)), *((unsigned long long *)(&resx
)));
859 { &_test_dqua
, "dqua", dfp_2args_x1
, 25, LONG_TEST
, "[Q]"},
860 { &_test_dquaq
, "dquaq", dfp_2args_x1
, 25, QUAD_TEST
, "[Q]"},
861 { NULL
, NULL
, NULL
, 0, 0, NULL
}
864 static void test_dfp_qua_ops(void)
867 unsigned long long u0
, u0x
, u1
, u1x
;
868 double res
, d0
, d1
, *d0p
, *d1p
;
869 double d0x
, d1x
, *d0xp
, *d1xp
;
877 while ((func
= dfp_qua_tests
[k
].test_func
)) {
879 dfp_test_t test_def
= dfp_qua_tests
[k
];
881 for (i
= 0; i
< test_def
.num_tests
; i
++) {
882 if (test_def
.precision
== LONG_TEST
) {
883 u0
= dfp64_vals
[test_def
.targs
[i
].fra_idx
];
884 u1
= dfp64_vals
[test_def
.targs
[i
].frb_idx
];
886 u0
= dfp128_vals
[test_def
.targs
[i
].fra_idx
* 2];
887 u0x
= dfp128_vals
[(test_def
.targs
[i
].fra_idx
* 2) + 1];
888 u1
= dfp128_vals
[test_def
.targs
[i
].frb_idx
* 2];
889 u1x
= dfp128_vals
[(test_def
.targs
[i
].frb_idx
* 2) + 1];
891 *(unsigned long long *)d0p
= u0
;
892 *(unsigned long long *)d1p
= u1
;
895 if (test_def
.precision
== QUAD_TEST
) {
896 *(unsigned long long *)d0xp
= u0x
;
897 *(unsigned long long *)d1xp
= u1x
;
901 for (RMC
= 0; RMC
< 4; RMC
++) {
904 printf("%s (RMC=%2d) %s %016llx", test_def
.name
, RMC
, test_def
.op
, u0
);
905 if (test_def
.precision
== LONG_TEST
) {
906 printf(", %016llx => %016llx\n", u1
, *((unsigned long long *)(&res
)));
909 printf(" %016llx, %016llx %016llx ==> %016llx %016llx\n",u0x
, u1
, u1x
,
910 *((unsigned long long *)(&res
)), *((unsigned long long *)(&resx
)));
920 static dfp_one_arg_test_t
922 { &_test_drrnd
, "drrnd", LONG_TEST
, "[RR]"},
923 { &_test_drrndq
, "drrndq", QUAD_TEST
, "[RR]"},
924 { NULL
, NULL
, 0, NULL
}
927 static void test_dfp_rrnd_ops(void)
930 unsigned long long u0
, u0x
;
931 double res
, d0
, *d0p
, d0x
, *d0xp
, reference_sig
, *reference_sig_p
;
932 long long reference_sig_vals
[] = {0ULL, 2ULL, 6ULL, 63ULL};
933 int num_reference_sig_vals
= sizeof(reference_sig_vals
)/sizeof(long long);
939 reference_sig_p
= &reference_sig
;
941 while ((func
= dfp_rrnd_tests
[k
].test_func
)) {
943 dfp_one_arg_test_t test_def
= dfp_rrnd_tests
[k
];
945 for (i
= 0; i
< NUM_DFP_VALS
; i
++) {
948 if (test_def
.precision
== LONG_TEST
) {
951 u0
= dfp128_vals
[i
* 2];
952 u0x
= dfp128_vals
[(i
* 2) + 1];
954 *(unsigned long long *)d0p
= u0
;
956 if (test_def
.precision
== QUAD_TEST
) {
957 *(unsigned long long *)d0xp
= u0x
;
961 for (j
= 0; j
< num_reference_sig_vals
; j
++) {
962 *(long long *)reference_sig_p
= reference_sig_vals
[j
];
964 for (RMC
= 0; RMC
< 4; RMC
++) {
967 printf("%s (RMC=%d, ref sig=%d) %s%016llx", test_def
.name
, RMC
,
968 (int)reference_sig_vals
[j
], test_def
.op
, u0
);
969 if (test_def
.precision
== LONG_TEST
) {
970 printf(" => %016llx\n",
971 *((unsigned long long *)(&res
)));
974 printf(" %016llx ==> %016llx %016llx\n",
975 u0x
, *((unsigned long long *)(&res
)), *((unsigned long long *)(&resx
)));
986 static dfp_one_arg_test_t
988 { &_test_diex
, "diex", LONG_TEST
, ">>"},
989 { &_test_diexq
, "diexq", QUAD_TEST
, ">>"},
990 { &_test_dxex
, "dxex", LONG_TEST
, "<<"},
991 { &_test_dxexq
, "dxexq", QUAD_TEST
, "<<"},
992 { NULL
, NULL
, 0, NULL
}
995 static void test_dfp_xiex_ops(void)
998 unsigned long long u0
, u0x
;
999 double res
, d0
, *d0p
, d0x
, *d0xp
, target_exp
, *target_exp_p
;
1000 /* The first two positions are placeholders and will be filled in later,
1001 * based on the precision of the DFP argument.
1003 long long target_exp_vals
[] = {0ULL, 0ULL, 0ULL, -1ULL, -2ULL, -3ULL, -4ULL, -5ULL};
1004 int num_exp_vals
= sizeof(target_exp_vals
)/sizeof(long long);
1009 target_exp_p
= &target_exp
;
1011 while ((func
= dfp_xiex_tests
[k
].test_func
)) {
1013 Bool insert_insn
= False
;
1014 dfp_one_arg_test_t test_def
= dfp_xiex_tests
[k
];
1016 if (!strncmp(test_def
.name
, "di", 2))
1019 if (test_def
.precision
== QUAD_TEST
) {
1020 target_exp_vals
[0] = 12288ULL; // > max biased exponent
1021 target_exp_vals
[1] = 5235ULL;
1023 target_exp_vals
[0] = 768ULL; // > max biased exponent
1024 target_exp_vals
[1] = 355ULL;
1027 for (i
= 0; i
< NUM_DFP_VALS
; i
++) {
1030 if (test_def
.precision
== QUAD_TEST
) {
1031 u0
= dfp128_vals
[i
* 2];
1032 u0x
= dfp128_vals
[(i
* 2) + 1];
1036 *(unsigned long long *)d0p
= u0
;
1038 if (test_def
.precision
== QUAD_TEST
) {
1039 *(unsigned long long *)d0xp
= u0x
;
1044 // This is just for extract insns (dexex[q])
1047 printf("%s %s ", test_def
.name
, test_def
.op
);
1048 if (test_def
.precision
== LONG_TEST
) {
1049 printf("%016llx => %016llx\n", u0
,
1050 *((unsigned long long *)(&res
)));
1053 printf("%016llx %016llx ==> %016llx %016llx\n", u0
, u0x
,
1054 *((unsigned long long *)(&res
)), *((unsigned long long *)(&resx
)));
1058 // The following for-loop is just for insert insns (diex[q])
1059 for (j
= 0; j
< num_exp_vals
; j
++) {
1060 *(long long *)target_exp_p
= target_exp_vals
[j
];
1064 printf("%s %s %5d, ", test_def
.name
, test_def
.op
, (int)target_exp_vals
[j
]);
1066 if (test_def
.precision
== LONG_TEST
) {
1067 printf("%016llx => %016llx\n", u0
,
1068 *((unsigned long long *)(&res
)));
1071 printf("%016llx %016llx ==> %016llx %016llx\n", u0
, u0x
,
1072 *((unsigned long long *)(&res
)), *((unsigned long long *)(&resx
)));
1081 static dfp_one_arg_test_t
1082 dfp_rint_tests
[] = {
1083 { &_test_drintn
, "drintn", LONG_TEST
, "~"},
1084 { &_test_drintnq
, "drintnq", QUAD_TEST
, "~"},
1085 { &_test_drintx
, "drintx", LONG_TEST
, "~"},
1086 { &_test_drintxq
, "drintxq", QUAD_TEST
, "~"},
1087 { NULL
, NULL
, 0, NULL
}
1090 static void test_dfp_rint_ops(void)
1093 unsigned long long u0
, u0x
;
1094 double res
, d0
, *d0p
, d0x
, *d0xp
;
1100 while ((func
= dfp_rint_tests
[k
].test_func
)) {
1102 dfp_one_arg_test_t test_def
= dfp_rint_tests
[k
];
1104 for (i
= 0; i
< NUM_DFP_VALS
; i
++) {
1107 if (test_def
.precision
== LONG_TEST
) {
1110 u0
= dfp128_vals
[i
* 2];
1111 u0x
= dfp128_vals
[(i
* 2) + 1];
1113 *(unsigned long long *)d0p
= u0
;
1115 if (test_def
.precision
== QUAD_TEST
) {
1116 *(unsigned long long *)d0xp
= u0x
;
1120 for (R
= 0; R
< 2; R
++) {
1121 for (RMC
= 0; RMC
< 4; RMC
++) {
1124 printf("%s (RM=%d) %s%016llx", test_def
.name
, (RMC
+ (R
<< 2)), test_def
.op
, u0
);
1125 if (test_def
.precision
== LONG_TEST
) {
1126 printf(" => %016llx\n",
1127 *((unsigned long long *)(&res
)));
1130 printf(" %016llx ==> %016llx %016llx\n",
1131 u0x
, *((unsigned long long *)(&res
)), *((unsigned long long *)(&resx
)));
1143 { &_test_dcmpo
, "dcmpo", dfp_2args_x1
, 25, LONG_TEST
, "<>"},
1144 { &_test_dcmpoq
, "dcmpoq", dfp_2args_x1
, 25, QUAD_TEST
, "<>"},
1145 { &_test_dcmpu
, "dcmpu", dfp_2args_x1
, 25, LONG_TEST
, "<>"},
1146 { &_test_dcmpuq
, "dcmpuq", dfp_2args_x1
, 25, QUAD_TEST
, "<>"},
1147 { NULL
, NULL
, NULL
, 0, 0, NULL
}
1150 static void test_dfp_cmp_ops(void)
1153 unsigned long long u0
, u0x
, u1
, u1x
;
1154 double d0
, d1
, *d0p
, *d1p
;
1155 double d0x
, d1x
, *d0xp
, *d1xp
;
1156 /* BF is a 3-bit instruction field that indicates the CR field in which the
1157 * result of the compare should be placed. We won't iterate through all
1158 * 8 possible BF values since storing compare results to a given field is
1159 * a well-tested mechanism in VEX. But we will test two BF values, just as
1169 while ((func
= dfp_cmp_tests
[k
].test_func
)) {
1171 dfp_test_t test_def
= dfp_cmp_tests
[k
];
1175 for (i
= 0; i
< test_def
.num_tests
; i
++) {
1176 unsigned int condreg
;
1179 if (test_def
.precision
== LONG_TEST
) {
1180 u0
= dfp64_vals
[test_def
.targs
[i
].fra_idx
];
1181 u1
= dfp64_vals
[test_def
.targs
[i
].frb_idx
];
1183 u0
= dfp128_vals
[test_def
.targs
[i
].fra_idx
* 2];
1184 u0x
= dfp128_vals
[(test_def
.targs
[i
].fra_idx
* 2) + 1];
1185 u1
= dfp128_vals
[test_def
.targs
[i
].frb_idx
* 2];
1186 u1x
= dfp128_vals
[(test_def
.targs
[i
].frb_idx
* 2) + 1];
1188 *(unsigned long long *)d0p
= u0
;
1189 *(unsigned long long *)d1p
= u1
;
1192 if (test_def
.precision
== QUAD_TEST
) {
1193 *(unsigned long long *)d0xp
= u0x
;
1194 *(unsigned long long *)d1xp
= u1x
;
1204 condreg
= ((flags
>> (4 * (7-BF
)))) & 0xf;
1205 printf("%s %016llx", test_def
.name
, u0
);
1206 if (test_def
.precision
== LONG_TEST
) {
1207 printf(" %s %016llx => %x (BF=%d)\n",
1208 test_def
.op
, u1
, condreg
, BF
);
1210 printf(" %016llx %s %016llx %016llx ==> %x (BF=%d)\n",
1211 u0x
, test_def
.op
, u1
, u1x
,
1229 { &test_dfp_cmp_ops
,
1230 "Test DFP compare instructions"},
1231 { &test_dfp_rint_ops
,
1232 "Test DFP round instructions"},
1233 { &test_dfp_xiex_ops
,
1234 "Test DFP insert/extract instructions"},
1235 { &test_dfp_rrnd_ops
,
1236 "Test DFP reround instructions"},
1237 { &test_dfp_qua_ops
,
1238 "Test DFP quantize instructions"},
1239 { &test_dfp_quai_ops
,
1240 "Test DFP quantize immediate instructions"},
1246 #if defined(HAS_DFP)
1249 test_driver_func_t func
;
1252 while ((func
= all_tests
[i
].test_category
)) {
1253 aTest
= all_tests
[i
];
1254 printf( "%s\n", aTest
.name
);