OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [testsuite/] [test-code-or1k/] [testfloat/] [testsoftfloat.c] - Blame information for rev 346

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 234 jeremybenn
 
2
/*
3
===============================================================================
4
 
5
This C source file is part of TestFloat, Release 2a, a package of programs
6
for testing the correctness of floating-point arithmetic complying to the
7
IEC/IEEE Standard for Floating-Point.
8
 
9
Written by John R. Hauser.  More information is available through the Web
10
page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
11
 
12
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
13
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
14
TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
15
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
16
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
17
 
18
Derivative works are acceptable, even for commercial purposes, so long as
19
(1) they include prominent notice that the work is derivative, and (2) they
20
include prominent notice akin to these four paragraphs for those parts of
21
this code that are retained.
22
 
23
Modified for use with or1ksim's testsuite.
24
 
25
Contributor Julius Baxter <julius.baxter@orsoc.se>
26
 
27
===============================================================================
28
*/
29
                                                                 /*
30
#include <stdlib.h>
31
#include <signal.h>
32
#include <string.h>
33
                                                                 */
34
#include "support.h" // OR1k support C library
35
#include "milieu.h"
36
#include "fail.h"
37
#include "softfloat.h"
38
#include "slowfloat.h"
39
#include "testCases.h"
40
#include "testLoops.h"
41
 
42
int8 clearFlags( void )
43
{
44
    int8 flags;
45
 
46
    flags = float_exception_flags;
47
    float_exception_flags = 0;
48
    return flags;
49
 
50
}
51
 
52
enum {
53
    INT32_TO_FLOAT32 = 1,
54
    FLOAT32_TO_INT32,
55
    FLOAT32_TO_INT32_ROUND_TO_ZERO,
56
    FLOAT32_ROUND_TO_INT,
57
    FLOAT32_ADD,
58
    FLOAT32_SUB,
59
    FLOAT32_MUL,
60
    FLOAT32_DIV,
61
    FLOAT32_REM,
62
    //    FLOAT32_SQRT,
63
    FLOAT32_EQ,
64
    FLOAT32_LE,
65
    FLOAT32_LT,
66
    FLOAT32_EQ_SIGNALING,
67
    FLOAT32_LE_QUIET,
68
    FLOAT32_LT_QUIET,
69
    NUM_FUNCTIONS
70
};
71
static struct {
72
    char *name;
73
    int8 numInputs;
74
    flag roundingPrecision, roundingMode;
75
    flag tininessMode, tininessModeAtReducedPrecision;
76
} functions[ NUM_FUNCTIONS ] = {
77
    { 0, 0, 0, 0, 0, 0 },
78
    { "int32_to_float32",                1, FALSE, TRUE,  FALSE, FALSE },
79
    { "float32_to_int32",                1, FALSE, TRUE,  FALSE, FALSE },
80
    { "float32_to_int32_round_to_zero",  1, FALSE, FALSE, FALSE, FALSE },
81
    { "float32_round_to_int",            1, FALSE, TRUE,  FALSE, FALSE },
82
    { "float32_add",                     2, FALSE, TRUE,  FALSE, FALSE },
83
    { "float32_sub",                     2, FALSE, TRUE,  FALSE, FALSE },
84
    { "float32_mul",                     2, FALSE, TRUE,  TRUE,  FALSE },
85
    { "float32_div",                     2, FALSE, TRUE,  FALSE, FALSE },
86
    { "float32_rem",                     2, FALSE, FALSE, FALSE, FALSE },
87
    //{ "float32_sqrt",                    1, FALSE, TRUE,  FALSE, FALSE },
88
    { "float32_eq",                      2, FALSE, FALSE, FALSE, FALSE },
89
    { "float32_le",                      2, FALSE, FALSE, FALSE, FALSE },
90
    { "float32_lt",                      2, FALSE, FALSE, FALSE, FALSE },
91
    { "float32_eq_signaling",            2, FALSE, FALSE, FALSE, FALSE },
92
    { "float32_le_quiet",                2, FALSE, FALSE, FALSE, FALSE },
93
    { "float32_lt_quiet",                2, FALSE, FALSE, FALSE, FALSE }
94
};
95
 
