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