1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*  Copyright (C) 2012 IBM
2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
3663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Author: Maynard Johnson <maynardj@us.ibm.com>
4663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
5663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng This program is free software; you can redistribute it and/or
6663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng modify it under the terms of the GNU General Public License as
7663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng published by the Free Software Foundation; either version 2 of the
8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng License, or (at your option) any later version.
9663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng This program is distributed in the hope that it will be useful, but
11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng WITHOUT ANY WARRANTY; without even the implied warranty of
12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng General Public License for more details.
14663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng You should have received a copy of the GNU General Public License
16663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng along with this program; if not, write to the Free Software
17663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 02111-1307, USA.
19663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
20663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng The GNU General Public License is contained in the file COPYING.
21663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */
22663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdio.h>
24663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdlib.h>
25663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdint.h>
26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(HAS_DFP)
28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f14 __asm__ ("fr14");
30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f15 __asm__ ("fr15");
31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f16 __asm__ ("fr16");
32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f17 __asm__ ("fr17");
33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f18 __asm__ ("fr18");
34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengregister double f19 __asm__ ("fr19");
35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef unsigned char Bool;
38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define True 1
39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define False 0
40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_CR(_arg) \
45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("mtcr  %0" : : "b"(_arg) : ALLCR );
46663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_XER(_arg) \
48663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" );
49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define GET_CR(_lval) \
51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("mfcr %0"  : "=b"(_lval) )
52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define GET_XER(_lval) \
54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
56663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define GET_CR_XER(_lval_cr,_lval_xer) \
57663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0)
58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_CR_ZERO \
60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      SET_CR(0)
61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_XER_ZERO \
63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      SET_XER(0)
64663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
65663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_CR_XER_ZERO \
66663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do { SET_CR_ZERO; SET_XER_ZERO; } while (0)
67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_FPSCR_ZERO \
69663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   do { double _d = 0.0; \
70663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \
71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define GET_FPSCR(_arg) \
74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    __asm__ __volatile__ ("mffs %0"  : "=f"(_arg) )
75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define SET_FPSCR_DRN \
77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    __asm__ __volatile__ ("mtfsf  1, %0, 0, 1" :  : "f"(f14) )
78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// The assembly-level instructions being tested
81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic Bool do_dot;
82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_dadd (void)
83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (do_dot)
85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("dadd. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
86663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   else
87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("dadd %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
88663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
90663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_dsub (void)
91663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (do_dot)
93663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("dsub. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   else
95663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("dsub %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
96663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
97663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_dmul (void)
99663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (do_dot)
101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("dmul. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   else
103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("dmul %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_ddiv (void)
107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (do_dot)
109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("ddiv. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   else
111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("ddiv %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// Quad DFP arith instructions
115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_daddq (void)
116663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (do_dot)
118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("daddq. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
119663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   else
120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("daddq %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_dsubq (void)
124663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (do_dot)
126663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("dsubq. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
127663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   else
128663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("dsubq %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
129663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
130663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
131663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_dmulq (void)
132663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
133663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (do_dot)
134663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("dmulq. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
135663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   else
136663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("dmulq %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
137663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
138663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
139663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_ddivq (void)
140663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
141663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (do_dot)
142663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("ddivq. %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   else
144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("ddivq %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_mffs (void)
148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   __asm__ __volatile__ ("mffs %0"  : "=f"(f14));
150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void _test_mtfsf (int upper)
153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (upper)
155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("mtfsf  1, %0, 0, 1" :  : "f"(f14) );
156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   else
157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      __asm__ __volatile__ ("mtfsf  1, %0, 0, 0" :  : "f"(f14) );
158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef void (*test_func_t)(void);
161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct test_table
162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_func_t test_category;
164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   char * name;
165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} test_table_t;
166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/*
168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *  345.0DD (0x2207c00000000000 0xe50)
169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *  1.2300e+5DD (0x2207c00000000000 0x14c000)
170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *  -16.0DD (0xa207c00000000000 0xe0)
171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *  0.00189DD (0x2206c00000000000 0xcf)
172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *  -4.1235DD (0xa205c00000000000 0x10a395bcf)
173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *  9.8399e+20DD (0x2209400000000000 0x253f1f534acdd4)
174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *  0DD (0x2208000000000000 0x0)
175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *  0DD (0x2208000000000000 0x0)
176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *  infDD (0x7800000000000000 0x0)
177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *  nanDD (0x7c00000000000000 0x0
178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */
179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic unsigned long long dfp128_vals[] = {
180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    // Some finite numbers
181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0x2207c00000000000ULL, 0x0000000000000e50ULL,
182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0x2207c00000000000ULL, 0x000000000014c000ULL,
183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0xa207c00000000000ULL, 0x00000000000000e0ULL,
184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0x2206c00000000000ULL, 0x00000000000000cfULL,
185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0xa205c00000000000ULL, 0x000000010a395bcfULL,
186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0x6209400000fd0000ULL, 0x00253f1f534acdd4ULL, // huge number
187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0x000400000089b000ULL, 0x0a6000d000000049ULL, // very small number
188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    // flavors of zero
189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0x2208000000000000ULL, 0x0000000000000000ULL,
190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0xa208000000000000ULL, 0x0000000000000000ULL, // negative
191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0xa248000000000000ULL, 0x0000000000000000ULL,
192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    // flavors of NAN
193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0x7c00000000000000ULL, 0x0000000000000000ULL, // quiet
194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0xfc00000000000000ULL, 0xc00100035b007700ULL,
195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0x7e00000000000000ULL, 0xfe000000d0e0a0d0ULL, // signaling
196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    // flavors of Infinity
197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0x7800000000000000ULL, 0x0000000000000000ULL,
198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0xf800000000000000ULL, 0x0000000000000000ULL, // negative
199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    0xf900000000000000ULL, 0x0000000000000000ULL
200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
201663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
202663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic unsigned long long dfp64_vals[] = {
203663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 // various finite numbers
204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0x2234000000000e50ULL,
205663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0x223400000014c000ULL,
206663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0xa2340000000000e0ULL,// negative
207663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0x22240000000000cfULL,
208663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0xa21400010a395bcfULL,// negative
209663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0x6e4d3f1f534acdd4ULL,// huge number
210663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0x000400000089b000ULL,// very small number
211663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 // flavors of zero
212663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0x2238000000000000ULL,
213663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0xa238000000000000ULL,
214663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0x4248000000000000ULL,
215663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 // flavors of NAN
216663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0x7e34000000000111ULL,
217663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0xfe000000d0e0a0d0ULL,//signaling
218663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0xfc00000000000000ULL,//quiet
219663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 // flavors of Infinity
220663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0x7800000000000000ULL,
221663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0xf800000000000000ULL,//negative
222663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                 0x7a34000000000000ULL,
223663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
224663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
225663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
226663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct dfp_test_args {
227663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int fra_idx;
228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int frb_idx;
229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} dfp_test_args_t;
230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// Index pairs from dfp64_vals or dfp128_vals array to be used with dfp_two_arg_tests
233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic dfp_test_args_t dfp_2args_x2[] = {
234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {0, 1},
235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {2, 1},
236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {3, 4},
237663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {0, 6},
238663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {2, 4},
239663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {5, 1},
240663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {5, 2},
241663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {7, 8},
242663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {7, 1},
243663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {9, 15},
244663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {8, 12},
245663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {7, 11},
246663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {13, 2},
247663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {13, 14},
248663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {15, 12},
249663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {14, 11},
250663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {12, 12},
251663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {12, 11},
252663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                  {11, 11}
253663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
254663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
255663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng// Index pairs from dfp64_vals array to be used with dfp_two_arg_tests
256663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic dfp_test_args_t dfp_2args_x1[] = {
257663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {0, 1},
258663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {2, 1},
259663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {3, 4},
260663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {0, 6},
261663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {2, 4},
262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {5, 1},
263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {5, 2},
264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {7, 1},
265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {7, 2},
266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {8, 0},
267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {8, 1},
268663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {8, 2},
269663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {7, 8},
270663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {12, 14},
271663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {12, 1},
272663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {12, 13},
273663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {12, 12},
274663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {12, 11},
275663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {11, 14},
276663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {11, 0},
277663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {11, 13},
278663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {11, 11},
279663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {14, 14},
280663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {14, 3},
281663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                    {14, 15},
282663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
283663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
284663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef enum {
285663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   LONG_TEST,
286663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   QUAD_TEST
287663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} precision_type_t;
288663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
289663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct dfp_test
290663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
291663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_func_t test_func;
292663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   const char * name;
293663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   dfp_test_args_t * targs;
294663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int num_tests;
295663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   precision_type_t precision;
296663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   const char * op;
297663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Bool cr_supported;
298663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} dfp_test_t;
299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic dfp_test_t
302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengdfp_two_arg_tests[] = {
303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     { &_test_dadd, "dadd", dfp_2args_x1, 25, LONG_TEST, "+", False},
304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     { &_test_dsub, "dsub", dfp_2args_x1, 25, LONG_TEST, "-", False},
305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     { &_test_dmul, "dmul", dfp_2args_x2, 19, LONG_TEST, "*", False},
306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     { &_test_ddiv, "ddiv", dfp_2args_x2, 19, LONG_TEST, "/", False},
307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     { &_test_daddq, "daddq", dfp_2args_x1, 25, QUAD_TEST, "+", False},
308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     { &_test_dsubq, "dsubq", dfp_2args_x1, 25, QUAD_TEST, "-", False},
309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     { &_test_dmulq, "dmulq", dfp_2args_x2, 19, QUAD_TEST, "*", False},
310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     { &_test_ddivq, "ddivq", dfp_2args_x2, 19, QUAD_TEST, "/", False},
311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                     { NULL, NULL, NULL, 0, 0, NULL}
312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
313663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
314663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void test_dfp_two_arg_ops(void)
315663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
316663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_func_t func;
317663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   unsigned long long u0, u0x, u1, u1x;
318663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   double res, d0, d1, *d0p, *d1p;
319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   double d0x, d1x, *d0xp, *d1xp;
320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int k = 0;
321663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   u0x = u1x = 0;
322663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   d0p = &d0;
323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   d0xp = &d0x;
324663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   d1p = &d1;
325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   d1xp = &d1x;
326663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   while ((func = dfp_two_arg_tests[k].test_func)) {
328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      int i, repeat = 1;
329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      dfp_test_t test_group = dfp_two_arg_tests[k];
330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      do_dot = False;
331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengagain:
333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      for (i = 0; i < test_group.num_tests; i++) {
334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         unsigned int condreg;
335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         unsigned int flags;
336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (test_group.precision == LONG_TEST) {
338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            u0 = dfp64_vals[test_group.targs[i].fra_idx];
339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            u1 = dfp64_vals[test_group.targs[i].frb_idx];
340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         } else {
341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            u0 = dfp128_vals[test_group.targs[i].fra_idx * 2];
342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            u0x = dfp128_vals[(test_group.targs[i].fra_idx * 2) + 1];
343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            u1 = dfp128_vals[test_group.targs[i].frb_idx * 2];
344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            u1x = dfp128_vals[(test_group.targs[i].frb_idx * 2) + 1];
345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         }
346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *(unsigned long long *)d0p = u0;
347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *(unsigned long long *)d1p = u1;
348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         f14 = d0;
349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         f16 = d1;
350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (test_group.precision == QUAD_TEST) {
351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            *(unsigned long long *)d0xp = u0x;
352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            *(unsigned long long *)d1xp = u1x;
353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            f15 = d0x;
354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            f17 = d1x;
355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         }
356663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
357663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         SET_FPSCR_ZERO;
358663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         SET_CR_XER_ZERO;
359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         (*func)();
360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         GET_CR(flags);
361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         res = f18;
362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
363663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         condreg = (flags & 0x000000f0) >> 4;
364663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         printf("%s%s %016llx", test_group.name, do_dot? "." : "", u0);
365663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (test_group.precision == LONG_TEST) {
366663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            printf(" %s %016llx => %016llx",
367663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                   test_group.op, u1, *((unsigned long long *)(&res)));
368663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         } else {
369663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            double resx = f19;
370663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            printf(" %016llx %s %016llx %016llx ==> %016llx %016llx",
371663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                   u0x, test_group.op, u1, u1x,
372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                   *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         }
374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         if (test_group.cr_supported)
375663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            printf(" (cr = %08x)\n", condreg);
376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         else
377663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            printf("\n");
378663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
379663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
380663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("\n");
381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (repeat) {
382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         repeat = 0;
383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         do_dot = True;
384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         goto again;
385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      k++;
387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf( "\n" );
388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
391663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid test_move_toFrom_fpscr(void)
392663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
393663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#define BFP_MAX_RM 3
394663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int shift = 0;
395663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   unsigned long long i, max_rm, expected_val;
396663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   double fpscr_in, fpscr_out;
397663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   unsigned long long * hex_fpscr_in = (unsigned long long *)&fpscr_in;
398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   unsigned long long * hex_fpscr_out = (unsigned long long *)&fpscr_out;
399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   max_rm = 4;
402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengagain:
403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* NOTE: The first time through this loop is for setting the binary
404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    * floating point rounding mode (bits 62:63 of FPSCR).  The second time
405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    * through is for setting the decimal floating point rounding mode
406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    * (bits 29:31 of FPSCR).  In the second time through this loop, the value
407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    * returned should include the final binary FP rounding mode, along with
408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    * the decimal FP rounding modes.
409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    */
410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   for (i = 0; i < max_rm; i++) {
411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      *hex_fpscr_in = (i << shift);
412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      f14 = fpscr_in;
413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _test_mtfsf(max_rm/8);
414663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      *hex_fpscr_in = 0ULL;
415663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      f14= fpscr_in;
416663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      _test_mffs();
417663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      fpscr_out = f14;
418663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (max_rm == 4) {
419663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *hex_fpscr_out &= (max_rm - 1) << shift;
420663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         expected_val = i << shift;
421663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      } else {
422663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *hex_fpscr_out &= BFP_MAX_RM | ((max_rm - 1) << shift);
423663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         expected_val = (i << shift) | BFP_MAX_RM;
424663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf("FPSCR %s floating point rounding mode %016llx == %016llx? %s\n",
427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng             (max_rm == 8) ? "decimal" : "binary",
428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng             *hex_fpscr_out, expected_val,
429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng             (expected_val == *hex_fpscr_out) ? "yes" : "no");
430663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (max_rm == 4) {
432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      max_rm = 8;
433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      shift = 32;
434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      goto again;
435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid test_rounding_modes(void)
439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int j;
441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   unsigned long long u0, u1, rm_idx;
442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   double res, d0, d1, *d0p, *d1p, fpscr;
443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   unsigned long long * hex_fpscr = (unsigned long long *)&fpscr;
444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   u0 = 0x26cc3f1f534acdd4ULL;
445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   u1 = 0x27feff197a42ba06ULL;
446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   d0p = &d0;
447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   d1p = &d1;
448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   for (j = 0; j < 12; j++) {
450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      for (rm_idx = 0; rm_idx < 8; rm_idx++) {
451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *hex_fpscr = 0ULL;
452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         __asm__ __volatile__ ("mffs %0"  : "=f"(f14));
453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         fpscr = f14;
454663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *hex_fpscr &= 0xFFFFFFF0FFFFFFFFULL;
455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *hex_fpscr |= (rm_idx << 32);
456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         f14 = fpscr;
457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         SET_FPSCR_DRN;
458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *(unsigned long long *)d0p = u0;
459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         *(unsigned long long *)d1p = u1;
460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         f14 = d0;
461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         f16 = d1;
462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         _test_dmul();
463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         res = f18;
464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         printf("test #%d: dmul with rounding mode %d: %016llx * %016llx => %016llx\n",
465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                j, (int)rm_idx, u0, u1, *((unsigned long long *)(&res)));
466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         printf("\n");
467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
468663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      // Changing the least significant bit of one of the dmul arguments give us more
469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      // opportunities for different rounding modes to yield different results which
470663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      // can then be validated.
471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      u0++;
472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic test_table_t
476663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         all_tests[] =
477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    { &test_dfp_two_arg_ops,
479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                      "Test DFP arithmetic instructions"},
480663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    { &test_rounding_modes,
481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                      "Test DFP rounding modes"},
482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    { &test_move_toFrom_fpscr,
483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    "Test move to/from FPSCR"},
484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                    { NULL, NULL }
485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
486663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif // HAS_DFP
487663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint main() {
489663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(HAS_DFP)
490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_table_t aTest;
492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   test_func_t func;
493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   int i = 0;
494663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
495663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   while ((func = all_tests[i].test_category)) {
496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      aTest = all_tests[i];
497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      printf( "%s\n", aTest.name );
498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      (*func)();
499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      i++;
500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif // HAS_DFP
503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   return 0;
504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng}
505