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
14void 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
24void 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
34void 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
44void 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
54void 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
69void 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
84void 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
98void 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
112void 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
130void 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
138void 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
156void 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
164void 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
180void 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
188void 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
204void 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
212void 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
228void 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
244void 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
260void 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
276int 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