1 #include <stdio.h>
2 #include <stdint.h>
3 #include "dfp_utils.h"
4
5 /* Test various DFP ops:
6 - extract biased exponent 64/128 bit
7 - extract significance 64/128 bit
8 - insert biased exponent 64/128 bit
9 - load and test 64/128 bit
10 - shift left/right 64/128 bit
11 - reround 64/128 bit
12 */
13
eedtr(_Decimal64 in)14 void eedtr(_Decimal64 in)
15 {
16 long out;
17 asm volatile(".insn rre, 0xb3e50000, %[out], %[in]\n\t"
18 :[out] "=d" (out) :[in] "f" (in));
19 printf("EEDTR ");
20 DFP_VAL_PRINT(in, _Decimal64);
21 printf(" -> %ld\n", out);
22 }
23
eextr(_Decimal128 in)24 void eextr(_Decimal128 in)
25 {
26 long out;
27 asm volatile(".insn rre, 0xb3ed0000, %[out], %[in]\n\t"
28 :[out] "=d" (out) :[in] "f" (in));
29 printf("EEXTR ");
30 DFP_VAL_PRINT(in, _Decimal128);
31 printf(" -> %ld\n", out);
32 }
33
esdtr(_Decimal64 in)34 void esdtr(_Decimal64 in)
35 {
36 long out;
37 asm volatile(".insn rre, 0xb3e70000, %[out], %[in]\n\t"
38 :[out] "=d" (out) :[in] "f" (in));
39 printf("ESDTR ");
40 DFP_VAL_PRINT(in, _Decimal64);
41 printf(" -> %ld\n", out);
42 }
43
esxtr(_Decimal128 in)44 void esxtr(_Decimal128 in)
45 {
46 long out;
47 asm volatile(".insn rre, 0xb3ef0000, %[out], %[in]\n\t"
48 :[out] "=d" (out) :[in] "f" (in));
49 printf("ESXTR ");
50 DFP_VAL_PRINT(in, _Decimal128);
51 printf(" -> %ld\n", out);
52 }
53
iedtr(_Decimal64 in,long amount)54 void iedtr(_Decimal64 in, long amount)
55 {
56 _Decimal64 out;
57
58 asm volatile (".insn rrf, 0xb3f60000, %[out], %[amount], %[in], 0\n\t"
59 :[out]"=f"(out)
60 :[in]"f"(in), [amount]"d"(amount));
61
62 printf("IEDTR ");
63 DFP_VAL_PRINT(in, _Decimal64);
64 printf(", %ld -> ", amount);
65 DFP_VAL_PRINT(out, _Decimal64);
66 printf("\n");
67 }
68
iextr(_Decimal128 in,long amount)69 void iextr(_Decimal128 in, long amount)
70 {
71 _Decimal128 out;
72
73 asm volatile (".insn rrf, 0xb3fe0000, %[out], %[amount], %[in], 0\n\t"
74 :[out]"=f"(out)
75 :[in]"f"(in), [amount]"d"(amount));
76
77 printf("IEXTR ");
78 DFP_VAL_PRINT(in, _Decimal128);
79 printf(", %ld -> ", amount);
80 DFP_VAL_PRINT(out, _Decimal128);
81 printf("\n");
82 }
83
ltdtr(_Decimal64 in)84 void ltdtr(_Decimal64 in)
85 {
86 _Decimal64 out;
87 int cc;
88 asm volatile(".insn rre, 0xb3d60000, %[out], %[in]\n\t"
89 "ipm %1\n\t"
90 "srl %1,28\n\t"
91 :[out] "=d" (out), "=d" (cc)
92 :[in] "f" (in));
93 printf("LTDTR ");
94 DFP_VAL_PRINT(in, _Decimal64);
95 printf(" -> %d\n", cc);
96 }
97
ltxtr(_Decimal128 in)98 void ltxtr(_Decimal128 in)
99 {
100 _Decimal128 out;
101 int cc;
102 asm volatile(".insn rre, 0xb3de0000, %[out], %[in]\n\t"
103 "ipm %1\n\t"
104 "srl %1,28\n\t"
105 :[out] "=f" (out), "=d" (cc)
106 :[in] "f" (in));
107 printf("LTXTR ");
108 DFP_VAL_PRINT(in, _Decimal128);
109 printf(" -> %d\n", cc);
110 }
111
qadtr(_Decimal64 op,_Decimal64 quan,uint8_t rm)112 void qadtr(_Decimal64 op, _Decimal64 quan, uint8_t rm)
113 {
114 _Decimal64 out;
115
116 asm volatile (
117 ".insn rrf, 0xb3f50000, %[out], %[quan], %[op], %[rm]\n\t"
118 :[out]"=f"(out)
119 :[op]"f"(op), [quan]"f"(quan), [rm]"d"(rm)
120 );
121 printf("QADTR ");
122 DFP_VAL_PRINT(op, _Decimal64);
123 printf(", ");
124 DFP_VAL_PRINT(quan, _Decimal64);
125 printf(", %x -> ", rm);
126 DFP_VAL_PRINT(out, _Decimal64);
127 printf("\n");
128 }
129
quantize64(_Decimal64 op,_Decimal64 quan)130 void quantize64(_Decimal64 op, _Decimal64 quan)
131 {
132 uint8_t i;
133
134 for (i = 0; i < 16; i++)
135 qadtr(op, quan, i);
136 }
137
qaxtr(_Decimal128 op,_Decimal128 quan,uint8_t rm)138 void qaxtr(_Decimal128 op, _Decimal128 quan, uint8_t rm)
139 {
140 _Decimal128 out;
141
142 asm volatile (
143 ".insn rrf, 0xb3fd0000, %[out], %[quan], %[op], %[rm]\n\t"
144 :[out]"=f"(out)
145 :[op]"f"(op), [quan]"f"(quan), [rm]"d"(rm)
146 );
147 printf("QAXTR ");
148 DFP_VAL_PRINT(op, _Decimal128);
149 printf(", ");
150 DFP_VAL_PRINT(quan, _Decimal128);
151 printf(", %x -> ", rm);
152 DFP_VAL_PRINT(out, _Decimal128);
153 printf("\n");
154 }
155
quantize128(_Decimal128 op,_Decimal128 quan)156 void quantize128(_Decimal128 op, _Decimal128 quan)
157 {
158 uint8_t i;
159
160 for (i = 0; i < 16; i++)
161 qaxtr(op, quan, i);
162 }
163
rrdtr(_Decimal64 op,uint8_t sig,uint8_t rm)164 void rrdtr(_Decimal64 op, uint8_t sig, uint8_t rm)
165 {
166 _Decimal64 out;
167
168 asm volatile (
169 ".insn rrf, 0xb3f70000, %[out], %[sig], %[op], %[rm]\n\t"
170 :[out]"=f"(out)
171 :[op]"f"(op), [sig]"d"(sig), [rm]"d"(rm)
172 );
173 printf("RRDTR ");
174 DFP_VAL_PRINT(op, _Decimal64);
175 printf(", %d, %x -> ", sig, rm);
176 DFP_VAL_PRINT(out, _Decimal64);
177 printf("\n");
178 }
179
reround64(_Decimal64 op,uint8_t sig)180 void reround64(_Decimal64 op, uint8_t sig)
181 {
182 uint8_t i;
183
184 for (i = 0; i < 16; i++)
185 rrdtr(op, sig, i);
186 }
187
rrxtr(_Decimal128 op,uint8_t sig,uint8_t rm)188 void rrxtr(_Decimal128 op, uint8_t sig, uint8_t rm)
189 {
190 _Decimal128 out;
191
192 asm volatile (
193 ".insn rrf, 0xb3ff0000, %[out], %[sig], %[op], %[rm]\n\t"
194 :[out]"=f"(out)
195 :[op]"f"(op), [sig]"d"(sig), [rm]"d"(rm)
196 );
197 printf("RRXTR ");
198 DFP_VAL_PRINT(op, _Decimal128);
199 printf(", %d, %x -> ", sig, rm);
200 DFP_VAL_PRINT(out, _Decimal128);
201 printf("\n");
202 }
203
reround128(_Decimal128 op,uint8_t sig)204 void reround128(_Decimal128 op, uint8_t sig)
205 {
206 uint8_t i;
207
208 for (i = 0; i < 16; i++)
209 rrxtr(op, sig, i);
210 }
211
sldt(_Decimal64 in,unsigned long amount)212 void sldt(_Decimal64 in, unsigned long amount)
213 {
214 _Decimal64 out;
215 int *shift = (int *) amount;
216
217 asm volatile (".insn rxf, 0xed0000000040, %[out], %[in], 0(%[amount])\n\t"
218 :[out]"=f"(out)
219 :[in]"f"(in),[amount]"a"(shift));
220
221 printf("SLDT ");
222 DFP_VAL_PRINT(in, _Decimal64);
223 printf(" -> ");
224 DFP_VAL_PRINT(out, _Decimal64);
225 printf("\n");
226 }
227
slxt(_Decimal128 in,unsigned long amount)228 void slxt(_Decimal128 in, unsigned long amount)
229 {
230 _Decimal128 out;
231 int *shift = (int *) amount;
232
233 asm volatile (".insn rxf, 0xed0000000048, %[out], %[in], 0(%[amount])\n\t"
234 :[out]"=f"(out)
235 :[in]"f"(in),[amount]"a"(shift));
236
237 printf("SLXT ");
238 DFP_VAL_PRINT(in, _Decimal128);
239 printf(" -> ");
240 DFP_VAL_PRINT(out, _Decimal128);
241 printf("\n");
242 }
243
srdt(_Decimal64 in,unsigned long amount)244 void srdt(_Decimal64 in, unsigned long amount)
245 {
246 _Decimal64 out;
247 int *shift = (int *) amount;
248
249 asm volatile (".insn rxf, 0xed0000000041, %[out], %[in], 0(%[amount])\n\t"
250 :[out]"=f"(out)
251 :[in]"f"(in),[amount]"a"(shift));
252
253 printf("SRDT ");
254 DFP_VAL_PRINT(in, _Decimal64);
255 printf(" -> ");
256 DFP_VAL_PRINT(out, _Decimal64);
257 printf("\n");
258 }
259
srxt(_Decimal128 in,unsigned long amount)260 void srxt(_Decimal128 in, unsigned long amount)
261 {
262 _Decimal128 out;
263 int *shift = (int *) amount;
264
265 asm volatile (".insn rxf, 0xed0000000049, %[out], %[in], 0(%[amount])\n\t"
266 :[out]"=f"(out)
267 :[in]"f"(in),[amount]"a"(shift));
268
269 printf("SRXT ");
270 DFP_VAL_PRINT(in, _Decimal128);
271 printf(" -> ");
272 DFP_VAL_PRINT(out, _Decimal128);
273 printf("\n");
274 }
275
main()276 int main() {
277 _Decimal64 d64 = 50.0005DD;
278 _Decimal128 d128 = 50.0005DL;
279
280 eedtr(d64);
281 eedtr(-d64);
282 eedtr(0.DD);
283 eextr(d128);
284 eextr(-d128);
285 eextr(0.DL);
286
287 esdtr(d64);
288 esdtr(-d64);
289 esdtr(0.DD);
290 esxtr(d128);
291 esxtr(-d128);
292 esxtr(0.DL);
293
294 ltdtr(d64);
295 ltdtr(-d64);
296 ltdtr(0.0DD);
297 ltxtr(d128);
298 ltxtr(-d128);
299 ltxtr(0.0DL);
300
301 d64 = 12345678.54321DD;
302 sldt(d64, 10);
303 sldt(-d64, 2);
304 sldt(0.DD, 2);
305 sldt(-0.DD, 2);
306
307 srdt(d64, 5);
308 srdt(-d64, 2);
309 srdt(0.DD, 2);
310 srdt(-0.DD, 2);
311
312 d128 = 12345678.54321DL;
313 slxt(d128, 10);
314 slxt(-d128, 2);
315 slxt(0.DL, 2);
316 slxt(-0.DL, 2);
317
318 srxt(d128, 10);
319 srxt(-d128, 2);
320 srxt(0.DL, 2);
321 srxt(-0.DL, 2);
322
323 d64 = 5.000005DD;
324 iedtr(d64, 391);
325 iedtr(d64, 392);
326 iedtr(d64, 393);
327 iedtr(-d64, 391);
328 iedtr(-d64, 392);
329 iedtr(-d64, 393);
330 iedtr(0.DD, 393);
331 iedtr(-0.DD, 393);
332 iedtr(1.DD, 393);
333
334 d128 = 5.000005DL;
335 iextr(d128, 6169);
336 iextr(d128, 6170);
337 iextr(d128, 6171);
338 iextr(-d128, 6169);
339 iextr(-d128, 6170);
340 iextr(-d128, 6171);
341 iextr(0.DL, 6171);
342 iextr(-0.DL, 6171);
343 iextr(1.DL, 6171);
344
345 d64 = 2.171234DD;
346 quantize64(d64, 0.001DD);
347 quantize64(-d64, 0.001DD);
348 quantize64(-d64, 0.DD);
349 quantize64(0.DD, 0.001DD);
350
351 d128 = 26365343648.171234DL;
352 quantize128(d128, 230.01DL);
353 quantize128(-d128, 230.01DL);
354 quantize128(d128, 0.DL);
355 quantize128(-0.DL, 230.01DL);
356
357 d64 = 2.174598DD;
358 reround64(d64, 3);
359 reround64(d64, 4);
360 reround64(d64, 5);
361 reround64(-d64, 3);
362 reround64(-d64, 4);
363 reround64(-d64, 5);
364 reround64(0.DD, 0);
365
366 d128 = 2.174598DL;
367 reround128(d128, 3);
368 reround128(d128, 4);
369 reround128(d128, 5);
370 reround128(-d128, 3);
371 reround128(-d128, 4);
372 reround128(-d128, 5);
373 reround128(0.DL, 0);
374
375 return 0;
376 }
377