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

Subversion Repositories fpu100

[/] [fpu100/] [tags/] [arelease/] [test_bench/] [SoftFloat/] [softfloat/] [bits32/] [templates/] [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
void float_raise( int8 flags )
47
{
48
 
49
    float_exception_flags |= flags;
50
 
51
}
52
 
53
/*----------------------------------------------------------------------------
54
| Internal canonical NaN format.
55
*----------------------------------------------------------------------------*/
56
typedef struct {
57
    flag sign;
58
    bits32 high, low;
59
} commonNaNT;
60
 
61
/*----------------------------------------------------------------------------
62
| The pattern for a default generated single-precision NaN.
63
*----------------------------------------------------------------------------*/
64
enum {
65
    float32_default_nan = 0xFFFFFFFF
66
};
67
 
68
/*----------------------------------------------------------------------------
69
| Returns 1 if the single-precision floating-point value `a' is a NaN;
70
| otherwise returns 0.
71
*----------------------------------------------------------------------------*/
72
 
73
flag float32_is_nan( float32 a )
74
{
75
 
76
    return ( 0xFF000000 < (bits32) ( a<<1 ) );
77
 
78
}
79
 
80
/*----------------------------------------------------------------------------
81
| Returns 1 if the single-precision floating-point value `a' is a signaling
82
| NaN; otherwise returns 0.
83
*----------------------------------------------------------------------------*/
84
 
85
flag float32_is_signaling_nan( float32 a )
86
{
87
 
88
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
89
 
90
}
91
 
92
/*----------------------------------------------------------------------------
93
| Returns the result of converting the single-precision floating-point NaN
94
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
95
| exception is raised.
96
*----------------------------------------------------------------------------*/
97
 
98
static commonNaNT float32ToCommonNaN( float32 a )
99
{
100
    commonNaNT z;
101
 
102
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
103
    z.sign = a>>31;
104
    z.low = 0;
105
    z.high = a<<9;
106
    return z;
107
 
108
}
109
 
110
/*----------------------------------------------------------------------------
111
| Returns the result of converting the canonical NaN `a' to the single-
112
| precision floating-point format.
113
*----------------------------------------------------------------------------*/
114
 
115
static float32 commonNaNToFloat32( commonNaNT a )
116
{
117
 
118
    return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>9 );
119
 
120
}
121
 
122
/*----------------------------------------------------------------------------
123
| Takes two single-precision floating-point values `a' and `b', one of which
124
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
125
| signaling NaN, the invalid exception is raised.
126
*----------------------------------------------------------------------------*/
127
 
128
static float32 propagateFloat32NaN( float32 a, float32 b )
129
{
130
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
131
 
132
    aIsNaN = float32_is_nan( a );
133
    aIsSignalingNaN = float32_is_signaling_nan( a );
134
    bIsNaN = float32_is_nan( b );
135
    bIsSignalingNaN = float32_is_signaling_nan( b );
136
    a |= 0x00400000;
137
    b |= 0x00400000;
138
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
139
    if ( aIsNaN ) {
140
        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
141
    }
142
    else {
143
        return b;
144
    }
145
 
146
}
147
 
148
/*----------------------------------------------------------------------------
149
| The pattern for a default generated double-precision NaN.  The `high' and
150
| `low' values hold the most- and least-significant bits, respectively.
151
*----------------------------------------------------------------------------*/
152
enum {
153
    float64_default_nan_high = 0xFFFFFFFF,
154
    float64_default_nan_low  = 0xFFFFFFFF
155
};
156
 
157
/*----------------------------------------------------------------------------
158
| Returns 1 if the double-precision floating-point value `a' is a NaN;
159
| otherwise returns 0.
160
*----------------------------------------------------------------------------*/
161
 
162
flag float64_is_nan( float64 a )
163
{
164
 
165
    return
166
           ( 0xFFE00000 <= (bits32) ( a.high<<1 ) )
167
        && ( a.low || ( a.high & 0x000FFFFF ) );
168
 
169
}
170
 
171
/*----------------------------------------------------------------------------
172
| Returns 1 if the double-precision floating-point value `a' is a signaling
173
| NaN; otherwise returns 0.
174
*----------------------------------------------------------------------------*/
175
 
176
flag float64_is_signaling_nan( float64 a )
177
{
178
 
179
    return
180
           ( ( ( a.high>>19 ) & 0xFFF ) == 0xFFE )
181
        && ( a.low || ( a.high & 0x0007FFFF ) );
182
 
183
}
184
 
185
/*----------------------------------------------------------------------------
186
| Returns the result of converting the double-precision floating-point NaN
187
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
188
| exception is raised.
189
*----------------------------------------------------------------------------*/
190
 
191
static commonNaNT float64ToCommonNaN( float64 a )
192
{
193
    commonNaNT z;
194
 
195
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
196
    z.sign = a.high>>31;
197
    shortShift64Left( a.high, a.low, 12, &z.high, &z.low );
198
    return z;
199
 
200
}
201
 
202
/*----------------------------------------------------------------------------
203
| Returns the result of converting the canonical NaN `a' to the double-
204
| precision floating-point format.
205
*----------------------------------------------------------------------------*/
206
 
207
static float64 commonNaNToFloat64( commonNaNT a )
208
{
209
    float64 z;
210
 
211
    shift64Right( a.high, a.low, 12, &z.high, &z.low );
212
    z.high |= ( ( (bits32) a.sign )<<31 ) | 0x7FF80000;
213
    return z;
214
 
215
}
216
 
217
/*----------------------------------------------------------------------------
218
| Takes two double-precision floating-point values `a' and `b', one of which
219
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
220
| signaling NaN, the invalid exception is raised.
221
*----------------------------------------------------------------------------*/
222
 
223
static float64 propagateFloat64NaN( float64 a, float64 b )
224
{
225
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
226
 
227
    aIsNaN = float64_is_nan( a );
228
    aIsSignalingNaN = float64_is_signaling_nan( a );
229
    bIsNaN = float64_is_nan( b );
230
    bIsSignalingNaN = float64_is_signaling_nan( b );
231
    a.high |= 0x00080000;
232
    b.high |= 0x00080000;
233
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
234
    if ( aIsNaN ) {
235
        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
236
    }
237
    else {
238
        return b;
239
    }
240
 
241
}
242
 

powered by: WebSVN 2.1.0

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