1#include <stdio.h>
2#include <stdint.h>
3#include "dfp_utils.h"
4#define __STDC_WANT_DEC_FP__ 1
5#include <float.h>
6
7#ifndef PFPO_FUNCTIONS
8#define PFPO_FUNCTIONS
9#define PFPO_F32_TO_D32   0x01080500
10#define PFPO_D32_TO_F32   0x01050800
11#define PFPO_F32_TO_D64   0x01090500
12#define PFPO_D32_TO_F64   0x01060800
13#define PFPO_F32_TO_D128  0x010A0500
14#define PFPO_D32_TO_F128  0x01070800
15#define PFPO_F64_TO_D32   0x01080600
16#define PFPO_D64_TO_F32   0x01050900
17#define PFPO_F64_TO_D64   0x01090600
18#define PFPO_D64_TO_F64   0x01060900
19#define PFPO_F64_TO_D128  0x010A0600
20#define PFPO_D64_TO_F128  0x01070900
21#define PFPO_D128_TO_F64  0x01060A00
22#define PFPO_F128_TO_D32  0x01080700
23#define PFPO_D128_TO_F32  0x01050A00
24#define PFPO_F128_TO_D64  0x01090700
25#define PFPO_D128_TO_F64  0x01060A00
26#define PFPO_F128_TO_D128 0x010A0700
27#define PFPO_D128_TO_F128 0x01070A00
28
29#define PFPO(initial, src_type, dst_type, fn_code, round, ret_code, cc) \
30({                                                                      \
31  register src_type src_reg asm("f4") = initial;                        \
32  register dst_type dst_reg asm("f0");                                  \
33  register unsigned long fn asm("0") = fn_code | (round & 0xf);         \
34  register unsigned int ret asm("1");                                   \
35  asm volatile(".short 0x010a\n\t"                                      \
36               "ipm %2\n\t"                                             \
37               "srl %2,28\n\t"                                          \
38               :"=f"(dst_reg), "=d"(ret), "=d" (cc)                     \
39               : "f"(src_reg), "d"(fn));                                \
40  ret_code = ret;                                                       \
41  dst_reg;                                                              \
42})
43
44#endif /* PFPO_FUNCTIONS */
45
46/* Test BFP <-> DFP conversions */
47int main()
48{
49  int cc;
50  uint8_t i, j;
51  unsigned int ret_code;
52
53  float f32;
54  double f64;
55  long double f128;
56
57  _Decimal32 d32;
58  _Decimal64 d64;
59  _Decimal128 d128;
60
61  float f32_in[] = {123.5656789, FLT_MAX, FLT_MIN};
62  double f64_in[] = {123456789999.5656789, DBL_MIN, DBL_MAX};
63  long double f128_in[] = {1234567812345678912345678912.5656789L,
64                           LDBL_MIN, LDBL_MAX};
65
66  _Decimal32 d32_in[] = {123.5656789DF, DEC32_MAX, DEC32_MIN};
67  _Decimal64 d64_in[] = {123456789999.5656789DD, DEC64_MIN, DEC64_MAX};
68  _Decimal128 d128_in[] = {1234567812345678912345678912.5656789DL,
69                           DEC128_MIN, DEC128_MAX};
70
71 /* valid function code */
72  PFPO(0., double, _Decimal64, 0x81090600, 0, ret_code, cc);
73  printf("pfpo test: function=%x ret=%d cc=%d\n", 0x81090600, ret_code, cc);
74
75 /* invalid function code */
76  PFPO(0., double, _Decimal64, 0x81990600, 0, ret_code, cc);
77  printf("pfpo test: function=%x ret=%d cc=%d\n", 0x81990600, ret_code, cc);
78
79  for (i = 0; i < 16; i++) {
80    if (i < 2 || i > 7) {
81
82      /* f32 -> d32 */
83      for(j = 0; j < 3; j++) {
84        printf("f32 -> d32: round=%x ", i);
85        printf("%f -> ", f32_in[j]);
86        d32 = PFPO(f32_in[j], float, _Decimal32, PFPO_F32_TO_D32,
87                   i, ret_code, cc);
88        DFP_VAL_PRINT(d32, _Decimal32);
89        printf(" ret=%d cc=%d\n", ret_code, cc);
90      }
91
92      /* f32 -> d64 */
93      for(j = 0; j < 3; j++) {
94        printf("f32 -> d64: round=%x ", i);
95        printf("%f -> ", f32_in[j]);
96        d64 = PFPO(f32_in[j], float, _Decimal64, PFPO_F32_TO_D64,
97                   i, ret_code, cc);
98        DFP_VAL_PRINT(d64, _Decimal64);
99        printf(" ret=%d cc=%d\n", ret_code, cc);
100      }
101
102      /* f32 -> d128 */
103      for(j = 0; j < 3; j++) {
104        printf("f32 -> d128: round=%x ", i);
105        printf("%f -> ", f32_in[j]);
106        d128 = PFPO(f32_in[j], float, _Decimal128, PFPO_F32_TO_D128,
107                    i, ret_code, cc);
108        DFP_VAL_PRINT(d128, _Decimal128);
109        printf(" ret=%d cc=%d\n", ret_code, cc);
110      }
111
112      /* f64 -> d32 */
113      for(j = 0; j < 3; j++) {
114        printf("f64 -> d32: round=%x ", i);
115        printf("%lf -> ", f64_in[j]);
116        d32 = PFPO(f64_in[j], double, _Decimal32, PFPO_F64_TO_D32,
117                   i, ret_code, cc);
118        DFP_VAL_PRINT(d32, _Decimal32);
119        printf(" ret=%d cc=%d\n", ret_code, cc);
120      }
121
122      /* f64 -> d64 */
123      for(j = 0; j < 3; j++) {
124        printf("f64 -> d64: round=%x ", i);
125        printf("%lf -> ", f64_in[j]);
126        d64 = PFPO(f64_in[j], double, _Decimal64, PFPO_F64_TO_D64,
127                   i, ret_code, cc);
128        DFP_VAL_PRINT(d64, _Decimal64);
129        printf(" ret=%d cc=%d\n", ret_code, cc);
130      }
131
132      /* f64 -> d128 */
133      for(j = 0; j < 3; j++) {
134        printf("f64 -> d128: round=%x ", i);
135        printf("%lf -> ", f64_in[j]);
136        d128 = PFPO(f64_in[j], double, _Decimal128, PFPO_F64_TO_D128,
137                   i, ret_code, cc);
138        DFP_VAL_PRINT(d128, _Decimal128);
139        printf(" ret=%d cc=%d\n", ret_code, cc);
140      }
141
142      /* f128 -> d32 */
143      for(j = 0; j < 3; j++) {
144        printf("f128 -> d32: round=%x ", i);
145        printf("%Lf -> ", f128_in[j]);
146        d32 = PFPO(f128_in[j], long double, _Decimal32, PFPO_F128_TO_D32,
147                   i, ret_code, cc);
148        DFP_VAL_PRINT(d32, _Decimal32);
149        printf(" ret=%d cc=%d\n", ret_code, cc);
150      }
151
152      /* f128 -> d64 */
153      for(j = 0; j < 3; j++) {
154        printf("f128 -> d6: round=%x ", i);
155        printf("%Lf -> ", f128_in[j]);
156        d64 = PFPO(f128_in[j], long double, _Decimal64, PFPO_F128_TO_D64,
157                   i, ret_code, cc);
158        DFP_VAL_PRINT(d64, _Decimal64);
159        printf(" ret=%d cc=%d\n", ret_code, cc);
160      }
161
162      /* f128 -> d128 */
163      for(j = 0; j < 3; j++) {
164        printf("f128 -> d128: round=%x ", i);
165        printf("%Lf -> ", f128_in[j]);
166        d128 = PFPO(f128_in[j], long double, _Decimal128, PFPO_F128_TO_D128,
167                   i, ret_code, cc);
168        DFP_VAL_PRINT(d128, _Decimal128);
169        printf(" ret=%d cc=%d\n", ret_code, cc);
170      }
171
172      /* d32 -> f32 */
173      for(j = 0; j < 3; j++) {
174        printf("d32 -> f32: round=%x ", i);
175        DFP_VAL_PRINT(d32_in[j], _Decimal32);
176        printf(" -> ");
177        f32 = PFPO(d32_in[j], _Decimal32, float, PFPO_D32_TO_F32,
178                   i, ret_code, cc);
179        printf("%f", f32);
180        printf(" ret=%d cc=%d\n", ret_code, cc);
181      }
182
183      /* d32 -> f64 */
184      for(j = 0; j < 3; j++) {
185        printf("d32 -> f64: round=%x ", i);
186        DFP_VAL_PRINT(d32_in[j], _Decimal32);
187        printf(" -> ");
188        f64 = PFPO(d32_in[j], _Decimal32, double, PFPO_D32_TO_F64,
189                   i, ret_code, cc);
190        printf("%lf", f64);
191        printf(" ret=%d cc=%d\n", ret_code, cc);
192      }
193
194      /* d32 -> f128 */
195      for(j = 0; j < 3; j++) {
196        printf("d32 -> f128: round=%x ", i);
197        DFP_VAL_PRINT(d32_in[j], _Decimal32);
198        printf(" -> ");
199        f128 = PFPO(d32_in[j], _Decimal32, long double, PFPO_D32_TO_F128,
200                   i, ret_code, cc);
201        printf("%Lf", f128);
202        printf(" ret=%d cc=%d\n", ret_code, cc);
203      }
204
205      /* d64 -> f32 */
206      for(j = 0; j < 3; j++) {
207        printf("d64 -> f32: round=%x ", i);
208        DFP_VAL_PRINT(d64_in[j], _Decimal64);
209        printf(" -> ");
210        f32 = PFPO(d64_in[j], _Decimal64, float, PFPO_D64_TO_F32,
211                   i, ret_code, cc);
212        printf("%f", f32);
213        printf(" ret=%d cc=%d\n", ret_code, cc);
214      }
215
216      /* d64 -> f64 */
217      for(j = 0; j < 3; j++) {
218        printf("d64 -> f64: round=%x ", i);
219        DFP_VAL_PRINT(d64_in[j], _Decimal64);
220        printf(" -> ");
221        f64 = PFPO(d64_in[j], _Decimal64, double, PFPO_D64_TO_F64,
222                   i, ret_code, cc);
223        printf("%lf", f64);
224        printf(" ret=%d cc=%d\n", ret_code, cc);
225      }
226
227      /* d64 -> f128 */
228      for(j = 0; j < 3; j++) {
229        printf("d64 -> f128: round=%x ", i);
230        DFP_VAL_PRINT(d64_in[j], _Decimal64);
231        printf(" -> ");
232        f128 = PFPO(d64_in[j], _Decimal64, long double, PFPO_D64_TO_F128,
233                   i, ret_code, cc);
234        printf("%Lf", f128);
235        printf(" ret=%d cc=%d\n", ret_code, cc);
236      }
237
238      /* d128 -> f32 */
239      for(j = 0; j < 3; j++) {
240        printf("d128 -> f32: round=%x ", i);
241        DFP_VAL_PRINT(d128_in[j], _Decimal128);
242        printf(" -> ");
243        f32 = PFPO(d128_in[j], _Decimal128, float, PFPO_D128_TO_F32,
244                   i, ret_code, cc);
245        printf("%f", f32);
246        printf(" ret=%d cc=%d\n", ret_code, cc);
247      }
248
249      /* d128 -> f64 */
250      for(j = 0; j < 3; j++) {
251        printf("d128 -> f64: round=%x ", i);
252        DFP_VAL_PRINT(d128_in[j], _Decimal128);
253        printf(" -> ");
254        f64 = PFPO(d128_in[j], _Decimal128, double, PFPO_D128_TO_F64,
255                   i, ret_code, cc);
256        printf("%lf", f64);
257        printf(" ret=%d cc=%d\n", ret_code, cc);
258      }
259
260      /* d128 -> f128 */
261      for(j = 0; j < 3; j++) {
262        printf("d128 -> f128: round=%x ", i);
263        DFP_VAL_PRINT(d128_in[j], _Decimal128);
264        printf(" -> ");
265        f128 = PFPO(d128_in[j], _Decimal128, long double, PFPO_D128_TO_F128,
266                   i, ret_code, cc);
267        printf("%Lf", f128);
268        printf(" ret=%d cc=%d\n", ret_code, cc);
269      }
270    }
271  }
272  return 0;
273}
274