1 
2 /*============================================================================
3 
4 This C source file is part of TestFloat, Release 3e, a package of programs for
5 testing the correctness of floating-point arithmetic complying with the IEEE
6 Standard for Floating-Point, by John R. Hauser.
7 
8 Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
9 University of California.  All rights reserved.
10 
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions are met:
13 
14  1. Redistributions of source code must retain the above copyright notice,
15     this list of conditions, and the following disclaimer.
16 
17  2. Redistributions in binary form must reproduce the above copyright notice,
18     this list of conditions, and the following disclaimer in the documentation
19     and/or other materials provided with the distribution.
20 
21  3. Neither the name of the University nor the names of its contributors may
22     be used to endorse or promote products derived from this software without
23     specific prior written permission.
24 
25 THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
26 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
28 DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
29 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 
36 =============================================================================*/
37 
38 #include <stdbool.h>
39 #include <stdint.h>
40 #include <string.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <signal.h>
44 #include "platform.h"
45 #include "fail.h"
46 #include "softfloat.h"
47 #include "slowfloat.h"
48 #include "functions.h"
49 #include "genCases.h"
50 #include "verCases.h"
51 #include "writeCase.h"
52 #include "testLoops.h"
53 
catchSIGINT(int signalCode)54 static void catchSIGINT( int signalCode )
55 {
56 
57     if ( verCases_stop ) exit( EXIT_FAILURE );
58     verCases_stop = true;
59 
60 }
61 
softfloat_clearExceptionFlags(void)62 static uint_fast8_t softfloat_clearExceptionFlags( void )
63 {
64     uint_fast8_t prevFlags;
65 
66     prevFlags = softfloat_exceptionFlags;
67     softfloat_exceptionFlags = 0;
68     return prevFlags;
69 
70 }
71 
72 static
73 void
testFunctionInstance(int functionCode,uint_fast8_t roundingMode,bool exact)74  testFunctionInstance(
75      int functionCode, uint_fast8_t roundingMode, bool exact )
76 {
77 #ifdef FLOAT16
78     float16_t (*trueFunction_abz_f16)( float16_t, float16_t );
79     float16_t (*subjFunction_abz_f16)( float16_t, float16_t );
80     bool (*trueFunction_ab_f16_z_bool)( float16_t, float16_t );
81     bool (*subjFunction_ab_f16_z_bool)( float16_t, float16_t );
82 #endif
83     float32_t (*trueFunction_abz_f32)( float32_t, float32_t );
84     float32_t (*subjFunction_abz_f32)( float32_t, float32_t );
85     bool (*trueFunction_ab_f32_z_bool)( float32_t, float32_t );
86     bool (*subjFunction_ab_f32_z_bool)( float32_t, float32_t );
87 #ifdef FLOAT64
88     float64_t (*trueFunction_abz_f64)( float64_t, float64_t );
89     float64_t (*subjFunction_abz_f64)( float64_t, float64_t );
90     bool (*trueFunction_ab_f64_z_bool)( float64_t, float64_t );
91     bool (*subjFunction_ab_f64_z_bool)( float64_t, float64_t );
92 #endif
93 #ifdef EXTFLOAT80
94     void (*trueFunction_abz_extF80M)(
95         const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
96     void (*subjFunction_abz_extF80M)(
97         const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
98     bool (*trueFunction_ab_extF80M_z_bool)(
99         const extFloat80_t *, const extFloat80_t * );
100     bool (*subjFunction_ab_extF80M_z_bool)(
101         const extFloat80_t *, const extFloat80_t * );
102 #endif
103 #ifdef FLOAT128
104     void (*trueFunction_abz_f128M)(
105         const float128_t *, const float128_t *, float128_t * );
106     void (*subjFunction_abz_f128M)(
107         const float128_t *, const float128_t *, float128_t * );
108     bool (*trueFunction_ab_f128M_z_bool)(
109         const float128_t *, const float128_t * );
110     bool (*subjFunction_ab_f128M_z_bool)(
111         const float128_t *, const float128_t * );
112 #endif
113 
114     fputs( "Testing ", stderr );
115     verCases_writeFunctionName( stderr );
116     fputs( ".\n", stderr );
117     switch ( functionCode ) {
118         /*--------------------------------------------------------------------
119         *--------------------------------------------------------------------*/
120 #ifdef FLOAT16
121      case UI32_TO_F16:
122         test_a_ui32_z_f16( slow_ui32_to_f16, ui32_to_f16 );
123         break;
124 #endif
125      case UI32_TO_F32:
126         test_a_ui32_z_f32( slow_ui32_to_f32, ui32_to_f32 );
127         break;
128 #ifdef FLOAT64
129      case UI32_TO_F64:
130         test_a_ui32_z_f64( slow_ui32_to_f64, ui32_to_f64 );
131         break;
132 #endif
133 #ifdef EXTFLOAT80
134      case UI32_TO_EXTF80:
135         test_a_ui32_z_extF80( slow_ui32_to_extF80M, ui32_to_extF80M );
136         break;
137 #endif
138 #ifdef FLOAT128
139      case UI32_TO_F128:
140         test_a_ui32_z_f128( slow_ui32_to_f128M, ui32_to_f128M );
141         break;
142 #endif
143 #ifdef FLOAT16
144      case UI64_TO_F16:
145         test_a_ui64_z_f16( slow_ui64_to_f16, ui64_to_f16 );
146         break;
147 #endif
148      case UI64_TO_F32:
149         test_a_ui64_z_f32( slow_ui64_to_f32, ui64_to_f32 );
150         break;
151 #ifdef FLOAT64
152      case UI64_TO_F64:
153         test_a_ui64_z_f64( slow_ui64_to_f64, ui64_to_f64 );
154         break;
155 #endif
156 #ifdef EXTFLOAT80
157      case UI64_TO_EXTF80:
158         test_a_ui64_z_extF80( slow_ui64_to_extF80M, ui64_to_extF80M );
159         break;
160 #endif
161 #ifdef FLOAT128
162      case UI64_TO_F128:
163         test_a_ui64_z_f128( slow_ui64_to_f128M, ui64_to_f128M );
164         break;
165 #endif
166 #ifdef FLOAT16
167      case I32_TO_F16:
168         test_a_i32_z_f16( slow_i32_to_f16, i32_to_f16 );
169         break;
170 #endif
171      case I32_TO_F32:
172         test_a_i32_z_f32( slow_i32_to_f32, i32_to_f32 );
173         break;
174 #ifdef FLOAT64
175      case I32_TO_F64:
176         test_a_i32_z_f64( slow_i32_to_f64, i32_to_f64 );
177         break;
178 #endif
179 #ifdef EXTFLOAT80
180      case I32_TO_EXTF80:
181         test_a_i32_z_extF80( slow_i32_to_extF80M, i32_to_extF80M );
182         break;
183 #endif
184 #ifdef FLOAT128
185      case I32_TO_F128:
186         test_a_i32_z_f128( slow_i32_to_f128M, i32_to_f128M );
187         break;
188 #endif
189 #ifdef FLOAT16
190      case I64_TO_F16:
191         test_a_i64_z_f16( slow_i64_to_f16, i64_to_f16 );
192         break;
193 #endif
194      case I64_TO_F32:
195         test_a_i64_z_f32( slow_i64_to_f32, i64_to_f32 );
196         break;
197 #ifdef FLOAT64
198      case I64_TO_F64:
199         test_a_i64_z_f64( slow_i64_to_f64, i64_to_f64 );
200         break;
201 #endif
202 #ifdef EXTFLOAT80
203      case I64_TO_EXTF80:
204         test_a_i64_z_extF80( slow_i64_to_extF80M, i64_to_extF80M );
205         break;
206 #endif
207 #ifdef FLOAT128
208      case I64_TO_F128:
209         test_a_i64_z_f128( slow_i64_to_f128M, i64_to_f128M );
210         break;
211 #endif
212         /*--------------------------------------------------------------------
213         *--------------------------------------------------------------------*/
214 #ifdef FLOAT16
215      case F16_TO_UI32:
216         test_a_f16_z_ui32_rx(
217             slow_f16_to_ui32, f16_to_ui32, roundingMode, exact );
218         break;
219      case F16_TO_UI64:
220         test_a_f16_z_ui64_rx(
221             slow_f16_to_ui64, f16_to_ui64, roundingMode, exact );
222         break;
223      case F16_TO_I32:
224         test_a_f16_z_i32_rx(
225             slow_f16_to_i32, f16_to_i32, roundingMode, exact );
226         break;
227      case F16_TO_I64:
228         test_a_f16_z_i64_rx(
229             slow_f16_to_i64, f16_to_i64, roundingMode, exact );
230         break;
231      case F16_TO_UI32_R_MINMAG:
232         test_a_f16_z_ui32_x(
233             slow_f16_to_ui32_r_minMag, f16_to_ui32_r_minMag, exact );
234         break;
235      case F16_TO_UI64_R_MINMAG:
236         test_a_f16_z_ui64_x(
237             slow_f16_to_ui64_r_minMag, f16_to_ui64_r_minMag, exact );
238         break;
239      case F16_TO_I32_R_MINMAG:
240         test_a_f16_z_i32_x(
241             slow_f16_to_i32_r_minMag, f16_to_i32_r_minMag, exact );
242         break;
243      case F16_TO_I64_R_MINMAG:
244         test_a_f16_z_i64_x(
245             slow_f16_to_i64_r_minMag, f16_to_i64_r_minMag, exact );
246         break;
247      case F16_TO_F32:
248         test_a_f16_z_f32( slow_f16_to_f32, f16_to_f32 );
249         break;
250 #ifdef FLOAT64
251      case F16_TO_F64:
252         test_a_f16_z_f64( slow_f16_to_f64, f16_to_f64 );
253         break;
254 #endif
255 #ifdef EXTFLOAT80
256      case F16_TO_EXTF80:
257         test_a_f16_z_extF80( slow_f16_to_extF80M, f16_to_extF80M );
258         break;
259 #endif
260 #ifdef FLOAT128
261      case F16_TO_F128:
262         test_a_f16_z_f128( slow_f16_to_f128M, f16_to_f128M );
263         break;
264 #endif
265      case F16_ROUNDTOINT:
266         test_az_f16_rx(
267             slow_f16_roundToInt, f16_roundToInt, roundingMode, exact );
268         break;
269      case F16_ADD:
270         trueFunction_abz_f16 = slow_f16_add;
271         subjFunction_abz_f16 = f16_add;
272         goto test_abz_f16;
273      case F16_SUB:
274         trueFunction_abz_f16 = slow_f16_sub;
275         subjFunction_abz_f16 = f16_sub;
276         goto test_abz_f16;
277      case F16_MUL:
278         trueFunction_abz_f16 = slow_f16_mul;
279         subjFunction_abz_f16 = f16_mul;
280         goto test_abz_f16;
281      case F16_DIV:
282         trueFunction_abz_f16 = slow_f16_div;
283         subjFunction_abz_f16 = f16_div;
284         goto test_abz_f16;
285      case F16_REM:
286         trueFunction_abz_f16 = slow_f16_rem;
287         subjFunction_abz_f16 = f16_rem;
288      test_abz_f16:
289         test_abz_f16( trueFunction_abz_f16, subjFunction_abz_f16 );
290         break;
291      case F16_MULADD:
292         test_abcz_f16( slow_f16_mulAdd, f16_mulAdd );
293         break;
294      case F16_SQRT:
295         test_az_f16( slow_f16_sqrt, f16_sqrt );
296         break;
297      case F16_EQ:
298         trueFunction_ab_f16_z_bool = slow_f16_eq;
299         subjFunction_ab_f16_z_bool = f16_eq;
300         goto test_ab_f16_z_bool;
301      case F16_LE:
302         trueFunction_ab_f16_z_bool = slow_f16_le;
303         subjFunction_ab_f16_z_bool = f16_le;
304         goto test_ab_f16_z_bool;
305      case F16_LT:
306         trueFunction_ab_f16_z_bool = slow_f16_lt;
307         subjFunction_ab_f16_z_bool = f16_lt;
308         goto test_ab_f16_z_bool;
309      case F16_EQ_SIGNALING:
310         trueFunction_ab_f16_z_bool = slow_f16_eq_signaling;
311         subjFunction_ab_f16_z_bool = f16_eq_signaling;
312         goto test_ab_f16_z_bool;
313      case F16_LE_QUIET:
314         trueFunction_ab_f16_z_bool = slow_f16_le_quiet;
315         subjFunction_ab_f16_z_bool = f16_le_quiet;
316         goto test_ab_f16_z_bool;
317      case F16_LT_QUIET:
318         trueFunction_ab_f16_z_bool = slow_f16_lt_quiet;
319         subjFunction_ab_f16_z_bool = f16_lt_quiet;
320      test_ab_f16_z_bool:
321         test_ab_f16_z_bool(
322             trueFunction_ab_f16_z_bool, subjFunction_ab_f16_z_bool );
323         break;
324 #endif
325         /*--------------------------------------------------------------------
326         *--------------------------------------------------------------------*/
327      case F32_TO_UI32:
328         test_a_f32_z_ui32_rx(
329             slow_f32_to_ui32, f32_to_ui32, roundingMode, exact );
330         break;
331      case F32_TO_UI64:
332         test_a_f32_z_ui64_rx(
333             slow_f32_to_ui64, f32_to_ui64, roundingMode, exact );
334         break;
335      case F32_TO_I32:
336         test_a_f32_z_i32_rx(
337             slow_f32_to_i32, f32_to_i32, roundingMode, exact );
338         break;
339      case F32_TO_I64:
340         test_a_f32_z_i64_rx(
341             slow_f32_to_i64, f32_to_i64, roundingMode, exact );
342         break;
343      case F32_TO_UI32_R_MINMAG:
344         test_a_f32_z_ui32_x(
345             slow_f32_to_ui32_r_minMag, f32_to_ui32_r_minMag, exact );
346         break;
347      case F32_TO_UI64_R_MINMAG:
348         test_a_f32_z_ui64_x(
349             slow_f32_to_ui64_r_minMag, f32_to_ui64_r_minMag, exact );
350         break;
351      case F32_TO_I32_R_MINMAG:
352         test_a_f32_z_i32_x(
353             slow_f32_to_i32_r_minMag, f32_to_i32_r_minMag, exact );
354         break;
355      case F32_TO_I64_R_MINMAG:
356         test_a_f32_z_i64_x(
357             slow_f32_to_i64_r_minMag, f32_to_i64_r_minMag, exact );
358         break;
359 #ifdef FLOAT16
360      case F32_TO_F16:
361         test_a_f32_z_f16( slow_f32_to_f16, f32_to_f16 );
362         break;
363 #endif
364 #ifdef FLOAT64
365      case F32_TO_F64:
366         test_a_f32_z_f64( slow_f32_to_f64, f32_to_f64 );
367         break;
368 #endif
369 #ifdef EXTFLOAT80
370      case F32_TO_EXTF80:
371         test_a_f32_z_extF80( slow_f32_to_extF80M, f32_to_extF80M );
372         break;
373 #endif
374 #ifdef FLOAT128
375      case F32_TO_F128:
376         test_a_f32_z_f128( slow_f32_to_f128M, f32_to_f128M );
377         break;
378 #endif
379      case F32_ROUNDTOINT:
380         test_az_f32_rx(
381             slow_f32_roundToInt, f32_roundToInt, roundingMode, exact );
382         break;
383      case F32_ADD:
384         trueFunction_abz_f32 = slow_f32_add;
385         subjFunction_abz_f32 = f32_add;
386         goto test_abz_f32;
387      case F32_SUB:
388         trueFunction_abz_f32 = slow_f32_sub;
389         subjFunction_abz_f32 = f32_sub;
390         goto test_abz_f32;
391      case F32_MUL:
392         trueFunction_abz_f32 = slow_f32_mul;
393         subjFunction_abz_f32 = f32_mul;
394         goto test_abz_f32;
395      case F32_DIV:
396         trueFunction_abz_f32 = slow_f32_div;
397         subjFunction_abz_f32 = f32_div;
398         goto test_abz_f32;
399      case F32_REM:
400         trueFunction_abz_f32 = slow_f32_rem;
401         subjFunction_abz_f32 = f32_rem;
402      test_abz_f32:
403         test_abz_f32( trueFunction_abz_f32, subjFunction_abz_f32 );
404         break;
405      case F32_MULADD:
406         test_abcz_f32( slow_f32_mulAdd, f32_mulAdd );
407         break;
408      case F32_SQRT:
409         test_az_f32( slow_f32_sqrt, f32_sqrt );
410         break;
411      case F32_EQ:
412         trueFunction_ab_f32_z_bool = slow_f32_eq;
413         subjFunction_ab_f32_z_bool = f32_eq;
414         goto test_ab_f32_z_bool;
415      case F32_LE:
416         trueFunction_ab_f32_z_bool = slow_f32_le;
417         subjFunction_ab_f32_z_bool = f32_le;
418         goto test_ab_f32_z_bool;
419      case F32_LT:
420         trueFunction_ab_f32_z_bool = slow_f32_lt;
421         subjFunction_ab_f32_z_bool = f32_lt;
422         goto test_ab_f32_z_bool;
423      case F32_EQ_SIGNALING:
424         trueFunction_ab_f32_z_bool = slow_f32_eq_signaling;
425         subjFunction_ab_f32_z_bool = f32_eq_signaling;
426         goto test_ab_f32_z_bool;
427      case F32_LE_QUIET:
428         trueFunction_ab_f32_z_bool = slow_f32_le_quiet;
429         subjFunction_ab_f32_z_bool = f32_le_quiet;
430         goto test_ab_f32_z_bool;
431      case F32_LT_QUIET:
432         trueFunction_ab_f32_z_bool = slow_f32_lt_quiet;
433         subjFunction_ab_f32_z_bool = f32_lt_quiet;
434      test_ab_f32_z_bool:
435         test_ab_f32_z_bool(
436             trueFunction_ab_f32_z_bool, subjFunction_ab_f32_z_bool );
437         break;
438         /*--------------------------------------------------------------------
439         *--------------------------------------------------------------------*/
440 #ifdef FLOAT64
441      case F64_TO_UI32:
442         test_a_f64_z_ui32_rx(
443             slow_f64_to_ui32, f64_to_ui32, roundingMode, exact );
444         break;
445      case F64_TO_UI64:
446         test_a_f64_z_ui64_rx(
447             slow_f64_to_ui64, f64_to_ui64, roundingMode, exact );
448         break;
449      case F64_TO_I32:
450         test_a_f64_z_i32_rx(
451             slow_f64_to_i32, f64_to_i32, roundingMode, exact );
452         break;
453      case F64_TO_I64:
454         test_a_f64_z_i64_rx(
455             slow_f64_to_i64, f64_to_i64, roundingMode, exact );
456         break;
457      case F64_TO_UI32_R_MINMAG:
458         test_a_f64_z_ui32_x(
459             slow_f64_to_ui32_r_minMag, f64_to_ui32_r_minMag, exact );
460         break;
461      case F64_TO_UI64_R_MINMAG:
462         test_a_f64_z_ui64_x(
463             slow_f64_to_ui64_r_minMag, f64_to_ui64_r_minMag, exact );
464         break;
465      case F64_TO_I32_R_MINMAG:
466         test_a_f64_z_i32_x(
467             slow_f64_to_i32_r_minMag, f64_to_i32_r_minMag, exact );
468         break;
469      case F64_TO_I64_R_MINMAG:
470         test_a_f64_z_i64_x(
471             slow_f64_to_i64_r_minMag, f64_to_i64_r_minMag, exact );
472         break;
473 #ifdef FLOAT16
474      case F64_TO_F16:
475         test_a_f64_z_f16( slow_f64_to_f16, f64_to_f16 );
476         break;
477 #endif
478      case F64_TO_F32:
479         test_a_f64_z_f32( slow_f64_to_f32, f64_to_f32 );
480         break;
481 #ifdef EXTFLOAT80
482      case F64_TO_EXTF80:
483         test_a_f64_z_extF80( slow_f64_to_extF80M, f64_to_extF80M );
484         break;
485 #endif
486 #ifdef FLOAT128
487      case F64_TO_F128:
488         test_a_f64_z_f128( slow_f64_to_f128M, f64_to_f128M );
489         break;
490 #endif
491      case F64_ROUNDTOINT:
492         test_az_f64_rx(
493             slow_f64_roundToInt, f64_roundToInt, roundingMode, exact );
494         break;
495      case F64_ADD:
496         trueFunction_abz_f64 = slow_f64_add;
497         subjFunction_abz_f64 = f64_add;
498         goto test_abz_f64;
499      case F64_SUB:
500         trueFunction_abz_f64 = slow_f64_sub;
501         subjFunction_abz_f64 = f64_sub;
502         goto test_abz_f64;
503      case F64_MUL:
504         trueFunction_abz_f64 = slow_f64_mul;
505         subjFunction_abz_f64 = f64_mul;
506         goto test_abz_f64;
507      case F64_DIV:
508         trueFunction_abz_f64 = slow_f64_div;
509         subjFunction_abz_f64 = f64_div;
510         goto test_abz_f64;
511      case F64_REM:
512         trueFunction_abz_f64 = slow_f64_rem;
513         subjFunction_abz_f64 = f64_rem;
514      test_abz_f64:
515         test_abz_f64( trueFunction_abz_f64, subjFunction_abz_f64 );
516         break;
517      case F64_MULADD:
518         test_abcz_f64( slow_f64_mulAdd, f64_mulAdd );
519         break;
520      case F64_SQRT:
521         test_az_f64( slow_f64_sqrt, f64_sqrt );
522         break;
523      case F64_EQ:
524         trueFunction_ab_f64_z_bool = slow_f64_eq;
525         subjFunction_ab_f64_z_bool = f64_eq;
526         goto test_ab_f64_z_bool;
527      case F64_LE:
528         trueFunction_ab_f64_z_bool = slow_f64_le;
529         subjFunction_ab_f64_z_bool = f64_le;
530         goto test_ab_f64_z_bool;
531      case F64_LT:
532         trueFunction_ab_f64_z_bool = slow_f64_lt;
533         subjFunction_ab_f64_z_bool = f64_lt;
534         goto test_ab_f64_z_bool;
535      case F64_EQ_SIGNALING:
536         trueFunction_ab_f64_z_bool = slow_f64_eq_signaling;
537         subjFunction_ab_f64_z_bool = f64_eq_signaling;
538         goto test_ab_f64_z_bool;
539      case F64_LE_QUIET:
540         trueFunction_ab_f64_z_bool = slow_f64_le_quiet;
541         subjFunction_ab_f64_z_bool = f64_le_quiet;
542         goto test_ab_f64_z_bool;
543      case F64_LT_QUIET:
544         trueFunction_ab_f64_z_bool = slow_f64_lt_quiet;
545         subjFunction_ab_f64_z_bool = f64_lt_quiet;
546      test_ab_f64_z_bool:
547         test_ab_f64_z_bool(
548             trueFunction_ab_f64_z_bool, subjFunction_ab_f64_z_bool );
549         break;
550 #endif
551         /*--------------------------------------------------------------------
552         *--------------------------------------------------------------------*/
553 #ifdef EXTFLOAT80
554      case EXTF80_TO_UI32:
555         test_a_extF80_z_ui32_rx(
556             slow_extF80M_to_ui32, extF80M_to_ui32, roundingMode, exact );
557         break;
558      case EXTF80_TO_UI64:
559         test_a_extF80_z_ui64_rx(
560             slow_extF80M_to_ui64, extF80M_to_ui64, roundingMode, exact );
561         break;
562      case EXTF80_TO_I32:
563         test_a_extF80_z_i32_rx(
564             slow_extF80M_to_i32, extF80M_to_i32, roundingMode, exact );
565         break;
566      case EXTF80_TO_I64:
567         test_a_extF80_z_i64_rx(
568             slow_extF80M_to_i64, extF80M_to_i64, roundingMode, exact );
569         break;
570      case EXTF80_TO_UI32_R_MINMAG:
571         test_a_extF80_z_ui32_x(
572             slow_extF80M_to_ui32_r_minMag, extF80M_to_ui32_r_minMag, exact );
573         break;
574      case EXTF80_TO_UI64_R_MINMAG:
575         test_a_extF80_z_ui64_x(
576             slow_extF80M_to_ui64_r_minMag, extF80M_to_ui64_r_minMag, exact );
577         break;
578      case EXTF80_TO_I32_R_MINMAG:
579         test_a_extF80_z_i32_x(
580             slow_extF80M_to_i32_r_minMag, extF80M_to_i32_r_minMag, exact );
581         break;
582      case EXTF80_TO_I64_R_MINMAG:
583         test_a_extF80_z_i64_x(
584             slow_extF80M_to_i64_r_minMag, extF80M_to_i64_r_minMag, exact );
585         break;
586 #ifdef FLOAT16
587      case EXTF80_TO_F16:
588         test_a_extF80_z_f16( slow_extF80M_to_f16, extF80M_to_f16 );
589         break;
590 #endif
591      case EXTF80_TO_F32:
592         test_a_extF80_z_f32( slow_extF80M_to_f32, extF80M_to_f32 );
593         break;
594 #ifdef FLOAT64
595      case EXTF80_TO_F64:
596         test_a_extF80_z_f64( slow_extF80M_to_f64, extF80M_to_f64 );
597         break;
598 #endif
599 #ifdef FLOAT128
600      case EXTF80_TO_F128:
601         test_a_extF80_z_f128( slow_extF80M_to_f128M, extF80M_to_f128M );
602         break;
603 #endif
604      case EXTF80_ROUNDTOINT:
605         test_az_extF80_rx(
606             slow_extF80M_roundToInt, extF80M_roundToInt, roundingMode, exact );
607         break;
608      case EXTF80_ADD:
609         trueFunction_abz_extF80M = slow_extF80M_add;
610         subjFunction_abz_extF80M = extF80M_add;
611         goto test_abz_extF80;
612      case EXTF80_SUB:
613         trueFunction_abz_extF80M = slow_extF80M_sub;
614         subjFunction_abz_extF80M = extF80M_sub;
615         goto test_abz_extF80;
616      case EXTF80_MUL:
617         trueFunction_abz_extF80M = slow_extF80M_mul;
618         subjFunction_abz_extF80M = extF80M_mul;
619         goto test_abz_extF80;
620      case EXTF80_DIV:
621         trueFunction_abz_extF80M = slow_extF80M_div;
622         subjFunction_abz_extF80M = extF80M_div;
623         goto test_abz_extF80;
624      case EXTF80_REM:
625         trueFunction_abz_extF80M = slow_extF80M_rem;
626         subjFunction_abz_extF80M = extF80M_rem;
627      test_abz_extF80:
628         test_abz_extF80( trueFunction_abz_extF80M, subjFunction_abz_extF80M );
629         break;
630      case EXTF80_SQRT:
631         test_az_extF80( slow_extF80M_sqrt, extF80M_sqrt );
632         break;
633      case EXTF80_EQ:
634         trueFunction_ab_extF80M_z_bool = slow_extF80M_eq;
635         subjFunction_ab_extF80M_z_bool = extF80M_eq;
636         goto test_ab_extF80_z_bool;
637      case EXTF80_LE:
638         trueFunction_ab_extF80M_z_bool = slow_extF80M_le;
639         subjFunction_ab_extF80M_z_bool = extF80M_le;
640         goto test_ab_extF80_z_bool;
641      case EXTF80_LT:
642         trueFunction_ab_extF80M_z_bool = slow_extF80M_lt;
643         subjFunction_ab_extF80M_z_bool = extF80M_lt;
644         goto test_ab_extF80_z_bool;
645      case EXTF80_EQ_SIGNALING:
646         trueFunction_ab_extF80M_z_bool = slow_extF80M_eq_signaling;
647         subjFunction_ab_extF80M_z_bool = extF80M_eq_signaling;
648         goto test_ab_extF80_z_bool;
649      case EXTF80_LE_QUIET:
650         trueFunction_ab_extF80M_z_bool = slow_extF80M_le_quiet;
651         subjFunction_ab_extF80M_z_bool = extF80M_le_quiet;
652         goto test_ab_extF80_z_bool;
653      case EXTF80_LT_QUIET:
654         trueFunction_ab_extF80M_z_bool = slow_extF80M_lt_quiet;
655         subjFunction_ab_extF80M_z_bool = extF80M_lt_quiet;
656      test_ab_extF80_z_bool:
657         test_ab_extF80_z_bool(
658             trueFunction_ab_extF80M_z_bool, subjFunction_ab_extF80M_z_bool );
659         break;
660 #endif
661         /*--------------------------------------------------------------------
662         *--------------------------------------------------------------------*/
663 #ifdef FLOAT128
664      case F128_TO_UI32:
665         test_a_f128_z_ui32_rx(
666             slow_f128M_to_ui32, f128M_to_ui32, roundingMode, exact );
667         break;
668      case F128_TO_UI64:
669         test_a_f128_z_ui64_rx(
670             slow_f128M_to_ui64, f128M_to_ui64, roundingMode, exact );
671         break;
672      case F128_TO_I32:
673         test_a_f128_z_i32_rx(
674             slow_f128M_to_i32, f128M_to_i32, roundingMode, exact );
675         break;
676      case F128_TO_I64:
677         test_a_f128_z_i64_rx(
678             slow_f128M_to_i64, f128M_to_i64, roundingMode, exact );
679         break;
680      case F128_TO_UI32_R_MINMAG:
681         test_a_f128_z_ui32_x(
682             slow_f128M_to_ui32_r_minMag, f128M_to_ui32_r_minMag, exact );
683         break;
684      case F128_TO_UI64_R_MINMAG:
685         test_a_f128_z_ui64_x(
686             slow_f128M_to_ui64_r_minMag, f128M_to_ui64_r_minMag, exact );
687         break;
688      case F128_TO_I32_R_MINMAG:
689         test_a_f128_z_i32_x(
690             slow_f128M_to_i32_r_minMag, f128M_to_i32_r_minMag, exact );
691         break;
692      case F128_TO_I64_R_MINMAG:
693         test_a_f128_z_i64_x(
694             slow_f128M_to_i64_r_minMag, f128M_to_i64_r_minMag, exact );
695         break;
696 #ifdef FLOAT16
697      case F128_TO_F16:
698         test_a_f128_z_f16( slow_f128M_to_f16, f128M_to_f16 );
699         break;
700 #endif
701      case F128_TO_F32:
702         test_a_f128_z_f32( slow_f128M_to_f32, f128M_to_f32 );
703         break;
704 #ifdef FLOAT64
705      case F128_TO_F64:
706         test_a_f128_z_f64( slow_f128M_to_f64, f128M_to_f64 );
707         break;
708 #endif
709 #ifdef EXTFLOAT80
710      case F128_TO_EXTF80:
711         test_a_f128_z_extF80( slow_f128M_to_extF80M, f128M_to_extF80M );
712         break;
713 #endif
714      case F128_ROUNDTOINT:
715         test_az_f128_rx(
716             slow_f128M_roundToInt, f128M_roundToInt, roundingMode, exact );
717         break;
718      case F128_ADD:
719         trueFunction_abz_f128M = slow_f128M_add;
720         subjFunction_abz_f128M = f128M_add;
721         goto test_abz_f128;
722      case F128_SUB:
723         trueFunction_abz_f128M = slow_f128M_sub;
724         subjFunction_abz_f128M = f128M_sub;
725         goto test_abz_f128;
726      case F128_MUL:
727         trueFunction_abz_f128M = slow_f128M_mul;
728         subjFunction_abz_f128M = f128M_mul;
729         goto test_abz_f128;
730      case F128_DIV:
731         trueFunction_abz_f128M = slow_f128M_div;
732         subjFunction_abz_f128M = f128M_div;
733         goto test_abz_f128;
734      case F128_REM:
735         trueFunction_abz_f128M = slow_f128M_rem;
736         subjFunction_abz_f128M = f128M_rem;
737      test_abz_f128:
738         test_abz_f128( trueFunction_abz_f128M, subjFunction_abz_f128M );
739         break;
740      case F128_MULADD:
741         test_abcz_f128( slow_f128M_mulAdd, f128M_mulAdd );
742         break;
743      case F128_SQRT:
744         test_az_f128( slow_f128M_sqrt, f128M_sqrt );
745         break;
746      case F128_EQ:
747         trueFunction_ab_f128M_z_bool = slow_f128M_eq;
748         subjFunction_ab_f128M_z_bool = f128M_eq;
749         goto test_ab_f128_z_bool;
750      case F128_LE:
751         trueFunction_ab_f128M_z_bool = slow_f128M_le;
752         subjFunction_ab_f128M_z_bool = f128M_le;
753         goto test_ab_f128_z_bool;
754      case F128_LT:
755         trueFunction_ab_f128M_z_bool = slow_f128M_lt;
756         subjFunction_ab_f128M_z_bool = f128M_lt;
757         goto test_ab_f128_z_bool;
758      case F128_EQ_SIGNALING:
759         trueFunction_ab_f128M_z_bool = slow_f128M_eq_signaling;
760         subjFunction_ab_f128M_z_bool = f128M_eq_signaling;
761         goto test_ab_f128_z_bool;
762      case F128_LE_QUIET:
763         trueFunction_ab_f128M_z_bool = slow_f128M_le_quiet;
764         subjFunction_ab_f128M_z_bool = f128M_le_quiet;
765         goto test_ab_f128_z_bool;
766      case F128_LT_QUIET:
767         trueFunction_ab_f128M_z_bool = slow_f128M_lt_quiet;
768         subjFunction_ab_f128M_z_bool = f128M_lt_quiet;
769      test_ab_f128_z_bool:
770         test_ab_f128_z_bool(
771             trueFunction_ab_f128M_z_bool, subjFunction_ab_f128M_z_bool );
772         break;
773 #endif
774     }
775     if ( (verCases_errorStop && verCases_anyErrors) || verCases_stop ) {
776         verCases_exitWithStatus();
777     }
778 
779 }
780 
781 enum { EXACT_FALSE = 1, EXACT_TRUE };
782 
783 static
784 void
testFunction(int functionCode,uint_fast8_t roundingPrecisionIn,int roundingCodeIn,int tininessCodeIn,int exactCodeIn)785  testFunction(
786      int functionCode,
787      uint_fast8_t roundingPrecisionIn,
788      int roundingCodeIn,
789      int tininessCodeIn,
790      int exactCodeIn
791  )
792 {
793     int functionAttribs;
794     uint_fast8_t roundingPrecision;
795     int roundingCode;
796     uint_fast8_t roundingMode;
797     int exactCode;
798     bool exact;
799     int tininessCode;
800     uint_fast8_t tininessMode;
801 
802     functionAttribs = functionInfos[functionCode].attribs;
803     verCases_functionNamePtr = functionInfos[functionCode].namePtr;
804     roundingPrecision = 32;
805     for (;;) {
806         if ( functionAttribs & FUNC_EFF_ROUNDINGPRECISION ) {
807             if ( roundingPrecisionIn ) roundingPrecision = roundingPrecisionIn;
808         } else {
809             roundingPrecision = 0;
810         }
811 #ifdef EXTFLOAT80
812         verCases_roundingPrecision = roundingPrecision;
813         if ( roundingPrecision ) {
814             slow_extF80_roundingPrecision = roundingPrecision;
815             extF80_roundingPrecision = roundingPrecision;
816         }
817 #endif
818         for (
819             roundingCode = 1; roundingCode < NUM_ROUNDINGMODES; ++roundingCode
820         ) {
821             if (
822                 functionAttribs
823                     & (FUNC_ARG_ROUNDINGMODE | FUNC_EFF_ROUNDINGMODE)
824             ) {
825                 if ( roundingCodeIn ) roundingCode = roundingCodeIn;
826             } else {
827                 roundingCode = 0;
828             }
829             verCases_roundingCode = roundingCode;
830             if ( roundingCode ) {
831                 roundingMode = roundingModes[roundingCode];
832                 if ( functionAttribs & FUNC_EFF_ROUNDINGMODE ) {
833                     slowfloat_roundingMode = roundingMode;
834                     softfloat_roundingMode = roundingMode;
835                 }
836             }
837             for (
838                 exactCode = EXACT_FALSE; exactCode <= EXACT_TRUE; ++exactCode
839             ) {
840                 if ( functionAttribs & FUNC_ARG_EXACT ) {
841                     if ( exactCodeIn ) exactCode = exactCodeIn;
842                 } else {
843                     exactCode = 0;
844                 }
845                 exact = (exactCode == EXACT_TRUE);
846                 verCases_usesExact = (exactCode != 0);
847                 verCases_exact = exact;
848                 for (
849                     tininessCode = 1;
850                     tininessCode < NUM_TININESSMODES;
851                     ++tininessCode
852                 ) {
853                     if (
854                         (functionAttribs & FUNC_EFF_TININESSMODE)
855                             || ((functionAttribs
856                                      & FUNC_EFF_TININESSMODE_REDUCEDPREC)
857                                     && roundingPrecision
858                                     && (roundingPrecision < 80))
859                     ) {
860                         if ( tininessCodeIn ) tininessCode = tininessCodeIn;
861                     } else {
862                         tininessCode = 0;
863                     }
864                     verCases_tininessCode = tininessCode;
865                     if ( tininessCode ) {
866                         tininessMode = tininessModes[tininessCode];
867                         slowfloat_detectTininess = tininessMode;
868                         softfloat_detectTininess = tininessMode;
869                     }
870                     testFunctionInstance( functionCode, roundingMode, exact );
871                     if ( tininessCodeIn || ! tininessCode ) break;
872                 }
873                 if ( exactCodeIn || ! exactCode ) break;
874             }
875             if ( roundingCodeIn || ! roundingCode ) break;
876         }
877         if ( roundingPrecisionIn || ! roundingPrecision ) break;
878         if ( roundingPrecision == 80 ) {
879             break;
880         } else if ( roundingPrecision == 64 ) {
881             roundingPrecision = 80;
882         } else if ( roundingPrecision == 32 ) {
883             roundingPrecision = 64;
884         }
885     }
886 
887 }
888 
clearExceptionFlags(void)889 static uint_fast8_t clearExceptionFlags( void )
890 {
891     uint_fast8_t prevFlags;
892 
893     prevFlags = slowfloat_exceptionFlags;
894     slowfloat_exceptionFlags = 0;
895     return prevFlags;
896 }
897 
main(int argc,char * argv[])898 int main( int argc, char *argv[] )
899 {
900     bool haveFunctionArg;
901     int functionCode, numOperands;
902     uint_fast8_t roundingPrecision;
903     int roundingCode, tininessCode, exactCode;
904     const char *argPtr;
905     unsigned long ui;
906     long i;
907     int functionMatchAttrib;
908 
909     /*------------------------------------------------------------------------
910     *------------------------------------------------------------------------*/
911     fail_programName = "testsoftfloat";
912     if ( argc <= 1 ) goto writeHelpMessage;
913     genCases_setLevel( 1 );
914     verCases_maxErrorCount = 20;
915     testLoops_trueFlagsFunction = clearExceptionFlags;
916     testLoops_subjFlagsFunction = softfloat_clearExceptionFlags;
917     haveFunctionArg = false;
918     functionCode = 0;
919     numOperands = 0;
920     roundingPrecision = 0;
921     roundingCode = 0;
922     tininessCode = 0;
923     exactCode = 0;
924     for (;;) {
925         --argc;
926         if ( ! argc ) break;
927         argPtr = *++argv;
928         if ( ! argPtr ) break;
929         if ( argPtr[0] == '-' ) ++argPtr;
930         if (
931             ! strcmp( argPtr, "help" ) || ! strcmp( argPtr, "-help" )
932                 || ! strcmp( argPtr, "h" )
933         ) {
934  writeHelpMessage:
935             fputs(
936 "testsoftfloat [<option>...] <function>\n"
937 "  <option>:  (* is default)\n"
938 "    -help            --Write this message and exit.\n"
939 "    -seed <num>      --Set pseudo-random number generator seed to <num>.\n"
940 " *  -seed 1\n"
941 "    -level <num>     --Testing level <num> (1 or 2).\n"
942 " *  -level 1\n"
943 "    -errors <num>    --Stop each function test after <num> errors.\n"
944 " *  -errors 20\n"
945 "    -errorstop       --Exit after first function with any error.\n"
946 "    -forever         --Test one function repeatedly (implies '-level 2').\n"
947 #ifdef EXTFLOAT80
948 "    -precision32     --For extF80, test only 32-bit rounding precision.\n"
949 "    -precision64     --For extF80, test only 64-bit rounding precision.\n"
950 "    -precision80     --For extF80, test only 80-bit rounding precision.\n"
951 #endif
952 "    -rnear_even      --Test only rounding to nearest/even.\n"
953 "    -rminMag         --Test only rounding to minimum magnitude (toward zero).\n"
954 "    -rmin            --Test only rounding to minimum (down).\n"
955 "    -rmax            --Test only rounding to maximum (up).\n"
956 "    -rnear_maxMag    --Test only rounding to nearest/maximum magnitude\n"
957 "                         (nearest/away).\n"
958 #ifdef FLOAT_ROUND_ODD
959 "    -rodd            --Test only rounding to odd (jamming).  (For rounding to\n"
960 "                         an integer value, 'minMag' rounding is done instead.)\n"
961 #endif
962 "    -tininessbefore  --Test only underflow tininess detected before rounding.\n"
963 "    -tininessafter   --Test only underflow tininess detected after rounding.\n"
964 "    -notexact        --Test only non-exact rounding to integer (no inexact\n"
965 "                         exceptions).\n"
966 "    -exact           --Test only exact rounding to integer (raising inexact\n"
967 "                         exceptions).\n"
968 "  <function>:\n"
969 "    <int>_to_<float>            <float>_add      <float>_eq\n"
970 "    <float>_to_<int>            <float>_sub      <float>_le\n"
971 "    <float>_to_<int>_r_minMag   <float>_mul      <float>_lt\n"
972 "    <float>_to_<float>          <float>_mulAdd   <float>_eq_signaling\n"
973 "    <float>_roundToInt          <float>_div      <float>_le_quiet\n"
974 "                                <float>_rem      <float>_lt_quiet\n"
975 "                                <float>_sqrt\n"
976 "    -all1            --All unary functions.\n"
977 "    -all2            --All binary functions.\n"
978 "  <int>:\n"
979 "    ui32             --Unsigned 32-bit integer.\n"
980 "    ui64             --Unsigned 64-bit integer.\n"
981 "    i32              --Signed 32-bit integer.\n"
982 "    i64              --Signed 64-bit integer.\n"
983 "  <float>:\n"
984 #ifdef FLOAT16
985 "    f16              --Binary 16-bit floating-point (half-precision).\n"
986 #endif
987 "    f32              --Binary 32-bit floating-point (single-precision).\n"
988 #ifdef FLOAT64
989 "    f64              --Binary 64-bit floating-point (double-precision).\n"
990 #endif
991 #ifdef EXTFLOAT80
992 "    extF80           --Binary 80-bit extended floating-point.\n"
993 #endif
994 #ifdef FLOAT128
995 "    f128             --Binary 128-bit floating-point (quadruple-precision).\n"
996 #endif
997                 ,
998                 stdout
999             );
1000             return EXIT_SUCCESS;
1001         } else if ( ! strcmp( argPtr, "seed" ) ) {
1002             if ( argc < 2 ) goto optionError;
1003             ui = strtoul( argv[1], (char **) &argPtr, 10 );
1004             if ( *argPtr ) goto optionError;
1005             srand( ui );
1006             --argc;
1007             ++argv;
1008         } else if ( ! strcmp( argPtr, "level" ) ) {
1009             if ( argc < 2 ) goto optionError;
1010             i = strtol( argv[1], (char **) &argPtr, 10 );
1011             if ( *argPtr ) goto optionError;
1012             genCases_setLevel( i );
1013             --argc;
1014             ++argv;
1015         } else if ( ! strcmp( argPtr, "level1" ) ) {
1016             genCases_setLevel( 1 );
1017         } else if ( ! strcmp( argPtr, "level2" ) ) {
1018             genCases_setLevel( 2 );
1019         } else if ( ! strcmp( argPtr, "errors" ) ) {
1020             if ( argc < 2 ) goto optionError;
1021             i = strtol( argv[1], (char **) &argPtr, 10 );
1022             if ( *argPtr ) goto optionError;
1023             verCases_maxErrorCount = i;
1024             --argc;
1025             ++argv;
1026         } else if ( ! strcmp( argPtr, "errorstop" ) ) {
1027             verCases_errorStop = true;
1028         } else if ( ! strcmp( argPtr, "forever" ) ) {
1029             genCases_setLevel( 2 );
1030             testLoops_forever = true;
1031 #ifdef EXTFLOAT80
1032         } else if ( ! strcmp( argPtr, "precision32" ) ) {
1033             roundingPrecision = 32;
1034         } else if ( ! strcmp( argPtr, "precision64" ) ) {
1035             roundingPrecision = 64;
1036         } else if ( ! strcmp( argPtr, "precision80" ) ) {
1037             roundingPrecision = 80;
1038 #endif
1039         } else if (
1040                ! strcmp( argPtr, "rnear_even" )
1041             || ! strcmp( argPtr, "rneareven" )
1042             || ! strcmp( argPtr, "rnearest_even" )
1043         ) {
1044             roundingCode = ROUND_NEAR_EVEN;
1045         } else if (
1046             ! strcmp( argPtr, "rminmag" ) || ! strcmp( argPtr, "rminMag" )
1047         ) {
1048             roundingCode = ROUND_MINMAG;
1049         } else if ( ! strcmp( argPtr, "rmin" ) ) {
1050             roundingCode = ROUND_MIN;
1051         } else if ( ! strcmp( argPtr, "rmax" ) ) {
1052             roundingCode = ROUND_MAX;
1053         } else if (
1054                ! strcmp( argPtr, "rnear_maxmag" )
1055             || ! strcmp( argPtr, "rnear_maxMag" )
1056             || ! strcmp( argPtr, "rnearmaxmag" )
1057             || ! strcmp( argPtr, "rnearest_maxmag" )
1058             || ! strcmp( argPtr, "rnearest_maxMag" )
1059         ) {
1060             roundingCode = ROUND_NEAR_MAXMAG;
1061 #ifdef FLOAT_ROUND_ODD
1062         } else if ( ! strcmp( argPtr, "rodd" ) ) {
1063             roundingCode = ROUND_ODD;
1064 #endif
1065         } else if ( ! strcmp( argPtr, "tininessbefore" ) ) {
1066             tininessCode = TININESS_BEFORE_ROUNDING;
1067         } else if ( ! strcmp( argPtr, "tininessafter" ) ) {
1068             tininessCode = TININESS_AFTER_ROUNDING;
1069         } else if ( ! strcmp( argPtr, "notexact" ) ) {
1070             exactCode = EXACT_FALSE;
1071         } else if ( ! strcmp( argPtr, "exact" ) ) {
1072             exactCode = EXACT_TRUE;
1073         } else if ( ! strcmp( argPtr, "all1" ) ) {
1074             haveFunctionArg = true;
1075             functionCode = 0;
1076             numOperands = 1;
1077         } else if ( ! strcmp( argPtr, "all2" ) ) {
1078             haveFunctionArg = true;
1079             functionCode = 0;
1080             numOperands = 2;
1081         } else {
1082             functionCode = 1;
1083             while ( strcmp( argPtr, functionInfos[functionCode].namePtr ) ) {
1084                 ++functionCode;
1085                 if ( functionCode == NUM_FUNCTIONS ) {
1086                     fail( "Invalid argument '%s'", *argv );
1087                 }
1088             }
1089             haveFunctionArg = true;
1090         }
1091     }
1092     if ( ! haveFunctionArg ) fail( "Function argument required" );
1093     /*------------------------------------------------------------------------
1094     *------------------------------------------------------------------------*/
1095     signal( SIGINT, catchSIGINT );
1096     signal( SIGTERM, catchSIGINT );
1097     if ( functionCode ) {
1098         if ( testLoops_forever ) {
1099             if ( ! roundingPrecision ) roundingPrecision = 80;
1100             if ( ! roundingCode ) roundingCode = ROUND_NEAR_EVEN;
1101         }
1102         testFunction(
1103             functionCode,
1104             roundingPrecision,
1105             roundingCode,
1106             tininessCode,
1107             exactCode
1108         );
1109     } else {
1110         if ( testLoops_forever ) {
1111              fail( "Can test only one function with '-forever' option" );
1112         }
1113         functionMatchAttrib =
1114             (numOperands == 1) ? FUNC_ARG_UNARY : FUNC_ARG_BINARY;
1115         for (
1116             functionCode = 1; functionCode < NUM_FUNCTIONS; ++functionCode
1117         ) {
1118             if ( functionInfos[functionCode].attribs & functionMatchAttrib ) {
1119                 testFunction(
1120                     functionCode,
1121                     roundingPrecision,
1122                     roundingCode,
1123                     tininessCode,
1124                     exactCode
1125                 );
1126             }
1127         }
1128     }
1129     verCases_exitWithStatus();
1130     /*------------------------------------------------------------------------
1131     *------------------------------------------------------------------------*/
1132  optionError:
1133     fail( "'%s' option requires numeric argument", *argv );
1134 
1135 }
1136 
1137