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