1457cba665b03815e2f375abd093aac35aaab303asewardj/*  Copyright (C) 2012 IBM
2457cba665b03815e2f375abd093aac35aaab303asewardj
3457cba665b03815e2f375abd093aac35aaab303asewardj Author: Maynard Johnson <maynardj@us.ibm.com>
4457cba665b03815e2f375abd093aac35aaab303asewardj
5457cba665b03815e2f375abd093aac35aaab303asewardj This program is free software; you can redistribute it and/or
6457cba665b03815e2f375abd093aac35aaab303asewardj modify it under the terms of the GNU General Public License as
7457cba665b03815e2f375abd093aac35aaab303asewardj published by the Free Software Foundation; either version 2 of the
8457cba665b03815e2f375abd093aac35aaab303asewardj License, or (at your option) any later version.
9457cba665b03815e2f375abd093aac35aaab303asewardj
10457cba665b03815e2f375abd093aac35aaab303asewardj This program is distributed in the hope that it will be useful, but
11457cba665b03815e2f375abd093aac35aaab303asewardj WITHOUT ANY WARRANTY; without even the implied warranty of
12457cba665b03815e2f375abd093aac35aaab303asewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13457cba665b03815e2f375abd093aac35aaab303asewardj General Public License for more details.
14457cba665b03815e2f375abd093aac35aaab303asewardj
15457cba665b03815e2f375abd093aac35aaab303asewardj You should have received a copy of the GNU General Public License
16457cba665b03815e2f375abd093aac35aaab303asewardj along with this program; if not, write to the Free Software
17457cba665b03815e2f375abd093aac35aaab303asewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18457cba665b03815e2f375abd093aac35aaab303asewardj 02111-1307, USA.
19457cba665b03815e2f375abd093aac35aaab303asewardj
20457cba665b03815e2f375abd093aac35aaab303asewardj The GNU General Public License is contained in the file COPYING.
21457cba665b03815e2f375abd093aac35aaab303asewardj */
22457cba665b03815e2f375abd093aac35aaab303asewardj
23457cba665b03815e2f375abd093aac35aaab303asewardj#include <stdio.h>
24457cba665b03815e2f375abd093aac35aaab303asewardj#include <stdlib.h>
25457cba665b03815e2f375abd093aac35aaab303asewardj#include <stdint.h>
26457cba665b03815e2f375abd093aac35aaab303asewardj
27457cba665b03815e2f375abd093aac35aaab303asewardj#if defined(HAS_DFP)
28457cba665b03815e2f375abd093aac35aaab303asewardj
29457cba665b03815e2f375abd093aac35aaab303asewardjtypedef union stuff {
30457cba665b03815e2f375abd093aac35aaab303asewardj   _Decimal64  dec_val;
31457cba665b03815e2f375abd093aac35aaab303asewardj   _Decimal128  dec_val128;
32457cba665b03815e2f375abd093aac35aaab303asewardj   unsigned long long u64_val;
33457cba665b03815e2f375abd093aac35aaab303asewardj   struct {
34dd690bf8d81c9119a7228446be12e3366e202176carll#if defined(VGP_ppc64le_linux)
35dd690bf8d81c9119a7228446be12e3366e202176carll      unsigned long long vall;
36dd690bf8d81c9119a7228446be12e3366e202176carll      unsigned long long valu;
37dd690bf8d81c9119a7228446be12e3366e202176carll#else
38457cba665b03815e2f375abd093aac35aaab303asewardj      unsigned long long valu;
39457cba665b03815e2f375abd093aac35aaab303asewardj      unsigned long long vall;
40dd690bf8d81c9119a7228446be12e3366e202176carll#endif
41457cba665b03815e2f375abd093aac35aaab303asewardj   } u128;
42457cba665b03815e2f375abd093aac35aaab303asewardj} dfp_val_t;
43457cba665b03815e2f375abd093aac35aaab303asewardj
44457cba665b03815e2f375abd093aac35aaab303asewardj
45457cba665b03815e2f375abd093aac35aaab303asewardjtypedef unsigned char Bool;
46457cba665b03815e2f375abd093aac35aaab303asewardj#define True 1
47457cba665b03815e2f375abd093aac35aaab303asewardj#define False 0
48457cba665b03815e2f375abd093aac35aaab303asewardj
49457cba665b03815e2f375abd093aac35aaab303asewardj
50457cba665b03815e2f375abd093aac35aaab303asewardj#define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
51457cba665b03815e2f375abd093aac35aaab303asewardj
52457cba665b03815e2f375abd093aac35aaab303asewardj#define SET_CR(_arg) \
53457cba665b03815e2f375abd093aac35aaab303asewardj      __asm__ __volatile__ ("mtcr  %0" : : "b"(_arg) : ALLCR );
54457cba665b03815e2f375abd093aac35aaab303asewardj
55457cba665b03815e2f375abd093aac35aaab303asewardj#define SET_XER(_arg) \
56457cba665b03815e2f375abd093aac35aaab303asewardj      __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" );
57457cba665b03815e2f375abd093aac35aaab303asewardj
58457cba665b03815e2f375abd093aac35aaab303asewardj#define GET_CR(_lval) \
59457cba665b03815e2f375abd093aac35aaab303asewardj      __asm__ __volatile__ ("mfcr %0"  : "=b"(_lval) )
60457cba665b03815e2f375abd093aac35aaab303asewardj
61457cba665b03815e2f375abd093aac35aaab303asewardj#define GET_XER(_lval) \
62457cba665b03815e2f375abd093aac35aaab303asewardj      __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
63457cba665b03815e2f375abd093aac35aaab303asewardj
64457cba665b03815e2f375abd093aac35aaab303asewardj#define GET_CR_XER(_lval_cr,_lval_xer) \
65457cba665b03815e2f375abd093aac35aaab303asewardj   do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0)
66457cba665b03815e2f375abd093aac35aaab303asewardj
67457cba665b03815e2f375abd093aac35aaab303asewardj#define SET_CR_ZERO \
68457cba665b03815e2f375abd093aac35aaab303asewardj      SET_CR(0)
69457cba665b03815e2f375abd093aac35aaab303asewardj
70457cba665b03815e2f375abd093aac35aaab303asewardj#define SET_XER_ZERO \
71457cba665b03815e2f375abd093aac35aaab303asewardj      SET_XER(0)
72457cba665b03815e2f375abd093aac35aaab303asewardj
73457cba665b03815e2f375abd093aac35aaab303asewardj#define SET_CR_XER_ZERO \
74457cba665b03815e2f375abd093aac35aaab303asewardj   do { SET_CR_ZERO; SET_XER_ZERO; } while (0)
75457cba665b03815e2f375abd093aac35aaab303asewardj
76457cba665b03815e2f375abd093aac35aaab303asewardj#define SET_FPSCR_ZERO \
77457cba665b03815e2f375abd093aac35aaab303asewardj   do { double _d = 0.0; \
78457cba665b03815e2f375abd093aac35aaab303asewardj        __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \
79457cba665b03815e2f375abd093aac35aaab303asewardj   } while (0)
80457cba665b03815e2f375abd093aac35aaab303asewardj
81457cba665b03815e2f375abd093aac35aaab303asewardj#define GET_FPSCR(_arg) \
82457cba665b03815e2f375abd093aac35aaab303asewardj    __asm__ __volatile__ ("mffs %0"  : "=f"(_arg) )
83457cba665b03815e2f375abd093aac35aaab303asewardj
84457cba665b03815e2f375abd093aac35aaab303asewardj#define SET_FPSCR_DRN \
85457cba665b03815e2f375abd093aac35aaab303asewardj    __asm__ __volatile__ ("mtfsf  1, %0, 0, 1" :  : "f"(f14) )
86457cba665b03815e2f375abd093aac35aaab303asewardj
87457cba665b03815e2f375abd093aac35aaab303asewardj#ifndef __powerpc64__
88457cba665b03815e2f375abd093aac35aaab303asewardjtypedef uint32_t HWord_t;
89457cba665b03815e2f375abd093aac35aaab303asewardj#else
90457cba665b03815e2f375abd093aac35aaab303asewardjtypedef uint64_t HWord_t;
91457cba665b03815e2f375abd093aac35aaab303asewardj#endif /* __powerpc64__ */
92457cba665b03815e2f375abd093aac35aaab303asewardj
93457cba665b03815e2f375abd093aac35aaab303asewardjenum BF_vals { BF_val1 = 0, BF_val2 = 1, BF_val3 =6};
94457cba665b03815e2f375abd093aac35aaab303asewardj
95457cba665b03815e2f375abd093aac35aaab303asewardj// The assembly-level instructions being tested
96256a6dab94dbd947cb1a9310e6c7b58261eddf29carllstatic void _test_dtstsf(unsigned int BF, unsigned int ref_sig, dfp_val_t *valB)
97457cba665b03815e2f375abd093aac35aaab303asewardj{
98256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   _Decimal64 f16 = valB->dec_val;
99457cba665b03815e2f375abd093aac35aaab303asewardj   register HWord_t r14 __asm__ ("r14");
100457cba665b03815e2f375abd093aac35aaab303asewardj   double f14;
101457cba665b03815e2f375abd093aac35aaab303asewardj   r14 = (HWord_t)&ref_sig;
102457cba665b03815e2f375abd093aac35aaab303asewardj
103457cba665b03815e2f375abd093aac35aaab303asewardj   __asm __volatile__ ("lfiwax %0, 0, %1" : "=f" (f14): "r" (r14));
104457cba665b03815e2f375abd093aac35aaab303asewardj   switch (BF) {
105457cba665b03815e2f375abd093aac35aaab303asewardj      case BF_val1:
106457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("dtstsf %0, %1, %2" : : "i" (BF_val1), "f" (f14), "f" (f16));
107457cba665b03815e2f375abd093aac35aaab303asewardj         break;
108457cba665b03815e2f375abd093aac35aaab303asewardj      case BF_val2:
109457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("dtstsf %0, %1, %2" : : "i" (BF_val2), "f" (f14), "f" (f16));
110457cba665b03815e2f375abd093aac35aaab303asewardj         break;
111457cba665b03815e2f375abd093aac35aaab303asewardj      case BF_val3:
112457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("dtstsf %0, %1, %2" : : "i" (BF_val3), "f" (f14), "f" (f16));
113457cba665b03815e2f375abd093aac35aaab303asewardj         break;
114457cba665b03815e2f375abd093aac35aaab303asewardj      default:
115457cba665b03815e2f375abd093aac35aaab303asewardj         fprintf(stderr, "Invalid value %d for BF\n", BF);
116457cba665b03815e2f375abd093aac35aaab303asewardj         break;
117457cba665b03815e2f375abd093aac35aaab303asewardj   }
118457cba665b03815e2f375abd093aac35aaab303asewardj}
119457cba665b03815e2f375abd093aac35aaab303asewardj
120256a6dab94dbd947cb1a9310e6c7b58261eddf29carllstatic void _test_dtstsfq(unsigned int BF, unsigned int ref_sig, dfp_val_t *valB)
121457cba665b03815e2f375abd093aac35aaab303asewardj{
122256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   _Decimal128 f16 = valB->dec_val128;
123457cba665b03815e2f375abd093aac35aaab303asewardj   register HWord_t r14 __asm__ ("r14");
124457cba665b03815e2f375abd093aac35aaab303asewardj   double f14;
125457cba665b03815e2f375abd093aac35aaab303asewardj   r14 = (HWord_t)&ref_sig;
126457cba665b03815e2f375abd093aac35aaab303asewardj
127457cba665b03815e2f375abd093aac35aaab303asewardj   __asm __volatile__ ("lfiwax %0, 0, %1" : "=f" (f14): "r" (r14));
128457cba665b03815e2f375abd093aac35aaab303asewardj   switch (BF) {
129457cba665b03815e2f375abd093aac35aaab303asewardj      case BF_val1:
130457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("dtstsfq %0, %1, %2" : : "i" (BF_val1), "f" (f14), "f" (f16));
131457cba665b03815e2f375abd093aac35aaab303asewardj         break;
132457cba665b03815e2f375abd093aac35aaab303asewardj      case BF_val2:
133457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("dtstsfq %0, %1, %2" : : "i" (BF_val2), "f" (f14), "f" (f16));
134457cba665b03815e2f375abd093aac35aaab303asewardj         break;
135457cba665b03815e2f375abd093aac35aaab303asewardj      case BF_val3:
136457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("dtstsfq %0, %1, %2" : : "i" (BF_val3), "f" (f14), "f" (f16));
137457cba665b03815e2f375abd093aac35aaab303asewardj         break;
138457cba665b03815e2f375abd093aac35aaab303asewardj      default:
139457cba665b03815e2f375abd093aac35aaab303asewardj         fprintf(stderr, "Invalid value %d for BF\n", BF);
140457cba665b03815e2f375abd093aac35aaab303asewardj         break;
141457cba665b03815e2f375abd093aac35aaab303asewardj   }
142457cba665b03815e2f375abd093aac35aaab303asewardj}
143457cba665b03815e2f375abd093aac35aaab303asewardj
144256a6dab94dbd947cb1a9310e6c7b58261eddf29carllstatic dfp_val_t _test_ddedpd(unsigned int SP, dfp_val_t *valB)
145457cba665b03815e2f375abd093aac35aaab303asewardj{
1467ea7aa23b433745c5ba163add38415aa79c92344bart   _Decimal64 ret = 0;
147457cba665b03815e2f375abd093aac35aaab303asewardj   dfp_val_t result;
148256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   _Decimal64 f16 = valB->dec_val;
149457cba665b03815e2f375abd093aac35aaab303asewardj   switch (SP) {
150457cba665b03815e2f375abd093aac35aaab303asewardj      case 0:
151457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("ddedpd. 0, %0, %1" : "=f" (ret) : "f" (f16));
152457cba665b03815e2f375abd093aac35aaab303asewardj         break;
153457cba665b03815e2f375abd093aac35aaab303asewardj      case 1:
154457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("ddedpd. 1, %0, %1" : "=f" (ret) : "f" (f16));
155457cba665b03815e2f375abd093aac35aaab303asewardj         break;
156457cba665b03815e2f375abd093aac35aaab303asewardj      case 2:
157457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("ddedpd. 2, %0, %1" : "=f" (ret) : "f" (f16));
158457cba665b03815e2f375abd093aac35aaab303asewardj         break;
159457cba665b03815e2f375abd093aac35aaab303asewardj      case 3:
160457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("ddedpd. 3, %0, %1" : "=f" (ret) : "f" (f16));
161457cba665b03815e2f375abd093aac35aaab303asewardj         break;
162457cba665b03815e2f375abd093aac35aaab303asewardj      default:
163457cba665b03815e2f375abd093aac35aaab303asewardj         fprintf(stderr, "Invalid value %d for SP\n", SP);
164457cba665b03815e2f375abd093aac35aaab303asewardj         break;
165457cba665b03815e2f375abd093aac35aaab303asewardj   }
166457cba665b03815e2f375abd093aac35aaab303asewardj   result.dec_val = ret;
167457cba665b03815e2f375abd093aac35aaab303asewardj   return result;
168457cba665b03815e2f375abd093aac35aaab303asewardj}
169457cba665b03815e2f375abd093aac35aaab303asewardj
170457cba665b03815e2f375abd093aac35aaab303asewardj
171256a6dab94dbd947cb1a9310e6c7b58261eddf29carllstatic dfp_val_t _test_ddedpdq(unsigned int SP, dfp_val_t *valB)
172457cba665b03815e2f375abd093aac35aaab303asewardj{
1737ea7aa23b433745c5ba163add38415aa79c92344bart   _Decimal128 ret = 0;
174457cba665b03815e2f375abd093aac35aaab303asewardj   dfp_val_t result;
175256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   _Decimal128 f16 = valB->dec_val128;
176457cba665b03815e2f375abd093aac35aaab303asewardj   switch (SP) {
177457cba665b03815e2f375abd093aac35aaab303asewardj      case 0:
178457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("ddedpdq 0, %0, %1" : "=f" (ret) : "f" (f16));
179457cba665b03815e2f375abd093aac35aaab303asewardj         break;
180457cba665b03815e2f375abd093aac35aaab303asewardj      case 1:
181457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("ddedpdq 1, %0, %1" : "=f" (ret) : "f" (f16));
182457cba665b03815e2f375abd093aac35aaab303asewardj         break;
183457cba665b03815e2f375abd093aac35aaab303asewardj      case 2:
184457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("ddedpdq 2, %0, %1" : "=f" (ret) : "f" (f16));
185457cba665b03815e2f375abd093aac35aaab303asewardj         break;
186457cba665b03815e2f375abd093aac35aaab303asewardj      case 3:
187457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("ddedpdq 3, %0, %1" : "=f" (ret) : "f" (f16));
188457cba665b03815e2f375abd093aac35aaab303asewardj         break;
189457cba665b03815e2f375abd093aac35aaab303asewardj      default:
190457cba665b03815e2f375abd093aac35aaab303asewardj         fprintf(stderr, "Invalid value %d for SP\n", SP);
191457cba665b03815e2f375abd093aac35aaab303asewardj         break;
192457cba665b03815e2f375abd093aac35aaab303asewardj   }
193457cba665b03815e2f375abd093aac35aaab303asewardj   result.dec_val128 = ret;
194457cba665b03815e2f375abd093aac35aaab303asewardj   return result;
195457cba665b03815e2f375abd093aac35aaab303asewardj}
196457cba665b03815e2f375abd093aac35aaab303asewardj
197256a6dab94dbd947cb1a9310e6c7b58261eddf29carllstatic dfp_val_t _test_denbcd(unsigned int S, dfp_val_t *valB)
198457cba665b03815e2f375abd093aac35aaab303asewardj{
1997ea7aa23b433745c5ba163add38415aa79c92344bart   _Decimal64 ret = 0;
200457cba665b03815e2f375abd093aac35aaab303asewardj   dfp_val_t result;
201256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   _Decimal64 f16 = valB->dec_val;
202457cba665b03815e2f375abd093aac35aaab303asewardj   switch (S) {
203457cba665b03815e2f375abd093aac35aaab303asewardj      case 0:
204457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("denbcd. 0, %0, %1" : "=f" (ret) : "f" (f16));
205457cba665b03815e2f375abd093aac35aaab303asewardj         break;
206457cba665b03815e2f375abd093aac35aaab303asewardj      case 1:
207457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("denbcd. 1, %0, %1" : "=f" (ret) : "f" (f16));
208457cba665b03815e2f375abd093aac35aaab303asewardj         break;
209457cba665b03815e2f375abd093aac35aaab303asewardj      default:
210457cba665b03815e2f375abd093aac35aaab303asewardj         fprintf(stderr, "Invalid value %d for S\n", S);
211457cba665b03815e2f375abd093aac35aaab303asewardj         break;
212457cba665b03815e2f375abd093aac35aaab303asewardj   }
213457cba665b03815e2f375abd093aac35aaab303asewardj   result.dec_val = ret;
214457cba665b03815e2f375abd093aac35aaab303asewardj   return result;
215457cba665b03815e2f375abd093aac35aaab303asewardj}
216457cba665b03815e2f375abd093aac35aaab303asewardj
217457cba665b03815e2f375abd093aac35aaab303asewardj
218256a6dab94dbd947cb1a9310e6c7b58261eddf29carllstatic dfp_val_t _test_denbcdq(unsigned int S, dfp_val_t *valB)
219457cba665b03815e2f375abd093aac35aaab303asewardj{
2207ea7aa23b433745c5ba163add38415aa79c92344bart   _Decimal128 ret = 0;
221457cba665b03815e2f375abd093aac35aaab303asewardj   dfp_val_t result;
222256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   _Decimal128 f16 = valB->dec_val128;
223457cba665b03815e2f375abd093aac35aaab303asewardj   switch (S) {
224457cba665b03815e2f375abd093aac35aaab303asewardj      case 0:
225457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("denbcdq 0, %0, %1" : "=f" (ret) : "f" (f16));
226457cba665b03815e2f375abd093aac35aaab303asewardj         break;
227457cba665b03815e2f375abd093aac35aaab303asewardj      case 1:
228457cba665b03815e2f375abd093aac35aaab303asewardj         __asm__ __volatile__ ("denbcdq 1, %0, %1" : "=f" (ret) : "f" (f16));
229457cba665b03815e2f375abd093aac35aaab303asewardj         break;
230457cba665b03815e2f375abd093aac35aaab303asewardj      default:
231457cba665b03815e2f375abd093aac35aaab303asewardj         fprintf(stderr, "Invalid value %d for S\n", S);
232457cba665b03815e2f375abd093aac35aaab303asewardj         break;
233457cba665b03815e2f375abd093aac35aaab303asewardj   }
234457cba665b03815e2f375abd093aac35aaab303asewardj   result.dec_val128 = ret;
235457cba665b03815e2f375abd093aac35aaab303asewardj   return result;
236457cba665b03815e2f375abd093aac35aaab303asewardj}
237457cba665b03815e2f375abd093aac35aaab303asewardj
238457cba665b03815e2f375abd093aac35aaab303asewardj
239256a6dab94dbd947cb1a9310e6c7b58261eddf29carlltypedef void (*test_funcp_t)(unsigned int imm, unsigned int imm2,  dfp_val_t *valB);
240256a6dab94dbd947cb1a9310e6c7b58261eddf29carlltypedef dfp_val_t (*test_func_bcdp_t)(unsigned int imm, dfp_val_t *valB);
241457cba665b03815e2f375abd093aac35aaab303asewardjtypedef void (*test_driver_func_t)(void);
242457cba665b03815e2f375abd093aac35aaab303asewardjtypedef struct test_table
243457cba665b03815e2f375abd093aac35aaab303asewardj{
244457cba665b03815e2f375abd093aac35aaab303asewardj   test_driver_func_t test_category;
245457cba665b03815e2f375abd093aac35aaab303asewardj   char * name;
246457cba665b03815e2f375abd093aac35aaab303asewardj} test_table_t;
247457cba665b03815e2f375abd093aac35aaab303asewardj
248457cba665b03815e2f375abd093aac35aaab303asewardj/*
249457cba665b03815e2f375abd093aac35aaab303asewardj *  345.0DD (0x2207c00000000000 0xe50)
250457cba665b03815e2f375abd093aac35aaab303asewardj *  1.2300e+5DD (0x2207c00000000000 0x14c000)
251457cba665b03815e2f375abd093aac35aaab303asewardj *  -16.0DD (0xa207c00000000000 0xe0)
252457cba665b03815e2f375abd093aac35aaab303asewardj *  0.00189DD (0x2206c00000000000 0xcf)
253457cba665b03815e2f375abd093aac35aaab303asewardj *  -4.1235DD (0xa205c00000000000 0x10a395bcf)
254457cba665b03815e2f375abd093aac35aaab303asewardj *  9.8399e+20DD (0x2209400000000000 0x253f1f534acdd4)
255457cba665b03815e2f375abd093aac35aaab303asewardj *  0DD (0x2208000000000000 0x0)
256457cba665b03815e2f375abd093aac35aaab303asewardj *  0DD (0x2208000000000000 0x0)
257457cba665b03815e2f375abd093aac35aaab303asewardj *  infDD (0x7800000000000000 0x0)
258457cba665b03815e2f375abd093aac35aaab303asewardj *  nanDD (0x7c00000000000000 0x0
259457cba665b03815e2f375abd093aac35aaab303asewardj */
260457cba665b03815e2f375abd093aac35aaab303asewardjstatic unsigned long long dfp128_vals[] = {
261457cba665b03815e2f375abd093aac35aaab303asewardj                                    // Some finite numbers
262457cba665b03815e2f375abd093aac35aaab303asewardj                                    0x2207c00000000000ULL, 0x0000000000000e50ULL,
263457cba665b03815e2f375abd093aac35aaab303asewardj                                    0x2207c00000000000ULL, 0x000000000014c000ULL,
264457cba665b03815e2f375abd093aac35aaab303asewardj                                    0xa207c00000000000ULL, 0x00000000000000e0ULL,
265457cba665b03815e2f375abd093aac35aaab303asewardj                                    0x2206c00000000000ULL, 0x00000000000000cfULL,
266457cba665b03815e2f375abd093aac35aaab303asewardj                                    0xa205c00000000000ULL, 0x000000010a395bcfULL,
267457cba665b03815e2f375abd093aac35aaab303asewardj                                    0x6209400000fd0000ULL, 0x00253f1f534acdd4ULL, // huge number
268457cba665b03815e2f375abd093aac35aaab303asewardj                                    0x000400000089b000ULL, 0x0a6000d000000049ULL, // very small number
269457cba665b03815e2f375abd093aac35aaab303asewardj                                    // flavors of zero
270457cba665b03815e2f375abd093aac35aaab303asewardj                                    0x2208000000000000ULL, 0x0000000000000000ULL,
271457cba665b03815e2f375abd093aac35aaab303asewardj                                    0xa208000000000000ULL, 0x0000000000000000ULL, // negative
272457cba665b03815e2f375abd093aac35aaab303asewardj                                    0xa248000000000000ULL, 0x0000000000000000ULL,
273457cba665b03815e2f375abd093aac35aaab303asewardj                                    // flavors of NAN
274457cba665b03815e2f375abd093aac35aaab303asewardj                                    0x7c00000000000000ULL, 0x0000000000000000ULL, // quiet
275457cba665b03815e2f375abd093aac35aaab303asewardj                                    0xfc00000000000000ULL, 0xc00100035b007700ULL,
276457cba665b03815e2f375abd093aac35aaab303asewardj                                    0x7e00000000000000ULL, 0xfe000000d0e0a0d0ULL, // signaling
277457cba665b03815e2f375abd093aac35aaab303asewardj                                    // flavors of Infinity
278457cba665b03815e2f375abd093aac35aaab303asewardj                                    0x7800000000000000ULL, 0x0000000000000000ULL,
279457cba665b03815e2f375abd093aac35aaab303asewardj                                    0xf800000000000000ULL, 0x0000000000000000ULL, // negative
280457cba665b03815e2f375abd093aac35aaab303asewardj                                    0xf900000000000000ULL, 0x0000000000000000ULL
281457cba665b03815e2f375abd093aac35aaab303asewardj};
282457cba665b03815e2f375abd093aac35aaab303asewardj
283457cba665b03815e2f375abd093aac35aaab303asewardjstatic unsigned long long dfp64_vals[] = {
284457cba665b03815e2f375abd093aac35aaab303asewardj                                 // various finite numbers
285457cba665b03815e2f375abd093aac35aaab303asewardj                                 0x2234000000000e50ULL,
286457cba665b03815e2f375abd093aac35aaab303asewardj                                 0x223400000014c000ULL,
287457cba665b03815e2f375abd093aac35aaab303asewardj                                 0xa2340000000000e0ULL,// negative
288457cba665b03815e2f375abd093aac35aaab303asewardj                                 0x22240000000000cfULL,
289457cba665b03815e2f375abd093aac35aaab303asewardj                                 0xa21400010a395bcfULL,// negative
290457cba665b03815e2f375abd093aac35aaab303asewardj                                 0x6e4d3f1f534acdd4ULL,// huge number
291457cba665b03815e2f375abd093aac35aaab303asewardj                                 0x000400000089b000ULL,// very small number
292457cba665b03815e2f375abd093aac35aaab303asewardj                                 // flavors of zero
293457cba665b03815e2f375abd093aac35aaab303asewardj                                 0x2238000000000000ULL,
294457cba665b03815e2f375abd093aac35aaab303asewardj                                 0xa238000000000000ULL,
295457cba665b03815e2f375abd093aac35aaab303asewardj                                 0x4248000000000000ULL,
296457cba665b03815e2f375abd093aac35aaab303asewardj                                 // flavors of NAN
297457cba665b03815e2f375abd093aac35aaab303asewardj                                 0x7e34000000000111ULL,
298457cba665b03815e2f375abd093aac35aaab303asewardj                                 0xfe000000d0e0a0d0ULL,//signaling
299457cba665b03815e2f375abd093aac35aaab303asewardj                                 0xfc00000000000000ULL,//quiet
300457cba665b03815e2f375abd093aac35aaab303asewardj                                 // flavors of Infinity
301457cba665b03815e2f375abd093aac35aaab303asewardj                                 0x7800000000000000ULL,
302457cba665b03815e2f375abd093aac35aaab303asewardj                                 0xf800000000000000ULL,//negative
303457cba665b03815e2f375abd093aac35aaab303asewardj                                 0x7a34000000000000ULL,
304457cba665b03815e2f375abd093aac35aaab303asewardj};
305457cba665b03815e2f375abd093aac35aaab303asewardj
306457cba665b03815e2f375abd093aac35aaab303asewardj/* The bcd64_vals and bdc128_vals hold the unique results of executing
307457cba665b03815e2f375abd093aac35aaab303asewardj * the ddedpd instruction on the basic dfp64 and dfp128 array values.
308457cba665b03815e2f375abd093aac35aaab303asewardj * Executing the inverse operation (denbcd) on these values with the
309457cba665b03815e2f375abd093aac35aaab303asewardj * appropriate S (signed) value should yield values approximating the
310457cba665b03815e2f375abd093aac35aaab303asewardj * original dfp values (except being 2^4 in magnitude since the decoding
311457cba665b03815e2f375abd093aac35aaab303asewardj * operation shifted the value one hex digit to the left to make room
312457cba665b03815e2f375abd093aac35aaab303asewardj * for signedness info).
313457cba665b03815e2f375abd093aac35aaab303asewardj */
314457cba665b03815e2f375abd093aac35aaab303asewardjstatic unsigned long long bcd64_vals[] = {
315457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x0000000000003450ULL,
316457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000000003450cULL,
317457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000000003450fULL,
318457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x0000000001230000ULL,
319457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000001230000cULL,
320457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000001230000fULL,
321457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x0000000000000160ULL,
322457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000000000160dULL,
323457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x0000000000000189ULL,
324457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000000000189cULL,
325457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000000000189fULL,
326457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x0000004123456789ULL,
327457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000004123456789dULL,
328457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x9839871234533354ULL,
329457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x839871234533354cULL,
330457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x839871234533354fULL,
331457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x0000000008864000ULL,
332457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000008864000cULL,
333457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000008864000fULL,
334457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x0000000000000000ULL,
335457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000000000000cULL,
336457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000000000000fULL,
337457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000000000000dULL,
338457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x0000000000000211ULL,
339457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000000000211cULL,
340457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000000000000211fULL,
341457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x0000003882028150ULL,
342457cba665b03815e2f375abd093aac35aaab303asewardj                                          0x000003882028150dULL
343457cba665b03815e2f375abd093aac35aaab303asewardj };
344457cba665b03815e2f375abd093aac35aaab303asewardj
345457cba665b03815e2f375abd093aac35aaab303asewardjstatic unsigned long long bcd128_vals[] = {
346457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x0000000000003450ULL,
347457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000000000003450cULL,
348457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000000000003450fULL,
349457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x0000000001230000ULL,
350457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000000001230000cULL,
351457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000000001230000fULL,
352457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x0000000000000160ULL,
353457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000000000000160dULL,
354457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x0000000000000189ULL,
355457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000000000000189cULL,
356457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000000000000189fULL,
357457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x0000004123456789ULL,
358457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000004123456789dULL,
359457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000097100000000ULL, 0x9839871234533354ULL,
360457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000971000000009ULL, 0x839871234533354cULL,
361457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000971000000009ULL, 0x839871234533354fULL,
362457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000010954000051ULL, 0x8000640000000049ULL,
363457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000109540000518ULL, 0x000640000000049cULL,
364457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000109540000518ULL, 0x000640000000049fULL,
365457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x0000000000000000ULL,
366457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000000000000000cULL,
367457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000000000000000fULL,
368457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000000000ULL, 0x000000000000000dULL,
369457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000080000ULL, 0x0200801330811600ULL,
370457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000800000ULL, 0x200801330811600dULL,
371457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000088170ULL, 0x0000003882028150ULL,
372457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000881700ULL, 0x000003882028150cULL,
373457cba665b03815e2f375abd093aac35aaab303asewardj                                           0x0000000000881700ULL, 0x000003882028150fULL
374457cba665b03815e2f375abd093aac35aaab303asewardj};
375457cba665b03815e2f375abd093aac35aaab303asewardj
376457cba665b03815e2f375abd093aac35aaab303asewardj// Both Long and Quad arrays of DFP values should have the same length, so it
377457cba665b03815e2f375abd093aac35aaab303asewardj// doesn't matter which array I use for calculating the following #define.
378457cba665b03815e2f375abd093aac35aaab303asewardj#define NUM_DFP_VALS (sizeof(dfp64_vals)/8)
379457cba665b03815e2f375abd093aac35aaab303asewardj
380457cba665b03815e2f375abd093aac35aaab303asewardjtypedef enum {
381457cba665b03815e2f375abd093aac35aaab303asewardj   LONG_TEST,
382457cba665b03815e2f375abd093aac35aaab303asewardj   QUAD_TEST
383457cba665b03815e2f375abd093aac35aaab303asewardj} precision_type_t;
384457cba665b03815e2f375abd093aac35aaab303asewardj
385457cba665b03815e2f375abd093aac35aaab303asewardjtypedef struct dfp_one_arg_test
386457cba665b03815e2f375abd093aac35aaab303asewardj{
387256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   test_funcp_t test_func;
388457cba665b03815e2f375abd093aac35aaab303asewardj   const char * name;
389457cba665b03815e2f375abd093aac35aaab303asewardj   precision_type_t precision;
390457cba665b03815e2f375abd093aac35aaab303asewardj   const char * op;
391457cba665b03815e2f375abd093aac35aaab303asewardj} dfp_one_arg_test_t;
392457cba665b03815e2f375abd093aac35aaab303asewardj
393457cba665b03815e2f375abd093aac35aaab303asewardjtypedef struct dfp_one_arg_bcd_test
394457cba665b03815e2f375abd093aac35aaab303asewardj{
395256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   test_func_bcdp_t test_func;
396457cba665b03815e2f375abd093aac35aaab303asewardj   const char * name;
397457cba665b03815e2f375abd093aac35aaab303asewardj   precision_type_t precision;
398457cba665b03815e2f375abd093aac35aaab303asewardj   const char * op;
399457cba665b03815e2f375abd093aac35aaab303asewardj} dfp_one_arg_bcd_test_t;
400457cba665b03815e2f375abd093aac35aaab303asewardj
401457cba665b03815e2f375abd093aac35aaab303asewardjstatic dfp_one_arg_bcd_test_t
402457cba665b03815e2f375abd093aac35aaab303asewardjdfp_test_dfp_ddedpd_tests[] = {
403457cba665b03815e2f375abd093aac35aaab303asewardj                            { &_test_ddedpd, "ddedpd", LONG_TEST, "[D->B]"},
404457cba665b03815e2f375abd093aac35aaab303asewardj                            { &_test_ddedpdq, "ddedpdq", QUAD_TEST, "[D->B]"},
405457cba665b03815e2f375abd093aac35aaab303asewardj                            { NULL, NULL, 0, NULL}
406457cba665b03815e2f375abd093aac35aaab303asewardj};
407457cba665b03815e2f375abd093aac35aaab303asewardj
408457cba665b03815e2f375abd093aac35aaab303asewardjstatic void test_dfp_ddedpd_ops(void)
409457cba665b03815e2f375abd093aac35aaab303asewardj{
410256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   test_func_bcdp_t func;
411457cba665b03815e2f375abd093aac35aaab303asewardj   dfp_val_t test_val;
412457cba665b03815e2f375abd093aac35aaab303asewardj
413457cba665b03815e2f375abd093aac35aaab303asewardj   int k = 0;
414457cba665b03815e2f375abd093aac35aaab303asewardj
415457cba665b03815e2f375abd093aac35aaab303asewardj   while ((func = dfp_test_dfp_ddedpd_tests[k].test_func)) {
4167ea7aa23b433745c5ba163add38415aa79c92344bart      int i;
417457cba665b03815e2f375abd093aac35aaab303asewardj      dfp_one_arg_bcd_test_t test_def = dfp_test_dfp_ddedpd_tests[k];
418457cba665b03815e2f375abd093aac35aaab303asewardj
419457cba665b03815e2f375abd093aac35aaab303asewardj      for (i = 0; i < NUM_DFP_VALS; i++) {
420457cba665b03815e2f375abd093aac35aaab303asewardj         unsigned int SP;
421457cba665b03815e2f375abd093aac35aaab303asewardj
422457cba665b03815e2f375abd093aac35aaab303asewardj         if (test_def.precision == LONG_TEST) {
423457cba665b03815e2f375abd093aac35aaab303asewardj            test_val.u64_val = dfp64_vals[i];
424457cba665b03815e2f375abd093aac35aaab303asewardj         } else {
425457cba665b03815e2f375abd093aac35aaab303asewardj            test_val.u128.valu = dfp128_vals[i * 2];
426457cba665b03815e2f375abd093aac35aaab303asewardj            test_val.u128.vall = dfp128_vals[(i * 2) + 1];
427457cba665b03815e2f375abd093aac35aaab303asewardj         }
428457cba665b03815e2f375abd093aac35aaab303asewardj
429457cba665b03815e2f375abd093aac35aaab303asewardj         for (SP = 0; SP < 4; SP++) {
430457cba665b03815e2f375abd093aac35aaab303asewardj            dfp_val_t result;
431256a6dab94dbd947cb1a9310e6c7b58261eddf29carll
432256a6dab94dbd947cb1a9310e6c7b58261eddf29carll	    /* There is an ABI change in how 128 bit arguments are aligned
433256a6dab94dbd947cb1a9310e6c7b58261eddf29carll             * with GCC 5.0.  The compiler generates a "note" about this
434256a6dab94dbd947cb1a9310e6c7b58261eddf29carll             * starting with GCC 4.8.  To avoid generating the "note", pass
435256a6dab94dbd947cb1a9310e6c7b58261eddf29carll             * the address of the 128-bit arguments rather then the value.
436256a6dab94dbd947cb1a9310e6c7b58261eddf29carll	     */
437256a6dab94dbd947cb1a9310e6c7b58261eddf29carll            result = (*func)(SP, &test_val);
438dd690bf8d81c9119a7228446be12e3366e202176carll            printf("%s (SP=%d) %s", test_def.name, SP, test_def.op);
439dd690bf8d81c9119a7228446be12e3366e202176carll            if (test_def.precision == LONG_TEST) {
440dd690bf8d81c9119a7228446be12e3366e202176carll               printf("%016llx ==> %016llx\n", test_val.u64_val, result.u64_val);
441dd690bf8d81c9119a7228446be12e3366e202176carll            } else {
442dd690bf8d81c9119a7228446be12e3366e202176carll               printf("%016llx %016llx ==> %016llx %016llx\n",
443dd690bf8d81c9119a7228446be12e3366e202176carll                      test_val.u128.valu, test_val.u128.vall,
444dd690bf8d81c9119a7228446be12e3366e202176carll                      result.u128.valu, result.u128.vall);
445457cba665b03815e2f375abd093aac35aaab303asewardj            }
446457cba665b03815e2f375abd093aac35aaab303asewardj         }
447457cba665b03815e2f375abd093aac35aaab303asewardj      }
448457cba665b03815e2f375abd093aac35aaab303asewardj      k++;
449457cba665b03815e2f375abd093aac35aaab303asewardj      printf( "\n" );
450457cba665b03815e2f375abd093aac35aaab303asewardj   }
451457cba665b03815e2f375abd093aac35aaab303asewardj}
452457cba665b03815e2f375abd093aac35aaab303asewardj
453457cba665b03815e2f375abd093aac35aaab303asewardjstatic dfp_one_arg_bcd_test_t
454457cba665b03815e2f375abd093aac35aaab303asewardjdfp_test_dfp_denbcd_tests[] = {
455457cba665b03815e2f375abd093aac35aaab303asewardj                            { &_test_denbcd, "denbcd", LONG_TEST, "[B->D]"},
456457cba665b03815e2f375abd093aac35aaab303asewardj                            { &_test_denbcdq, "denbcdq", QUAD_TEST, "[B->D]"},
457457cba665b03815e2f375abd093aac35aaab303asewardj                            { NULL, NULL, 0, NULL}
458457cba665b03815e2f375abd093aac35aaab303asewardj};
459457cba665b03815e2f375abd093aac35aaab303asewardj
460457cba665b03815e2f375abd093aac35aaab303asewardjstatic void test_dfp_denbcd_ops(void)
461457cba665b03815e2f375abd093aac35aaab303asewardj{
462256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   test_func_bcdp_t func;
463457cba665b03815e2f375abd093aac35aaab303asewardj   dfp_val_t test_val;
464457cba665b03815e2f375abd093aac35aaab303asewardj   int num_test_vals;
465457cba665b03815e2f375abd093aac35aaab303asewardj
466457cba665b03815e2f375abd093aac35aaab303asewardj   int k = 0;
467457cba665b03815e2f375abd093aac35aaab303asewardj
468457cba665b03815e2f375abd093aac35aaab303asewardj   while ((func = dfp_test_dfp_denbcd_tests[k].test_func)) {
4697ea7aa23b433745c5ba163add38415aa79c92344bart      int i;
470457cba665b03815e2f375abd093aac35aaab303asewardj      dfp_one_arg_bcd_test_t test_def = dfp_test_dfp_denbcd_tests[k];
471457cba665b03815e2f375abd093aac35aaab303asewardj      if (test_def.precision == LONG_TEST)
472457cba665b03815e2f375abd093aac35aaab303asewardj         num_test_vals = sizeof(bcd64_vals)/sizeof(unsigned long long);
473457cba665b03815e2f375abd093aac35aaab303asewardj      else
474457cba665b03815e2f375abd093aac35aaab303asewardj         num_test_vals = sizeof(bcd128_vals)/(2 * sizeof(unsigned long long));
475457cba665b03815e2f375abd093aac35aaab303asewardj
476457cba665b03815e2f375abd093aac35aaab303asewardj      for (i = 0; i < num_test_vals; i++) {
477457cba665b03815e2f375abd093aac35aaab303asewardj         unsigned int S;
478457cba665b03815e2f375abd093aac35aaab303asewardj         dfp_val_t result;
479457cba665b03815e2f375abd093aac35aaab303asewardj         /* The DPD-to-BCD decodings may contain up to 3 decodings for each normal DFP
480457cba665b03815e2f375abd093aac35aaab303asewardj          * value: the first is an unsigned decoding, and the other two are
481457cba665b03815e2f375abd093aac35aaab303asewardj          * signed decodings, with SP[1] set to '0' and '1' respectively at decode
482457cba665b03815e2f375abd093aac35aaab303asewardj          * time. But some of the results of decodings were duplicates, so they were
483457cba665b03815e2f375abd093aac35aaab303asewardj          * not included in the bcd64_vals and bcd128_vals arrays.
484457cba665b03815e2f375abd093aac35aaab303asewardj          *
485457cba665b03815e2f375abd093aac35aaab303asewardj          * When doing the encoding operation (denbcd), we'll attempt both S=0 and
486457cba665b03815e2f375abd093aac35aaab303asewardj          * S=1; one or the other should encode the BCD value to something close to
487457cba665b03815e2f375abd093aac35aaab303asewardj          * its original DFP value (except being 2^4 in magnitude since the decoding
488457cba665b03815e2f375abd093aac35aaab303asewardj          * operation shifted the value one hex digit to the left to make room
489457cba665b03815e2f375abd093aac35aaab303asewardj          * for signedness info).
490457cba665b03815e2f375abd093aac35aaab303asewardj          */
491457cba665b03815e2f375abd093aac35aaab303asewardj         for (S = 0; S < 2; S++) {
492457cba665b03815e2f375abd093aac35aaab303asewardj            if (test_def.precision == LONG_TEST) {
493457cba665b03815e2f375abd093aac35aaab303asewardj               test_val.u64_val = bcd64_vals[i];
494457cba665b03815e2f375abd093aac35aaab303asewardj            } else {
495457cba665b03815e2f375abd093aac35aaab303asewardj               test_val.u128.valu = bcd128_vals[i * 2];
496457cba665b03815e2f375abd093aac35aaab303asewardj               test_val.u128.vall = bcd128_vals[(i * 2) + 1];
497457cba665b03815e2f375abd093aac35aaab303asewardj            }
498457cba665b03815e2f375abd093aac35aaab303asewardj
499256a6dab94dbd947cb1a9310e6c7b58261eddf29carll	    /* There is an API change in how 128 bit arguments are aligned
500256a6dab94dbd947cb1a9310e6c7b58261eddf29carll             * with GCC 5.0.  The compiler generates a "note" about this
501256a6dab94dbd947cb1a9310e6c7b58261eddf29carll             * starting with GCC 4.8.  To avoid generating the "note", pass
502256a6dab94dbd947cb1a9310e6c7b58261eddf29carll             * the address of the 128-bit arguments rather then the value.
503256a6dab94dbd947cb1a9310e6c7b58261eddf29carll	     */
504256a6dab94dbd947cb1a9310e6c7b58261eddf29carll            result = (*func)(S, &test_val);
505dd690bf8d81c9119a7228446be12e3366e202176carll            printf("%s (S=%d) %s", test_def.name, S, test_def.op);
506dd690bf8d81c9119a7228446be12e3366e202176carll            if (test_def.precision == LONG_TEST) {
507dd690bf8d81c9119a7228446be12e3366e202176carll               printf("%016llx ==> %016llx\n", test_val.u64_val, result.u64_val);
508dd690bf8d81c9119a7228446be12e3366e202176carll            } else {
509dd690bf8d81c9119a7228446be12e3366e202176carll               printf("%016llx %016llx ==> %016llx %016llx\n",
510dd690bf8d81c9119a7228446be12e3366e202176carll                      test_val.u128.valu, test_val.u128.vall,
511dd690bf8d81c9119a7228446be12e3366e202176carll                      result.u128.valu, result.u128.vall);
512457cba665b03815e2f375abd093aac35aaab303asewardj            }
513457cba665b03815e2f375abd093aac35aaab303asewardj         }
514457cba665b03815e2f375abd093aac35aaab303asewardj      }
515457cba665b03815e2f375abd093aac35aaab303asewardj      k++;
516457cba665b03815e2f375abd093aac35aaab303asewardj      printf( "\n" );
517457cba665b03815e2f375abd093aac35aaab303asewardj   }
518457cba665b03815e2f375abd093aac35aaab303asewardj}
519457cba665b03815e2f375abd093aac35aaab303asewardj
520457cba665b03815e2f375abd093aac35aaab303asewardj
521457cba665b03815e2f375abd093aac35aaab303asewardjstatic dfp_one_arg_test_t
522457cba665b03815e2f375abd093aac35aaab303asewardjdfp_test_significance_tests[] = {
523457cba665b03815e2f375abd093aac35aaab303asewardj                                          { &_test_dtstsf,  "dtstsf", LONG_TEST, "[tSig]"},
524457cba665b03815e2f375abd093aac35aaab303asewardj                                          { &_test_dtstsfq, "dtstsfq", QUAD_TEST, "[tSig]"},
525457cba665b03815e2f375abd093aac35aaab303asewardj                                          { NULL, NULL, 0, NULL}
526457cba665b03815e2f375abd093aac35aaab303asewardj};
527457cba665b03815e2f375abd093aac35aaab303asewardj
528457cba665b03815e2f375abd093aac35aaab303asewardjstatic void test_dfp_test_significance_ops(void)
529457cba665b03815e2f375abd093aac35aaab303asewardj{
530256a6dab94dbd947cb1a9310e6c7b58261eddf29carll   test_funcp_t func;
531457cba665b03815e2f375abd093aac35aaab303asewardj   dfp_val_t test_valB;
532457cba665b03815e2f375abd093aac35aaab303asewardj   int k = 0;
533457cba665b03815e2f375abd093aac35aaab303asewardj   unsigned int BF_vals[] = {BF_val1, BF_val2, BF_val3};
534457cba665b03815e2f375abd093aac35aaab303asewardj   unsigned int reference_sig, reference_sig_vals[] = {0U, 1U, 2U, 4U, 6U, 63U};
535457cba665b03815e2f375abd093aac35aaab303asewardj   int num_reference_sig_vals = sizeof(reference_sig_vals)/sizeof(unsigned int);
536457cba665b03815e2f375abd093aac35aaab303asewardj
537457cba665b03815e2f375abd093aac35aaab303asewardj   while ((func = dfp_test_significance_tests[k].test_func)) {
538457cba665b03815e2f375abd093aac35aaab303asewardj      int i;
539457cba665b03815e2f375abd093aac35aaab303asewardj      dfp_one_arg_test_t test_def = dfp_test_significance_tests[k];
540457cba665b03815e2f375abd093aac35aaab303asewardj
541457cba665b03815e2f375abd093aac35aaab303asewardj      for (i = 0; i < NUM_DFP_VALS; i++) {
542457cba665b03815e2f375abd093aac35aaab303asewardj         int j;
543457cba665b03815e2f375abd093aac35aaab303asewardj         if (test_def.precision == LONG_TEST) {
544457cba665b03815e2f375abd093aac35aaab303asewardj            test_valB.u64_val = dfp64_vals[i];
545457cba665b03815e2f375abd093aac35aaab303asewardj         } else {
546457cba665b03815e2f375abd093aac35aaab303asewardj            test_valB.u128.valu = dfp128_vals[i * 2];
547457cba665b03815e2f375abd093aac35aaab303asewardj            test_valB.u128.vall = dfp128_vals[(i * 2) + 1];
548457cba665b03815e2f375abd093aac35aaab303asewardj         }
549457cba665b03815e2f375abd093aac35aaab303asewardj
550457cba665b03815e2f375abd093aac35aaab303asewardj         for (j = 0; j < num_reference_sig_vals; j++) {
551457cba665b03815e2f375abd093aac35aaab303asewardj            int bf_idx, BF;
552457cba665b03815e2f375abd093aac35aaab303asewardj            reference_sig = reference_sig_vals[j];
553457cba665b03815e2f375abd093aac35aaab303asewardj            for (bf_idx = 0; bf_idx < sizeof(BF_vals)/sizeof(unsigned int); bf_idx++) {
554457cba665b03815e2f375abd093aac35aaab303asewardj               unsigned int condreg;
555457cba665b03815e2f375abd093aac35aaab303asewardj               unsigned int flags;
556457cba665b03815e2f375abd093aac35aaab303asewardj               BF = BF_vals[bf_idx];
557457cba665b03815e2f375abd093aac35aaab303asewardj               SET_FPSCR_ZERO;
558457cba665b03815e2f375abd093aac35aaab303asewardj               SET_CR_XER_ZERO;
559256a6dab94dbd947cb1a9310e6c7b58261eddf29carll               /* There is an ABI change in how 128 bit arguments are aligned
560256a6dab94dbd947cb1a9310e6c7b58261eddf29carll                * with GCC 5.0.  The compiler generates a "note" about this
561256a6dab94dbd947cb1a9310e6c7b58261eddf29carll                * starting with GCC 4.9.  To avoid generating the "note", pass
562256a6dab94dbd947cb1a9310e6c7b58261eddf29carll                * the address of the 128-bit arguments rather then the value.
563256a6dab94dbd947cb1a9310e6c7b58261eddf29carll                */
564256a6dab94dbd947cb1a9310e6c7b58261eddf29carll               (*func)(BF, reference_sig, &test_valB);
565457cba665b03815e2f375abd093aac35aaab303asewardj               GET_CR(flags);
566457cba665b03815e2f375abd093aac35aaab303asewardj
567457cba665b03815e2f375abd093aac35aaab303asewardj               condreg = ((flags >> (4 * (7-BF)))) & 0xf;
568dd690bf8d81c9119a7228446be12e3366e202176carll               printf("%s (ref_sig=%d) %s", test_def.name, reference_sig, test_def.op);
569dd690bf8d81c9119a7228446be12e3366e202176carll               if (test_def.precision == LONG_TEST) {
570dd690bf8d81c9119a7228446be12e3366e202176carll                  printf("%016llx", test_valB.u64_val);
571dd690bf8d81c9119a7228446be12e3366e202176carll               } else {
572dd690bf8d81c9119a7228446be12e3366e202176carll                  printf("%016llx %016llx", test_valB.u128.valu, test_valB.u128.vall);
573457cba665b03815e2f375abd093aac35aaab303asewardj               }
574457cba665b03815e2f375abd093aac35aaab303asewardj               printf(" => %x (BF=%d)\n", condreg, BF);
575457cba665b03815e2f375abd093aac35aaab303asewardj            }
576457cba665b03815e2f375abd093aac35aaab303asewardj         }
577457cba665b03815e2f375abd093aac35aaab303asewardj         printf( "\n" );
578457cba665b03815e2f375abd093aac35aaab303asewardj      }
579457cba665b03815e2f375abd093aac35aaab303asewardj      k++;
580457cba665b03815e2f375abd093aac35aaab303asewardj   }
581457cba665b03815e2f375abd093aac35aaab303asewardj}
582457cba665b03815e2f375abd093aac35aaab303asewardj
583457cba665b03815e2f375abd093aac35aaab303asewardjstatic test_table_t
584457cba665b03815e2f375abd093aac35aaab303asewardj         all_tests[] =
585457cba665b03815e2f375abd093aac35aaab303asewardj{
586457cba665b03815e2f375abd093aac35aaab303asewardj                    { &test_dfp_test_significance_ops,
587457cba665b03815e2f375abd093aac35aaab303asewardj                      "Test DFP test significance instructions"},
588457cba665b03815e2f375abd093aac35aaab303asewardj                    { &test_dfp_ddedpd_ops,
589457cba665b03815e2f375abd093aac35aaab303asewardj                      "Test DFP DPD-to-BCD instructions"},
590457cba665b03815e2f375abd093aac35aaab303asewardj                    { &test_dfp_denbcd_ops,
591457cba665b03815e2f375abd093aac35aaab303asewardj                      "Test DFP BCD-to-DPD instructions"},
592457cba665b03815e2f375abd093aac35aaab303asewardj                    { NULL, NULL }
593457cba665b03815e2f375abd093aac35aaab303asewardj};
594457cba665b03815e2f375abd093aac35aaab303asewardj#endif // HAS_DFP
595457cba665b03815e2f375abd093aac35aaab303asewardj
596457cba665b03815e2f375abd093aac35aaab303asewardjint main() {
597457cba665b03815e2f375abd093aac35aaab303asewardj#if defined(HAS_DFP)
598457cba665b03815e2f375abd093aac35aaab303asewardj
599457cba665b03815e2f375abd093aac35aaab303asewardj   test_table_t aTest;
600457cba665b03815e2f375abd093aac35aaab303asewardj   test_driver_func_t func;
601457cba665b03815e2f375abd093aac35aaab303asewardj   int i = 0;
602457cba665b03815e2f375abd093aac35aaab303asewardj
603457cba665b03815e2f375abd093aac35aaab303asewardj   while ((func = all_tests[i].test_category)) {
604457cba665b03815e2f375abd093aac35aaab303asewardj      aTest = all_tests[i];
605457cba665b03815e2f375abd093aac35aaab303asewardj      printf( "%s\n", aTest.name );
606457cba665b03815e2f375abd093aac35aaab303asewardj      (*func)();
607457cba665b03815e2f375abd093aac35aaab303asewardj      i++;
608457cba665b03815e2f375abd093aac35aaab303asewardj   }
609457cba665b03815e2f375abd093aac35aaab303asewardj
610457cba665b03815e2f375abd093aac35aaab303asewardj#endif // HAS_DFP
611457cba665b03815e2f375abd093aac35aaab303asewardj   return 0;
612457cba665b03815e2f375abd093aac35aaab303asewardj}
613