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
193int 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