1 #include <stdio.h>
2 #include "opcodes.h"
3 #include "dfp_utils.h"
4 #define __STDC_WANT_DEC_FP__ 1
5 #include <float.h>
6 
7 #define L2D(insn,  initial, target,round)                               \
8   ({                                                                    \
9     register unsigned long source asm("2") =  initial;                  \
10     register typeof(target) _t asm("f0");                               \
11     asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source));             \
12     _t;                                                                 \
13   })
14 
15 #define I2D(insn,  initial, target,round)                               \
16   ({                                                                    \
17     register int source asm("2") =  initial;                            \
18     register typeof(target) _t asm("f0");                               \
19     asm volatile(insn(round,0,0,2) :"=f" (_t):"d"(source));             \
20     _t;                                                                 \
21 })
22 
23 #define D2L(insn, initial, type, round, cc)                             \
24   ({                                                                    \
25     register type source asm("f0") =  initial;                          \
26     register unsigned long target asm ("2") = 0;                        \
27     asm volatile(insn(round,0,2,0)                                      \
28                  "ipm %1\n\t"                                           \
29                  "srl %1,28\n\t"                                        \
30                  :"=d" (target), "=d" (cc) :"f"(source):"cc");          \
31     target;                                                             \
32   })
33 
34 #define D2I(insn, initial, type, round, cc)                             \
35   ({                                                                    \
36     register type source asm("f0") =  initial;                          \
37     register int target asm ("2") = 0;                                  \
38     asm volatile(insn(round,0,2,0)                                      \
39                  "ipm %1\n\t"                                           \
40                  "srl %1,28\n\t"                                        \
41                  :"=d" (target), "=d" (cc) :"f"(source):"cc");          \
42     target;                                                             \
43 })
44 
45 
46 #define DO_PRINT_L2D(insn, l, d, round)                                 \
47   ({                                                                    \
48     printf(#insn " round=%d %lu -> ", 0x##round, l);                    \
49     d = L2D(insn, l, d, round);                                         \
50     DFP_VAL_PRINT(d, typeof(d));                                        \
51     printf("\n");                                                       \
52   })
53 
54 #define DO_INSN_L2D(insn, round, type)                                  \
55   ({                                                                    \
56     type d;                                                             \
57     DO_PRINT_L2D(insn, 0UL, d, round);                                  \
58     DO_PRINT_L2D(insn, 1UL, d, round);                                  \
59     DO_PRINT_L2D(insn, 0xffffffffUL, d, round);                         \
60     DO_PRINT_L2D(insn, 0x80000000UL, d, round);                         \
61     DO_PRINT_L2D(insn, 0x7fffffffUL, d, round);                         \
62     DO_PRINT_L2D(insn, 0x100000000UL, d, round);                        \
63     DO_PRINT_L2D(insn, 0xffffffffffffffffUL, d, round);                 \
64     DO_PRINT_L2D(insn, 0x8000000000000000UL, d, round);                 \
65     DO_PRINT_L2D(insn, 0x7fffffffffffffffUL, d, round);                 \
66   })
67 
68 #define DO_PRINT_I2D(insn, l, d, round)                                 \
69   ({                                                                    \
70     printf(#insn " round=%d %d -> ", 0x##round, l);                     \
71     d = I2D(insn, l, d, round);                                         \
72     DFP_VAL_PRINT(d, typeof(d));                                        \
73     printf("\n");                                                       \
74   })
75 
76 #define DO_INSN_I2D(insn, round, type)                                  \
77   ({                                                                    \
78     type d;                                                             \
79     DO_PRINT_I2D(insn, 0, d, round);                                    \
80     DO_PRINT_I2D(insn, 1, d, round);                                    \
81     DO_PRINT_I2D(insn, 0xffffffff, d, round);                           \
82     DO_PRINT_I2D(insn, 0x80000000, d, round);                           \
83     DO_PRINT_I2D(insn, 0x7fffffff, d, round);                           \
84    })
85 
86 #define DO_PRINT_D2L(insn, d, type, round, cc)                          \
87   ({                                                                    \
88     printf(#insn " round=%d ", 0x##round);                              \
89     DFP_VAL_PRINT(d, type);                                             \
90     printf(" -> %lu ", D2L(insn, d, type, round, cc));                  \
91     printf("cc=%d\n", cc);                                              \
92   })
93 
94 #define DO_INSN_D2L(insn, round, type)                                  \
95   ({                                                                    \
96     int cc;                                                             \
97     type d;                                                             \
98     d = -1.1DD;                                                         \
99     DO_PRINT_D2L(insn, d, type, round, cc);                             \
100     d = 0.DD;                                                           \
101     DO_PRINT_D2L(insn, d, type, round, cc);                             \
102     d = 1.DD;                                                           \
103     DO_PRINT_D2L(insn, d, type, round, cc);                             \
104     d = 1.4DD;                                                          \
105     DO_PRINT_D2L(insn, d, type, round, cc);                             \
106     d = 1.5DD;                                                          \
107     DO_PRINT_D2L(insn, d, type, round, cc);                             \
108     d = 1.6DD;                                                          \
109     DO_PRINT_D2L(insn, d, type, round, cc);                             \
110     d = 1.6E+4DD;                                                       \
111     DO_PRINT_D2L(insn, d, type, round, cc);                             \
112     d = 1.6E+8DD;                                                       \
113     DO_PRINT_D2L(insn, d, type, round, cc);                             \
114     d = 1.6E+4DD;                                                       \
115     DO_PRINT_D2L(insn, d, type, round, cc);                             \
116     d = 1.6E+12DD;                                                      \
117     DO_PRINT_D2L(insn, d, type, round, cc);                             \
118     d = 1.6E+20DD;                                                      \
119     DO_PRINT_D2L(insn, d, type, round, cc);                             \
120     d = 1.6E+200DD;                                                     \
121     DO_PRINT_D2L(insn, d, type, round, cc);                             \
122     d = 1.6E-4DD;                                                       \
123     DO_PRINT_D2L(insn, d, type, round, cc);                             \
124     d = DEC32_MIN;                                                      \
125     DO_PRINT_D2L(insn, d, type, round, cc);                             \
126     d = DEC32_MAX;                                                      \
127     DO_PRINT_D2L(insn, d, type, round, cc);                             \
128     d = DEC64_MIN;                                                      \
129     DO_PRINT_D2L(insn, d, type, round, cc);                             \
130     d = DEC64_MAX;                                                      \
131     DO_PRINT_D2L(insn, d, type, round, cc);                             \
132   })
133 
134 #define DO_PRINT_D2I(insn, d, type, round, cc)                          \
135   ({                                                                    \
136     printf(#insn " round=%d ", 0x##round);                              \
137     DFP_VAL_PRINT(d, type);                                             \
138     printf(" -> %d ", D2I(insn, d, type, round, cc));                   \
139     printf("cc=%d\n", cc);                                              \
140   })
141 
142 #define DO_INSN_D2I(insn, round, type)                                  \
143   ({                                                                    \
144     int cc;                                                             \
145     type d;                                                             \
146     d = -1.1DD;                                                         \
147     DO_PRINT_D2I(insn, d, type, round, cc);                             \
148     d = 0.DD;                                                           \
149     DO_PRINT_D2I(insn, d, type, round, cc);                             \
150     d = 1.DD;                                                           \
151     DO_PRINT_D2I(insn, d, type, round, cc);                             \
152     d = 1.4DD;                                                          \
153     DO_PRINT_D2I(insn, d, type, round, cc);                             \
154     d = 1.5DD;                                                          \
155     DO_PRINT_D2I(insn, d, type, round, cc);                             \
156     d = 1.6DD;                                                          \
157     DO_PRINT_D2I(insn, d, type, round, cc);                             \
158     d = 1.6E+4DD;                                                       \
159     DO_PRINT_D2I(insn, d, type, round, cc);                             \
160     d = 1.6E+8DD;                                                       \
161     DO_PRINT_D2I(insn, d, type, round, cc);                             \
162     d = 1.6E+4DD;                                                       \
163     DO_PRINT_D2I(insn, d, type, round, cc);                             \
164     d = 1.6E+12DD;                                                      \
165     DO_PRINT_D2I(insn, d, type, round, cc);                             \
166     d = 1.6E+20DD;                                                      \
167     DO_PRINT_D2I(insn, d, type, round, cc);                             \
168     d = 1.6E+200DD;                                                     \
169     DO_PRINT_D2I(insn, d, type, round, cc);                             \
170     d = 1.6E-4DD;                                                       \
171     DO_PRINT_D2I(insn, d, type, round, cc);                             \
172     d = DEC32_MIN;                                                      \
173     DO_PRINT_D2I(insn, d, type, round, cc);                             \
174     d = DEC32_MAX;                                                      \
175     DO_PRINT_D2I(insn, d, type, round, cc);                             \
176     d = DEC64_MIN;                                                      \
177     DO_PRINT_D2I(insn, d, type, round, cc);                             \
178     d = DEC64_MAX;                                                      \
179     DO_PRINT_D2I(insn, d, type, round, cc);                             \
180   })
181 
182 #define DO_D2L(round)                                                   \
183   ({                                                                    \
184     DO_INSN_D2L(CLFDTR, round, _Decimal64);                             \
185     DO_INSN_D2L(CLGDTR, round, _Decimal64);                             \
186     DO_INSN_D2I(CFDTR,  round, _Decimal64);                             \
187     DO_INSN_D2L(CLFXTR, round, _Decimal128);                            \
188     DO_INSN_D2L(CLGXTR, round, _Decimal128);                            \
189     DO_INSN_D2I(CFXTR,  round, _Decimal128);                            \
190   })
191 
192 
main()193 int main()
194 {
195   /* rounding mode is not used for the following insns */
196   DO_INSN_I2D(CDFTR,  0, _Decimal64);
197   DO_INSN_I2D(CXFTR,  0, _Decimal128);
198   DO_INSN_L2D(CDLFTR, 0, _Decimal64);
199   DO_INSN_L2D(CXLFTR, 0, _Decimal128);
200   DO_INSN_L2D(CXLGTR, 0, _Decimal128);
201 
202   /* Omit rounding mode value 0 and 2 as the current DFP rounding
203      mode is chosen for these values. */
204   DO_INSN_L2D(CDLGTR, 1, _Decimal64);
205   DO_D2L(1);
206 
207   DO_INSN_L2D(CDLGTR, 3, _Decimal64);
208   DO_D2L(3);
209 
210   DO_INSN_L2D(CDLGTR, 4, _Decimal64);
211   DO_D2L(4);
212 
213   DO_INSN_L2D(CDLGTR, 5, _Decimal64);
214   DO_D2L(5);
215 
216   DO_INSN_L2D(CDLGTR, 6, _Decimal64);
217   DO_D2L(6);
218 
219   DO_INSN_L2D(CDLGTR, 7, _Decimal64);
220   DO_D2L(7);
221 
222   DO_INSN_L2D(CDLGTR, 8, _Decimal64);
223   DO_D2L(8);
224 
225   DO_INSN_L2D(CDLGTR, 9, _Decimal64);
226   DO_D2L(9);
227 
228   DO_INSN_L2D(CDLGTR, a, _Decimal64);
229   DO_D2L(a);
230 
231   DO_INSN_L2D(CDLGTR, b, _Decimal64);
232   DO_D2L(b);
233 
234   DO_INSN_L2D(CDLGTR, c, _Decimal64);
235   DO_D2L(c);
236 
237   DO_INSN_L2D(CDLGTR, d, _Decimal64);
238   DO_D2L(d);
239 
240   DO_INSN_L2D(CDLGTR, e, _Decimal64);
241   DO_D2L(e);
242 
243   DO_INSN_L2D(CDLGTR, f, _Decimal64);
244   DO_D2L(f);
245 
246   return 0;
247 }
248