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 */
main()47 int 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