1 /*
2 Copyright (c) 2007-2011, Intel Corp.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13 * Neither the name of Intel Corporation nor the names of its contributors
14 may be used to endorse or promote products derived from this software
15 without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 // readtest.c - read tests from stdin
30 //
31 // This programs reads test of the form:
32 //
33 // <TESTID> <FUNCTION> <OP1> <OP2> <OP3> <RESULT> <STATUS>
34 //
35 // The testID is simply a string used to help identify which tail may be failing.
36 // The function name is generally one of the BID library function names. Up to 3
37 // operands follow the function name, and then the expected result and expected
38 // status value.
39 //
40 // Each test is read, the appropriate function is called, and the results are
41 // compared with the expected results. The operands, and results can appear as
42 // decimal numbers (e.g. 6.25), or as hexadecimal representations surrounded by
43 // square brackets (e.g. [31c0000000012345]). The status value is a hexadecimal
44 // value (without the leading 0x).
45
46 #define STRMAX 1024
47 #include <stdio.h> // for printf
48 #include <stdlib.h>
49 #include <string.h>
50 #include <ctype.h>
51 #include <wchar.h>
52 #if !defined _MSC_VER && !defined __INTEL_COMPILER
53 #include <fenv.h>
54 #endif
55
56 #include "test_bid_conf.h"
57 #include "test_bid_functions.h"
58
59 int copy_str_to_wstr();
60
61 enum _OPTYPE { OP_NONE, OP_DEC128, OP_DPD128, OP_DEC64, OP_DPD64,
62 OP_DEC32, OP_DPD32,
63 OP_INT64, OP_BID_UINT64, OP_INT32, OP_BID_UINT32, OP_BIN64, OP_BIN32,
64 OP_BIN80, OP_BIN128,
65 OP_INT16, OP_BID_UINT16, OP_INT8, OP_BID_UINT8, OP_LINT, OP_STRING
66 };
67
68 // Compare modes: EXACT does a bitwise compare, FUZZY does a bitwise unless NaN vs. NaN
69 // EQUAL uses bid<size>_quiet_equal
70
71 enum _CMPTYPE { CMP_NONE, CMP_EXACT, CMP_FUZZY,
72 CMP_EXACTSTATUS, CMP_FUZZYSTATUS,
73 CMP_EQUAL, CMP_EQUALSTATUS, CMP_RELATIVEERR
74 };
75
76 typedef BID_UINT32 decimal32;
77 typedef BID_UINT64 decimal64;
78 typedef BID_UINT128 decimal128;
79
80 #define GETTEST1(res,op1) restype = (res); op1type = (op1); get_test();
81 #define GETTEST2(res,op1,op2) restype = (res); op1type = (op1); op2type = (op2); get_test();
82 #define GETTEST3(res,op1,op2,op3) restype = (res); op1type = (op1); op2type = (op2); op3type = (op3); get_test();
83
84 BID_EXTERN_C char *decStatusToString (const int status);
85 BID_EXTERN_C int check128 (BID_UINT128 a, BID_UINT128 b);
86 BID_EXTERN_C int check64 (BID_UINT64 a, BID_UINT64 b);
87 BID_EXTERN_C int compare_status (BID_FPSC bid, int dpd);
88 BID_EXTERN_C void print_status (int st);
89 BID_EXTERN_C void get_status (int st, char *status_str);
90 BID_EXTERN_C char *func;
91 BID_EXTERN_C double fabs(double);
92 double ulp; // current integer difference computed_result-expected_result
93 double ulp_add;
94 int Underflow_Before;
95 int li_size_test, li_size_run;
96 double mre;
97 float snan_check32;
98 double snan_check64;
99 long double snan_check80;
100 double mre_max[5] = {2.0, 2.0, 2.0, 2.0, 2.0};
101 unsigned int trans_flags_mask = 0x05;
102 int not_special_arg_res;
103 int SNaN_passed_incorrectly32 = 0;
104 int SNaN_passed_incorrectly64 = 0;
105 int SNaN_passed_incorrectly80 = 0;
106 int Den_passed_incorrectly32 = 0;
107 int Den_passed_incorrectly64 = 0;
108 int Den_passed_incorrectly80 = 0;
109 int arg32_den, res32_den, arg32_snan;
110 int arg64_den, res64_den, arg64_snan;
111 int arg80_den, res80_den, arg80_snan;
112 int res128_den;
113 int pollution_workaround;
114
115 fexcept_t ini_binary_flags, saved_binary_flags, test_binary_flags;
116 int ini_binary_rmode, saved_binary_rmode, test_binary_rmode;
117 fexcept_t fp_fl;
118
119 void save_binary_status();
120 int check_restore_binary_status();
121 int check_pollution_workaround(void);
122
123 #ifndef HPUX_OS
124 #ifndef FE_UNNORMAL
125 #define FE_UNNORMAL 2
126 #endif
127 #ifndef FE_DENORMAL
128 #define FE_DENORMAL 2
129 #endif
130 #else
131 #ifndef FE_UNNORMAL
132 #define FE_UNNORMAL 0x4000
133 #endif
134 #ifndef FE_DENORMAL
135 #define FE_DENORMAL 0x4000
136 #endif
137 #endif
138
139 #define getop128(bid, dpd, op, str) \
140 if (*op == '[') { \
141 if ((sscanf(op+1, BID_FMT_LLX16""BID_FMT_LLX16, &(bid.w[BID_HIGH_128W]), &(bid.w[BID_LOW_128W])) == 2) || \
142 (sscanf(op+1, ""BID_FMT_LLX16","BID_FMT_LLX16"", &(bid.w[BID_HIGH_128W]), &(bid.w[BID_LOW_128W])) == 2)) {\
143 dpd = bid; \
144 BIDECIMAL_CALL1_NORND_RESREF(bid128_to_string, str, bid); \
145 } else { \
146 printf("Internal error - can't read number form string %s\n", op+1); \
147 exit(1); \
148 } \
149 } else { \
150 BIDECIMAL_CALL1_RESARG(bid128_from_string, (bid), (op)); \
151 dpd = bid; \
152 if ( !strcmp(func, "bid128_from_string") || !strcmp(func, "bid_strtod128") || !strcmp(func, "bid_wcstod128") || !strcmp(func, "bid_strtod128") || !strcmp(func, "bid128_nan") ) { \
153 strcpy(str, op); \
154 } else { \
155 BIDECIMAL_CALL1_NORND_RESREF(bid128_to_string, str, bid); \
156 } \
157 } \
158
159 #define getop32(bid, dpd, op, str) \
160 if (*op == '[') { \
161 if (sscanf((op)+1, BID_FMT_X8, &(bid))) { \
162 dpd = (bid); \
163 BIDECIMAL_CALL1_NORND_RESREF(bid32_to_string, str, bid); \
164 } else { \
165 printf("Internal error - can't read number form string %s\n", (op)+1); \
166 exit(1); \
167 } \
168 } else { \
169 BIDECIMAL_CALL1_RESARG(bid32_from_string, bid, op); \
170 dpd = bid; \
171 if ( !strcmp(func, "bid32_from_string") || !strcmp(func, "bid_strtod32") || !strcmp(func, "bid_wcstod32") || !strcmp(func, "bid32_nan") ) { \
172 strcpy(str, op); \
173 } else { \
174 BIDECIMAL_CALL1_NORND_RESREF(bid32_to_string, str, bid); \
175 } \
176 } \
177
178
179 #define getop64(bid, dpd, op, str) \
180 if (*op == '[') { \
181 if (sscanf(op+1, BID_FMT_LLX16, &bid)) { \
182 dpd = bid; \
183 BIDECIMAL_CALL1_NORND_RESREF(bid64_to_string, str, bid); \
184 } else { \
185 printf("Internal error - can't read number form string %s\n", (op)+1); \
186 exit(1); \
187 } \
188 } else { \
189 BIDECIMAL_CALL1_RESARG(bid64_from_string, bid, op); \
190 dpd = bid; \
191 if ( !strcmp(func, "bid64_from_string") || !strcmp(func, "bid_strtod64") || !strcmp(func, "bid_wcstod64") || !strcmp(func, "bid64_nan") ) { \
192 strcpy(str, op); \
193 } else { \
194 BIDECIMAL_CALL1_NORND_RESREF(bid64_to_string, str, bid); \
195 } \
196 }
197
198 #define getop32i(bid, op, str) \
199 if (*op == '[') { \
200 if (!sscanf(op+1, "%08x", &bid)) { \
201 printf("Internal error - can't read number form string %s\n", (op)+1); \
202 exit(1); \
203 } \
204 } else { \
205 if (!sscanf(op, "%d", &bid)) { \
206 printf("Internal error - can't read number form string %s\n", op); \
207 exit(1); \
208 } \
209 } \
210 sprintf(str, "%d", bid);
211
212 #define getop16i(bid, op, str) \
213 if (*op == '[') { \
214 if (!sscanf(op+1, "%04x", &bid)) { \
215 printf("Internal error - can't read number form string %s\n", (op)+1); \
216 exit(1); \
217 } \
218 } else { \
219 if (!sscanf(op, "%d", &bid)) { \
220 printf("Internal error - can't read number form string %s\n", (op)); \
221 exit(1); \
222 } \
223 } \
224 sprintf(str, "%d", bid);
225
226 #define getop8i(bid, op, str) \
227 if (*op == '[') { \
228 if (!sscanf(op+1, "%02x", &bid)) { \
229 } else { \
230 printf("Internal error - can't read number form string %s\n", (op)+1); \
231 exit(1); \
232 } \
233 } else { \
234 if (!sscanf(op, "%d", &bid)) { \
235 printf("Internal error - can't read number form string %s\n", (op)); \
236 exit(1); \
237 } \
238 } \
239 sprintf(str, "%d", bid);
240
241 #define getop32u(bid, op, str) \
242 if (*op == '[') { \
243 if (!sscanf(op+1, "%08x", &bid)) { \
244 printf("Internal error - can't read number form string %s\n", (op)+1); \
245 exit(1); \
246 } \
247 } else { \
248 if (!sscanf(op, "%u", &bid)) { \
249 printf("Internal error - can't read number form string %s\n", (op)); \
250 exit(1); \
251 } \
252 } \
253 sprintf(str, "%u", bid);
254
255 #define getop16u(bid, op, str) \
256 if (*op == '[') { \
257 if (!sscanf(op+1, "%04x", &bid)) { \
258 printf("Internal error - can't read number form string %s\n", (op)+1); \
259 exit(1); \
260 } \
261 } else { \
262 if (!sscanf(op, "%u", &bid)) { \
263 printf("Internal error - can't read number form string %s\n", (op)); \
264 exit(1); \
265 } \
266 } \
267 sprintf(str, "%u", bid);
268
269 #define getop8u(bid, op, str) \
270 if (*op == '[') { \
271 if (!sscanf(op+1, "%02x", &bid)) { \
272 printf("Internal error - can't read number form string %s\n", (op)+1); \
273 exit(1); \
274 } \
275 } else { \
276 if (!sscanf(op, "%u", &bid)) { \
277 printf("Internal error - can't read number form string %s\n", (op)); \
278 exit(1); \
279 } \
280 } \
281 sprintf(str, "%u", bid);
282
283 #define getop64i(bid, op, str) \
284 if (*op == '[') { \
285 if (!sscanf(op+1, BID_FMT_LLX16, &bid)) { \
286 printf("Internal error - can't read number form string %s\n", (op)+1); \
287 exit(1); \
288 } \
289 } else { \
290 if (!sscanf(op, BID_FMT_LLD, &bid)) { \
291 printf("Internal error - can't read number form string %s\n", (op)); \
292 exit(1); \
293 } \
294 } \
295 sprintf(str, BID_FMT_LLD, bid);
296
297 #define getop64u(bid, op, str) \
298 if (*op == '[') { \
299 if (!sscanf(op+1, BID_FMT_LLX16, &bid)) { \
300 printf("Internal error - can't read number form string %s\n", (op)+1); \
301 exit(1); \
302 } \
303 } else { \
304 if (!sscanf(op, BID_FMT_LLU, &bid)) { \
305 printf("Internal error - can't read number form string %s\n", (op)); \
306 exit(1); \
307 } \
308 } \
309 sprintf(str, BID_FMT_LLU, bid);
310
311 #define getopquad(quad1, quad2, op, str) \
312 if (*op == '[') { \
313 if (sscanf(op+1, BID_FMT_LLX16""BID_FMT_LLX16, ((BID_UINT64*)&quad1+BID_HIGH_128W), (BID_UINT64*)&quad1+BID_LOW_128W) != 2) { \
314 printf("Internal error - can't read number form string %s\n", (op)+1); \
315 exit(1); \
316 } \
317 } \
318 strcpy(str, "unavalable");
319
320 #if BID_BIG_ENDIAN
321 #define getopldbl(ldbl1, ldbl2, op, str) \
322 { \
323 int tmpi; \
324 arg80_den = arg80_snan = 0; \
325 if (*op == '[') { \
326 if (sscanf(op+1, BID_FMT_LLX16""BID_FMT_X4, (BID_UINT64*)&ldbl1, &tmpi) != 2) { \
327 printf("Internal error - can't read number form string %s\n", (op)+1); \
328 exit(1); \
329 } else {\
330 *((unsigned short*)((BID_UINT64*)&ldbl1+1)) = tmpi & 0xffff; \
331 } \
332 } else { \
333 double dtmp; \
334 if (!sscanf (op, "%lf", &dtmp)) { \
335 printf("Internal error - can't read number form string %s\n", (op)); \
336 exit(1); \
337 } \
338 ldbl1 = (BINARY80)dtmp; \
339 } \
340 { short *px = (short*)&ldbl1; \
341 if (((*(px) & 0x7fff) == 0x7fff) && ((*(px+1) & 0x8000) == 0x8000) && ((*(px+1) & 0x3fff) || (*(px+2) & 0xffff) || (*(px+3) & 0xffff) || (*(px+0) & 0xffff)) && !(*(px+1) & 0x4000)) arg80_snan = 1; \
342 if (((*(px) & 0x7fff) == 0x0000) && ((*(px+1) & 0x8000) != 0x8000) && ((*(px+1) & 0x3fff) || (*(px+2) & 0xffff) || (*(px+3) & 0xffff) || (*(px+0) & 0xffff))) arg80_den = 1; \
343 } \
344 sprintf(str, "%27.17e", (double)ldbl1); \
345 }
346 #else
347 #define getopldbl(ldbl1, ldbl2, op, str) \
348 arg80_den = arg80_snan = 0; \
349 if (*op == '[') { \
350 if (sscanf(op+1, BID_FMT_X4""BID_FMT_LLX16, (unsigned short*)((BID_UINT64*)&ldbl1+1), (BID_UINT64*)&ldbl1) != 2) { \
351 printf("Internal error - can't read number form string %s\n", (op)+1); \
352 exit(1); \
353 } \
354 } else { \
355 double dtmp; \
356 if (!sscanf (op, "%lf", &dtmp)) { \
357 printf("Internal error - can't read number form string %s\n", (op)); \
358 exit(1); \
359 } \
360 ldbl1 = (BINARY80)dtmp; \
361 } \
362 { short *px = (short*)&ldbl1; \
363 if (((*(px+4) & 0x7fff) == 0x7fff) && ((*(px+3) & 0x8000) == 0x8000) && ((*(px+3) & 0x3fff) || (*(px+2) & 0xffff) || (*(px+1) & 0xffff) || (*(px+0) & 0xffff)) && !(*(px+3) & 0x4000)) arg80_snan = 1; \
364 if (((*(px+4) & 0x7fff) == 0x0000) && ((*(px+3) & 0x8000) != 0x8000) && ((*(px+3) & 0x3fff) || (*(px+2) & 0xffff) || (*(px+1) & 0xffff) || (*(px+0) & 0xffff))) arg80_den = 1; \
365 } \
366 sprintf(str, "%27.17e", (double)ldbl1);
367 #endif
368
369 #define getopdbl(dbl1, dbl2, op, str) \
370 arg64_den = arg64_snan = 0; \
371 if (*op == '[') { \
372 if (!sscanf(op+1, BID_FMT_LLX16, (BID_UINT64*)&dbl1)) { \
373 printf("Internal error - can't read number form string %s\n", (op)+1); \
374 exit(1); \
375 } \
376 } else { \
377 if (!sscanf (op, "%lf", &dbl1)) { \
378 printf("Internal error - can't read number form string %s\n", (op)); \
379 exit(1); \
380 } \
381 } \
382 { int *px = (int*)&dbl1; \
383 if (((*(px+BID_HIGH_128W) & 0x7ff00000) == 0x7ff00000) && ((*(px+BID_HIGH_128W) & 0x0007ffff) || (*(px+BID_LOW_128W) & 0xffffffff)) && !(*(px+BID_HIGH_128W) & 0x00080000)) arg64_snan = 1; \
384 if (((*(px+BID_HIGH_128W) & 0x7ff00000) == 0x00000000) && ((*(px+BID_HIGH_128W) & 0x000fffff) || (*(px+BID_LOW_128W) & 0xffffffff))) arg64_den = 1; \
385 } \
386 sprintf(str, "%27.17e", dbl1);
387
388 #define getopflt(flt1, flt2, op, str) \
389 arg32_den = arg32_snan = 0; \
390 if (*op == '[') { \
391 if (!sscanf(op+1, BID_FMT_X8, (BID_UINT32*)&flt1)) { \
392 printf("Internal error - can't read number form string %s\n", (op)+1); \
393 exit(1); \
394 } \
395 } else { \
396 if (!sscanf (op, "%f", &flt1)) { \
397 printf("Internal error - can't read number form string %s\n", (op)); \
398 exit(1); \
399 } \
400 } \
401 { int *px = (int*)&flt1; \
402 if (((*(px) & 0x7f800000) == 0x7f800000) && (*(px) & 0x003fffff) && !(*(px) & 0x00400000)) arg32_snan = 1; \
403 if (((*(px) & 0x7f800000) == 0x00000000) && (*(px) & 0x007fffff)) arg32_den = 1; \
404 } \
405 sprintf(str, "%18.9e", flt1);
406
407 BID_EXTERN_C void get_ops (void);
408 BID_EXTERN_C void get_test (void);
409 BID_EXTERN_C void gen_ops (void);
410 BID_EXTERN_C void print_mismatch (enum _CMPTYPE cmp);
411 BID_EXTERN_C void check_results (enum _CMPTYPE cmp);
412 BID_EXTERN_C int st_compare (char **a, char **b);
413 BID_EXTERN_C int status_compare (char *stat1, char *stat2);
414 BID_EXTERN_C int setrounding (char *s);
415
416 unsigned int fpsf_0 = 0;
417
418 int args_set;
419
420 #if !DECIMAL_GLOBAL_EXCEPTION_FLAGS
421 unsigned int pfpsf_value;
422 unsigned int *pfpsf = &pfpsf_value;
423 #endif
424
425 #if defined LINUX && !defined HPUX_OS
426 #include <getopt.h>
427 #endif
428
429 #ifndef __COMPAR_FN_T
430 # define __COMPAR_FN_T
431 #if !defined(WINDOWS)
432 typedef int (*__compar_fn_t) (__const void *, __const void *);
433 #endif
434 #endif
435
436 #define STRMAX 1024
437
438 enum _OPTYPE restype, op1type, op2type, op3type;
439
440 BID_UINT128 A, B, C, T, Q, R, R_1;
441 BID_UINT64 A64, B64, C64, CC64, T64, Q64, R64, Rt64, R64_1;
442 BID_UINT32 A32, B32, C32, T32, Q32, R32, Rt32, R32_1;
443 BINARY128 Aquad, Rquad, Rtquad;
444 BINARY80 Aldbl, Rldbl, Rtldbl;
445 double Adbl, Rdbl, Rtdbl;
446 float Aflt, Rflt, Rtflt;
447
448 BID_UINT32 a32, b32, c32, q32, r32;
449 BID_UINT64 a64, b64, c64, q64, r64;
450 BID_UINT128 a, b, c, q, r;
451
452 signed char AI8;
453 unsigned char AUI8;
454 short AI16, BI16;
455 unsigned short AUI16, BUI16;
456 int AI32, BI32;
457 unsigned int AUI32, BUI32, CUI32;
458 BID_SINT64 AI64;
459 BID_UINT64 AUI64;
460 long int BLI, li1, li2;
461
462 unsigned int u1, u2;
463 int i1, i2, n;
464
465 unsigned short u1_16, u2_16;
466 short i1_16, i2_16;
467
468 unsigned char u1_8, u2_8;
469 signed char i1_8, i2_8;
470
471 unsigned int expected_status;
472
473 #if !DECIMAL_GLOBAL_ROUNDING
474 unsigned int rnd_mode;
475 #endif
476 unsigned int tmp_status;
477 unsigned int rnd = 0;
478
479 char funcstr[STRMAX];
480 char *func = funcstr;
481 char string[STRMAX]; // conversion buffer
482 char str1[STRMAX];
483
484 // Input and result operands
485 char op1[STRMAX], op2[STRMAX], op3[STRMAX]; // conversion strings
486 char res[STRMAX];
487
488 char *endptr;
489 wchar_t wistr1[STRMAX], *wendptr;
490 char str_prefix[STRMAX];
491 char istr1[STRMAX], istr2[STRMAX], istr3[STRMAX], str2[STRMAX];
492 char convstr[STRMAX];
493 char res[STRMAX], rstr[STRMAX];
494 char version[STRMAX];
495 int extended, precision, minExponent, maxExponent;
496 char rounding[STRMAX];
497 int line_counter;
498 char result[STRMAX];
499 char status_str[STRMAX];
500 char exp_result[STRMAX], exp_status[STRMAX];
501 char line[STRMAX];
502 char full_line[STRMAX];
503 char *p;
504 BID_UINT64 Qi64, qi64;
505 int specop_opt;
506 int randop_opt;
507 int answer_opt;
508 int canon_opt;
509 int canon_dpd_opt;
510 int prec;
511 int expon_min;
512 int expon_max;
513 int no128trans = 0;
514 int no64trans = 0;
515
516
517 int debug_opt = 0;
518 #if defined UNCHANGED_BINARY_STATUS_FLAGS
519 int check_binary_flags_opt = 1;
520 #else
521 int check_binary_flags_opt = 0;
522 #endif
523 int underflow_before_opt = 0;
524 int underflow_after_opt = 0;
525 int tests = 0, fail_res = 0, fail_status = 0;
526
527 // char * decimal32ToString(const decimal32 *, char *);
528 // char * decimal64ToString(const decimal64 *, char *);
529 // char * decimal128ToString(const decimal128 *, char *);
530
531 char *roundstr[] = { "even", "away", "up", "down", "zero" };
532 char *roundstr_bid[] =
533 { "half_even", "down", "up", "zero", "half_away" };
534
535 int
setrounding(char * s)536 setrounding (char *s) {
537 if (strcmp (s, "half_even") == 0 || strcmp (s, "even") == 0) {
538 rnd = rnd_mode = BID_ROUNDING_TO_NEAREST;
539 strcpy (rounding, roundstr[0]);
540 } else if (strcmp (s, "half_away") == 0 || strcmp (s, "away") == 0) {
541 rnd = rnd_mode = BID_ROUNDING_TIES_AWAY;
542 strcpy (rounding, roundstr[1]);
543 } else if (strcmp (s, "up") == 0) {
544 rnd = rnd_mode = BID_ROUNDING_UP;
545 strcpy (rounding, roundstr[2]);
546 } else if (strcmp (s, "down") == 0) {
547 rnd = rnd_mode = BID_ROUNDING_DOWN;
548 strcpy (rounding, roundstr[3]);
549 } else if (strcmp (s, "zero") == 0) {
550 rnd = rnd_mode = BID_ROUNDING_TO_ZERO;
551 strcpy (rounding, roundstr[4]);
552 } else {
553 printf
554 ("setrounding: unknown rounding mode string!!! Mode unchanged.\n");
555 }
556 return 1;
557 }
558
559 // Return TRUE (1) if 'a' and 'b' are incomtible results from some BID and DPD
560 // functions. Ignore the payload of NaNs
561 int
check128(BID_UINT128 a,BID_UINT128 b)562 check128 (BID_UINT128 a, BID_UINT128 b) {
563 if (a.w[BID_LOW_128W] == b.w[BID_LOW_128W]
564 && a.w[BID_HIGH_128W] == b.w[BID_HIGH_128W])
565 return 0;
566
567 return 1;
568 }
569
570 // Get rid of 0x0D and 0x0A symbols in the string s.
strRemove0D0A(char * s)571 void strRemove0D0A(char* s) {
572 int i = 0;
573 while( (s[i]!=0) && (s[i]!=0x0D) && (s[i]!=0x0A) ) i++;
574 s[i]=0;
575 }
576
577 // Get rid of trailing spaces in the string s.
strRemoveTrailingSpaces(char * s)578 void strRemoveTrailingSpaces(char* s) {
579 int i=0;
580 while( s[i]!=0 ) i++; i--;
581 while( (s[i]==' ') && (i>=0) ) { s[i]=0; i--; }
582 }
583
584 int
check64(BID_UINT64 a,BID_UINT64 b)585 check64 (BID_UINT64 a, BID_UINT64 b) {
586 if (a == b)
587 return 0;
588
589 return 1;
590 }
591
592 int
check32(BID_UINT32 a32,BID_UINT32 b32)593 check32 (BID_UINT32 a32, BID_UINT32 b32) {
594 if (a32 == b32)
595 return 0;
596
597 return 1;
598 }
599
600 #define MASK_STEERING_BITS 0x6000000000000000ull
601 #define MASK_EXP 0x7ffe000000000000ull
602 #define EXP_P1 0x0002000000000000ull
603 #define SMALL_COEFF_MASK128 0x0001ffffffffffffull
604 #define MASK_BINARY_EXPONENT2 0x1ff8000000000000ull
605 #define MASK_BINARY_EXPONENT1 0x7fe0000000000000ull
606 #define MASK_BINARY_SIG2 0x0007ffffffffffffull
607 #define MASK_BINARY_SIG1 0x001fffffffffffffull
608 #define MASK_BINARY_OR2 0x0020000000000000ull
609 #define MASK_STEERING_BITS32 0x60000000
610 #define MASK_BINARY_EXPONENT1_32 0x7f800000
611 #define MASK_BINARY_SIG1_32 0x007fffff
612 #define MASK_BINARY_EXPONENT2_32 0x1fe00000
613 #define MASK_BINARY_SIG2_32 0x001fffff
614 #define MASK_BINARY_OR2_32 0x00800000
615 #define SHIFT_EXP1_32 23
616 #define SHIFT_EXP2_32 21
617 #define SHIFT_EXP1_64 53
618 #define SHIFT_EXP2_64 51
619 #define SHIFT_EXP1_128 17
620 #define SHIFT_EXP2_128 15
621
622
623 #define GET_EXP_32(r, x) \
624 { \
625 if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) { \
626 r = (x & MASK_BINARY_EXPONENT2_32) >> SHIFT_EXP2_32; \
627 } else { \
628 r = (x & MASK_BINARY_EXPONENT1_32) >> SHIFT_EXP1_32; \
629 } \
630 }
631
632 #define GET_MANT_32(r, x) \
633 { \
634 if ((x & MASK_STEERING_BITS32) == MASK_STEERING_BITS32) { \
635 r = (x & MASK_BINARY_SIG2_32) | MASK_BINARY_OR2_32; \
636 } else { \
637 r = (x & MASK_BINARY_SIG1_32); \
638 } \
639 }
640
641 #define GET_EXP_64(r, x) \
642 { \
643 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { \
644 r = (x & MASK_BINARY_EXPONENT2) >> SHIFT_EXP2_64; \
645 } else { \
646 r = (x & MASK_BINARY_EXPONENT1) >> SHIFT_EXP1_64; \
647 } \
648 }
649
650 #define GET_MANT_64(r, x) \
651 { \
652 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { \
653 r = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2; \
654 } else { \
655 r = (x & MASK_BINARY_SIG1); \
656 } \
657 }
658
659 #define MASK_EXP2 0x1fff800000000000ull
660 #define MASK_SIG2 0x00007fffffffffffull
661
662 #define GET_EXP_128(r, x) \
663 { \
664 if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) { \
665 r = (x & MASK_EXP2) >> SHIFT_EXP2_128; \
666 } else { \
667 r = (x & MASK_EXP) >> SHIFT_EXP1_128; \
668 } \
669 }
670
671 #define GET_MANT_128(r, x) \
672 { \
673 if ((x.w[BID_HIGH_128W] & MASK_STEERING_BITS) == MASK_STEERING_BITS) { \
674 r.w[BID_HIGH_128W] = (x.w[BID_HIGH_128W] & MASK_SIG2) | EXP_P1; \
675 r.w[BID_LOW_128W] = x.w[BID_LOW_128W]; \
676 } else { \
677 r.w[BID_HIGH_128W] = (x.w[BID_HIGH_128W] & SMALL_COEFF_MASK128); \
678 r.w[BID_LOW_128W] = x.w[BID_LOW_128W]; \
679 } \
680 }
681
682
683
684 int
check128_rel(BID_UINT128 a,BID_UINT128 b)685 check128_rel(BID_UINT128 a, BID_UINT128 b)
686 {
687 BID_UINT128 r;
688 BID_UINT128 r1, r2, m1, m2;
689 BID_UINT64 e1, e2;
690 int sign, less;
691 int t1, t2, t3, t4;
692
693 BIDECIMAL_CALL1_NORND_NOSTAT (bid128_isNaN, t1, a);
694 BIDECIMAL_CALL1_NORND_NOSTAT (bid128_isNaN, t2, b);
695 BIDECIMAL_CALL1_NORND_NOSTAT (bid128_isInf, t3, a);
696 BIDECIMAL_CALL1_NORND_NOSTAT (bid128_isInf, t4, b);
697
698 //if (bid128_isNaN(a)||bid128_isNaN(b) || bid128_isInf(a)||bid128_isInf(b)) {
699 if (t1 || t2 || t3 || t4) {
700 if (a.w[BID_LOW_128W] == b.w[BID_LOW_128W] && a.w[BID_HIGH_128W] == b.w[BID_HIGH_128W]) return 0;
701 else {
702 if(t3) {
703 a.w[BID_HIGH_128W] = (a.w[BID_HIGH_128W] & 0x8000000000000000ull) | 0x5FFFED09BEAD87C0ull;
704 a.w[BID_LOW_128W] = 0x378D8E63FFFFFFFFull;
705 } else if(t4) {
706 b.w[BID_HIGH_128W] = (b.w[BID_HIGH_128W] & 0x8000000000000000ull) | 0x5FFFED09BEAD87C0ull;
707 b.w[BID_LOW_128W] = 0x378D8E63FFFFFFFFull;
708 }
709 else return 1;
710 }
711 }
712
713 if ((a.w[BID_HIGH_128W] & 0x8000000000000000ull) != (b.w[BID_HIGH_128W] & 0x8000000000000000ull)) {
714 return 1;
715 }
716
717 if (a.w[BID_HIGH_128W] & 0x8000000000000000ull) sign = 1;
718
719 GET_EXP_128(e1, a.w[BID_HIGH_128W])
720 GET_EXP_128(e2, b.w[BID_HIGH_128W])
721 GET_MANT_128(m1, a)
722 GET_MANT_128(m2, b)
723
724 if (e1 < e2) {
725 BIDECIMAL_CALL2 (bid128_quantize, r1, a, b);
726 r2 = b;
727 GET_EXP_128(e1, r1.w[BID_HIGH_128W])
728 GET_EXP_128(e2, r2.w[BID_HIGH_128W])
729 GET_MANT_128(m1, r1)
730 GET_MANT_128(m2, r2)
731 } else if (e2 < e1) {
732 r1 = a;
733 BIDECIMAL_CALL2 (bid128_quantize, r2, b, a);
734 GET_EXP_128(e1, r1.w[BID_HIGH_128W])
735 GET_EXP_128(e2, r2.w[BID_HIGH_128W])
736 GET_MANT_128(m1, r1)
737 GET_MANT_128(m2, r2)
738 } else {
739 r1 = a;
740 r2 = b;
741 }
742
743 if (e1 != e2) {
744 printf("ERROR a, b "BID_FMT_LLX16" "BID_FMT_LLX16" "BID_FMT_LLX16" "BID_FMT_LLX16"\n", a.w[BID_HIGH_128W], a.w[BID_LOW_128W], b.w[BID_HIGH_128W], b.w[BID_LOW_128W]);
745 printf("ERROR r1, r2 "BID_FMT_LLX16" "BID_FMT_LLX16" "BID_FMT_LLX16" "BID_FMT_LLX16"\n", r1.w[BID_HIGH_128W], r1.w[BID_LOW_128W], r2.w[BID_HIGH_128W], r2.w[BID_LOW_128W]);
746 return 1;
747 }
748
749 ulp = m1.w[BID_LOW_128W] > m2.w[BID_LOW_128W] ?
750 m1.w[BID_LOW_128W] - m2.w[BID_LOW_128W] : m2.w[BID_LOW_128W]- m1.w[BID_LOW_128W];
751 //TODO HIGH part difference
752 BIDECIMAL_CALL2_NORND (bid128_quiet_less, less, a, b);
753 if (less) ulp *= -1.0;
754 //printf("ulp %f +add %f max %f\n", ulp, ulp+ulp_add, mre_max[rnd_mode]);
755 if (fabs(ulp+ulp_add) > mre_max[rnd_mode]) {
756 return 1;
757 }
758
759 return 0;
760 }
761
762 int
check64_rel(BID_UINT64 a,BID_UINT64 b)763 check64_rel(BID_UINT64 a, BID_UINT64 b)
764 {
765 BID_UINT64 r1, r2;
766 BID_UINT64 e1, e2, m1, m2;
767 int sign, less;
768 int t1, t2, t3, t4;
769
770 BIDECIMAL_CALL1_NORND_NOSTAT (bid64_isNaN, t1, a);
771 BIDECIMAL_CALL1_NORND_NOSTAT (bid64_isNaN, t2, b);
772 BIDECIMAL_CALL1_NORND_NOSTAT (bid64_isInf, t3, a);
773 BIDECIMAL_CALL1_NORND_NOSTAT (bid64_isInf, t4, b);
774
775 //if (bid64_isNaN(a) || bid64_isNaN(b) || bid64_isInf(a) || bid64_isInf(b)) {
776 if (t1 || t2 || t3 || t4) {
777 if (a == b) return 0;
778 else return 1;
779 }
780
781 if ((a & 0x8000000000000000ull) != (b & 0x8000000000000000ull)) {
782 return 1;
783 }
784 if (a & 0x8000000000000000ull) sign = 1;
785
786 GET_EXP_64(e1, a)
787 GET_EXP_64(e2, b)
788 GET_MANT_64(m1, a)
789 GET_MANT_64(m2, b)
790
791 if (e1 < e2) {
792 BIDECIMAL_CALL2 (bid64_quantize, r1, a, b);
793 r2 = b;
794 GET_EXP_64(e1, r1)
795 GET_EXP_64(e2, r2)
796 GET_MANT_64(m1, r1)
797 GET_MANT_64(m2, r2)
798 } else if (e2 < e1) {
799 r1 = a;
800 BIDECIMAL_CALL2 (bid64_quantize, r2, b, a);
801 GET_EXP_64(e1, r1)
802 GET_EXP_64(e2, r2)
803 GET_MANT_64(m1, r1)
804 GET_MANT_64(m2, r2)
805 } else {
806 r1 = a;
807 r2 = b;
808 }
809
810 if (e1 != e2) {
811 printf("ERROR a, b "BID_FMT_LLX16" "BID_FMT_LLX16"\n", a, b);
812 printf("ERROR r1, r2 "BID_FMT_LLX16" "BID_FMT_LLX16"\n", r1, r2);
813 return 1;
814 }
815
816 ulp = m1 > m2 ? m1 - m2 : m2 - m1;
817 BIDECIMAL_CALL2_NORND (bid64_quiet_less, less, a, b);
818 if (less) ulp *= -1.0;
819 //printf("ulp %f +add %f max %f\n", ulp, ulp+ulp_add, mre_max[rnd_mode]);
820 if (fabs(ulp+ulp_add) > mre_max[rnd_mode]) {
821 return 1;
822 }
823
824 return 0;
825 }
826
827 int
check32_rel(BID_UINT32 a32,BID_UINT32 b32)828 check32_rel(BID_UINT32 a32, BID_UINT32 b32)
829 {
830 BID_UINT32 r1, r2;
831 BID_UINT32 e1, e2, m1, m2;
832 int sign, less;
833 int aexp, bexp, amant, bmant;
834 int t1, t2, t3, t4;
835
836 BIDECIMAL_CALL1_NORND_NOSTAT (bid32_isNaN, t1, a32);
837 BIDECIMAL_CALL1_NORND_NOSTAT (bid32_isNaN, t2, b32);
838 BIDECIMAL_CALL1_NORND_NOSTAT (bid32_isInf, t3, a32);
839 BIDECIMAL_CALL1_NORND_NOSTAT (bid32_isInf, t4, b32);
840
841 //if (bid32_isNaN(a32)||bid32_isNaN(b32)||bid32_isInf(a32)||bid32_isInf(b32)) {
842 if (t1 || t2 || t3 || t4) {
843
844 if (a32 == b32) return 0;
845 else return 1;
846
847 }
848
849 if ((a32 & 0x80000000) != (b32 & 0x80000000)) {
850 return 1;
851 }
852 if (a32 & 0x80000000) sign = 1;
853
854 GET_EXP_32(e1, a32)
855 GET_EXP_32(e2, b32)
856 GET_MANT_32(m1, a32)
857 GET_MANT_32(m2, b32)
858
859 if (e1 < e2) {
860 BIDECIMAL_CALL2 (bid32_quantize, r1, a32, b32);
861 r2 = b32;
862 GET_EXP_32(e1, r1)
863 GET_EXP_32(e2, r2)
864 GET_MANT_32(m1, r1)
865 GET_MANT_32(m2, r2)
866 } else if (e2 < e1) {
867 r1 = a32;
868 BIDECIMAL_CALL2 (bid32_quantize, r2, b32, a32);
869 GET_EXP_32(e1, r1)
870 GET_EXP_32(e2, r2)
871 GET_MANT_32(m1, r1)
872 GET_MANT_32(m2, r2)
873 } else {
874 r1 = a32;
875 r2 = b32;
876 }
877
878 if (e1 != e2) {
879 printf("ERROR a, b %08x %08x\n", a32, b32);
880 printf("ERROR r1, r2 %08x %08x\n", r1, r2);
881 return 1;
882 }
883
884 ulp = m1 > m2 ? m1 - m2 : m2 - m1;
885 BIDECIMAL_CALL2_NORND (bid32_quiet_less, less, a32, b32);
886 if (less) ulp *= -1.0;
887 //printf("ulp %f +add %f max %f\n", ulp, ulp+ulp_add, mre_max[rnd_mode]);
888 if (fabs(ulp+ulp_add) > mre_max[rnd_mode]) {
889 return 1;
890 }
891
892 return 0;
893 }
894
895
896 void
get_ops(void)897 get_ops (void) {
898 unsigned int save_rnd = rnd;
899 rnd = rnd_mode = BID_ROUNDING_TO_NEAREST;
900
901 // Initialize second arg for comparing - required by modf function but can give false errors if argument is not initialized
902 B32 = 0;
903 B64 = 0ull;
904 B.w[BID_LOW_128W] = B.w[BID_HIGH_128W] = 0ull;
905
906 strcpy (istr1, "");
907 strcpy (istr2, "");
908 strcpy (istr3, "");
909
910 switch (op1type) {
911 case OP_DEC32:
912 getop32 (A32, a32, op1, istr1);
913 break;
914 case OP_DEC64:
915 getop64 (A64, a64, op1, istr1);
916 break;
917 case OP_DEC128:
918 getop128 (A, a, op1, istr1);
919 break;
920 case OP_INT8:
921 getop8i (AI32, op1, istr1);
922 AI8=(char)AI32;
923 break;
924 case OP_INT16:
925 getop16i (AI32, op1, istr1);
926 AI16=(short)AI32;
927 break;
928 case OP_INT32:
929 getop32i (AI32, op1, istr1);
930 break;
931 case OP_BID_UINT8:
932 getop8u (AUI32, op1, istr1);
933 AUI8=(unsigned char)AUI32;
934 break;
935 case OP_BID_UINT16:
936 getop16u (AUI32, op1, istr1);
937 AUI16=(unsigned short)AUI32;
938 break;
939 case OP_BID_UINT32:
940 getop32u (AUI32, op1, istr1);
941 break;
942 case OP_INT64:
943 getop64i (AI64, op1, istr1);
944 break;
945 case OP_BID_UINT64:
946 getop64u (AUI64, op1, istr1);
947 break;
948 case OP_BIN128:
949 getopquad (Aquad, Aquad, op1, istr1);
950 break;
951 case OP_BIN80:
952 getopldbl (Aldbl, Aldbl, op1, istr1);
953 break;
954 case OP_BIN64:
955 getopdbl (Adbl, Adbl, op1, istr1);
956 break;
957 case OP_BIN32:
958 getopflt (Aflt, Aflt, op1, istr1);
959 break;
960 case OP_NONE:
961 break;
962 default:
963 printf ("Error: getops unexpected operand 1 type, %d\n", op1type);
964 }
965
966 switch (op2type) {
967 case OP_DEC32:
968 getop32 (B32, b32, op2, istr2);
969 break;
970 case OP_DEC64:
971 getop64 (B64, b64, op2, istr2);
972 break;
973 case OP_DEC128:
974 getop128 (B, b, op2, istr2);
975 break;
976 case OP_INT16:
977 getop16i (BI32, op2, istr2);
978 BI16=(short)BI32;
979 break;
980 case OP_INT32:
981 getop32i (BI32, op2, istr2);
982 break;
983 case OP_BID_UINT32: // Skip because converted with sscanf
984 getop32u (BUI32, op2, istr2);
985 break;
986 case OP_LINT:
987 if (li_size_run == 64) {
988 getop64i (*(BID_SINT64*)&BLI, op2, istr2);
989 } else {
990 getop32i (*(BID_SINT32*)&BLI, op2, istr2);
991 }
992 break;
993 case OP_NONE:
994 break;
995 default:
996 printf ("Error: getops unexpected operand 2 type, %d\n", op2type);
997 }
998
999 switch (op3type) {
1000 case OP_DEC32:
1001 getop32 (C32, c32, op3, istr3);
1002 break;
1003 case OP_DEC64:
1004 getop64 (CC64, c64, op3, istr3);
1005 break;
1006 case OP_DEC128:
1007 getop128 (C, c, op3, istr3);
1008 break;
1009 case OP_BID_UINT32: // Skip because converted with sscanf
1010 getop32u (CUI32, op3, istr3);
1011 break;
1012 case OP_NONE:
1013 break;
1014 default:
1015 printf ("Error: getops unexpected operand 3 type, %d\n", op3type);
1016 exit (-1);
1017 }
1018 rnd = rnd_mode = save_rnd;
1019
1020 // true second res of frexp function
1021 if (!strcmp (func, "bid32_frexp") || !strcmp (func, "bid64_frexp") || !strcmp (func, "bid128_frexp")) {
1022 i1 = BI32;
1023 }
1024 // true second res of modf function
1025 R32_1 = B32;
1026 R64_1 = B64;
1027 R_1 = B;
1028
1029 }
1030
1031 void
get_test(void)1032 get_test (void) {
1033
1034 //initialize results so we can easy compare frexp function
1035 i1 = i2 = 0;
1036 u1_16 = u2_16 = 0;
1037 i1_16 = i2_16 = 0;
1038 u1_8 = u2_8 = 0;
1039 i1_8 = i2_8 = 0;
1040 Qi64 = qi64 = 0;
1041
1042 get_ops ();
1043
1044 switch (restype) {
1045 case OP_DEC32:
1046 case OP_DPD32:
1047 getop32 (R32, q32, res, rstr);
1048 break;
1049 case OP_DEC64:
1050 case OP_DPD64:
1051 getop64 (R64, q64, res, rstr);
1052 break;
1053 case OP_DEC128:
1054 case OP_DPD128:
1055 getop128 (R, q, res, rstr);
1056 break;
1057 case OP_INT8:
1058 getop8i (i1, res, rstr);
1059 break;
1060 case OP_INT16:
1061 getop16i (i1, res, rstr);
1062 break;
1063 case OP_INT32: // Skip because converted with sscanf
1064 getop32i (i1, res, rstr);
1065 break;
1066 case OP_BID_UINT8:
1067 getop8u (i1, res, rstr);
1068 break;
1069 case OP_BID_UINT16:
1070 getop16u (i1, res, rstr);
1071 break;
1072 case OP_BID_UINT32:
1073 getop32u (i1, res, rstr);
1074 break;
1075 case OP_INT64:
1076 getop64i (qi64, res, rstr);
1077 break;
1078 case OP_BID_UINT64:
1079 getop64u (qi64, res, rstr);
1080 break;
1081 case OP_BIN128:
1082 getopquad (Rtquad, Rtquad, res, rstr);
1083 break;
1084 case OP_BIN80:
1085 getopldbl (Rtldbl, Rtldbl, res, rstr);
1086 break;
1087 case OP_BIN64:
1088 getopdbl (Rtdbl, Rtdbl, res, rstr);
1089 break;
1090 case OP_BIN32:
1091 getopflt (Rtflt, Rtflt, res, rstr);
1092 break;
1093 case OP_LINT:
1094 if (li_size_run == 64) {
1095 getop64i (*(BID_SINT64*)&li1, res, rstr);
1096 } else {
1097 getop32i (*(BID_SINT32*)&li1, res, rstr);
1098 }
1099 break;
1100 case OP_NONE:
1101 break;
1102 default:
1103 printf ("Error: get_test unexpected result type, %d\n", restype);
1104 }
1105 }
1106
1107 void
print_mismatch(enum _CMPTYPE cmp)1108 print_mismatch (enum _CMPTYPE cmp) {
1109 int i;
1110 char str[STRMAX];
1111
1112 if (answer_opt) {
1113 if (*op3)
1114 printf ("test%d %s %s %s %s ", tests, func, op1, op2, op3);
1115 else if (*op2)
1116 printf ("test%d %s %s %s ", tests, func, op1, op2);
1117 else
1118 printf ("test%d %s %s ", tests, func, op1);
1119 switch (restype) {
1120
1121 case OP_STRING:
1122 printf("STRING result is not implemented\n");
1123 break;
1124 case OP_DEC128:
1125 case OP_DPD128:
1126 printf ("[" BID_FMT_LLX16 "" BID_FMT_LLX16 "] %02x\n", Q.w[BID_HIGH_128W],
1127 Q.w[BID_LOW_128W], *pfpsf);
1128 break;
1129
1130 case OP_DEC64:
1131 case OP_DPD64:
1132 printf ("[" BID_FMT_LLX16 "] %02x\n", Q64, *pfpsf);
1133 break;
1134
1135 case OP_DEC32:
1136 case OP_DPD32:
1137 printf ("[" BID_FMT_X8 "] %02x\n", Q32, *pfpsf);
1138 break;
1139
1140 case OP_INT8:
1141 case OP_INT16:
1142 case OP_INT32:
1143 printf ("%d %02x\n", i2, *pfpsf);
1144 break;
1145
1146 case OP_BID_UINT8:
1147 case OP_BID_UINT16:
1148 case OP_BID_UINT32:
1149 printf ("%u %02x\n", i2, *pfpsf);
1150 break;
1151
1152 case OP_INT64:
1153 printf (BID_FMT_LLD16 " %02x\n", Qi64, *pfpsf);
1154 break;
1155
1156 case OP_LINT:
1157 if (li_size_run == 64)
1158 printf (BID_FMT_LLD16 " %02x\n", *(BID_SINT64*)&li2, *pfpsf);
1159 else
1160 printf ("%d %02x\n", *(BID_SINT32*)&li2, *pfpsf);
1161 break;
1162
1163 case OP_BID_UINT64:
1164 printf (BID_FMT_LLU16 " %02x\n", Qi64, *pfpsf);
1165 break;
1166
1167 case OP_BIN128:
1168 printf ("[" BID_FMT_LLX16 " " BID_FMT_LLX16 "] %02x\n",
1169 *((BID_UINT64 *) & Rquad + BID_HIGH_128W),
1170 *((BID_UINT64 *) & Rquad + BID_LOW_128W), *pfpsf);
1171 break;
1172
1173 case OP_BIN80:
1174 #if BID_BIG_ENDIAN
1175 printf ("[" BID_FMT_LLX16 "" BID_FMT_X4 "] %02x\n", *((BID_UINT64 *) & Rldbl),
1176 ((BID_UINT32) (*((BID_UINT64 *) & Rldbl + 1))) & 0xffff, *pfpsf);
1177 #else
1178 printf ("[" BID_FMT_X4 "" BID_FMT_LLX16 "] %02x\n",
1179 ((BID_UINT32) (*((BID_UINT64 *) & Rldbl + 1))) & 0xffff,
1180 *((BID_UINT64 *) & Rldbl), *pfpsf);
1181 #endif
1182 break;
1183
1184 case OP_BIN64:
1185 printf ("[" BID_FMT_LLX16 "] %02x\n", *((BID_UINT64 *) & Rdbl), *pfpsf);
1186 break;
1187
1188 case OP_BIN32:
1189 printf ("[" BID_FMT_X8 "] %02x\n", *((BID_UINT32 *) & Rflt), *pfpsf);
1190 break;
1191
1192 default:
1193 printf ("print_mismatch: unknown result type %d\n", restype);
1194 }
1195 return;
1196 }
1197
1198 // Print mismatch line
1199 switch (restype) {
1200 case OP_DEC128:
1201 case OP_DPD128:
1202 printf ("// BID result: " BID_FMT_LLX16 "" BID_FMT_LLX16
1203 ", Expected results: " BID_FMT_LLX16 "" BID_FMT_LLX16 "\n",
1204 Q.w[BID_HIGH_128W], Q.w[BID_LOW_128W], R.w[BID_HIGH_128W],
1205 R.w[BID_LOW_128W]);
1206 if (!strcmp(func, "bid128_modf")) {
1207 printf ("// BID second result: " BID_FMT_LLX16 "" BID_FMT_LLX16
1208 ", Expected results: " BID_FMT_LLX16 "" BID_FMT_LLX16 "\n",
1209 B.w[BID_HIGH_128W], B.w[BID_LOW_128W], R_1.w[BID_HIGH_128W],
1210 R_1.w[BID_LOW_128W]);
1211 }
1212 break;
1213 case OP_DEC64:
1214 case OP_DPD64:
1215 printf ("// BID result: " BID_FMT_LLX16 ", Expected result: " BID_FMT_LLX16
1216 "\n", Q64, R64);
1217 if (!strcmp(func, "bid64_modf")) {
1218 printf ("// BID second result: " BID_FMT_LLX16 ", Expected result: " BID_FMT_LLX16
1219 "\n", B64, R64_1);
1220 }
1221 break;
1222 case OP_DEC32:
1223 case OP_DPD32:
1224 printf ("// BID result: " BID_FMT_X8 ", Expected result: " BID_FMT_X8 "\n",
1225 Q32, R32);
1226 if (!strcmp(func, "bid32_modf")) {
1227 printf ("// BID second result: " BID_FMT_X8 ", Expected result: " BID_FMT_X8 "\n",
1228 B32, R32_1);
1229 }
1230 break;
1231 case OP_INT8:
1232 case OP_INT16:
1233 case OP_INT32:
1234 printf ("// BID result: %d, Expected result: %d\n", i2, i1);
1235 break;
1236 case OP_BID_UINT8:
1237 case OP_BID_UINT16:
1238 case OP_BID_UINT32:
1239 printf ("// BID result: %u, Expected result: %u\n", i2, i1);
1240 break;
1241 case OP_INT64:
1242 printf ("// BID result: " BID_FMT_LLD16 ", Expected result: " BID_FMT_LLD16
1243 "\n", Qi64, qi64);
1244 break;
1245 case OP_LINT:
1246 if (li_size_run == 64)
1247 printf ("// BID result: " BID_FMT_LLD16 ", Expected result: " BID_FMT_LLD16
1248 "\n",*(BID_SINT64*)&li2, *(BID_SINT64*)&li1);
1249 else
1250 printf ("// BID result: %d, Expected result: %d \n",*(BID_SINT32*)&li2, *(BID_SINT32*)&li1);
1251 break;
1252 case OP_BID_UINT64:
1253 printf ("// BID result: " BID_FMT_LLU16 ", Expected result: " BID_FMT_LLU16
1254 "\n", Qi64, qi64);
1255 break;
1256 case OP_BIN128:
1257 printf ("// BID result: " BID_FMT_LLX16 " " BID_FMT_LLX16
1258 ", Expected result: " BID_FMT_LLX16 " " BID_FMT_LLX16 "\n",
1259 *((BID_UINT64 *) & Rquad + BID_HIGH_128W),
1260 *((BID_UINT64 *) & Rquad + BID_LOW_128W),
1261 *((BID_UINT64 *) & Rtquad + BID_HIGH_128W),
1262 *((BID_UINT64 *) & Rtquad + BID_LOW_128W));
1263 break;
1264 case OP_BIN80:
1265 #if BID_BIG_ENDIAN
1266 printf ("// BID result: " BID_FMT_LLX16 "" BID_FMT_X4 ", Expected result: "
1267 BID_FMT_LLX16 "" BID_FMT_X4 " \n", *((BID_UINT64 *) & Rldbl + 0),
1268 ((BID_UINT32) (*((BID_UINT64 *) & Rldbl + 1))) & 0xffff,
1269 *((BID_UINT64 *) & Rtldbl + 0),
1270 ((BID_UINT32) (*((BID_UINT64 *) & Rtldbl + 1))) & 0xffff);
1271 #else
1272 printf ("// BID result: " BID_FMT_X4 "" BID_FMT_LLX16 ", Expected result: "
1273 BID_FMT_X4 "" BID_FMT_LLX16 " \n",
1274 ((BID_UINT32) (*((BID_UINT64 *) & Rldbl + 1))) & 0xffff,
1275 *((BID_UINT64 *) & Rldbl + 0),
1276 ((BID_UINT32) (*((BID_UINT64 *) & Rtldbl + 1))) & 0xffff,
1277 *((BID_UINT64 *) & Rtldbl + 0));
1278 #endif
1279 break;
1280 case OP_BIN64:
1281 printf ("// BID result: " BID_FMT_LLX16 ", Expected result: " BID_FMT_LLX16
1282 "\n", *((BID_UINT64 *) & Rdbl), *((BID_UINT64 *) & Rtdbl));
1283 break;
1284 case OP_BIN32:
1285 printf ("// BID result: " BID_FMT_X8 ", Expected result: " BID_FMT_X8 "\n",
1286 *((BID_UINT32 *) & Rflt), *((BID_UINT32 *) & Rtflt));
1287 break;
1288 default:
1289 printf ("print_mismatch: unknown result type %d\n", restype);
1290 exit (-1);
1291 }
1292
1293 if (!strcmp(func, "bid32_frexp") || !strcmp(func, "bid64_frexp") || !strcmp(func, "bid128_frexp") ) {
1294 printf ("// BID second result: %d, Expected result: %d\n", i2, i1);
1295 }
1296
1297 // Print statuses
1298 printf ("// BID status : %03x, Expected status: %03x (PUOZDI Bits)\n",
1299 *pfpsf, expected_status);
1300
1301 switch (restype) {
1302 case OP_DEC128:
1303 BIDECIMAL_CALL1_NORND_RESREF (bid128_to_string, str1, Q);
1304 BIDECIMAL_CALL1_NORND_RESREF (bid128_to_string, str2, R);
1305 printf ("// Result BID128 String: %s\n", str1);
1306 printf ("// Expected BID128 String: %s\n", str2);
1307 break;
1308 case OP_DEC64:
1309 BIDECIMAL_CALL1_NORND_RESREF (bid64_to_string, str1, Q64);
1310 BIDECIMAL_CALL1_NORND_RESREF (bid64_to_string, str2, R64);
1311 printf ("// Result BID64 String: %s\n", str1);
1312 printf ("// Expected BID64 String: %s\n", str2);
1313 break;
1314 case OP_DEC32:
1315 BIDECIMAL_CALL1_NORND_RESREF (bid32_to_string, str1, Q32);
1316 BIDECIMAL_CALL1_NORND_RESREF (bid32_to_string, str2, R32);
1317 printf ("// Result BID32 String: %s\n", str1);
1318 printf ("// Expected BID32 String: %s\n", str2);
1319 break;
1320 case OP_DPD128:
1321 {
1322 BID_UINT128 Qbid, Rbid;
1323 BIDECIMAL_CALL1_NORND_NOSTAT (bid_dpd_to_bid128, Qbid, Q);
1324 BIDECIMAL_CALL1_NORND_NOSTAT (bid_dpd_to_bid128, Rbid, R);
1325 BIDECIMAL_CALL1_NORND_RESREF (bid128_to_string, str2, Qbid);
1326 BIDECIMAL_CALL1_NORND_RESREF (bid128_to_string, str2, Rbid);
1327 printf ("// Result BID128 String: %s\n", str1);
1328 printf ("// Expected BID128 String: %s\n", str2);
1329 }
1330 break;
1331 case OP_DPD64:
1332 {
1333 BID_UINT64 Qbid, Rbid;
1334 BIDECIMAL_CALL1_NORND_NOSTAT (bid_dpd_to_bid64, Qbid, Q64);
1335 BIDECIMAL_CALL1_NORND_NOSTAT (bid_dpd_to_bid64, Rbid, R64);
1336 BIDECIMAL_CALL1_NORND_RESREF (bid64_to_string, str1, Qbid);
1337 BIDECIMAL_CALL1_NORND_RESREF (bid64_to_string, str2, Rbid);
1338 printf ("// Result BID64 String: %s\n", str1);
1339 printf ("// Expected BID64 String: %s\n", str2);
1340 }
1341 break;
1342 case OP_DPD32:
1343 {
1344 BID_UINT32 Qbid, Rbid;
1345 BIDECIMAL_CALL1_NORND_NOSTAT (bid_dpd_to_bid32, Qbid, Q32);
1346 BIDECIMAL_CALL1_NORND_NOSTAT (bid_dpd_to_bid32, Rbid, R32);
1347 BIDECIMAL_CALL1_NORND_RESREF (bid32_to_string, str1, Qbid);
1348 BIDECIMAL_CALL1_NORND_RESREF (bid32_to_string, str2, Rbid);
1349 printf ("// Result BID32 String: %s\n", str1);
1350 printf ("// Expected BID32 String: %s\n", str2);
1351 }
1352 break;
1353 case OP_INT8:
1354 case OP_BID_UINT8:
1355 case OP_INT16:
1356 case OP_BID_UINT16:
1357 case OP_INT32:
1358 case OP_BID_UINT32:
1359 case OP_INT64:
1360 case OP_BID_UINT64:
1361 case OP_LINT:
1362 break;
1363 case OP_BIN128:
1364 // sprintf(str1, "%.17le", Rquad); \
1365 // sprintf(str2, "%.17le", Rtquad); \
1366
1367 strcpy (str1, "unavailable");
1368 strcpy (str2, "unavailable");
1369 printf ("// BID128 quad res: %s\n", str1);
1370 printf ("// Expected quad res : %s\n", str2);
1371 break;
1372 case OP_BIN80:
1373 sprintf (str1, "%.17le", (double) Rldbl);
1374 sprintf (str2, "%.17le", (double) Rtldbl);
1375 printf ("// BID80 double res (cast to double): %s\n", str1);
1376 printf ("// Expected double res (cast to double): %s\n", str2);
1377 break;
1378 case OP_BIN64:
1379 sprintf (str1, "%.17le", Rdbl);
1380 sprintf (str2, "%.17le", Rtdbl);
1381 printf ("// BID64 double res: %s\n", str1);
1382 printf ("// Expected double res : %s\n", str2);
1383 break;
1384 case OP_BIN32:
1385 sprintf (str1, "%.9e", Rflt);
1386 sprintf (str2, "%.9e", Rtflt);
1387 printf ("// BID32 double res: %s\n", str1);
1388 printf ("// decimal32 double res : %s\n", str2);
1389 break;
1390 default:
1391 printf ("print_mismatch unknown result type %d\n", restype);
1392 exit (-1);
1393 }
1394
1395 printf ("// Input operand strings: %s %s %s\n", istr1, istr2, istr3);
1396 fail_res++;
1397 sprintf (line, "%s %s %s %s\n", func, op1, op2, op3);
1398 printf ("// Ulp error: %e\n", ulp+ulp_add);
1399 printf ("// Full input string: %s\n", full_line);
1400 printf ("// Input string number: %d\n", line_counter);
1401 printf ("// FAILED(%s)\n\n", rounding);
1402 }
1403
1404 void
check_results(enum _CMPTYPE cmp)1405 check_results (enum _CMPTYPE cmp) {
1406 char *p;
1407 tests++;
1408
1409 //printf("frexp i1 i2 %d %d \n", i1, i2);
1410
1411 //printf("arg dbl %08X \n", *((int*)&Adbl+BID_HIGH_128W));
1412 if (p = strstr (func, "binary64_to")) {
1413 //printf("check fo binary snan\n");
1414 if (SNaN_passed_incorrectly64 && ((*((int*)&Adbl+BID_HIGH_128W) & 0x7ff80000) == 0x7ff00000) &&
1415 ((*((int*)&Adbl+BID_HIGH_128W) & 0x0007ffff) || (*((int*)&Adbl+BID_LOW_128W) & 0xffffffff))
1416 ) {
1417 //printf("set invalid for 64\n");
1418 *pfpsf |= BID_INVALID_EXCEPTION;
1419 }
1420 }
1421 if (p = strstr (func, "binary32_to")) {
1422 if (SNaN_passed_incorrectly32 && ((*((int*)&Aflt) & 0x7fc00000) == 0x7f800000) &&
1423 ((*((int*)&Aflt) & 0x003fffff))
1424 ) {
1425 //printf("set invalid for 32\n");
1426 *pfpsf |= BID_INVALID_EXCEPTION;
1427 }
1428 }
1429 if (p = strstr (func, "binary80_to")) {
1430 //printf("check fo binary snan\n");
1431 if (SNaN_passed_incorrectly80 && ((*((int*)&Aldbl+2) & 0x7fff) == 0x7fff) &&
1432 ((*((int*)&Aldbl+BID_HIGH_128W) & 0xc0000000) == 0x80000000) &&
1433 ((*((int*)&Aldbl+BID_HIGH_128W) & 0x7fffffff) || (*((int*)&Aldbl+BID_LOW_128W) & 0xffffffff))
1434 ) {
1435 //printf("set invalid for 80\n");
1436 *pfpsf |= BID_INVALID_EXCEPTION;
1437 }
1438 }
1439
1440 if (check_restore_binary_status()) {
1441 print_mismatch(cmp);
1442 return;
1443 }
1444
1445 if (debug_opt || answer_opt) {
1446 print_mismatch (cmp);
1447 return;
1448 }
1449
1450 if (!strcmp (func, "bid64_to_string")) {
1451 BIDECIMAL_CALL1_RESARG (bid64_from_string, Q64, convstr);
1452 } else if (!strcmp (func, "bid128_to_string")) {
1453 BIDECIMAL_CALL1_RESARG (bid128_from_string, Q, convstr);
1454 } else if (!strcmp (func, "bid32_to_string")) {
1455 BIDECIMAL_CALL1_RESARG (bid32_from_string, Q32, convstr);
1456 }
1457
1458 if (restype == OP_DEC128 && cmp == CMP_EXACTSTATUS) {
1459 if (expected_status != *pfpsf || R.w[BID_LOW_128W] != Q.w[BID_LOW_128W]
1460 || R.w[BID_HIGH_128W] != Q.w[BID_HIGH_128W] || i1 != i2 || Qi64 != qi64)
1461 print_mismatch (cmp);
1462 } else if (restype == OP_DEC64 && cmp == CMP_EXACTSTATUS) {
1463 if (expected_status != *pfpsf || R64 != Q64 || i1 != i2 || Qi64 != qi64)
1464 print_mismatch (cmp);
1465 } else if (restype == OP_DEC32
1466 && (cmp == CMP_EXACTSTATUS || cmp == CMP_FUZZYSTATUS)) {
1467 if (expected_status != *pfpsf || R32 != Q32 || i1 != i2 || Qi64 != qi64 || R32_1 != B32)
1468 print_mismatch (cmp);
1469 } else if (restype == OP_LINT
1470 && (cmp == CMP_EXACTSTATUS || cmp == CMP_FUZZYSTATUS)) {
1471 if (expected_status != *pfpsf || li1 != li2)
1472 print_mismatch (cmp);
1473 } else if (restype == OP_DEC32 && (cmp == CMP_RELATIVEERR)) {
1474 if ((expected_status&trans_flags_mask) != (*pfpsf&trans_flags_mask) || check32_rel(R32, Q32))
1475 print_mismatch (cmp);
1476 } else if (restype == OP_DEC128 && cmp == CMP_FUZZYSTATUS) {
1477 if (expected_status != *pfpsf || check128 (R, Q) || i1 != i2 || Qi64 != qi64 || check128 (R_1, B))
1478 print_mismatch (cmp);
1479 } else if (restype == OP_LINT && cmp == CMP_FUZZYSTATUS) {
1480 if (expected_status != *pfpsf || li1 != li2)
1481 print_mismatch (cmp);
1482 } else if (restype == OP_DEC128 && cmp == CMP_RELATIVEERR) {
1483 if ((expected_status&trans_flags_mask) != (*pfpsf&trans_flags_mask) || check128_rel(R, Q))
1484 print_mismatch (cmp);
1485 } else if (restype == OP_DEC64 && cmp == CMP_FUZZYSTATUS) {
1486 if (expected_status != *pfpsf || check64 (R64, Q64) || i1 != i2 || Qi64 != qi64 || R64_1 != B64)
1487 print_mismatch (cmp);
1488 } else if (restype == OP_LINT && cmp == CMP_FUZZYSTATUS) {
1489 if (expected_status != *pfpsf || li1 != li2)
1490 print_mismatch (cmp);
1491 } else if (restype == OP_DEC64 && cmp == CMP_RELATIVEERR) {
1492 if ((expected_status&trans_flags_mask) != (*pfpsf&trans_flags_mask) || check64_rel(R64, Q64))
1493 print_mismatch (cmp);
1494 } else if (restype == OP_DEC128 && cmp == CMP_EQUALSTATUS) {
1495 int c;
1496 unsigned int tmp_pfpsf = *pfpsf;
1497 BIDECIMAL_CALL2_NORND (bid128_quiet_not_equal, c, Q, R);
1498 if (expected_status != tmp_pfpsf || (check128 (R, Q) && c))
1499 print_mismatch (cmp);
1500 } else if (restype == OP_DEC64 && cmp == CMP_EQUALSTATUS) {
1501 int c;
1502 unsigned int tmp_pfpsf = *pfpsf;
1503 BIDECIMAL_CALL2_NORND (bid64_quiet_not_equal, c, Q64, R64);
1504 if (expected_status != tmp_pfpsf || (check64 (R64, Q64) && c))
1505 print_mismatch (cmp);
1506 } else if (restype == OP_DEC32 && cmp == CMP_EQUALSTATUS) {
1507 int c;
1508 unsigned int tmp_pfpsf = *pfpsf;
1509 BIDECIMAL_CALL2_NORND (bid32_quiet_not_equal, c, Q32, R32);
1510 if (expected_status != tmp_pfpsf || (check32 (R32, Q32) && c))
1511 print_mismatch (cmp);
1512 } else if (restype == OP_DPD32 && cmp == CMP_FUZZYSTATUS) {
1513 if (expected_status != *pfpsf || check32 (R32, Q32))
1514 print_mismatch (cmp);
1515 } else if (restype == OP_DPD64 && cmp == CMP_FUZZYSTATUS) {
1516 if (expected_status != *pfpsf || check64 (R64, Q64))
1517 print_mismatch (cmp);
1518 } else if (restype == OP_DPD128 && cmp == CMP_FUZZYSTATUS) {
1519 if (expected_status != *pfpsf || check128 (R, Q))
1520 print_mismatch (cmp);
1521 } else if (restype == OP_INT32 || restype == OP_INT16
1522 || restype == OP_INT8) {
1523 if (expected_status != *pfpsf || i1 != i2)
1524 print_mismatch (cmp);
1525 } else if (restype == OP_BID_UINT32 || restype == OP_BID_UINT16
1526 || restype == OP_BID_UINT8) {
1527 if (expected_status != *pfpsf || i1 != i2)
1528 print_mismatch (cmp);
1529 } else if (restype == OP_INT64) {
1530 if (expected_status != *pfpsf || qi64 != Qi64)
1531 print_mismatch (cmp);
1532 } else if (restype == OP_BID_UINT64) {
1533 if (expected_status != *pfpsf || qi64 != Qi64)
1534 print_mismatch (cmp);
1535 } else if (restype == OP_BIN128) {
1536 if (expected_status != *pfpsf
1537 || *((BID_UINT64*)&Rquad) != *((BID_UINT64*)&Rtquad)
1538 || *((BID_UINT64*)&Rquad+1) != *((BID_UINT64*)&Rtquad+1))
1539 print_mismatch (cmp);
1540 } else if (restype == OP_BIN80) {
1541 if (expected_status != *pfpsf
1542 || *((BID_UINT64 *) & Rldbl) != *((BID_UINT64 *) & Rtldbl)
1543 || (*((BID_UINT64 *) & Rldbl + 1) & 0xffff) !=
1544 (*((BID_UINT64 *) & Rtldbl + 1) & 0xffff))
1545 print_mismatch (cmp);
1546 } else if (restype == OP_BIN64) {
1547 if (expected_status != *pfpsf
1548 || (*(BID_UINT64 *) & Rdbl != *(BID_UINT64 *) & Rtdbl))
1549 print_mismatch (cmp);
1550 } else if (restype == OP_BIN32) {
1551 if (expected_status != *pfpsf
1552 || (*(BID_UINT32 *) & Rflt != *(BID_UINT32 *) & Rtflt))
1553 print_mismatch (cmp);
1554 } else if (restype == OP_DPD64 && cmp == CMP_EXACTSTATUS) {
1555 if (expected_status != *pfpsf || R64 != Q64)
1556 print_mismatch (cmp);
1557 } else if (restype == OP_DPD32 && cmp == CMP_EXACTSTATUS) {
1558 if (expected_status != *pfpsf || R32 != Q32)
1559 print_mismatch (cmp);
1560 } else if (restype == OP_DPD128 && cmp == CMP_EXACTSTATUS) {
1561 if (expected_status != *pfpsf || R.w[BID_LOW_128W] != Q.w[BID_LOW_128W]
1562 || R.w[BID_HIGH_128W] != Q.w[BID_HIGH_128W])
1563 print_mismatch (cmp);
1564 } else {
1565 printf
1566 ("Unknown combination of result type (%d) and compare type (%d)\n",
1567 restype, cmp);
1568 // exit (-1);
1569 }
1570 }
1571
1572 // int st_compare(void *a, void *b) {
1573 int
st_compare(char ** a,char ** b)1574 st_compare (char **a, char **b) {
1575 return strcmp (*a, *b);
1576 }
1577
1578 int
status_compare(char * stat1,char * stat2)1579 status_compare (char *stat1, char *stat2) {
1580 char s1[STRMAX], s2[STRMAX];
1581 char *wp1[64], *wp2[64];
1582 int wp1n = 0, wp2n = 0;
1583 char *p;
1584 int i;
1585
1586 strcpy (s1, stat1);
1587 strcpy (s2, stat2);
1588 for (p = s1; *p; p++) {
1589 wp1[wp1n++] = p;
1590 while (*p && *++p != ' ');
1591 if (*p == ' ') {
1592 *p = 0;
1593 // printf("Found 1: %s\n", wp1[wp1n-1]);
1594 continue;
1595 } else {
1596 // printf("Found 1: %s\n", wp1[wp1n-1]);
1597 break;
1598 }
1599 }
1600 for (p = s2; *p; p++) {
1601 wp2[wp2n++] = p;
1602 while (*p && *++p != ' ');
1603 if (*p == ' ') {
1604 *p = 0;
1605 // printf("Found 2: %s\n", wp2[wp2n-1]);
1606 continue;
1607 } else {
1608 // printf("Found 2: %s\n", wp2[wp2n-1]);
1609 break;
1610 }
1611 }
1612 if (wp1n != wp2n)
1613 return 1;
1614 #ifdef LINUX
1615 qsort (wp1, wp1n, sizeof (char *), (__compar_fn_t) st_compare);
1616 qsort (wp2, wp2n, sizeof (char *), (__compar_fn_t) st_compare);
1617 #else
1618 qsort (wp1, wp1n, sizeof (char *),
1619 (int (__cdecl *) (const void *, const void *)) st_compare);
1620 qsort (wp2, wp2n, sizeof (char *),
1621 (int (__cdecl *) (const void *, const void *)) st_compare);
1622 #endif
1623 for (i = 0; i < wp1n; i++) {
1624 // printf("Comparing %s and %s\n", wp1[i], wp2[i]);
1625 if (strcmp (wp1[i], wp2[i]))
1626 return 1;
1627 }
1628 return 0;
1629 }
1630
check_skip(char * func)1631 int check_skip(char *func)
1632 {
1633 if (no128trans) {
1634 if (!strcmp(func, "bid128_sin") || !strcmp(func, "bid128_cos") || !strcmp(func, "bid128_tan") ||
1635 !strcmp(func, "bid128_asin") || !strcmp(func, "bid128_acos") || !strcmp(func, "bid128_atan") ||
1636 !strcmp(func, "bid128_sinh") || !strcmp(func, "bid128_cosh") || !strcmp(func, "bid128_tanh") ||
1637 !strcmp(func, "bid128_asinh") || !strcmp(func, "bid128_acosh") || !strcmp(func, "bid128_atanh") ||
1638 !strcmp(func, "bid128_exp") || !strcmp(func, "bid128_expm1") ||
1639 !strcmp(func, "bid128_log") || !strcmp(func, "bid128_log10") || !strcmp(func, "bid128_log1p") ||
1640 !strcmp(func, "bid128_atan2") || !strcmp(func, "bid128_hypot") || !strcmp(func, "bid128_pow") ||
1641 !strcmp(func, "bid128_cbrt")
1642 ) return 1;
1643 }
1644 if (no64trans) {
1645 if (!strcmp(func, "bid64_sin") || !strcmp(func, "bid64_cos") || !strcmp(func, "bid64_tan") ||
1646 !strcmp(func, "bid64_asin") || !strcmp(func, "bid64_acos") || !strcmp(func, "bid64_atan") ||
1647 !strcmp(func, "bid64_sinh") || !strcmp(func, "bid64_cosh") || !strcmp(func, "bid64_tanh") ||
1648 !strcmp(func, "bid64_asinh") || !strcmp(func, "bid64_acosh") || !strcmp(func, "bid64_atanh") ||
1649 !strcmp(func, "bid64_exp") || !strcmp(func, "bid64_expm1") ||
1650 !strcmp(func, "bid64_log") || !strcmp(func, "bid64_log10") || !strcmp(func, "bid64_log1p") ||
1651 !strcmp(func, "bid64_atan2") || !strcmp(func, "bid64_hypot") || !strcmp(func, "bid64_pow") ||
1652 !strcmp(func, "bid64_cbrt")
1653 ) return 1;
1654 }
1655 if (li_size_run != li_size_test) return 1;
1656 return 0;
1657 }
1658
1659
check_snan_passing32(float x)1660 void check_snan_passing32(float x)
1661 {
1662 int *px = (int*)&x;
1663 if (*(px) & 0x00400000) SNaN_passed_incorrectly32 = 1;
1664 }
1665
check_snan_passing64(double x)1666 void check_snan_passing64(double x)
1667 {
1668 int *px = (int*)&x;
1669 if (*(px+BID_HIGH_128W) & 0x00080000) SNaN_passed_incorrectly64 = 1;
1670 }
1671
check_snan_passing80(long double x)1672 void check_snan_passing80(long double x)
1673 {
1674 int *px = (int*)&x;
1675 #if BID_BIG_ENDIAN
1676 if (*(px+BID_HIGH_128W) & 0x40000000) SNaN_passed_incorrectly80 = 1;
1677 #else
1678 if (*(px) & 0x00008000) SNaN_passed_incorrectly80 = 1;
1679 #endif
1680
1681 }
1682
check_den_passing32(float x)1683 void check_den_passing32(float x)
1684 {
1685 #if !defined _MSC_VER && !defined __INTEL_COMPILER
1686 fexcept_t ff;
1687 fegetexceptflag(&ff, FE_ALL_EXCEPT);
1688 if (ff & FE_DENORMAL) Den_passed_incorrectly32 = 1;
1689 #endif
1690 }
check_den_passing64(double x)1691 void check_den_passing64(double x)
1692 {
1693 #if !defined _MSC_VER && !defined __INTEL_COMPILER
1694 fexcept_t ff;
1695 fegetexceptflag(&ff, FE_ALL_EXCEPT);
1696 if (ff & FE_DENORMAL) Den_passed_incorrectly64 = 1;
1697 #endif
1698 }
check_den_passing80(long double x)1699 void check_den_passing80(long double x)
1700 {
1701 #if !defined _MSC_VER && !defined __INTEL_COMPILER
1702 fexcept_t ff;
1703 fegetexceptflag(&ff, FE_ALL_EXCEPT);
1704 if (ff & FE_DENORMAL) Den_passed_incorrectly80 = 1;
1705 #endif
1706 }
1707
1708
1709 int
main(int argc,char * argv[])1710 main (int argc, char *argv[]) {
1711 int ch, digit_optind = 0;
1712 int skip_test;
1713 char **arg;
1714 char *end_of_args = (char*)-1;
1715
1716 strcpy (rounding, "half_even");
1717
1718 if (sizeof(long int) == 8) {
1719 li_size_test = 64;
1720 li_size_run = 64;
1721 } else {
1722 li_size_test = 32;
1723 li_size_run = 32;
1724 }
1725
1726 arg = argv + 1; // point to first command-line parameter
1727 while (*arg && **arg == '-') { // Process all options
1728 if (strcmp (*arg, "-d") == 0)
1729 debug_opt = 1;
1730 if (strcmp (*arg, "-ub") == 0)
1731 underflow_before_opt = 1;
1732 if (strcmp (*arg, "-ua") == 0)
1733 underflow_after_opt = 1;
1734 if (strcmp (*arg, "-h") == 0) {
1735 printf ("Usage: runtests [-d]\n");
1736 exit (0);
1737 }
1738 if (strcmp (*arg, "-ulp") == 0) {
1739 arg++;
1740 argc--;
1741 sscanf(*arg, "%lf", &mre_max[0]);
1742 mre_max[4] = mre_max[3] = mre_max[2] = mre_max[1] = mre_max[0];
1743 }
1744 if (strcmp (*arg, "-bin_flags") == 0) {
1745 check_binary_flags_opt = 1;
1746 arg++;
1747 argc--;
1748 sscanf(*arg, "%x", (int*)&ini_binary_flags);
1749 }
1750 if (strcmp (*arg, "-no128trans") == 0) {
1751 no128trans = 1;
1752 }
1753 if (strcmp (*arg, "-no64trans") == 0) {
1754 no64trans = 1;
1755 }
1756 arg++;
1757 }
1758
1759 if (underflow_before_opt && underflow_after_opt) {
1760 printf("Both underflow before and after rounding checking mode set, please specify just one.\n");
1761 printf ("Usage: runtests [-d]\n");
1762 exit (0);
1763 } else if (!underflow_before_opt && !underflow_after_opt) underflow_before_opt = 1;
1764
1765 rnd_mode = 0;
1766 rnd_mode |= BID_ROUNDING_TO_NEAREST;
1767
1768 *((int*)&snan_check64+BID_HIGH_128W) = 0x7ff00000;
1769 *((int*)&snan_check64+BID_LOW_128W) = 0x00000001;
1770 check_snan_passing64(snan_check64);
1771 *((int*)&snan_check32) = 0x7f800010;
1772 check_snan_passing32(snan_check32);
1773 #if BID_BIG_ENDIAN
1774 *((int*)&snan_check80) = 0x7fff8000;
1775 *((int*)&snan_check80+1) = 0;
1776 *((short*)&snan_check80+4) = 1;
1777 #else
1778 *((short*)&snan_check80+4) = 0x7fff;
1779 *((int*)&snan_check80+1) = 0x80000000;
1780 *((int*)&snan_check80+0) = 0x00000001;
1781 #endif
1782 check_snan_passing80(snan_check80);
1783
1784 *((int*)&snan_check64+BID_HIGH_128W) = 0x00000000;
1785 *((int*)&snan_check64+BID_LOW_128W) = 0x00000001;
1786 #if !defined _MSC_VER && !defined __INTEL_COMPILER
1787 feclearexcept (FE_ALL_EXCEPT);
1788 check_den_passing64(snan_check64);
1789 *((int*)&snan_check32) = 0x00000001;
1790 feclearexcept (FE_ALL_EXCEPT);
1791 check_den_passing32(snan_check32);
1792 #endif
1793 #if BID_BIG_ENDIAN
1794 *((short*)&snan_check80+4) = 0x0000;
1795 *((int*)&snan_check80+1) = 0x00000000;
1796 *((int*)&snan_check80+0) = 0x00000001;
1797 #else
1798 *((int*)&snan_check80) = 0x00000000;
1799 *((int*)&snan_check80+1) = 0;
1800 *((short*)&snan_check80+4) = 1;
1801 #endif
1802 #if !defined _MSC_VER && !defined __INTEL_COMPILER
1803 feclearexcept (FE_ALL_EXCEPT);
1804 check_den_passing80(snan_check80);
1805 feclearexcept (FE_ALL_EXCEPT);
1806 #endif
1807 //printf("snan32 passed incorr %d\n", SNaN_passed_incorrectly32);
1808 //printf("snan64 passed incorr %d\n", SNaN_passed_incorrectly64);
1809 //printf("snan80 passed incorr %d\n", SNaN_passed_incorrectly80);
1810 //printf("den32 passed incorr %d\n", Den_passed_incorrectly32);
1811 //printf("den64 passed incorr %d\n", Den_passed_incorrectly64);
1812 //printf("den80 passed incorr %d\n", Den_passed_incorrectly80);
1813
1814 line_counter=0;
1815 while (!feof (stdin)) {
1816 int st;
1817
1818 op1type = OP_NONE;
1819 op2type = OP_NONE;
1820 op3type = OP_NONE;
1821 restype = OP_NONE;
1822
1823 fgets (line, 1023, stdin);
1824 line_counter++;
1825 strRemove0D0A(line);
1826 strcpy(full_line, line);
1827 if (feof (stdin))
1828 break;
1829
1830 // printf("Read line: %s", line);
1831 if (p = strstr (line, "--")) *p = 0; // Remove comment
1832 strRemoveTrailingSpaces(line);
1833
1834 // Reset BID status flags
1835 *pfpsf = 0;
1836
1837 if (line[0] == 0)
1838 continue;
1839
1840 // Extract ulp field from line, if present:
1841 if (p = strstr (line, "ulp=")) {
1842 if (p < end_of_args) end_of_args = p;
1843 if ( sscanf(p+4, "%le", &ulp_add) != 1 ) ulp_add=0.0;
1844 } else {
1845 ulp_add=0.0;
1846 }
1847
1848 // Determine if underflow, indicated as expected have to be set only for before rounding mode
1849 if (p = strstr (line, "underflow_before_only")) {
1850 if (p < end_of_args) end_of_args = p;
1851 Underflow_Before = 1;
1852 } else {
1853 Underflow_Before = 0;
1854 }
1855
1856 // Read string prefix for from string conversions
1857 if (p = strstr (line, "str_prefix=")) {
1858 if (p < end_of_args) end_of_args = p;
1859 { int i = 0; while ( *(p+12+i) != '|' && *(p+12+i) != 0 ) {
1860 str_prefix[i] = *(p+12+i);
1861 i++;
1862 }
1863 str_prefix[i] = 0;
1864 }
1865 } else {
1866 strcpy(str_prefix, "");
1867 }
1868
1869 // Extract long int size from line, if present:
1870 if (p = strstr (line, "longintsize=")) {
1871 if (p < end_of_args) end_of_args = p;
1872 if ( sscanf(p+12, "%d", &li_size_test) != 1 ) li_size_test=0;
1873 } else {
1874 li_size_test=li_size_run;
1875 }
1876
1877 //printf();
1878 if (end_of_args != (char*)-1) {
1879 *end_of_args = 0;
1880 strRemoveTrailingSpaces(line);
1881 end_of_args = (char*)-1;
1882 }
1883
1884 args_set = 0;
1885 if (sscanf (line, "%s %d %s %s %s %s %x", funcstr, &rnd_mode,
1886 op1, op2, op3, res, &expected_status) == 7) {
1887 //printf("read8 %d\n", rnd_mode);
1888 args_set = 1;
1889 }
1890 if (!args_set) {
1891 if (sscanf (line, "%s %d %s %s %s %x", funcstr, &rnd_mode,
1892 op1, op2, res, &expected_status) == 6) {
1893 //printf("read7 %d\n", rnd_mode);
1894 args_set = 1;
1895 }
1896 }
1897 if (!args_set) {
1898 if (sscanf(line, "%s %d %s %s %x", funcstr, &rnd_mode, op1,
1899 res, &expected_status) == 5) {
1900 //printf("read6 %d\n", rnd_mode);
1901 args_set = 1;
1902 }
1903 }
1904
1905 skip_test = check_skip(funcstr);
1906 pollution_workaround = check_pollution_workaround();
1907
1908
1909 //printf("str %s op1 %s, skip %d\n", line, op1, skip_test);
1910 if (args_set && !skip_test) {
1911 rnd = rnd_mode;
1912 // set ulp thresholds for transcendentals
1913 if (p = strstr (funcstr, "128")) {
1914 mre_max[0] = 2.0;
1915 mre_max[1] = 5.0;
1916 mre_max[2] = 5.0;
1917 mre_max[3] = 5.0;
1918 mre_max[4] = 2.0;
1919 } else if (p = strstr (funcstr, "64")) {
1920 mre_max[0] = 0.55;
1921 mre_max[1] = 1.05;
1922 mre_max[2] = 1.05;
1923 mre_max[3] = 1.05;
1924 mre_max[4] = 0.55;
1925 } else if (p = strstr (funcstr, "32")) {
1926 mre_max[0] = 0.5;
1927 mre_max[1] = 1.01;
1928 mre_max[2] = 1.01;
1929 mre_max[3] = 1.01;
1930 mre_max[4] = 0.5;
1931 }
1932
1933 strcpy (rounding, roundstr_bid[rnd]);
1934
1935 //clean expected underflow if it is for before rounding mode and we are checking after rounidng
1936 if ((expected_status & 0x10) && Underflow_Before && underflow_after_opt) expected_status &= ~0x00000010;
1937
1938 #include "readtest.h"
1939
1940 } else {
1941 if (!skip_test) printf ("SKIPPED (line %d): %s\n", line_counter,line);
1942 }
1943 }
1944
1945 printf ("Total tests: %d, failed result: %d, failed status: %d\n",
1946 tests, fail_res, fail_status);
1947 return 0;
1948
1949 }
1950
copy_str_to_wstr()1951 int copy_str_to_wstr() {
1952 int i = 0;
1953 if (strstr (funcstr, "wcstod")) {
1954 while (istr1[i] != 0 && istr1[i] != '\n') {
1955 wistr1[i] = (wchar_t)istr1[i];
1956 i++;
1957 }
1958 wistr1[i] = 0;
1959 }
1960 return 1;
1961 }
1962
1963
save_binary_status()1964 void save_binary_status()
1965 {
1966 #if !defined _MSC_VER && !defined __INTEL_COMPILER
1967 if (check_binary_flags_opt) {
1968 feclearexcept (FE_ALL_EXCEPT);
1969 fesetexceptflag(&ini_binary_flags, FE_ALL_EXCEPT);
1970 fegetexceptflag(&saved_binary_flags, FE_ALL_EXCEPT);
1971 }
1972 #endif
1973 }
1974
check_restore_binary_status()1975 int check_restore_binary_status()
1976 {
1977 char *p;
1978 //printf("snan arg, passed incor %d %d\n", arg64_snan, SNaN_passed_incorrectly64);
1979 if (check_binary_flags_opt || debug_opt) {
1980 #if !defined _MSC_VER && !defined __INTEL_COMPILER
1981 fegetexceptflag(&test_binary_flags, FE_ALL_EXCEPT);
1982
1983 if (p = strstr (func, "binary32_to")) {
1984 if (arg32_den && Den_passed_incorrectly32) saved_binary_flags |= (test_binary_flags & FE_UNNORMAL);
1985 if (arg32_snan && SNaN_passed_incorrectly32) saved_binary_flags |= (test_binary_flags & FE_INVALID);
1986 }
1987 if (p = strstr (func, "binary64_to")) {
1988 if (arg64_den && Den_passed_incorrectly64) saved_binary_flags |= (test_binary_flags & FE_UNNORMAL);
1989 if (arg64_snan && SNaN_passed_incorrectly64) saved_binary_flags |= (test_binary_flags & FE_INVALID);
1990 }
1991 if (p = strstr (func, "binary80_to")) {
1992 if (arg80_den && Den_passed_incorrectly80) saved_binary_flags |= (test_binary_flags & FE_UNNORMAL);
1993 if (arg80_snan && SNaN_passed_incorrectly80) saved_binary_flags |= (test_binary_flags & FE_INVALID);
1994 }
1995 // !!!! Workaround, do not favor non-standard denormal flag for now
1996 saved_binary_flags |= (test_binary_flags & FE_UNNORMAL);
1997 // !!!! Workaround, do not favor non-standard denormal flag for now
1998 if (test_binary_flags != saved_binary_flags && !pollution_workaround ) {
1999 printf("// ERROR: BINARY Exception flags polluted!\n");
2000 printf("// Saved value %X, value after BID call %X\n", *(int*)&saved_binary_flags, *(int*)&test_binary_flags );
2001 return 1;
2002 }
2003 #endif
2004 }
2005 return 0;
2006 }
2007
check_pollution_workaround(void)2008 int check_pollution_workaround(void)
2009 {
2010 char *p;
2011 if ((p = strstr (func, "sin")) ||
2012 (p = strstr (func, "cos")) ||
2013 (p = strstr (func, "tan")) ||
2014 (p = strstr (func, "exp")) ||
2015 (p = strstr (func, "log")) ||
2016 (p = strstr (func, "erf")) ||
2017 (p = strstr (func, "hypot")) ||
2018 (p = strstr (func, "pow")) ||
2019 (p = strstr (func, "cbrt")) ||
2020 (p = strstr (func, "gamma"))
2021 ) {
2022 return 1;
2023 } else {
2024 return 0;
2025 }
2026
2027 }
2028
2029