8 * vfmin/vfmax instruction execution.
14 asm(".pushsection .rwx,\"awx\",@progbits\n"
16 /* e7 89 a0 00 2e ef */
17 "insn: vfmaxsb %v24,%v25,%v26,0\n"
20 static void vfminmax(unsigned int op
,
21 unsigned int m4
, unsigned int m5
, unsigned int m6
,
22 void *v1
, const void *v2
, const void *v3
)
24 insn
[3] = (m6
<< 4) | m5
;
25 insn
[4] = (m4
<< 4) | 0x0e;
28 asm("vl %%v25,%[v2]\n"
32 : [v1
] "=m" (*(char (*)[16])v1
)
33 : [v2
] "m" (*(char (*)[16])v2
)
34 , [v3
] "m" (*(char (*)[16])v3
)
36 : "v24", "v25", "v26");
40 * Floating-point value classes.
43 #define N_SIGNED_CLASSES 8
44 static const size_t float_sizes
[N_FORMATS
] = {
45 /* M4 == 2: short */ 4,
46 /* M4 == 3: long */ 8,
47 /* M4 == 4: extended */ 16,
49 static const size_t e_bits
[N_FORMATS
] = {
50 /* M4 == 2: short */ 8,
51 /* M4 == 3: long */ 11,
52 /* M4 == 4: extended */ 15,
54 static const unsigned char signed_floats
[N_FORMATS
][N_SIGNED_CLASSES
][2][16] = {
57 /* -inf */ {{0xff, 0x80, 0x00, 0x00},
58 {0xff, 0x80, 0x00, 0x00}},
59 /* -Fn */ {{0xc2, 0x28, 0x00, 0x00},
60 {0xc2, 0x29, 0x00, 0x00}},
61 /* -0 */ {{0x80, 0x00, 0x00, 0x00},
62 {0x80, 0x00, 0x00, 0x00}},
63 /* +0 */ {{0x00, 0x00, 0x00, 0x00},
64 {0x00, 0x00, 0x00, 0x00}},
65 /* +Fn */ {{0x42, 0x28, 0x00, 0x00},
66 {0x42, 0x2a, 0x00, 0x00}},
67 /* +inf */ {{0x7f, 0x80, 0x00, 0x00},
68 {0x7f, 0x80, 0x00, 0x00}},
69 /* QNaN */ {{0x7f, 0xff, 0xff, 0xff},
70 {0x7f, 0xff, 0xff, 0xfe}},
71 /* SNaN */ {{0x7f, 0xbf, 0xff, 0xff},
72 {0x7f, 0xbf, 0xff, 0xfd}},
77 /* -inf */ {{0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
78 {0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
79 /* -Fn */ {{0xc0, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
80 {0xc0, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
81 /* -0 */ {{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
82 {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
83 /* +0 */ {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
84 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
85 /* +Fn */ {{0x40, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
86 {0x40, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
87 /* +inf */ {{0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
88 {0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
89 /* QNaN */ {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
90 {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}},
91 /* SNaN */ {{0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
92 {0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd}},
95 /* M4 == 4: extended */
97 /* -inf */ {{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
98 {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
99 /* -Fn */ {{0xc0, 0x04, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
100 {0xc0, 0x04, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
101 /* -0 */ {{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
102 {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
103 /* +0 */ {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
104 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
105 /* +Fn */ {{0x40, 0x04, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
106 {0x40, 0x04, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
107 /* +inf */ {{0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
108 {0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
109 /* QNaN */ {{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
110 {0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}},
111 /* SNaN */ {{0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
112 {0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd}},
117 * PoP tables as close to the original as possible.
123 const char *table
[N_SIGNED_CLASSES
][N_SIGNED_CLASSES
];
128 .m6_desc
= "IEEE MinNum",
130 /* -inf -Fn -0 +0 +Fn +inf QNaN SNaN */
131 {/* -inf */ "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(b*)"},
132 {/* -Fn */ "T(b)", "T(M(a,b))", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(b*)"},
133 {/* -0 */ "T(b)", "T(b)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(b*)"},
134 {/* +0 */ "T(b)", "T(b)", "T(b)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(b*)"},
135 {/* +Fn */ "T(b)", "T(b)", "T(b)", "T(b)", "T(M(a,b))", "T(a)", "T(a)", "Xi: T(b*)"},
136 {/* +inf */ "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "T(a)", "Xi: T(b*)"},
137 {/* QNaN */ "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(b*)"},
138 {/* SNaN */ "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)"},
144 .m6_desc
= "JAVA Math.Min()",
146 /* -inf -Fn -0 +0 +Fn +inf QNaN SNaN */
147 {/* -inf */ "T(b)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(b)", "Xi: T(b*)"},
148 {/* -Fn */ "T(b)", "T(M(a,b))", "T(a)", "T(a)", "T(a)", "T(a)", "T(b)", "Xi: T(b*)"},
149 {/* -0 */ "T(b)", "T(b)", "T(b)", "T(a)", "T(a)", "T(a)", "T(b)", "Xi: T(b*)"},
150 {/* +0 */ "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "T(a)", "T(b)", "Xi: T(b*)"},
151 {/* +Fn */ "T(b)", "T(b)", "T(b)", "T(b)", "T(M(a,b))", "T(a)", "T(b)", "Xi: T(b*)"},
152 {/* +inf */ "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "Xi: T(b*)"},
153 {/* QNaN */ "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(b*)"},
154 {/* SNaN */ "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)"},
160 .m6_desc
= "C-style Min Macro",
162 /* -inf -Fn -0 +0 +Fn +inf QNaN SNaN */
163 {/* -inf */ "T(b)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(b)", "Xi: T(b)"},
164 {/* -Fn */ "T(b)", "T(M(a,b))", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(b)", "Xi: T(b)"},
165 {/* -0 */ "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "T(a)", "Xi: T(b)", "Xi: T(b)"},
166 {/* +0 */ "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "T(a)", "Xi: T(b)", "Xi: T(b)"},
167 {/* +Fn */ "T(b)", "T(b)", "T(b)", "T(b)", "T(M(a,b))", "T(a)", "Xi: T(b)", "Xi: T(b)"},
168 {/* +inf */ "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(b)", "Xi: T(b)"},
169 {/* QNaN */ "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)"},
170 {/* SNaN */ "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)"},
176 .m6_desc
= "C++ algorithm.min()",
178 /* -inf -Fn -0 +0 +Fn +inf QNaN SNaN */
179 {/* -inf */ "T(b)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(a)", "Xi: T(a)"},
180 {/* -Fn */ "T(b)", "T(M(a,b))", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(a)", "Xi: T(a)"},
181 {/* -0 */ "T(b)", "T(b)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(a)", "Xi: T(a)"},
182 {/* +0 */ "T(b)", "T(b)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(a)", "Xi: T(a)"},
183 {/* +Fn */ "T(b)", "T(b)", "T(b)", "T(b)", "T(M(a,b))", "T(a)", "Xi: T(a)", "Xi: T(a)"},
184 {/* +inf */ "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(a)", "Xi: T(a)"},
185 {/* QNaN */ "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)"},
186 {/* SNaN */ "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)"},
194 /* -inf -Fn -0 +0 +Fn +inf QNaN SNaN */
195 {/* -inf */ "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(a)"},
196 {/* -Fn */ "T(b)", "T(M(a,b))", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(a)"},
197 {/* -0 */ "T(b)", "T(b)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(a)"},
198 {/* +0 */ "T(b)", "T(b)", "T(b)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(a)"},
199 {/* +Fn */ "T(b)", "T(b)", "T(b)", "T(b)", "T(M(a,b))", "T(a)", "T(a)", "Xi: T(a)"},
200 {/* +inf */ "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "T(a)", "Xi: T(a)"},
201 {/* QNaN */ "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(a)"},
202 {/* SNaN */ "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(a)", "Xi: T(a)"},
209 .m6_desc
= "IEEE MaxNum",
211 /* -inf -Fn -0 +0 +Fn +inf QNaN SNaN */
212 {/* -inf */ "T(a)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(b*)"},
213 {/* -Fn */ "T(a)", "T(M(a,b))", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(b*)"},
214 {/* -0 */ "T(a)", "T(a)", "T(a)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(b*)"},
215 {/* +0 */ "T(a)", "T(a)", "T(a)", "T(a)", "T(b)", "T(b)", "T(a)", "Xi: T(b*)"},
216 {/* +Fn */ "T(a)", "T(a)", "T(a)", "T(a)", "T(M(a,b))", "T(b)", "T(a)", "Xi: T(b*)"},
217 {/* +inf */ "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(b*)"},
218 {/* QNaN */ "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(b*)"},
219 {/* SNaN */ "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)"},
225 .m6_desc
= "JAVA Math.Max()",
227 /* -inf -Fn -0 +0 +Fn +inf QNaN SNaN */
228 {/* -inf */ "T(a)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "Xi: T(b*)"},
229 {/* -Fn */ "T(a)", "T(M(a,b))", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "Xi: T(b*)"},
230 {/* -0 */ "T(a)", "T(a)", "T(a)", "T(b)", "T(b)", "T(b)", "T(b)", "Xi: T(b*)"},
231 {/* +0 */ "T(a)", "T(a)", "T(a)", "T(a)", "T(b)", "T(b)", "T(b)", "Xi: T(b*)"},
232 {/* +Fn */ "T(a)", "T(a)", "T(a)", "T(a)", "T(M(a,b))", "T(b)", "T(b)", "Xi: T(b*)"},
233 {/* +inf */ "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(b)", "Xi: T(b*)"},
234 {/* QNaN */ "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(b*)"},
235 {/* SNaN */ "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)", "Xi: T(a*)"},
241 .m6_desc
= "C-style Max Macro",
243 /* -inf -Fn -0 +0 +Fn +inf QNaN SNaN */
244 {/* -inf */ "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "Xi: T(b)", "Xi: T(b)"},
245 {/* -Fn */ "T(a)", "T(M(a,b))", "T(b)", "T(b)", "T(b)", "T(b)", "Xi: T(b)", "Xi: T(b)"},
246 {/* -0 */ "T(a)", "T(a)", "T(b)", "T(b)", "T(b)", "T(b)", "Xi: T(b)", "Xi: T(b)"},
247 {/* +0 */ "T(a)", "T(a)", "T(b)", "T(b)", "T(b)", "T(b)", "Xi: T(b)", "Xi: T(b)"},
248 {/* +Fn */ "T(a)", "T(a)", "T(a)", "T(a)", "T(M(a,b))", "T(b)", "Xi: T(b)", "Xi: T(b)"},
249 {/* +inf */ "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(b)", "Xi: T(b)", "Xi: T(b)"},
250 {/* QNaN */ "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)"},
251 {/* SNaN */ "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)"},
257 .m6_desc
= "C++ algorithm.max()",
259 /* -inf -Fn -0 +0 +Fn +inf QNaN SNaN */
260 {/* -inf */ "T(a)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "Xi: T(a)", "Xi: T(a)"},
261 {/* -Fn */ "T(a)", "T(M(a,b))", "T(b)", "T(b)", "T(b)", "T(b)", "Xi: T(a)", "Xi: T(a)"},
262 {/* -0 */ "T(a)", "T(a)", "T(a)", "T(a)", "T(b)", "T(b)", "Xi: T(a)", "Xi: T(a)"},
263 {/* +0 */ "T(a)", "T(a)", "T(a)", "T(a)", "T(b)", "T(b)", "Xi: T(a)", "Xi: T(a)"},
264 {/* +Fn */ "T(a)", "T(a)", "T(a)", "T(a)", "T(M(a,b))", "T(b)", "Xi: T(a)", "Xi: T(a)"},
265 {/* +inf */ "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(a)", "Xi: T(a)"},
266 {/* QNaN */ "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)"},
267 {/* SNaN */ "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)", "Xi: T(a)"},
275 /* -inf -Fn -0 +0 +Fn +inf QNaN SNaN */
276 {/* -inf */ "T(a)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(a)"},
277 {/* -Fn */ "T(a)", "T(M(a,b))", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(a)"},
278 {/* -0 */ "T(a)", "T(a)", "T(a)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(a)"},
279 {/* +0 */ "T(a)", "T(a)", "T(a)", "T(a)", "T(b)", "T(b)", "T(a)", "Xi: T(a)"},
280 {/* +Fn */ "T(a)", "T(a)", "T(a)", "T(a)", "T(M(a,b))", "T(b)", "T(a)", "Xi: T(a)"},
281 {/* +inf */ "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "T(a)", "Xi: T(a)"},
282 {/* QNaN */ "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(b)", "T(a)", "Xi: T(a)"},
283 {/* SNaN */ "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(b)", "Xi: T(a)", "Xi: T(a)"},
288 static void dump_v(FILE *f
, const void *v
, size_t n
)
290 for (int i
= 0; i
< n
; i
++) {
291 fprintf(f
, "%02x", ((const unsigned char *)v
)[i
]);
295 static int signed_test(struct signed_test
*test
, int m4
, int m5
,
296 const void *v1_exp
, bool xi_exp
,
297 const void *v2
, const void *v3
)
299 size_t n
= (m5
& 8) ? float_sizes
[m4
- 2] : 16;
303 feclearexcept(FE_ALL_EXCEPT
);
304 vfminmax(test
->op
, m4
, m5
, test
->m6
, v1
, v2
, v3
);
305 xi
= fetestexcept(FE_ALL_EXCEPT
) == FE_INVALID
;
307 if (memcmp(v1
, v1_exp
, n
) != 0 || xi
!= xi_exp
) {
308 fprintf(stderr
, "[ FAILED ] %s ", test
->m6_desc
);
309 dump_v(stderr
, v2
, n
);
310 fprintf(stderr
, ", ");
311 dump_v(stderr
, v3
, n
);
312 fprintf(stderr
, ", %d, %d, %d: actual=", m4
, m5
, test
->m6
);
313 dump_v(stderr
, v1
, n
);
314 fprintf(stderr
, "/%d, expected=", (int)xi
);
315 dump_v(stderr
, v1_exp
, n
);
316 fprintf(stderr
, "/%d\n", (int)xi_exp
);
323 static void snan_to_qnan(char *v
, int m4
)
325 size_t bit
= 1 + e_bits
[m4
- 2];
326 v
[bit
/ 8] |= 1 << (7 - (bit
% 8));
334 for (i
= 0; i
< sizeof(signed_tests
) / sizeof(signed_tests
[0]); i
++) {
335 struct signed_test
*test
= &signed_tests
[i
];
338 for (m4
= 2; m4
<= 4; m4
++) {
339 const unsigned char (*floats
)[2][16] = signed_floats
[m4
- 2];
340 size_t float_size
= float_sizes
[m4
- 2];
343 for (m5
= 0; m5
<= 8; m5
+= 8) {
344 char v1_exp
[16], v2
[16], v3
[16];
349 for (i2
= 0; i2
< N_SIGNED_CLASSES
* 2; i2
++) {
352 for (i3
= 0; i3
< N_SIGNED_CLASSES
* 2; i3
++) {
353 const char *spec
= test
->table
[i2
/ 2][i3
/ 2];
355 memcpy(&v2
[pos
], floats
[i2
/ 2][i2
% 2], float_size
);
356 memcpy(&v3
[pos
], floats
[i3
/ 2][i3
% 2], float_size
);
357 if (strcmp(spec
, "T(a)") == 0 ||
358 strcmp(spec
, "Xi: T(a)") == 0) {
359 memcpy(&v1_exp
[pos
], &v2
[pos
], float_size
);
360 } else if (strcmp(spec
, "T(b)") == 0 ||
361 strcmp(spec
, "Xi: T(b)") == 0) {
362 memcpy(&v1_exp
[pos
], &v3
[pos
], float_size
);
363 } else if (strcmp(spec
, "Xi: T(a*)") == 0) {
364 memcpy(&v1_exp
[pos
], &v2
[pos
], float_size
);
365 snan_to_qnan(&v1_exp
[pos
], m4
);
366 } else if (strcmp(spec
, "Xi: T(b*)") == 0) {
367 memcpy(&v1_exp
[pos
], &v3
[pos
], float_size
);
368 snan_to_qnan(&v1_exp
[pos
], m4
);
369 } else if (strcmp(spec
, "T(M(a,b))") == 0) {
371 * Comparing floats is risky, since the compiler
372 * might generate the same instruction that we are
373 * testing. Compare ints instead. This works,
374 * because we get here only for +-Fn, and the
375 * corresponding test values have identical
378 int v2_int
= *(int *)&v2
[pos
];
379 int v3_int
= *(int *)&v3
[pos
];
381 if ((v2_int
< v3_int
) ==
382 ((test
->op
== VFMIN
) != (v2_int
< 0))) {
383 memcpy(&v1_exp
[pos
], &v2
[pos
], float_size
);
385 memcpy(&v1_exp
[pos
], &v3
[pos
], float_size
);
388 fprintf(stderr
, "Unexpected spec: %s\n", spec
);
391 xi_exp
|= spec
[0] == 'X';
394 if ((m5
& 8) || pos
== 16) {
395 ret
|= signed_test(test
, m4
, m5
,
396 v1_exp
, xi_exp
, v2
, v3
);
404 ret
|= signed_test(test
, m4
, m5
, v1_exp
, xi_exp
, v2
, v3
);