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

Subversion Repositories fpu100

[/] [fpu100/] [tags/] [arelease/] [test_bench/] [SoftFloat/] [softfloat/] [bits32/] [386-Win32-GCC/] [softfloat-specialize] - Blame information for rev 27

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

Line No. Rev Author Line
1 6 jidan
 
2
/*============================================================================
3
 
4
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5
Arithmetic Package, Release 2b.
6
 
7
Written by John R. Hauser.  This work was made possible in part by the
8
International Computer Science Institute, located at Suite 600, 1947 Center
9
Street, Berkeley, California 94704.  Funding was partially provided by the
10
National Science Foundation under grant MIP-9311980.  The original version
11
of this code was written as part of a project to build a fixed-point vector
12
processor in collaboration with the University of California at Berkeley,
13
overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
14
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
15
arithmetic/SoftFloat.html'.
16
 
17
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
18
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
19
RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
20
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
21
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
22
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
23
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
24
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
25
 
26
Derivative works are acceptable, even for commercial purposes, so long as
27
(1) the source code for the derivative work includes prominent notice that
28
the work is derivative, and (2) the source code includes prominent notice with
29
these four paragraphs for those parts of this code that are retained.
30
 
31
=============================================================================*/
32
 
33
/*----------------------------------------------------------------------------
34
| Underflow tininess-detection mode, statically initialized to default value.
35
| (The declaration in `softfloat.h' must match the `int8' type here.)
36
*----------------------------------------------------------------------------*/
37
int8 float_detect_tininess = float_tininess_after_rounding;
38
 
39
/*----------------------------------------------------------------------------
40
| Raises the exceptions specified by `flags'.  Floating-point traps can be
41
| defined here if desired.  It is currently not possible for such a trap
42
| to substitute a result value.  If traps are not implemented, this routine
43
| should be simply `float_exception_flags |= flags;'.
44
*----------------------------------------------------------------------------*/
45
 
46
// create the exceptions for the FPU core
47
void float_raise( int8 flags )
48
{
49
    //float_exception_flags |= flags;
50
        if (flags == float_flag_inexact) exceptions.ine=1; else
51
        if (flags == float_flag_overflow) exceptions.overflow=1; else
52
        if (flags == float_flag_underflow) exceptions.underflow=1; else
53
        if (flags == float_flag_divbyzero) exceptions.div_zero=1; else
54
        if (flags == float_flag_invalid) exceptions.invalid=1;
55
}
56
 
57
/*----------------------------------------------------------------------------
58
| Internal canonical NaN format.
59
*----------------------------------------------------------------------------*/
60
typedef struct {
61
    flag sign;
62
    bits32 high, low;
63
} commonNaNT;
64
 
65
/*----------------------------------------------------------------------------
66
| The pattern for a default generated single-precision NaN.
67
*----------------------------------------------------------------------------*/
68
enum {
69
    float32_default_nan = 0xFFC00000
70
};
71
 
72
/*----------------------------------------------------------------------------
73
| Returns 1 if the single-precision floating-point value `a' is a NaN;
74
| otherwise returns 0.
75
*----------------------------------------------------------------------------*/
76
 
77
flag float32_is_nan( float32 a )
78
{
79
 
80
    return ( 0xFF000000 < (bits32) ( a<<1 ) );
81
 
82
}
83
 
84
/*----------------------------------------------------------------------------
85
| Returns 1 if the single-precision floating-point value `a' is a signaling
86
| NaN; otherwise returns 0.
87
*----------------------------------------------------------------------------*/
88
 
89
flag float32_is_signaling_nan( float32 a )
90
{
91
 
92
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
93
 
94
}
95
 
96
/*----------------------------------------------------------------------------
97
| Returns the result of converting the single-precision floating-point NaN
98
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
99
| exception is raised.
100
*----------------------------------------------------------------------------*/
101
 
102
static commonNaNT float32ToCommonNaN( float32 a )
103
{
104
    commonNaNT z;
105
 
106
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
107
    z.sign = a>>31;
108
    z.low = 0;
109
    z.high = a<<9;
110
    return z;
111
 
112
}
113
 
114
/*----------------------------------------------------------------------------
115
| Returns the result of converting the canonical NaN `a' to the single-
116
| precision floating-point format.
117
*----------------------------------------------------------------------------*/
118
 
119
static float32 commonNaNToFloat32( commonNaNT a )
120
{
121
 
122
    return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>9 );
123
 
124
}
125
 