96
enum {
97
    ROUND_NEAREST_EVEN = 1,
98
    ROUND_TO_ZERO,
99
    ROUND_DOWN,
100
    ROUND_UP,
101
    NUM_ROUNDINGMODES
102
};
103
enum {
104
    TININESS_BEFORE_ROUNDING = 1,
105
    TININESS_AFTER_ROUNDING,
106
    NUM_TININESSMODES
107
};
108
 
109
static void
110
 testFunctionVariety(
111
     uint8 functionCode,
112
     int8 roundingPrecision,
113
     int8 roundingMode,
114
     int8 tininessMode
115
 )
116
{
117
    uint8 roundingCode;
118
    int8 tininessCode;
119
 
120
    functionName = functions[ functionCode ].name;
121
    if ( roundingPrecision == 32 ) {
122
        roundingPrecisionName = "32";
123
    }
124
    else {
125
        roundingPrecisionName = 0;
126
    }
127
    switch ( roundingMode ) {
128
     case 0:
129
        roundingModeName = 0;
130
        roundingCode = float_round_nearest_even;
131
        break;
132
     case ROUND_NEAREST_EVEN:
133
        roundingModeName = "nearest_even";
134
        roundingCode = float_round_nearest_even;
135
        break;
136
     case ROUND_TO_ZERO:
137
        roundingModeName = "to_zero";
138
        roundingCode = float_round_to_zero;
139
        break;
140
     case ROUND_DOWN:
141
        roundingModeName = "down";
142
        roundingCode = float_round_down;
143
        break;
144
     case ROUND_UP:
145
        roundingModeName = "up";
146
        roundingCode = float_round_up;
147
        break;
148
    default: // To keep GCC happy
149
        roundingModeName = "nearest_even";
150
        roundingCode = float_round_nearest_even;
151
        break;
152
    }
153
    float_rounding_mode = roundingCode;
154
    slow_float_rounding_mode = roundingCode;
155
    switch ( tininessMode ) {
156
     case 0:
157
        tininessModeName = 0;
158
        tininessCode = float_tininess_after_rounding;
159
        break;
160
     case TININESS_BEFORE_ROUNDING:
161
        tininessModeName = "before";
162
        tininessCode = float_tininess_before_rounding;
163
        break;
164
     case TININESS_AFTER_ROUNDING:
165
        tininessModeName = "after";
166
        tininessCode = float_tininess_after_rounding;
167
        break;
168
    default:
169
      tininessCode = -1; // to keep GCC happy
170
    }
171
    float_detect_tininess = tininessCode;
172
    slow_float_detect_tininess = tininessCode;
173
    printf( "Testing "/*, stderr*/ );
174
    writeFunctionName( /*stderr*/ );
175
    printf( ".\n"/*, stderr*/ );
176
    switch ( functionCode ) {
177
     case INT32_TO_FLOAT32:
178
        test_a_int32_z_float32( slow_int32_to_float32, int32_to_float32 );
179
        break;
180
     case FLOAT32_TO_INT32:
181
        test_a_float32_z_int32( slow_float32_to_int32, float32_to_int32 );
182
        break;
183
     case FLOAT32_TO_INT32_ROUND_TO_ZERO:
184
        test_a_float32_z_int32(
185
            slow_float32_to_int32_round_to_zero,
186
            float32_to_int32_round_to_zero
187
        );
188
        break;
189
     case FLOAT32_ROUND_TO_INT:
190
        test_az_float32( slow_float32_round_to_int, float32_round_to_int );
191
        break;
192
     case FLOAT32_ADD:
193
        test_abz_float32( slow_float32_add, float32_add );
194
        break;
195
     case FLOAT32_SUB:
196
        test_abz_float32( slow_float32_sub, float32_sub );
197
        break;
198
     case FLOAT32_MUL:
199
        test_abz_float32( slow_float32_mul, float32_mul );
200
        break;
201
     case FLOAT32_DIV:
202
        test_abz_float32( slow_float32_div, float32_div );
203
        break;
204
     case FLOAT32_REM:
205
        test_abz_float32( slow_float32_rem, float32_rem );
206
        break;
207
        //     case FLOAT32_SQRT:
208
        //        test_az_float32( slow_float32_sqrt, float32_sqrt );
209
        //        break;
210
     case FLOAT32_EQ:
211
        test_ab_float32_z_flag( slow_float32_eq, float32_eq );
212
        break;
213
     case FLOAT32_LE:
214
        test_ab_float32_z_flag( slow_float32_le, float32_le );
215
        break;
216
     case FLOAT32_LT:
217
        test_ab_float32_z_flag( slow_float32_lt, float32_lt );
218
        break;
219
     case FLOAT32_EQ_SIGNALING:
220
        test_ab_float32_z_flag(
221
            slow_float32_eq_signaling, float32_eq_signaling );
222
        break;
223
     case FLOAT32_LE_QUIET:
224
        test_ab_float32_z_flag( slow_float32_le_quiet, float32_le_quiet );
225
        break;
226
     case FLOAT32_LT_QUIET:
227
        test_ab_float32_z_flag( slow_float32_lt_quiet, float32_lt_quiet );
228
        break;
229
    }
230
    if ( ( errorStop && anyErrors ) || stop ) exitWithStatus();
231
 
232
}
233
 
