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
main()100 int 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