1 /*  Copyright (C) 2012 IBM
2 
3  Author: Maynard Johnson <maynardj@us.ibm.com>
4 
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.
9 
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.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18  02111-1307, USA.
19 
20  The GNU General Public License is contained in the file COPYING.
21  */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <string.h>
27 
28 #if defined(HAS_DFP)
29 
30 register double f14 __asm__ ("fr14");
31 register double f15 __asm__ ("fr15");
32 register double f16 __asm__ ("fr16");
33 register double f17 __asm__ ("fr17");
34 register double f18 __asm__ ("fr18");
35 register double f19 __asm__ ("fr19");
36 
37 
38 typedef unsigned char Bool;
39 #define True 1
40 #define False 0
41 
42 
43 #define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
44 
45 #define SET_CR(_arg) \
46       __asm__ __volatile__ ("mtcr  %0" : : "b"(_arg) : ALLCR );
47 
48 #define SET_XER(_arg) \
49       __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" );
50 
51 #define GET_CR(_lval) \
52       __asm__ __volatile__ ("mfcr %0"  : "=b"(_lval) )
53 
54 #define GET_XER(_lval) \
55       __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
56 
57 #define GET_CR_XER(_lval_cr,_lval_xer) \
58    do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0)
59 
60 #define SET_CR_ZERO \
61       SET_CR(0)
62 
63 #define SET_XER_ZERO \
64       SET_XER(0)
65 
66 #define SET_CR_XER_ZERO \
67    do { SET_CR_ZERO; SET_XER_ZERO; } while (0)
68 
69 #define SET_FPSCR_ZERO \
70    do { double _d = 0.0; \
71         __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \
72    } while (0)
73 
74 #define GET_FPSCR(_arg) \
75     __asm__ __volatile__ ("mffs %0"  : "=f"(_arg) )
76 
77 #define SET_FPSCR_DRN \
78     __asm__ __volatile__ ("mtfsf  1, %0, 0, 1" :  : "f"(f14) )
79 
80 
81 // The assembly-level instructions being tested
_test_drintx(int R,int RMC)82 static void _test_drintx(int R, int RMC)
83 {
84    if (RMC < 0 || RMC > 3 || R < 0 || R > 1) {
85       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", R, RMC);
86       return;
87    }
88    switch (RMC) {
89       case 0:
90          if (R)
91             __asm__ __volatile__ ("drintx 1, %0, %1, 0" : "=f" (f18) : "f" (f16));
92          else
93             __asm__ __volatile__ ("drintx 0, %0, %1, 0" : "=f" (f18) : "f" (f16));
94          break;
95       case 1:
96          if (R)
97             __asm__ __volatile__ ("drintx 1, %0, %1, 1" : "=f" (f18) : "f" (f16));
98          else
99             __asm__ __volatile__ ("drintx 0, %0, %1, 1" : "=f" (f18) : "f" (f16));
100          break;
101       case 2:
102          if (R)
103             __asm__ __volatile__ ("drintx 1, %0, %1, 2" : "=f" (f18) : "f" (f16));
104          else
105             __asm__ __volatile__ ("drintx 0, %0, %1, 2" : "=f" (f18) : "f" (f16));
106          break;
107       case 3:
108          if (R)
109             __asm__ __volatile__ ("drintx 1, %0, %1, 3" : "=f" (f18) : "f" (f16));
110          else
111             __asm__ __volatile__ ("drintx 0, %0, %1, 3" : "=f" (f18) : "f" (f16));
112          break;
113       default:
114          break;
115    }
116 }
117 
_test_drintn(int R,int RMC)118 static void _test_drintn(int R, int RMC)
119 {
120    if (RMC < 0 || RMC > 3 || R < 0 || R > 1) {
121       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", R, RMC);
122       return;
123    }
124    switch (RMC) {
125       case 0:
126          if (R)
127             __asm__ __volatile__ ("drintn 1, %0, %1, 0" : "=f" (f18) : "f" (f16));
128          else
129             __asm__ __volatile__ ("drintn 0, %0, %1, 0" : "=f" (f18) : "f" (f16));
130          break;
131       case 1:
132          if (R)
133             __asm__ __volatile__ ("drintn 1, %0, %1, 1" : "=f" (f18) : "f" (f16));
134          else
135             __asm__ __volatile__ ("drintn 0, %0, %1, 1" : "=f" (f18) : "f" (f16));
136          break;
137       case 2:
138          if (R)
139             __asm__ __volatile__ ("drintn 1, %0, %1, 2" : "=f" (f18) : "f" (f16));
140          else
141             __asm__ __volatile__ ("drintn 0, %0, %1, 2" : "=f" (f18) : "f" (f16));
142          break;
143       case 3:
144          if (R)
145             __asm__ __volatile__ ("drintn 1, %0, %1, 3" : "=f" (f18) : "f" (f16));
146          else
147             __asm__ __volatile__ ("drintn 0, %0, %1, 3" : "=f" (f18) : "f" (f16));
148          break;
149       default:
150          break;
151    }
152 }
153 
154 
_test_diex(int a,int b)155 static void _test_diex(int a __attribute__((unused)), int b __attribute__((unused)))
156 {
157    __asm__ __volatile__ ("diex  %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
158 }
159 
_test_dxex(int a,int b)160 static void _test_dxex(int a __attribute__((unused)), int b __attribute__((unused)))
161 {
162    __asm__ __volatile__ ("dxex  %0, %1" : "=f" (f18) : "f" (f16));
163 }
164 
_test_dcmpo(int BF,int x)165 static void _test_dcmpo(int BF, int x __attribute__((unused)))
166 {
167    if (BF < 0 || BF > 7) {
168       fprintf(stderr, "Invalid input to asm test: a=%d\n", BF);
169       return;
170    }
171    switch (BF) {
172       case 0:
173          __asm__ __volatile__ ("dcmpo  0, %0, %1" :  : "f" (f14),"f" (f16));
174          break;
175       case 1:
176          __asm__ __volatile__ ("dcmpo  1, %0, %1" :  : "f" (f14),"f" (f16));
177          break;
178       case 2:
179          __asm__ __volatile__ ("dcmpo  2, %0, %1" :  : "f" (f14),"f" (f16));
180          break;
181       case 3:
182          __asm__ __volatile__ ("dcmpo  3, %0, %1" :  : "f" (f14),"f" (f16));
183          break;
184       case 4:
185          __asm__ __volatile__ ("dcmpo  4, %0, %1" :  : "f" (f14),"f" (f16));
186          break;
187       case 5:
188          __asm__ __volatile__ ("dcmpo  5, %0, %1" :  : "f" (f14),"f" (f16));
189          break;
190       case 6:
191          __asm__ __volatile__ ("dcmpo  6, %0, %1" :  : "f" (f14),"f" (f16));
192          break;
193       case 7:
194          __asm__ __volatile__ ("dcmpo  7, %0, %1" :  : "f" (f14),"f" (f16));
195          break;
196       default:
197          break;
198    }
199 }
200 
_test_dcmpu(int BF,int x)201 static void _test_dcmpu(int BF, int x __attribute__((unused)))
202 {
203    if (BF < 0 || BF > 7) {
204       fprintf(stderr, "Invalid input to asm test: a=%d\n", BF);
205       return;
206    }
207    switch (BF) {
208       case 0:
209          __asm__ __volatile__ ("dcmpu  0, %0, %1" :  : "f" (f14),"f" (f16));
210          break;
211       case 1:
212          __asm__ __volatile__ ("dcmpu  1, %0, %1" :  : "f" (f14),"f" (f16));
213          break;
214       case 2:
215          __asm__ __volatile__ ("dcmpu  2, %0, %1" :  : "f" (f14),"f" (f16));
216          break;
217       case 3:
218          __asm__ __volatile__ ("dcmpu  3, %0, %1" :  : "f" (f14),"f" (f16));
219          break;
220       case 4:
221          __asm__ __volatile__ ("dcmpu  4, %0, %1" :  : "f" (f14),"f" (f16));
222          break;
223       case 5:
224          __asm__ __volatile__ ("dcmpu  5, %0, %1" :  : "f" (f14),"f" (f16));
225          break;
226       case 6:
227          __asm__ __volatile__ ("dcmpu  6, %0, %1" :  : "f" (f14),"f" (f16));
228          break;
229       case 7:
230          __asm__ __volatile__ ("dcmpu  7, %0, %1" :  : "f" (f14),"f" (f16));
231          break;
232       default:
233          break;
234    }
235 }
236 
237 // Quad instruction testing
_test_drintxq(int R,int RMC)238 static void _test_drintxq(int R, int RMC)
239 {
240    if (RMC < 0 || RMC > 3 || R < 0 || R > 1) {
241       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", R, RMC);
242       return;
243    }
244    switch (RMC) {
245       case 0:
246          if (R)
247             __asm__ __volatile__ ("drintxq 1, %0, %1, 0" : "=f" (f18) : "f" (f16));
248          else
249             __asm__ __volatile__ ("drintxq 0, %0, %1, 0" : "=f" (f18) : "f" (f16));
250          break;
251       case 1:
252          if (R)
253             __asm__ __volatile__ ("drintxq 1, %0, %1, 1" : "=f" (f18) : "f" (f16));
254          else
255             __asm__ __volatile__ ("drintxq 0, %0, %1, 1" : "=f" (f18) : "f" (f16));
256          break;
257       case 2:
258          if (R)
259             __asm__ __volatile__ ("drintxq 1, %0, %1, 2" : "=f" (f18) : "f" (f16));
260          else
261             __asm__ __volatile__ ("drintxq 0, %0, %1, 2" : "=f" (f18) : "f" (f16));
262          break;
263       case 3:
264          if (R)
265             __asm__ __volatile__ ("drintxq 1, %0, %1, 3" : "=f" (f18) : "f" (f16));
266          else
267             __asm__ __volatile__ ("drintxq 0, %0, %1, 3" : "=f" (f18) : "f" (f16));
268          break;
269       default:
270          break;
271    }
272 }
273 
_test_drintnq(int R,int RMC)274 static void _test_drintnq(int R, int RMC)
275 {
276    if (RMC < 0 || RMC > 3 || R < 0 || R > 1) {
277       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", R, RMC);
278       return;
279    }
280    switch (RMC) {
281       case 0:
282          if (R)
283             __asm__ __volatile__ ("drintnq 1, %0, %1, 0" : "=f" (f18) : "f" (f16));
284          else
285             __asm__ __volatile__ ("drintnq 0, %0, %1, 0" : "=f" (f18) : "f" (f16));
286          break;
287       case 1:
288          if (R)
289             __asm__ __volatile__ ("drintnq 1, %0, %1, 1" : "=f" (f18) : "f" (f16));
290          else
291             __asm__ __volatile__ ("drintnq 0, %0, %1, 1" : "=f" (f18) : "f" (f16));
292          break;
293       case 2:
294          if (R)
295             __asm__ __volatile__ ("drintnq 1, %0, %1, 2" : "=f" (f18) : "f" (f16));
296          else
297             __asm__ __volatile__ ("drintnq 0, %0, %1, 2" : "=f" (f18) : "f" (f16));
298          break;
299       case 3:
300          if (R)
301             __asm__ __volatile__ ("drintnq 1, %0, %1, 3" : "=f" (f18) : "f" (f16));
302          else
303             __asm__ __volatile__ ("drintnq 0, %0, %1, 3" : "=f" (f18) : "f" (f16));
304          break;
305       default:
306          break;
307    }
308 }
309 
_test_diexq(int a,int b)310 static void _test_diexq(int a __attribute__((unused)), int b __attribute__((unused)))
311 {
312    __asm__ __volatile__ ("diexq  %0, %1, %2" : "=f" (f18) : "f" (f14),"f" (f16));
313 }
314 
_test_dxexq(int a,int b)315 static void _test_dxexq(int a __attribute__((unused)), int b __attribute__((unused)))
316 {
317    __asm__ __volatile__ ("dxexq  %0, %1" : "=f" (f18) : "f" (f16));
318 }
319 
_test_dcmpoq(int BF,int x)320 static void _test_dcmpoq(int BF, int x __attribute__((unused)))
321 {
322    if (BF < 0 || BF > 7) {
323       fprintf(stderr, "Invalid input to asm test: a=%d\n", BF );
324       return;
325    }
326    switch (BF) {
327       case 0:
328          __asm__ __volatile__ ("dcmpoq  0, %0, %1" :  : "f" (f14),"f" (f16));
329          break;
330       case 1:
331          __asm__ __volatile__ ("dcmpoq  1, %0, %1" :  : "f" (f14),"f" (f16));
332          break;
333       case 2:
334          __asm__ __volatile__ ("dcmpoq  2, %0, %1" :  : "f" (f14),"f" (f16));
335          break;
336       case 3:
337          __asm__ __volatile__ ("dcmpoq  3, %0, %1" :  : "f" (f14),"f" (f16));
338          break;
339       case 4:
340          __asm__ __volatile__ ("dcmpoq  4, %0, %1" :  : "f" (f14),"f" (f16));
341          break;
342       case 5:
343          __asm__ __volatile__ ("dcmpoq  5, %0, %1" :  : "f" (f14),"f" (f16));
344          break;
345       case 6:
346          __asm__ __volatile__ ("dcmpoq  6, %0, %1" :  : "f" (f14),"f" (f16));
347          break;
348       case 7:
349          __asm__ __volatile__ ("dcmpoq  7, %0, %1" :  : "f" (f14),"f" (f16));
350          break;
351       default:
352          break;
353    }
354 }
355 
_test_dcmpuq(int BF,int x)356 static void _test_dcmpuq(int BF, int x __attribute__((unused)))
357 {
358    if (BF < 0 || BF > 7) {
359       fprintf(stderr, "Invalid input to asm test: a=%d\n", BF);
360       return;
361    }
362    switch (BF) {
363       case 0:
364          __asm__ __volatile__ ("dcmpuq  0, %0, %1" :  : "f" (f14),"f" (f16));
365          break;
366       case 1:
367          __asm__ __volatile__ ("dcmpuq  1, %0, %1" :  : "f" (f14),"f" (f16));
368          break;
369       case 2:
370          __asm__ __volatile__ ("dcmpuq  2, %0, %1" :  : "f" (f14),"f" (f16));
371          break;
372       case 3:
373          __asm__ __volatile__ ("dcmpuq  3, %0, %1" :  : "f" (f14),"f" (f16));
374          break;
375       case 4:
376          __asm__ __volatile__ ("dcmpuq  4, %0, %1" :  : "f" (f14),"f" (f16));
377          break;
378       case 5:
379          __asm__ __volatile__ ("dcmpuq  5, %0, %1" :  : "f" (f14),"f" (f16));
380          break;
381       case 6:
382          __asm__ __volatile__ ("dcmpuq  6, %0, %1" :  : "f" (f14),"f" (f16));
383          break;
384       case 7:
385          __asm__ __volatile__ ("dcmpuq  7, %0, %1" :  : "f" (f14),"f" (f16));
386          break;
387       default:
388          break;
389    }
390 }
391 
_test_drrnd(int x,int RMC)392 static void _test_drrnd(int x __attribute__((unused)), int RMC)
393 {
394    if (RMC < 0 || RMC > 31) {
395       fprintf(stderr, "Invalid input to asm test: a=%d\n", RMC);
396       return;
397    }
398    switch (RMC) {
399       case 0:
400          __asm__ __volatile__ ("drrnd %0, %1, %2, 0" : "=f" (f18) : "f" (f14), "f" (f16));
401          break;
402       case 1:
403          __asm__ __volatile__ ("drrnd %0, %1, %2, 1" : "=f" (f18) : "f" (f14), "f" (f16));
404          break;
405       case 2:
406          __asm__ __volatile__ ("drrnd %0, %1, %2, 2" : "=f" (f18) : "f" (f14), "f" (f16));
407          break;
408       case 3:
409          __asm__ __volatile__ ("drrnd %0, %1, %2, 3" : "=f" (f18) : "f" (f14), "f" (f16));
410          break;
411       default:
412          break;
413    }
414 }
415 
_test_drrndq(int x,int RMC)416 static void _test_drrndq(int x __attribute__((unused)), int RMC)
417 {
418    if (RMC < 0 || RMC > 3) {
419       fprintf(stderr, "Invalid input to asm test: a=%dn", RMC);
420       return;
421    }
422    switch (RMC) {
423       case 0:
424          __asm__ __volatile__ ("drrndq %0, %1, %2, 0" : "=f" (f18) : "f" (f14), "f" (f16));
425          break;
426       case 1:
427          __asm__ __volatile__ ("drrndq %0, %1, %2, 1" : "=f" (f18) : "f" (f14), "f" (f16));
428          break;
429       case 2:
430          __asm__ __volatile__ ("drrndq %0, %1, %2, 2" : "=f" (f18) : "f" (f14), "f" (f16));
431          break;
432       case 3:
433          __asm__ __volatile__ ("drrndq %0, %1, %2, 3" : "=f" (f18) : "f" (f14), "f" (f16));
434          break;
435       default:
436          break;
437    }
438 }
439 
_test_dqua(int x,int RMC)440 static void _test_dqua(int x __attribute__((unused)), int RMC)
441 {
442    if (RMC < 0 || RMC > 3) {
443       fprintf(stderr, "Invalid input to asm test: a=%d\n", RMC);
444       return;
445    }
446    switch (RMC) {
447       case 0:
448          __asm__ __volatile__ ("dqua %0, %1, %2, 0" : "=f" (f18) : "f" (f14), "f" (f16));
449          break;
450       case 1:
451          __asm__ __volatile__ ("dqua %0, %1, %2, 1" : "=f" (f18) : "f" (f14), "f" (f16));
452          break;
453       case 2:
454          __asm__ __volatile__ ("dqua %0, %1, %2, 2" : "=f" (f18) : "f" (f14), "f" (f16));
455          break;
456       case 3:
457          __asm__ __volatile__ ("dqua %0, %1, %2, 3" : "=f" (f18) : "f" (f14), "f" (f16));
458          break;
459       default:
460          break;
461    }
462 }
463 
_test_dquaq(int x,int RMC)464 static void _test_dquaq(int x __attribute__((unused)), int RMC)
465 {
466    if (RMC < 0 || RMC > 3) {
467       fprintf(stderr, "Invalid input to asm test: a=%d\n", RMC);
468       return;
469    }
470    switch (RMC) {
471       case 0:
472          __asm__ __volatile__ ("dquaq %0, %1, %2, 0" : "=f" (f18) : "f" (f14), "f" (f16));
473          break;
474       case 1:
475          __asm__ __volatile__ ("dquaq %0, %1, %2, 1" : "=f" (f18) : "f" (f14), "f" (f16));
476          break;
477       case 2:
478          __asm__ __volatile__ ("dquaq %0, %1, %2, 2" : "=f" (f18) : "f" (f14), "f" (f16));
479          break;
480       case 3:
481          __asm__ __volatile__ ("dquaq %0, %1, %2, 3" : "=f" (f18) : "f" (f14), "f" (f16));
482          break;
483       default:
484          break;
485    }
486 }
487 
488 static int TE_vals[] = { -16, -2, 0, 5};
489 #define TE_VAL_LEN sizeof(TE_vals)/sizeof(int)
__is_TE_val(int x)490 static Bool __is_TE_val(int x)
491 {
492    int i;
493    for (i = 0; i < TE_VAL_LEN; i++) {
494       if (x==TE_vals[i])
495          return True;
496    }
497    return False;
498 }
499 
_test_dquai(int TE,int RMC)500 static void _test_dquai(int TE, int RMC)
501 {
502    if (RMC < 0 || RMC > 3 || !__is_TE_val(TE)) {
503       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", TE, RMC);
504       return;
505    }
506    switch (RMC) {
507       case 0:
508          switch (TE) {
509             case -16:
510                __asm__ __volatile__ ("dquai -16, %0, %1, 0" : "=f" (f18) : "f" (f16));
511                break;
512             case -2:
513                __asm__ __volatile__ ("dquai  -2, %0, %1, 0" : "=f" (f18) : "f" (f16));
514                break;
515             case 0:
516                __asm__ __volatile__ ("dquai   0, %0, %1, 0" : "=f" (f18) : "f" (f16));
517                break;
518             case 5:
519                __asm__ __volatile__ ("dquai   5, %0, %1, 0" : "=f" (f18) : "f" (f16));
520                break;
521             default:
522                break;
523          }
524          break;
525       case 1:
526          switch (TE) {
527             case -16:
528                __asm__ __volatile__ ("dquai -16, %0, %1, 1" : "=f" (f18) : "f" (f16));
529                break;
530             case -2:
531                __asm__ __volatile__ ("dquai  -2, %0, %1, 1" : "=f" (f18) : "f" (f16));
532                break;
533             case 0:
534                __asm__ __volatile__ ("dquai   0, %0, %1, 1" : "=f" (f18) : "f" (f16));
535                break;
536             case 5:
537                __asm__ __volatile__ ("dquai   5, %0, %1, 1" : "=f" (f18) : "f" (f16));
538                break;
539             default:
540                break;
541          }
542          break;
543       case 2:
544          switch (TE) {
545             case -16:
546                __asm__ __volatile__ ("dquai -16, %0, %1, 2" : "=f" (f18) : "f" (f16));
547                break;
548             case -2:
549                __asm__ __volatile__ ("dquai  -2, %0, %1, 2" : "=f" (f18) : "f" (f16));
550                break;
551             case 0:
552                __asm__ __volatile__ ("dquai   0, %0, %1, 2" : "=f" (f18) : "f" (f16));
553                break;
554             case 5:
555                __asm__ __volatile__ ("dquai   5, %0, %1, 2" : "=f" (f18) : "f" (f16));
556                break;
557             default:
558                break;
559          }
560          break;
561       case 3:
562          switch (TE) {
563             case -16:
564                __asm__ __volatile__ ("dquai -16, %0, %1, 3" : "=f" (f18) : "f" (f16));
565                break;
566             case -2:
567                __asm__ __volatile__ ("dquai  -2, %0, %1, 3" : "=f" (f18) : "f" (f16));
568                break;
569             case 0:
570                __asm__ __volatile__ ("dquai   0, %0, %1, 3" : "=f" (f18) : "f" (f16));
571                break;
572             case 5:
573                __asm__ __volatile__ ("dquai   5, %0, %1, 3" : "=f" (f18) : "f" (f16));
574                break;
575             default:
576                break;
577          }
578          break;
579       default:
580          break;
581    }
582 }
583 
_test_dquaiq(int TE,int RMC)584 static void _test_dquaiq(int TE, int RMC)
585 {
586    if (RMC < 0 || RMC > 3 || !__is_TE_val(TE)) {
587       fprintf(stderr, "Invalid inputs to asm test: a=%d, b=%d\n", TE, RMC);
588       return;
589    }
590    switch (RMC) {
591       case 0:
592          switch (TE) {
593             case -16:
594                __asm__ __volatile__ ("dquaiq -16, %0, %1, 0" : "=f" (f18) : "f" (f16));
595                break;
596             case -2:
597                __asm__ __volatile__ ("dquaiq  -2, %0, %1, 0" : "=f" (f18) : "f" (f16));
598                break;
599             case 0:
600                __asm__ __volatile__ ("dquaiq   0, %0, %1, 0" : "=f" (f18) : "f" (f16));
601                break;
602             case 5:
603                __asm__ __volatile__ ("dquaiq   5, %0, %1, 0" : "=f" (f18) : "f" (f16));
604                break;
605             default:
606                break;
607          }
608          break;
609       case 1:
610          switch (TE) {
611             case -16:
612                __asm__ __volatile__ ("dquaiq -16, %0, %1, 1" : "=f" (f18) : "f" (f16));
613                break;
614             case -2:
615                __asm__ __volatile__ ("dquaiq  -2, %0, %1, 1" : "=f" (f18) : "f" (f16));
616                break;
617             case 0:
618                __asm__ __volatile__ ("dquaiq   0, %0, %1, 1" : "=f" (f18) : "f" (f16));
619                break;
620             case 5:
621                __asm__ __volatile__ ("dquaiq   5, %0, %1, 1" : "=f" (f18) : "f" (f16));
622                break;
623             default:
624                break;
625          }
626          break;
627       case 2:
628          switch (TE) {
629             case -16:
630                __asm__ __volatile__ ("dquaiq -16, %0, %1, 2" : "=f" (f18) : "f" (f16));
631                break;
632             case -2:
633                __asm__ __volatile__ ("dquaiq  -2, %0, %1, 2" : "=f" (f18) : "f" (f16));
634                break;
635             case 0:
636                __asm__ __volatile__ ("dquaiq   0, %0, %1, 2" : "=f" (f18) : "f" (f16));
637                break;
638             case 5:
639                __asm__ __volatile__ ("dquaiq   5, %0, %1, 2" : "=f" (f18) : "f" (f16));
640                break;
641             default:
642                break;
643          }
644          break;
645       case 3:
646          switch (TE) {
647             case -16:
648                __asm__ __volatile__ ("dquaiq -16, %0, %1, 3" : "=f" (f18) : "f" (f16));
649                break;
650             case -2:
651                __asm__ __volatile__ ("dquaiq  -2, %0, %1, 3" : "=f" (f18) : "f" (f16));
652                break;
653             case 0:
654                __asm__ __volatile__ ("dquaiq   0, %0, %1, 3" : "=f" (f18) : "f" (f16));
655                break;
656             case 5:
657                __asm__ __volatile__ ("dquaiq   5, %0, %1, 3" : "=f" (f18) : "f" (f16));
658                break;
659             default:
660                break;
661          }
662          break;
663       default:
664          break;
665    }
666 }
667 
668 
669 typedef void (*test_func_t)(int a, int b);
670 typedef void (*test_driver_func_t)(void);
671 typedef struct test_table
672 {
673    test_driver_func_t test_category;
674    char * name;
675 } test_table_t;
676 
677 /*
678  *  345.0DD (0x2207c00000000000 0xe50)
679  *  1.2300e+5DD (0x2207c00000000000 0x14c000)
680  *  -16.0DD (0xa207c00000000000 0xe0)
681  *  0.00189DD (0x2206c00000000000 0xcf)
682  *  -4.1235DD (0xa205c00000000000 0x10a395bcf)
683  *  9.8399e+20DD (0x2209400000000000 0x253f1f534acdd4)
684  *  0DD (0x2208000000000000 0x0)
685  *  0DD (0x2208000000000000 0x0)
686  *  infDD (0x7800000000000000 0x0)
687  *  nanDD (0x7c00000000000000 0x0
688  */
689 static unsigned long long dfp128_vals[] = {
690                                     // Some finite numbers
691                                     0x2207c00000000000ULL, 0x0000000000000e50ULL,
692                                     0x2207c00000000000ULL, 0x000000000014c000ULL,
693                                     0xa207c00000000000ULL, 0x00000000000000e0ULL,
694                                     0x2206c00000000000ULL, 0x00000000000000cfULL,
695                                     0xa205c00000000000ULL, 0x000000010a395bcfULL,
696                                     0x6209400000fd0000ULL, 0x00253f1f534acdd4ULL, // huge number
697                                     0x000400000089b000ULL, 0x0a6000d000000049ULL, // very small number
698                                     // flavors of zero
699                                     0x2208000000000000ULL, 0x0000000000000000ULL,
700                                     0xa208000000000000ULL, 0x0000000000000000ULL, // negative
701                                     0xa248000000000000ULL, 0x0000000000000000ULL,
702                                     // flavors of NAN
703                                     0x7c00000000000000ULL, 0x0000000000000000ULL, // quiet
704                                     0xfc00000000000000ULL, 0xc00100035b007700ULL,
705                                     0x7e00000000000000ULL, 0xfe000000d0e0a0d0ULL, // signaling
706                                     // flavors of Infinity
707                                     0x7800000000000000ULL, 0x0000000000000000ULL,
708                                     0xf800000000000000ULL, 0x0000000000000000ULL, // negative
709                                     0xf900000000000000ULL, 0x0000000000000000ULL
710 };
711 
712 static unsigned long long dfp64_vals[] = {
713                                  // various finite numbers
714                                  0x2234000000000e50ULL,
715                                  0x223400000014c000ULL,
716                                  0xa2340000000000e0ULL,// negative
717                                  0x22240000000000cfULL,
718                                  0xa21400010a395bcfULL,// negative
719                                  0x6e4d3f1f534acdd4ULL,// huge number
720                                  0x000400000089b000ULL,// very small number
721                                  // flavors of zero
722                                  0x2238000000000000ULL,
723                                  0xa238000000000000ULL,
724                                  0x4248000000000000ULL,
725                                  // flavors of NAN
726                                  0x7e34000000000111ULL,
727                                  0xfe000000d0e0a0d0ULL,//signaling
728                                  0xfc00000000000000ULL,//quiet
729                                  // flavors of Infinity
730                                  0x7800000000000000ULL,
731                                  0xf800000000000000ULL,//negative
732                                  0x7a34000000000000ULL,
733 };
734 
735 // Both Long and Quad arrays of DFP values should have the same length.
736 // If that length is changed, t
737 #define NUM_DFP_VALS (sizeof(dfp64_vals)/8)
738 
739 typedef struct dfp_test_args {
740    int fra_idx;
741    int frb_idx;
742 } dfp_test_args_t;
743 
744 
745 // Index pairs from dfp64_vals array to be used with dfp_two_arg_tests
746 static dfp_test_args_t dfp_2args_x1[] = {
747                                     {0, 1},
748                                     {2, 1},
749                                     {3, 4},
750                                     {0, 6},
751                                     {2, 4},
752                                     {5, 1},
753                                     {5, 2},
754                                     {7, 1},
755                                     {7, 2},
756                                     {8, 0},
757                                     {8, 1},
758                                     {8, 2},
759                                     {7, 8},
760                                     {12, 14},
761                                     {12, 1},
762                                     {12, 13},
763                                     {12, 12},
764                                     {12, 11},
765                                     {11, 14},
766                                     {11, 0},
767                                     {11, 13},
768                                     {11, 11},
769                                     {14, 14},
770                                     {14, 3},
771                                     {14, 15},
772 };
773 
774 typedef enum {
775    LONG_TEST,
776    QUAD_TEST
777 } precision_type_t;
778 
779 typedef struct dfp_test
780 {
781    test_func_t test_func;
782    const char * name;
783    dfp_test_args_t * targs;
784    int num_tests;
785    precision_type_t precision;
786    const char * op;
787 } dfp_test_t;
788 
789 typedef struct dfp_one_arg_test
790 {
791    test_func_t test_func;
792    const char * name;
793    precision_type_t precision;
794    const char * op;
795 } dfp_one_arg_test_t;
796 
797 
798 static dfp_one_arg_test_t
799 dfp_quai_tests[] = {
800                     { &_test_dquai, "dquai", LONG_TEST, "[QI]"},
801                     { &_test_dquaiq, "dquaiq", QUAD_TEST, "[QI]"},
802                     { NULL, NULL, 0, NULL}
803 };
804 
test_dfp_quai_ops(void)805 static void test_dfp_quai_ops(void)
806 {
807    test_func_t func;
808    unsigned long long u0, u0x;
809    double res, d0, *d0p, d0x, *d0xp;
810 
811    int k = 0;
812    u0 = u0x = 0;
813    d0p = &d0;
814    d0xp = &d0x;
815 
816    while ((func = dfp_quai_tests[k].test_func)) {
817       int i;
818       dfp_one_arg_test_t test_def = dfp_quai_tests[k];
819 
820       for (i = 0; i < NUM_DFP_VALS; i++) {
821          int TE, RMC;
822 
823          if (test_def.precision == LONG_TEST) {
824             u0 = dfp64_vals[i];
825          } else {
826             u0 = dfp128_vals[i * 2];
827             u0x = dfp128_vals[(i * 2) + 1];
828          }
829          *(unsigned long long *)d0p = u0;
830          f16 = d0;
831          if (test_def.precision == QUAD_TEST) {
832             *(unsigned long long *)d0xp = u0x;
833             f17 = d0x;
834          }
835 
836          for (TE = 0; TE < TE_VAL_LEN; TE++) {
837             for (RMC = 0; RMC < 4; RMC++) {
838                (*func)(TE_vals[TE], RMC);
839                res = f18;
840                printf("%s (RMC=%2d, TE=%3d) %s %016llx", test_def.name, RMC,
841                       TE_vals[TE], test_def.op, u0);
842                if (test_def.precision == LONG_TEST) {
843                   printf(" => %016llx\n",
844                          *((unsigned long long *)(&res)));
845                } else {
846                   double resx = f19;
847                   printf(" %016llx ==> %016llx %016llx\n",
848                          u0x, *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
849                }
850             }
851          }
852       }
853       k++;
854       printf( "\n" );
855    }
856 }
857 
858 
859 static dfp_test_t
860 dfp_qua_tests[] = {
861                    { &_test_dqua, "dqua", dfp_2args_x1, 25, LONG_TEST, "[Q]"},
862                    { &_test_dquaq, "dquaq", dfp_2args_x1, 25, QUAD_TEST, "[Q]"},
863                    { NULL, NULL, NULL, 0, 0, NULL}
864 };
865 
test_dfp_qua_ops(void)866 static void test_dfp_qua_ops(void)
867 {
868    test_func_t func;
869    unsigned long long u0, u0x, u1, u1x;
870    double res, d0, d1, *d0p, *d1p;
871    double d0x, d1x, *d0xp, *d1xp;
872    int k = 0;
873    u0x = u1x = 0;
874    d0p = &d0;
875    d0xp = &d0x;
876    d1p = &d1;
877    d1xp = &d1x;
878 
879    while ((func = dfp_qua_tests[k].test_func)) {
880       int i, RMC;
881       dfp_test_t test_def = dfp_qua_tests[k];
882 
883       for (i = 0; i < test_def.num_tests; i++) {
884          if (test_def.precision == LONG_TEST) {
885             u0 = dfp64_vals[test_def.targs[i].fra_idx];
886             u1 = dfp64_vals[test_def.targs[i].frb_idx];
887          } else {
888             u0 = dfp128_vals[test_def.targs[i].fra_idx * 2];
889             u0x = dfp128_vals[(test_def.targs[i].fra_idx * 2) + 1];
890             u1 = dfp128_vals[test_def.targs[i].frb_idx * 2];
891             u1x = dfp128_vals[(test_def.targs[i].frb_idx * 2) + 1];
892          }
893          *(unsigned long long *)d0p = u0;
894          *(unsigned long long *)d1p = u1;
895          f14 = d0;
896          f16 = d1;
897          if (test_def.precision == QUAD_TEST) {
898             *(unsigned long long *)d0xp = u0x;
899             *(unsigned long long *)d1xp = u1x;
900             f15 = d0x;
901             f17 = d1x;
902          }
903          for (RMC = 0; RMC < 4; RMC++) {
904             (*func)(-1, RMC);
905             res = f18;
906             printf("%s (RMC=%2d) %s %016llx", test_def.name, RMC, test_def.op, u0);
907             if (test_def.precision == LONG_TEST) {
908                printf(", %016llx => %016llx\n", u1, *((unsigned long long *)(&res)));
909             } else {
910                double resx = f19;
911                printf(" %016llx, %016llx %016llx ==> %016llx %016llx\n",u0x, u1, u1x,
912                       *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
913             }
914          }
915       }
916       k++;
917       printf( "\n" );
918    }
919 }
920 
921 
922 static dfp_one_arg_test_t
923 dfp_rrnd_tests[] = {
924                     { &_test_drrnd, "drrnd", LONG_TEST, "[RR]"},
925                     { &_test_drrndq, "drrndq", QUAD_TEST, "[RR]"},
926                     { NULL, NULL, 0, NULL}
927 };
928 
test_dfp_rrnd_ops(void)929 static void test_dfp_rrnd_ops(void)
930 {
931    test_func_t func;
932    unsigned long long u0, u0x;
933    double res, d0, *d0p, d0x, *d0xp, reference_sig, *reference_sig_p;
934    long long reference_sig_vals[] = {0ULL, 2ULL, 6ULL, 63ULL};
935    int num_reference_sig_vals = sizeof(reference_sig_vals)/sizeof(long long);
936 
937    int k = 0;
938    u0 = u0x = 0;
939    d0p = &d0;
940    d0xp = &d0x;
941    reference_sig_p = &reference_sig;
942 
943    while ((func = dfp_rrnd_tests[k].test_func)) {
944       int i, j;
945       dfp_one_arg_test_t test_def = dfp_rrnd_tests[k];
946 
947       for (i = 0; i < NUM_DFP_VALS; i++) {
948          int RMC;
949 
950          if (test_def.precision == LONG_TEST) {
951             u0 = dfp64_vals[i];
952          } else {
953             u0 = dfp128_vals[i * 2];
954             u0x = dfp128_vals[(i * 2) + 1];
955          }
956          *(unsigned long long *)d0p = u0;
957          f16 = d0;
958          if (test_def.precision == QUAD_TEST) {
959             *(unsigned long long *)d0xp = u0x;
960             f17 = d0x;
961          }
962 
963          for (j = 0; j < num_reference_sig_vals; j++) {
964             *(long long *)reference_sig_p = reference_sig_vals[j];
965             f14 = reference_sig;
966             for (RMC = 0; RMC < 4; RMC++) {
967                (*func)(-1, RMC);
968                res = f18;
969                printf("%s (RMC=%d, ref sig=%d) %s%016llx", test_def.name, RMC,
970                       (int)reference_sig_vals[j], test_def.op, u0);
971                if (test_def.precision == LONG_TEST) {
972                   printf(" => %016llx\n",
973                          *((unsigned long long *)(&res)));
974                } else {
975                   double resx = f19;
976                   printf(" %016llx ==> %016llx %016llx\n",
977                          u0x, *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
978                }
979             }
980          }
981       }
982       k++;
983       printf( "\n" );
984    }
985 }
986 
987 
988 static dfp_one_arg_test_t
989 dfp_xiex_tests[] = {
990                        { &_test_diex, "diex", LONG_TEST, ">>"},
991                        { &_test_diexq, "diexq", QUAD_TEST, ">>"},
992                        { &_test_dxex, "dxex", LONG_TEST, "<<"},
993                        { &_test_dxexq, "dxexq", QUAD_TEST, "<<"},
994                        { NULL, NULL, 0, NULL}
995 };
996 
test_dfp_xiex_ops(void)997 static void test_dfp_xiex_ops(void)
998 {
999    test_func_t func;
1000    unsigned long long u0, u0x;
1001    double res, d0, *d0p, d0x, *d0xp, target_exp, *target_exp_p;
1002    /* The first two positions are placeholders and will be filled in later,
1003     * based on the precision of the DFP argument.
1004     */
1005    long long target_exp_vals[] = {0ULL, 0ULL, 0ULL, -1ULL, -2ULL, -3ULL, -4ULL, -5ULL};
1006    int num_exp_vals = sizeof(target_exp_vals)/sizeof(long long);
1007    int k = 0;
1008    u0 = u0x = 0;
1009    d0p = &d0;
1010    d0xp = &d0x;
1011    target_exp_p = &target_exp;
1012 
1013    while ((func = dfp_xiex_tests[k].test_func)) {
1014       int i;
1015       Bool insert_insn = False;
1016       dfp_one_arg_test_t test_def = dfp_xiex_tests[k];
1017 
1018       if (!strncmp(test_def.name, "di", 2))
1019          insert_insn = True;
1020 
1021       if (test_def.precision == QUAD_TEST) {
1022          target_exp_vals[0] = 12288ULL; // > max biased exponent
1023          target_exp_vals[1] = 5235ULL;
1024       } else {
1025          target_exp_vals[0] = 768ULL; // > max biased exponent
1026          target_exp_vals[1] = 355ULL;
1027       }
1028 
1029       for (i = 0; i < NUM_DFP_VALS; i++) {
1030          unsigned int j;
1031 
1032          if (test_def.precision == QUAD_TEST) {
1033             u0 = dfp128_vals[i * 2];
1034             u0x = dfp128_vals[(i * 2) + 1];
1035          } else {
1036             u0 = dfp64_vals[i];
1037          }
1038          *(unsigned long long *)d0p = u0;
1039          f16 = d0;
1040          if (test_def.precision == QUAD_TEST) {
1041             *(unsigned long long *)d0xp = u0x;
1042             f17 = d0x;
1043          }
1044 
1045          if (!insert_insn) {
1046             // This is just for extract insns (dexex[q])
1047             (*func)(0, 0);
1048             res = f18;
1049             printf("%s %s ", test_def.name, test_def.op);
1050             if (test_def.precision == LONG_TEST) {
1051                printf("%016llx => %016llx\n", u0,
1052                       *((unsigned long long *)(&res)));
1053             } else {
1054                double resx = f19;
1055                printf("%016llx %016llx ==> %016llx %016llx\n", u0, u0x,
1056                       *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
1057             }
1058             continue;
1059          }
1060          // The following for-loop is just for insert insns (diex[q])
1061          for (j = 0; j < num_exp_vals; j++) {
1062             *(long long *)target_exp_p = target_exp_vals[j];
1063             f14 = target_exp;
1064             (*func)(0, 0);
1065             res = f18;
1066             printf("%s %s %5d, ", test_def.name, test_def.op, (int)target_exp_vals[j]);
1067 
1068             if (test_def.precision == LONG_TEST) {
1069                printf("%016llx => %016llx\n", u0,
1070                       *((unsigned long long *)(&res)));
1071             } else {
1072                double resx = f19;
1073                printf("%016llx %016llx ==> %016llx %016llx\n", u0, u0x,
1074                       *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
1075             }
1076          }
1077       }
1078       k++;
1079       printf( "\n" );
1080    }
1081 }
1082 
1083 static dfp_one_arg_test_t
1084 dfp_rint_tests[] = {
1085                     { &_test_drintn, "drintn", LONG_TEST, "~"},
1086                     { &_test_drintnq, "drintnq", QUAD_TEST, "~"},
1087                     { &_test_drintx, "drintx", LONG_TEST, "~"},
1088                     { &_test_drintxq, "drintxq", QUAD_TEST, "~"},
1089                     { NULL, NULL, 0, NULL}
1090 };
1091 
test_dfp_rint_ops(void)1092 static void test_dfp_rint_ops(void)
1093 {
1094    test_func_t func;
1095    unsigned long long u0, u0x;
1096    double res, d0, *d0p, d0x, *d0xp;
1097    int k = 0;
1098    u0 = u0x = 0;
1099    d0p = &d0;
1100    d0xp = &d0x;
1101 
1102    while ((func = dfp_rint_tests[k].test_func)) {
1103       int i;
1104       dfp_one_arg_test_t test_def = dfp_rint_tests[k];
1105 
1106       for (i = 0; i < NUM_DFP_VALS; i++) {
1107          int R, RMC;
1108 
1109          if (test_def.precision == LONG_TEST) {
1110             u0 = dfp64_vals[i];
1111          } else {
1112             u0 = dfp128_vals[i * 2];
1113             u0x = dfp128_vals[(i * 2) + 1];
1114          }
1115          *(unsigned long long *)d0p = u0;
1116          f16 = d0;
1117          if (test_def.precision == QUAD_TEST) {
1118             *(unsigned long long *)d0xp = u0x;
1119             f17 = d0x;
1120          }
1121 
1122          for (R = 0; R < 2; R++) {
1123             for (RMC = 0; RMC < 4; RMC++) {
1124                (*func)(R, RMC);
1125                res = f18;
1126                printf("%s (RM=%d) %s%016llx", test_def.name, (RMC + (R << 2)), test_def.op, u0);
1127                if (test_def.precision == LONG_TEST) {
1128                   printf(" => %016llx\n",
1129                          *((unsigned long long *)(&res)));
1130                } else {
1131                   double resx = f19;
1132                   printf(" %016llx ==> %016llx %016llx\n",
1133                          u0x, *((unsigned long long *)(&res)), *((unsigned long long *)(&resx)));
1134                }
1135             }
1136          }
1137       }
1138       k++;
1139       printf( "\n" );
1140    }
1141 }
1142 
1143 static dfp_test_t
1144 dfp_cmp_tests[] = {
1145                      { &_test_dcmpo, "dcmpo", dfp_2args_x1, 25, LONG_TEST, "<>"},
1146                      { &_test_dcmpoq, "dcmpoq", dfp_2args_x1, 25, QUAD_TEST, "<>"},
1147                      { &_test_dcmpu, "dcmpu", dfp_2args_x1, 25, LONG_TEST, "<>"},
1148                      { &_test_dcmpuq, "dcmpuq", dfp_2args_x1, 25, QUAD_TEST, "<>"},
1149                      { NULL, NULL, NULL, 0, 0, NULL}
1150 };
1151 
test_dfp_cmp_ops(void)1152 static void test_dfp_cmp_ops(void)
1153 {
1154    test_func_t func;
1155    unsigned long long u0, u0x, u1, u1x;
1156    double d0, d1, *d0p, *d1p;
1157    double d0x, d1x, *d0xp, *d1xp;
1158    /* BF is a 3-bit instruction field that indicates the CR field in which the
1159     * result of the compare should be placed.  We won't iterate through all
1160     * 8 possible BF values since storing compare results to a given field is
1161     * a well-tested mechanism in VEX.  But we will test two BF values, just as
1162     * a sniff-test.
1163     */
1164    int k = 0, BF;
1165    u0x = u1x = 0;
1166    d0p = &d0;
1167    d0xp = &d0x;
1168    d1p = &d1;
1169    d1xp = &d1x;
1170 
1171    while ((func = dfp_cmp_tests[k].test_func)) {
1172       int i, repeat = 1;
1173       dfp_test_t test_def = dfp_cmp_tests[k];
1174       BF = 0;
1175 
1176 again:
1177       for (i = 0; i < test_def.num_tests; i++) {
1178          unsigned int condreg;
1179          unsigned int flags;
1180 
1181          if (test_def.precision == LONG_TEST) {
1182             u0 = dfp64_vals[test_def.targs[i].fra_idx];
1183             u1 = dfp64_vals[test_def.targs[i].frb_idx];
1184          } else {
1185             u0 = dfp128_vals[test_def.targs[i].fra_idx * 2];
1186             u0x = dfp128_vals[(test_def.targs[i].fra_idx * 2) + 1];
1187             u1 = dfp128_vals[test_def.targs[i].frb_idx * 2];
1188             u1x = dfp128_vals[(test_def.targs[i].frb_idx * 2) + 1];
1189          }
1190          *(unsigned long long *)d0p = u0;
1191          *(unsigned long long *)d1p = u1;
1192          f14 = d0;
1193          f16 = d1;
1194          if (test_def.precision == QUAD_TEST) {
1195             *(unsigned long long *)d0xp = u0x;
1196             *(unsigned long long *)d1xp = u1x;
1197             f15 = d0x;
1198             f17 = d1x;
1199          }
1200 
1201          SET_FPSCR_ZERO;
1202          SET_CR_XER_ZERO;
1203          (*func)(BF, 0);
1204          GET_CR(flags);
1205 
1206          condreg = ((flags >> (4 * (7-BF)))) & 0xf;
1207          printf("%s %016llx", test_def.name, u0);
1208          if (test_def.precision == LONG_TEST) {
1209             printf(" %s %016llx => %x (BF=%d)\n",
1210                    test_def.op, u1, condreg, BF);
1211          } else {
1212             printf(" %016llx %s %016llx %016llx ==> %x (BF=%d)\n",
1213                    u0x, test_def.op, u1, u1x,
1214                    condreg, BF);
1215          }
1216       }
1217       if (repeat) {
1218          repeat = 0;
1219          BF = 5;
1220          goto again;
1221       }
1222       k++;
1223       printf( "\n" );
1224    }
1225 }
1226 
1227 
1228 static test_table_t
1229          all_tests[] =
1230 {
1231                     { &test_dfp_cmp_ops,
1232                       "Test DFP compare instructions"},
1233                     { &test_dfp_rint_ops,
1234                       "Test DFP round instructions"},
1235                     { &test_dfp_xiex_ops,
1236                       "Test DFP insert/extract instructions"},
1237                     { &test_dfp_rrnd_ops,
1238                       "Test DFP reround instructions"},
1239                     { &test_dfp_qua_ops,
1240                       "Test DFP quantize instructions"},
1241                     { &test_dfp_quai_ops,
1242                       "Test DFP quantize immediate instructions"},
1243                     { NULL, NULL }
1244 };
1245 #endif // HAS_DFP
1246 
main()1247 int main() {
1248 #if defined(HAS_DFP)
1249 
1250    test_table_t aTest;
1251    test_driver_func_t func;
1252    int i = 0;
1253 
1254    while ((func = all_tests[i].test_category)) {
1255       aTest = all_tests[i];
1256       printf( "%s\n", aTest.name );
1257       (*func)();
1258       i++;
1259    }
1260 
1261 #endif // HAS_DFP
1262    return 0;
1263 }
1264