234
static void
235
 testFunction(
236
     uint8 functionCode,
237
     int8 roundingPrecisionIn,
238
     int8 roundingModeIn,
239
     int8 tininessModeIn
240
 )
241
{
242
    int8 roundingPrecision, roundingMode, tininessMode;
243
 
244
    roundingPrecision = 32;
245
    for (;;) {
246
        if ( ! functions[ functionCode ].roundingPrecision ) {
247
            roundingPrecision = 0;
248
        }
249
        else if ( roundingPrecisionIn ) {
250
            roundingPrecision = roundingPrecisionIn;
251
        }
252
        for ( roundingMode = 1;
253
              roundingMode < NUM_ROUNDINGMODES;
254
              ++roundingMode
255
            ) {
256
            if ( ! functions[ functionCode ].roundingMode ) {
257
                roundingMode = 0;
258
            }
259
            else if ( roundingModeIn ) {
260
                roundingMode = roundingModeIn;
261
            }
262
            for ( tininessMode = 1;
263
                  tininessMode < NUM_TININESSMODES;
264
                  ++tininessMode
265
                ) {
266
                if (    ( roundingPrecision == 32 )
267
                     || ( roundingPrecision == 64 ) ) {
268
                    if ( ! functions[ functionCode ]
269
                               .tininessModeAtReducedPrecision
270
                       ) {
271
                        tininessMode = 0;
272
                    }
273
                    else if ( tininessModeIn ) {
274
                        tininessMode = tininessModeIn;
275
                    }
276
                }
277
                else {
278
                    if ( ! functions[ functionCode ].tininessMode ) {
279
                        tininessMode = 0;
280
                    }
281
                    else if ( tininessModeIn ) {
282
                        tininessMode = tininessModeIn;
283
                    }
284
                }
285
                testFunctionVariety(
286
                    functionCode, roundingPrecision, roundingMode, tininessMode
287
                );
288
                if ( tininessModeIn || ! tininessMode ) break;
289
            }
290
            if ( roundingModeIn || ! roundingMode ) break;
291
        }
292
        if ( roundingPrecisionIn || ! roundingPrecision ) break;
293
        if ( roundingPrecision == 80 ) {
294
            break;
295
        }
296
        else if ( roundingPrecision == 64 ) {
297
            roundingPrecision = 80;
298
        }
299
        else if ( roundingPrecision == 32 ) {
300
            roundingPrecision = 64;
301
        }
302
    }
303
 
304
}
305
 