126
/*----------------------------------------------------------------------------
127
| Takes two single-precision floating-point values `a' and `b', one of which
128
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
129
| signaling NaN, the invalid exception is raised.
130
*----------------------------------------------------------------------------*/
131
 
132
static float32 propagateFloat32NaN( float32 a, float32 b )
133
{
134
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
135
 
136
    aIsNaN = float32_is_nan( a );
137
    aIsSignalingNaN = float32_is_signaling_nan( a );
138
    bIsNaN = float32_is_nan( b );
139
    bIsSignalingNaN = float32_is_signaling_nan( b );
140
    a |= 0x00400000;
141
    b |= 0x00400000;
142
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
143
    if ( aIsSignalingNaN ) {
144
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
145
        return bIsNaN ? b : a;
146
    }
147
    else if ( aIsNaN ) {
148
        if ( bIsSignalingNaN | ! bIsNaN ) return a;
149
 returnLargerSignificand:
150
        if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
151
        if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
152
        return ( a < b ) ? a : b;
153
    }
154
    else {
155
        return b;
156
    }
157
 
158
}
159
 
160
/*----------------------------------------------------------------------------
161
| The pattern for a default generated double-precision NaN.  The `high' and
162
| `low' values hold the most- and least-significant bits, respectively.
163
*----------------------------------------------------------------------------*/
164
enum {
165
    float64_default_nan_high = 0xFFF80000,
166
    float64_default_nan_low  = 0x00000000
167
};
168
 
169
/*----------------------------------------------------------------------------
170
| Returns 1 if the double-precision floating-point value `a' is a NaN;
171
| otherwise returns 0.
172
*----------------------------------------------------------------------------*/
173
 
174
flag float64_is_nan( float64 a )
175
{
176
 
177
    return
178
           ( 0xFFE00000 <= (bits32) ( a.high<<1 ) )
179
        && ( a.low || ( a.high & 0x000FFFFF ) );
180
 
181
}
182
 
183
/*----------------------------------------------------------------------------
184
| Returns 1 if the double-precision floating-point value `a' is a signaling
185
| NaN; otherwise returns 0.
186
*----------------------------------------------------------------------------*/
187
 
188
flag float64_is_signaling_nan( float64 a )
189
{
190
 
191
    return
192
           ( ( ( a.high>>19 ) & 0xFFF ) == 0xFFE )
193
        && ( a.low || ( a.high & 0x0007FFFF ) );
194
 
195
}
196
 
197
/*----------------------------------------------------------------------------
198
| Returns the result of converting the double-precision floating-point NaN
199
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
200
| exception is raised.
201
*----------------------------------------------------------------------------*/
202
 
203
static commonNaNT float64ToCommonNaN( float64 a )
204
{
205
    commonNaNT z;
206
 
207
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
208
    z.sign = a.high>>31;
209
    shortShift64Left( a.high, a.low, 12, &z.high, &z.low );
210
    return z;
211
 
212
}
213
 
214
/*----------------------------------------------------------------------------
215
| Returns the result of converting the canonical NaN `a' to the double-
216
| precision floating-point format.
217
*----------------------------------------------------------------------------*/
218
 
219
static float64 commonNaNToFloat64( commonNaNT a )
220
{
221
    float64 z;
222
 
223
    shift64Right( a.high, a.low, 12, &z.high, &z.low );
224
    z.high |= ( ( (bits32) a.sign )<<31 ) | 0x7FF80000;
225
    return z;
226
 
227
}
228
 
229
/*----------------------------------------------------------------------------
230
| Takes two double-precision floating-point values `a' and `b', one of which
231
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
232
| signaling NaN, the invalid exception is raised.
233
*----------------------------------------------------------------------------*/
234
 
235
static float64 propagateFloat64NaN( float64 a, float64 b )
236
{
237
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
238
 
239
    aIsNaN = float64_is_nan( a );
240
    aIsSignalingNaN = float64_is_signaling_nan( a );
241
    bIsNaN = float64_is_nan( b );
242
    bIsSignalingNaN = float64_is_signaling_nan( b );
243
    a.high |= 0x00080000;
244
    b.high |= 0x00080000;
245
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
246
    if ( aIsSignalingNaN ) {
247
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
248
        return bIsNaN ? b : a;
249
    }
250
    else if ( aIsNaN ) {
251
        if ( bIsSignalingNaN | ! bIsNaN ) return a;
252
 returnLargerSignificand:
253
        if ( lt64( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
254
        if ( lt64( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
255
        return ( a.high < b.high ) ? a : b;
256
    }
257
    else {
258
        return b;
259
    }
260
 
261
}
262
 

powered by: WebSVN 2.1.0

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