xref: /qemu/tests/tcg/riscv64/test-fcvtmod.c (revision 94d68c11362240a26ce425f56e2451d88f6814e1)
1*a47842d1SChristoph Müllner #include <stdio.h>
2*a47842d1SChristoph Müllner #include <stddef.h>
3*a47842d1SChristoph Müllner #include <stdint.h>
4*a47842d1SChristoph Müllner 
5*a47842d1SChristoph Müllner #define FFLAG_NX_SHIFT 0 /* inexact */
6*a47842d1SChristoph Müllner #define FFLAG_UF_SHIFT 1 /* underflow */
7*a47842d1SChristoph Müllner #define FFLAG_OF_SHIFT 2 /* overflow */
8*a47842d1SChristoph Müllner #define FFLAG_DZ_SHIFT 3 /* divide by zero */
9*a47842d1SChristoph Müllner #define FFLAG_NV_SHIFT 4 /* invalid operation */
10*a47842d1SChristoph Müllner 
11*a47842d1SChristoph Müllner #define FFLAG_NV (1UL << FFLAG_NV_SHIFT)
12*a47842d1SChristoph Müllner #define FFLAG_DZ (1UL << FFLAG_DZ_SHIFT)
13*a47842d1SChristoph Müllner #define FFLAG_OF (1UL << FFLAG_OF_SHIFT)
14*a47842d1SChristoph Müllner #define FFLAG_UF (1UL << FFLAG_UF_SHIFT)
15*a47842d1SChristoph Müllner #define FFLAG_NX (1UL << FFLAG_NX_SHIFT)
16*a47842d1SChristoph Müllner 
17*a47842d1SChristoph Müllner typedef struct fp64_fcvt_fcvtmod_testcase {
18*a47842d1SChristoph Müllner     const char* name;
19*a47842d1SChristoph Müllner     union {
20*a47842d1SChristoph Müllner         uint64_t inp_lu;
21*a47842d1SChristoph Müllner         double inp_lf;
22*a47842d1SChristoph Müllner     };
23*a47842d1SChristoph Müllner     uint64_t exp_fcvt;
24*a47842d1SChristoph Müllner     uint8_t exp_fcvt_fflags;
25*a47842d1SChristoph Müllner     uint64_t exp_fcvtmod;
26*a47842d1SChristoph Müllner     uint8_t exp_fcvtmod_fflags;
27*a47842d1SChristoph Müllner } fp64_fcvt_fcvtmod_testcase_t;
28*a47842d1SChristoph Müllner 
print_fflags(uint8_t fflags)29*a47842d1SChristoph Müllner void print_fflags(uint8_t fflags)
30*a47842d1SChristoph Müllner {
31*a47842d1SChristoph Müllner     int set = 0;
32*a47842d1SChristoph Müllner 
33*a47842d1SChristoph Müllner     if (fflags == 0) {
34*a47842d1SChristoph Müllner         printf("-");
35*a47842d1SChristoph Müllner         return;
36*a47842d1SChristoph Müllner     }
37*a47842d1SChristoph Müllner 
38*a47842d1SChristoph Müllner     if (fflags & FFLAG_NV) {
39*a47842d1SChristoph Müllner         printf("%sFFLAG_NV", set ? " | " : "");
40*a47842d1SChristoph Müllner         set = 1;
41*a47842d1SChristoph Müllner     }
42*a47842d1SChristoph Müllner     if (fflags & FFLAG_DZ) {
43*a47842d1SChristoph Müllner         printf("%sFFLAG_DZ", set ? " | " : "");
44*a47842d1SChristoph Müllner         set = 1;
45*a47842d1SChristoph Müllner     }
46*a47842d1SChristoph Müllner     if (fflags & FFLAG_OF) {
47*a47842d1SChristoph Müllner         printf("%sFFLAG_OF", set ? " | " : "");
48*a47842d1SChristoph Müllner         set = 1;
49*a47842d1SChristoph Müllner     }
50*a47842d1SChristoph Müllner     if (fflags & FFLAG_UF) {
51*a47842d1SChristoph Müllner         printf("%sFFLAG_UF", set ? " | " : "");
52*a47842d1SChristoph Müllner         set = 1;
53*a47842d1SChristoph Müllner     }
54*a47842d1SChristoph Müllner     if (fflags & FFLAG_NX) {
55*a47842d1SChristoph Müllner         printf("%sFFLAG_NX", set ? " | " : "");
56*a47842d1SChristoph Müllner         set = 1;
57*a47842d1SChristoph Müllner     }
58*a47842d1SChristoph Müllner }
59*a47842d1SChristoph Müllner 
60*a47842d1SChristoph Müllner /* Clear all FP flags. */
clear_fflags()61*a47842d1SChristoph Müllner static inline void clear_fflags()
62*a47842d1SChristoph Müllner {
63*a47842d1SChristoph Müllner     __asm__ __volatile__("fsflags zero");
64*a47842d1SChristoph Müllner }
65*a47842d1SChristoph Müllner 
66*a47842d1SChristoph Müllner /* Read all FP flags. */
get_fflags()67*a47842d1SChristoph Müllner static inline uint8_t get_fflags()
68*a47842d1SChristoph Müllner {
69*a47842d1SChristoph Müllner     uint64_t v;
70*a47842d1SChristoph Müllner     __asm__ __volatile__("frflags %0" : "=r"(v));
71*a47842d1SChristoph Müllner     return (uint8_t)v;
72*a47842d1SChristoph Müllner }
73*a47842d1SChristoph Müllner 
74*a47842d1SChristoph Müllner /* Move input value (without conversations) into an FP register. */
do_fmv_d_x(uint64_t inp)75*a47842d1SChristoph Müllner static inline double do_fmv_d_x(uint64_t inp)
76*a47842d1SChristoph Müllner {
77*a47842d1SChristoph Müllner     double fpr;
78*a47842d1SChristoph Müllner     __asm__ __volatile__("fmv.d.x %0, %1" : "=f"(fpr) : "r"(inp));
79*a47842d1SChristoph Müllner     return fpr;
80*a47842d1SChristoph Müllner }
81*a47842d1SChristoph Müllner 
do_fcvt_w_d(uint64_t inp,uint8_t * fflags)82*a47842d1SChristoph Müllner static inline uint64_t do_fcvt_w_d(uint64_t inp, uint8_t *fflags)
83*a47842d1SChristoph Müllner {
84*a47842d1SChristoph Müllner     uint64_t ret;
85*a47842d1SChristoph Müllner     double fpr = do_fmv_d_x(inp);
86*a47842d1SChristoph Müllner 
87*a47842d1SChristoph Müllner     clear_fflags();
88*a47842d1SChristoph Müllner 
89*a47842d1SChristoph Müllner     __asm__ __volatile__("fcvt.w.d %0, %1, rtz" : "=r"(ret) : "f"(fpr));
90*a47842d1SChristoph Müllner 
91*a47842d1SChristoph Müllner     *fflags = get_fflags();
92*a47842d1SChristoph Müllner 
93*a47842d1SChristoph Müllner     return ret;
94*a47842d1SChristoph Müllner }
95*a47842d1SChristoph Müllner 
do_fcvtmod_w_d(uint64_t inp,uint8_t * fflags)96*a47842d1SChristoph Müllner static inline uint64_t do_fcvtmod_w_d(uint64_t inp, uint8_t *fflags)
97*a47842d1SChristoph Müllner {
98*a47842d1SChristoph Müllner     uint64_t ret;
99*a47842d1SChristoph Müllner     double fpr = do_fmv_d_x(inp);
100*a47842d1SChristoph Müllner 
101*a47842d1SChristoph Müllner     clear_fflags();
102*a47842d1SChristoph Müllner 
103*a47842d1SChristoph Müllner     /* fcvtmod.w.d rd, rs1, rtz = 1100001 01000 rs1 001 rd 1010011 */
104*a47842d1SChristoph Müllner     asm(".insn r  0x53, 0x1, 0x61, %0, %1, f8" : "=r"(ret) : "f"(fpr));
105*a47842d1SChristoph Müllner 
106*a47842d1SChristoph Müllner     *fflags = get_fflags();
107*a47842d1SChristoph Müllner 
108*a47842d1SChristoph Müllner     return ret;
109*a47842d1SChristoph Müllner }
110*a47842d1SChristoph Müllner 
111*a47842d1SChristoph Müllner static const fp64_fcvt_fcvtmod_testcase_t tests[] = {
112*a47842d1SChristoph Müllner     /* Zero (exp=0, frac=0) */
113*a47842d1SChristoph Müllner     { .name = "+0.0",
114*a47842d1SChristoph Müllner       .inp_lf = 0x0p0,
115*a47842d1SChristoph Müllner       .exp_fcvt = 0x0000000000000000,
116*a47842d1SChristoph Müllner       .exp_fcvt_fflags = 0,
117*a47842d1SChristoph Müllner       .exp_fcvtmod = 0x0000000000000000,
118*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = 0 },
119*a47842d1SChristoph Müllner     { .name = "-0.0",
120*a47842d1SChristoph Müllner       .inp_lf = -0x0p0,
121*a47842d1SChristoph Müllner       .exp_fcvt = 0x0000000000000000,
122*a47842d1SChristoph Müllner       .exp_fcvt_fflags = 0,
123*a47842d1SChristoph Müllner       .exp_fcvtmod = 0x0000000000000000,
124*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = 0 },
125*a47842d1SChristoph Müllner 
126*a47842d1SChristoph Müllner     /* Subnormal: exp=0 frac!=0 */
127*a47842d1SChristoph Müllner     { .name = "Subnormal frac=1",
128*a47842d1SChristoph Müllner       .inp_lu = 0x0000000000000001,
129*a47842d1SChristoph Müllner       .exp_fcvt = 0x0000000000000000,
130*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
131*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
132*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
133*a47842d1SChristoph Müllner     { .name = "Subnormal frac=0xf..f",
134*a47842d1SChristoph Müllner       .inp_lu = 0x0000ffffffffffff,
135*a47842d1SChristoph Müllner       .exp_fcvt = 0x0000000000000000,
136*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
137*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
138*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
139*a47842d1SChristoph Müllner     { .name = "Neg subnormal frac=1",
140*a47842d1SChristoph Müllner       .inp_lu = 0x0000000000000001,
141*a47842d1SChristoph Müllner       .exp_fcvt = 0x0000000000000000,
142*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
143*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
144*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
145*a47842d1SChristoph Müllner     { .name = "Neg subnormal frac=0xf..f",
146*a47842d1SChristoph Müllner       .inp_lu = 0x8000ffffffffffff,
147*a47842d1SChristoph Müllner       .exp_fcvt = 0x0000000000000000,
148*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
149*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
150*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
151*a47842d1SChristoph Müllner 
152*a47842d1SChristoph Müllner     /* Infinity: exp=0x7ff, frac=0 */
153*a47842d1SChristoph Müllner     { .name = "+INF",
154*a47842d1SChristoph Müllner       .inp_lu = 0x7ff0000000000000,
155*a47842d1SChristoph Müllner       .exp_fcvt = 0x000000007fffffff, /* int32 max */
156*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NV,
157*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
158*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NV },
159*a47842d1SChristoph Müllner     { .name = "-INF",
160*a47842d1SChristoph Müllner       .inp_lu = 0xfff0000000000000,
161*a47842d1SChristoph Müllner       .exp_fcvt = 0xffffffff80000000, /* int32 min */
162*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NV,
163*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
164*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NV },
165*a47842d1SChristoph Müllner 
166*a47842d1SChristoph Müllner     /* NaN: exp=7ff, frac!=0 */
167*a47842d1SChristoph Müllner     { .name = "canonical NaN",
168*a47842d1SChristoph Müllner       .inp_lu = 0x7ff8000000000000,
169*a47842d1SChristoph Müllner       .exp_fcvt = 0x000000007fffffff, /* int32 max */
170*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NV,
171*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
172*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NV },
173*a47842d1SChristoph Müllner     { .name = "non-canonical NaN",
174*a47842d1SChristoph Müllner       .inp_lu = 0x7ff8000000100000,
175*a47842d1SChristoph Müllner       .exp_fcvt = 0x000000007fffffff, /* int32 min */
176*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NV,
177*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
178*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NV },
179*a47842d1SChristoph Müllner 
180*a47842d1SChristoph Müllner     /* Normal numbers: exp!=0, exp!=7ff */
181*a47842d1SChristoph Müllner     { .name = "+smallest normal value",
182*a47842d1SChristoph Müllner       .inp_lu = 0x0010000000000000,
183*a47842d1SChristoph Müllner       .exp_fcvt = 0,
184*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
185*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
186*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
187*a47842d1SChristoph Müllner     { .name = "-smallest normal value",
188*a47842d1SChristoph Müllner       .inp_lu = 0x8010000000000000,
189*a47842d1SChristoph Müllner       .exp_fcvt = 0,
190*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
191*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
192*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
193*a47842d1SChristoph Müllner 
194*a47842d1SChristoph Müllner     { .name = "+0.5",
195*a47842d1SChristoph Müllner       .inp_lf = 0x1p-1,
196*a47842d1SChristoph Müllner       .exp_fcvt = 0,
197*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
198*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
199*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
200*a47842d1SChristoph Müllner     { .name = "-0.5",
201*a47842d1SChristoph Müllner       .inp_lf = -0x1p-1,
202*a47842d1SChristoph Müllner       .exp_fcvt = 0,
203*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
204*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
205*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
206*a47842d1SChristoph Müllner 
207*a47842d1SChristoph Müllner     { .name = "+value just below 1.0",
208*a47842d1SChristoph Müllner       .inp_lu = 0x3fefffffffffffff,
209*a47842d1SChristoph Müllner       .exp_fcvt = 0,
210*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
211*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
212*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
213*a47842d1SChristoph Müllner     { .name = "-value just above -1.0",
214*a47842d1SChristoph Müllner       .inp_lu = 0xbfefffffffffffff,
215*a47842d1SChristoph Müllner       .exp_fcvt = 0,
216*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
217*a47842d1SChristoph Müllner       .exp_fcvtmod = 0,
218*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
219*a47842d1SChristoph Müllner 
220*a47842d1SChristoph Müllner     { .name = "+1.0",
221*a47842d1SChristoph Müllner       .inp_lf = 0x1p0,
222*a47842d1SChristoph Müllner       .exp_fcvt = 0x0000000000000001,
223*a47842d1SChristoph Müllner       .exp_fcvt_fflags = 0,
224*a47842d1SChristoph Müllner       .exp_fcvtmod = 0x0000000000000001,
225*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = 0 },
226*a47842d1SChristoph Müllner     { .name = "-1.0",
227*a47842d1SChristoph Müllner       .inp_lf = -0x1p0,
228*a47842d1SChristoph Müllner       .exp_fcvt = 0xffffffffffffffff,
229*a47842d1SChristoph Müllner       .exp_fcvt_fflags = 0,
230*a47842d1SChristoph Müllner       .exp_fcvtmod = 0xffffffffffffffff,
231*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = 0 },
232*a47842d1SChristoph Müllner 
233*a47842d1SChristoph Müllner     { .name = "+1.5",
234*a47842d1SChristoph Müllner       .inp_lu = 0x3ff8000000000000,
235*a47842d1SChristoph Müllner       .exp_fcvt = 1,
236*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
237*a47842d1SChristoph Müllner       .exp_fcvtmod = 1,
238*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
239*a47842d1SChristoph Müllner     { .name = "-1.5",
240*a47842d1SChristoph Müllner       .inp_lu = 0xbff8000000000000,
241*a47842d1SChristoph Müllner       .exp_fcvt = 0xffffffffffffffff,
242*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NX,
243*a47842d1SChristoph Müllner       .exp_fcvtmod = 0xffffffffffffffff,
244*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NX },
245*a47842d1SChristoph Müllner 
246*a47842d1SChristoph Müllner     { .name = "+max int32 (2147483647)",
247*a47842d1SChristoph Müllner       .inp_lu = 0x41dfffffffc00000,
248*a47842d1SChristoph Müllner       .exp_fcvt = 0x000000007fffffff,
249*a47842d1SChristoph Müllner       .exp_fcvt_fflags = 0,
250*a47842d1SChristoph Müllner       .exp_fcvtmod = 0x000000007fffffff,
251*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = 0 },
252*a47842d1SChristoph Müllner     { .name = "+max int32 +1 (2147483648)",
253*a47842d1SChristoph Müllner       .inp_lf = 0x1p31,
254*a47842d1SChristoph Müllner       .exp_fcvt = 0x000000007fffffff,
255*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NV,
256*a47842d1SChristoph Müllner       .exp_fcvtmod = (uint64_t)-2147483648l, /* int32 min */
257*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NV },
258*a47842d1SChristoph Müllner     { .name = "+max int32 +2 (2147483649)",
259*a47842d1SChristoph Müllner       .inp_lu = 0x41e0000000200000,
260*a47842d1SChristoph Müllner       .exp_fcvt = 0x000000007fffffff,
261*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NV,
262*a47842d1SChristoph Müllner       .exp_fcvtmod = (uint64_t)-2147483647l, /* int32 min +1 */
263*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NV },
264*a47842d1SChristoph Müllner 
265*a47842d1SChristoph Müllner     { .name = "-max int32 (-2147483648)",
266*a47842d1SChristoph Müllner       .inp_lf = -0x1p31,
267*a47842d1SChristoph Müllner       .exp_fcvt = 0xffffffff80000000,
268*a47842d1SChristoph Müllner       .exp_fcvt_fflags = 0,
269*a47842d1SChristoph Müllner       .exp_fcvtmod = 0xffffffff80000000,
270*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = 0 },
271*a47842d1SChristoph Müllner     { .name = "-max int32 -1 (-2147483649)",
272*a47842d1SChristoph Müllner       .inp_lf = -0x1.00000002p+31,
273*a47842d1SChristoph Müllner       .exp_fcvt = 0xffffffff80000000,
274*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NV,
275*a47842d1SChristoph Müllner       .exp_fcvtmod = 2147483647, /* int32 max */
276*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NV },
277*a47842d1SChristoph Müllner     { .name = "-max int32 -2 (-2147483650)",
278*a47842d1SChristoph Müllner       .inp_lf = -0x1.00000004p+31,
279*a47842d1SChristoph Müllner       .exp_fcvt = 0xffffffff80000000,
280*a47842d1SChristoph Müllner       .exp_fcvt_fflags = FFLAG_NV,
281*a47842d1SChristoph Müllner       .exp_fcvtmod = 2147483646, /* int32 max -1 */
282*a47842d1SChristoph Müllner       .exp_fcvtmod_fflags = FFLAG_NV },
283*a47842d1SChristoph Müllner };
284*a47842d1SChristoph Müllner 
run_fcvtmod_tests()285*a47842d1SChristoph Müllner int run_fcvtmod_tests()
286*a47842d1SChristoph Müllner {
287*a47842d1SChristoph Müllner     uint64_t act_fcvt;
288*a47842d1SChristoph Müllner     uint8_t act_fcvt_fflags;
289*a47842d1SChristoph Müllner     uint64_t act_fcvtmod;
290*a47842d1SChristoph Müllner     uint8_t act_fcvtmod_fflags;
291*a47842d1SChristoph Müllner 
292*a47842d1SChristoph Müllner     for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
293*a47842d1SChristoph Müllner         const fp64_fcvt_fcvtmod_testcase_t *t = &tests[i];
294*a47842d1SChristoph Müllner 
295*a47842d1SChristoph Müllner         act_fcvt = do_fcvt_w_d(t->inp_lu, &act_fcvt_fflags);
296*a47842d1SChristoph Müllner         int fcvt_correct = act_fcvt == t->exp_fcvt &&
297*a47842d1SChristoph Müllner                     act_fcvt_fflags == t->exp_fcvt_fflags;
298*a47842d1SChristoph Müllner         act_fcvtmod = do_fcvtmod_w_d(t->inp_lu, &act_fcvtmod_fflags);
299*a47842d1SChristoph Müllner         int fcvtmod_correct = act_fcvtmod == t->exp_fcvtmod &&
300*a47842d1SChristoph Müllner                        act_fcvtmod_fflags == t->exp_fcvtmod_fflags;
301*a47842d1SChristoph Müllner 
302*a47842d1SChristoph Müllner         if (fcvt_correct && fcvtmod_correct) {
303*a47842d1SChristoph Müllner             continue;
304*a47842d1SChristoph Müllner         }
305*a47842d1SChristoph Müllner 
306*a47842d1SChristoph Müllner         printf("Test %zu (%s) failed!\n", i, t->name);
307*a47842d1SChristoph Müllner 
308*a47842d1SChristoph Müllner         double fpr = do_fmv_d_x(t->inp_lu);
309*a47842d1SChristoph Müllner         printf("inp_lu: 0x%016lx == %lf\n", t->inp_lu, fpr);
310*a47842d1SChristoph Müllner         printf("inp_lf: %lf\n", t->inp_lf);
311*a47842d1SChristoph Müllner 
312*a47842d1SChristoph Müllner         uint32_t sign = (t->inp_lu >> 63);
313*a47842d1SChristoph Müllner         uint32_t exp = (uint32_t)(t->inp_lu >> 52) & 0x7ff;
314*a47842d1SChristoph Müllner         uint64_t frac = t->inp_lu & 0xfffffffffffffull; /* significand */
315*a47842d1SChristoph Müllner         int true_exp = exp - 1023;
316*a47842d1SChristoph Müllner         int shift = true_exp - 52;
317*a47842d1SChristoph Müllner         uint64_t true_frac = frac | 1ull << 52;
318*a47842d1SChristoph Müllner 
319*a47842d1SChristoph Müllner         printf("sign=%d, exp=0x%03x, frac=0x%012lx\n", sign, exp, frac);
320*a47842d1SChristoph Müllner         printf("true_exp=%d, shift=%d, true_frac=0x%016lx\n", true_exp, shift, true_frac);
321*a47842d1SChristoph Müllner 
322*a47842d1SChristoph Müllner         if (!fcvt_correct) {
323*a47842d1SChristoph Müllner             printf("act_fcvt: 0x%016lx == %li\n", act_fcvt, act_fcvt);
324*a47842d1SChristoph Müllner             printf("exp_fcvt: 0x%016lx == %li\n", t->exp_fcvt, t->exp_fcvt);
325*a47842d1SChristoph Müllner             printf("act_fcvt_fflags: "); print_fflags(act_fcvt_fflags); printf("\n");
326*a47842d1SChristoph Müllner             printf("exp_fcvt_fflags: "); print_fflags(t->exp_fcvt_fflags); printf("\n");
327*a47842d1SChristoph Müllner         }
328*a47842d1SChristoph Müllner 
329*a47842d1SChristoph Müllner         if (!fcvtmod_correct) {
330*a47842d1SChristoph Müllner             printf("act_fcvtmod: 0x%016lx == %li\n", act_fcvtmod, act_fcvtmod);
331*a47842d1SChristoph Müllner             printf("exp_fcvtmod: 0x%016lx == %li\n", t->exp_fcvtmod, t->exp_fcvtmod);
332*a47842d1SChristoph Müllner             printf("act_fcvtmod_fflags: "); print_fflags(act_fcvtmod_fflags); printf("\n");
333*a47842d1SChristoph Müllner             printf("exp_fcvtmod_fflags: "); print_fflags(t->exp_fcvtmod_fflags); printf("\n");
334*a47842d1SChristoph Müllner         }
335*a47842d1SChristoph Müllner 
336*a47842d1SChristoph Müllner         return 1;
337*a47842d1SChristoph Müllner     }
338*a47842d1SChristoph Müllner 
339*a47842d1SChristoph Müllner     return 0;
340*a47842d1SChristoph Müllner }
341*a47842d1SChristoph Müllner 
main()342*a47842d1SChristoph Müllner int main()
343*a47842d1SChristoph Müllner {
344*a47842d1SChristoph Müllner     return run_fcvtmod_tests();
345*a47842d1SChristoph Müllner }
346