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 I2D(insn,  initial, target,round)                               \
8  ({                                                                    \
9    register int 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 D2I(insn, initial, type, round, cc)                             \
16  ({                                                                    \
17    register type source asm("f0") =  initial;                          \
18    register int target asm ("2") = 0;                                  \
19    asm volatile(insn(round,0,2,0)                                      \
20                 "ipm %1\n\t"                                           \
21                 "srl %1,28\n\t"                                        \
22                 :"=d" (target), "=d" (cc) :"f"(source):"cc");          \
23    target;                                                             \
24})
25
26
27#define DO_PRINT_I2D(insn, l, d, round)                                 \
28  ({                                                                    \
29    printf(#insn " round=%d %d -> ", 0x##round, l);                     \
30    d = I2D(insn, l, d, round);                                         \
31    DFP_VAL_PRINT(d, typeof(d));                                        \
32    printf("\n");                                                       \
33  })
34
35#define DO_INSN_I2D(insn, round, type)                                  \
36  ({                                                                    \
37    type d;                                                             \
38    DO_PRINT_I2D(insn, 0, d, round);                                    \
39    DO_PRINT_I2D(insn, 1, d, round);                                    \
40    DO_PRINT_I2D(insn, 0xffffffff, d, round);                           \
41    DO_PRINT_I2D(insn, 0x80000000, d, round);                           \
42    DO_PRINT_I2D(insn, 0x7fffffff, d, round);                           \
43   })
44
45#define DO_PRINT_D2I(insn, d, type, round, cc)                          \
46  ({                                                                    \
47    printf(#insn " round=%d ", 0x##round);                              \
48    DFP_VAL_PRINT(d, type);                                             \
49    printf(" -> %d ", D2I(insn, d, type, round, cc));                   \
50    printf("cc=%d\n", cc);                                              \
51  })
52
53#define DO_INSN_D2I(insn, round, type)                                  \
54  ({                                                                    \
55    int cc;                                                             \
56    type d;                                                             \
57    d = -1.1DD;                                                         \
58    DO_PRINT_D2I(insn, d, type, round, cc);                             \
59    d = 0.DD;                                                           \
60    DO_PRINT_D2I(insn, d, type, round, cc);                             \
61    d = 1.DD;                                                           \
62    DO_PRINT_D2I(insn, d, type, round, cc);                             \
63    d = 1.4DD;                                                          \
64    DO_PRINT_D2I(insn, d, type, round, cc);                             \
65    d = 1.5DD;                                                          \
66    DO_PRINT_D2I(insn, d, type, round, cc);                             \
67    d = 1.6DD;                                                          \
68    DO_PRINT_D2I(insn, d, type, round, cc);                             \
69    d = 1.6E+4DD;                                                       \
70    DO_PRINT_D2I(insn, d, type, round, cc);                             \
71    d = 1.6E+8DD;                                                       \
72    DO_PRINT_D2I(insn, d, type, round, cc);                             \
73    d = 1.6E+4DD;                                                       \
74    DO_PRINT_D2I(insn, d, type, round, cc);                             \
75    d = 1.6E+12DD;                                                      \
76    DO_PRINT_D2I(insn, d, type, round, cc);                             \
77    d = 1.6E+20DD;                                                      \
78    DO_PRINT_D2I(insn, d, type, round, cc);                             \
79    d = 1.6E+200DD;                                                     \
80    DO_PRINT_D2I(insn, d, type, round, cc);                             \
81    d = 1.6E-4DD;                                                       \
82    DO_PRINT_D2I(insn, d, type, round, cc);                             \
83    d = DEC32_MIN;                                                      \
84    DO_PRINT_D2I(insn, d, type, round, cc);                             \
85    d = DEC32_MAX;                                                      \
86    DO_PRINT_D2I(insn, d, type, round, cc);                             \
87    d = DEC64_MIN;                                                      \
88    DO_PRINT_D2I(insn, d, type, round, cc);                             \
89    d = DEC64_MAX;                                                      \
90    DO_PRINT_D2I(insn, d, type, round, cc);                             \
91  })
92
93#define DO_D2I(round)                                                   \
94  ({                                                                    \
95    DO_INSN_D2I(CGDTRA,  round, _Decimal64);                            \
96    DO_INSN_D2I(CGXTRA,  round, _Decimal128);                           \
97  })
98
99
100int main()
101{
102  /* rounding mode is not used for the I64 -> D128 conversion */
103  DO_INSN_I2D(CXGTRA, 0, _Decimal128);
104
105  /* Omit rounding mode value 0 and 2 as the current DFP rounding
106     mode is chosen for these values. */
107  DO_INSN_I2D(CDGTRA, 1, _Decimal64);
108  DO_D2I(1);
109
110  DO_INSN_I2D(CDGTRA, 3, _Decimal64);
111  DO_D2I(3);
112
113  DO_INSN_I2D(CDGTRA, 4, _Decimal64);
114  DO_D2I(4);
115
116  DO_INSN_I2D(CDGTRA, 5, _Decimal64);
117  DO_D2I(5);
118
119  DO_INSN_I2D(CDGTRA, 6, _Decimal64);
120  DO_D2I(6);
121
122  DO_INSN_I2D(CDGTRA, 7, _Decimal64);
123  DO_D2I(7);
124
125  DO_INSN_I2D(CDGTRA, 8, _Decimal64);
126  DO_D2I(8);
127
128  DO_INSN_I2D(CDGTRA, 9, _Decimal64);
129  DO_D2I(9);
130
131  DO_INSN_I2D(CDGTRA, a, _Decimal64);
132  DO_D2I(a);
133
134  DO_INSN_I2D(CDGTRA, b, _Decimal64);
135  DO_D2I(b);
136
137  DO_INSN_I2D(CDGTRA, c, _Decimal64);
138  DO_D2I(c);
139
140  DO_INSN_I2D(CDGTRA, d, _Decimal64);
141  DO_D2I(d);
142
143  DO_INSN_I2D(CDGTRA, e, _Decimal64);
144  DO_D2I(e);
145
146  DO_INSN_I2D(CDGTRA, f, _Decimal64);
147  DO_D2I(f);
148
149  return 0;
150}
151