306
int
307
main( int argc, char **argv )
308
{
309
  //char *argPtr;
310
    flag functionArgument;
311
    uint8 functionCode;
312
    int8 operands, roundingPrecision, roundingMode, tininessMode;
313
    /*
314
    fail_programName = "testsoftfloat";
315
    if ( argc <= 1 ) goto writeHelpMessage;
316
    */
317
    testCases_setLevel( 1 );
318
    trueName = "true";
319
    testName = "soft";
320
    errorStop = FALSE;
321
    forever = FALSE;
322
    maxErrorCount = 5000;
323
    trueFlagsPtr = &slow_float_exception_flags;
324
    testFlagsFunctionPtr = clearFlags;
325
    functionArgument = TRUE;
326
    functionCode = 0;
327
    operands = 0;
328
    roundingPrecision = 0;
329
    roundingMode = 0;
330
    tininessMode = 0;
331
    /*
332
    --argc;
333
    ++argv;
334
    while ( argc && ( argPtr = argv[ 0 ] ) ) {
335
        if ( argPtr[ 0 ] == '-' ) ++argPtr;
336
        if ( strcmp( argPtr, "help" ) == 0 ) {
337
 writeHelpMessage:
338
            fputs(
339
"testsoftfloat [<option>...] <function>\n"
340
"  <option>:  (* is default)\n"
341
"    -help            --Write this message and exit.\n"
342
"    -level <num>     --Testing level <num> (1 or 2).\n"
343
" *  -level 1\n"
344
"    -errors <num>    --Stop each function test after <num> errors.\n"
345
" *  -errors 20\n"
346
"    -errorstop       --Exit after first function with any error.\n"
347
"    -forever         --Test one function repeatedly (implies `-level 2').\n"
348
#ifdef FLOATX80
349
"    -precision32     --Only test rounding precision equivalent to float32.\n"
350
"    -precision64     --Only test rounding precision equivalent to float64.\n"
351
"    -precision80     --Only test maximum rounding precision.\n"
352
#endif
353
"    -nearesteven     --Only test rounding to nearest/even.\n"
354
"    -tozero          --Only test rounding to zero.\n"
355
"    -down            --Only test rounding down.\n"
356
"    -up              --Only test rounding up.\n"
357
"    -tininessbefore  --Only test underflow tininess before rounding.\n"
358
"    -tininessafter   --Only test underflow tininess after rounding.\n"
359
"  <function>:\n"
360
"    int32_to_<float>                 <float>_add   <float>_eq\n"
361
"    <float>_to_int32                 <float>_sub   <float>_le\n"
362
"    <float>_to_int32_round_to_zero   <float>_mul   <float>_lt\n"
363
#ifdef BITS64
364
"    int64_to_<float>                 <float>_div   <float>_eq_signaling\n"
365
"    <float>_to_int64                 <float>_rem   <float>_le_quiet\n"
366
"    <float>_to_int64_round_to_zero                 <float>_lt_quiet\n"
367
"    <float>_to_<float>\n"
368
"    <float>_round_to_int\n"
369
"    <float>_sqrt\n"
370
#else
371
"    <float>_to_<float>               <float>_div   <float>_eq_signaling\n"
372
"    <float>_round_to_int             <float>_rem   <float>_le_quiet\n"
373
"    <float>_sqrt                                   <float>_lt_quiet\n"
374
#endif
375
"    -all1            --All 1-operand functions.\n"
376
"    -all2            --All 2-operand functions.\n"
377
"    -all             --All functions.\n"
378
"  <float>:\n"
379
"    float32          --Single precision.\n"
380
"    float64          --Double precision.\n"
381
#ifdef FLOATX80
382
"    floatx80         --Extended double precision.\n"
383
#endif
384
#ifdef FLOAT128
385
"    float128         --Quadruple precision.\n"
386
#endif
387
                ,
388
                stdout
389
            );
390
            return EXIT_SUCCESS;
391
        }
392
        else if ( strcmp( argPtr, "level" ) == 0 ) {
393
            if ( argc < 2 ) goto optionError;
394
            testCases_setLevel( atoi( argv[ 1 ] ) );
395
            --argc;
396
            ++argv;
397
        }
398
        else if ( strcmp( argPtr, "level1" ) == 0 ) {
399
            testCases_setLevel( 1 );
400
        }
401
        else if ( strcmp( argPtr, "level2" ) == 0 ) {
402
            testCases_setLevel( 2 );
403
        }
404
        else if ( strcmp( argPtr, "errors" ) == 0 ) {
405
            if ( argc < 2 ) {
406
     optionError:
407
                fail( "`%s' option requires numeric argument", argv[ 0 ] );
408
            }
409
            maxErrorCount = atoi( argv[ 1 ] );
410
            --argc;
411
            ++argv;
412
        }
413
        else if ( strcmp( argPtr, "errorstop" ) == 0 ) {
414
            errorStop = TRUE;
415
        }
416
        else if ( strcmp( argPtr, "forever" ) == 0 ) {
417
            testCases_setLevel( 2 );
418
            forever = TRUE;
419
        }
420
#ifdef FLOATX80
421
        else if ( strcmp( argPtr, "precision32" ) == 0 ) {
422
            roundingPrecision = 32;
423
        }
424
        else if ( strcmp( argPtr, "precision64" ) == 0 ) {
425
            roundingPrecision = 64;
426
        }
427
        else if ( strcmp( argPtr, "precision80" ) == 0 ) {
428
            roundingPrecision = 80;
429
        }
430
#endif
431
        else if (    ( strcmp( argPtr, "nearesteven" ) == 0 )
432
                  || ( strcmp( argPtr, "nearest_even" ) == 0 ) ) {
433
            roundingMode = ROUND_NEAREST_EVEN;
434
        }
435
        else if (    ( strcmp( argPtr, "tozero" ) == 0 )
436
                  || ( strcmp( argPtr, "to_zero" ) == 0 ) ) {
437
            roundingMode = ROUND_TO_ZERO;
438
        }
439
        else if ( strcmp( argPtr, "down" ) == 0 ) {
440
            roundingMode = ROUND_DOWN;
441
        }
442
        else if ( strcmp( argPtr, "up" ) == 0 ) {
443
            roundingMode = ROUND_UP;
444
        }
445
        else if ( strcmp( argPtr, "tininessbefore" ) == 0 ) {
446
            tininessMode = TININESS_BEFORE_ROUNDING;
447
        }
448
        else if ( strcmp( argPtr, "tininessafter" ) == 0 ) {
449
            tininessMode = TININESS_AFTER_ROUNDING;
450
        }
451
        else if ( strcmp( argPtr, "all1" ) == 0 ) {
452
            functionArgument = TRUE;
453
            functionCode = 0;
454
            operands = 1;
455
        }
456
        else if ( strcmp( argPtr, "all2" ) == 0 ) {
457
            functionArgument = TRUE;
458
            functionCode = 0;
459
            operands = 2;
460
        }
461
        else if ( strcmp( argPtr, "all" ) == 0 ) {
462
            functionArgument = TRUE;
463
            functionCode = 0;
464
            operands = 0;
465
        }
466
        else {
467
            for ( functionCode = 1;
468
                  functionCode < NUM_FUNCTIONS;
469
                  ++functionCode
470
                ) {
471
                if ( strcmp( argPtr, functions[ functionCode ].name ) == 0 ) {
472
                    break;
473
                }
474
            }
475
            if ( functionCode == NUM_FUNCTIONS ) {
476
                fail( "Invalid option or function `%s'", argv[ 0 ] );
477
            }
478
            functionArgument = TRUE;
479
        }
480
        --argc;
481
        ++argv;
482
    }
483
 
484
    */
485
 
486
    // Test just a single function
487
    if ( functionCode ) {
488
        testFunction(
489
            functionCode, roundingPrecision, roundingMode, tininessMode );
490
    }
491
    else {
492
        if ( operands == 1 ) {
493
            for ( functionCode = 1;
494
                  functionCode < NUM_FUNCTIONS;
495
                  ++functionCode
496
                ) {
497
                if ( functions[ functionCode ].numInputs == 1 ) {
498
                    testFunction(
499
                        functionCode,
500
                        roundingPrecision,
501
                        roundingMode,
502
                        tininessMode
503
                    );
504
                }
505
            }
506
        }
507
        else if ( operands == 2 ) {
508
            for ( functionCode = 1;
509
                  functionCode < NUM_FUNCTIONS;
510
                  ++functionCode
511
                ) {
512
                if ( functions[ functionCode ].numInputs == 2 ) {
513
                    testFunction(
514
                        functionCode,
515
                        roundingPrecision,
516
                        roundingMode,
517
                        tininessMode
518
                    );
519
                }
520
            }
521
        }
522
        else {
523
            for ( functionCode = 1;
524
                  functionCode < NUM_FUNCTIONS;
525
                  ++functionCode
526
                ) {
527
                testFunction(
528
                    functionCode, roundingPrecision, roundingMode, tininessMode
529
                );
530
            }
531
        }
532
    }
533
    exitWithStatus();
534
 
535
    // Shouldn't reach here.
536
    return 1;
537
}
538
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.