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