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

Subversion Repositories fpu100

[/] [fpu100/] [tags/] [arelease/] [test_bench/] [SoftFloat/] [softfloat/] [bits32/] [SPARC-Solaris-GCC/] [softfloat-specialize] - Blame information for rev 21

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_before_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 = 0x7FFFFFFF
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
    return bIsSignalingNaN ? b : aIsSignalingNaN ? a : bIsNaN ? b : a;
140
 
141
}
142
 
143
/*----------------------------------------------------------------------------
144
| The pattern for a default generated double-precision NaN.  The `high' and
145
| `low' values hold the most- and least-significant bits, respectively.
146
*----------------------------------------------------------------------------*/
147
enum {
148
    float64_default_nan_high = 0x7FFFFFFF,
149
    float64_default_nan_low  = 0xFFFFFFFF
150
};
151
 
152
/*----------------------------------------------------------------------------
153
| Returns 1 if the double-precision floating-point value `a' is a NaN;
154
| otherwise returns 0.
155
*----------------------------------------------------------------------------*/
156
 
157
flag float64_is_nan( float64 a )
158
{
159
 
160
    return
161
           ( 0xFFE00000 <= (bits32) ( a.high<<1 ) )
162
        && ( a.low || ( a.high & 0x000FFFFF ) );
163
 
164
}
165
 
166
/*----------------------------------------------------------------------------
167
| Returns 1 if the double-precision floating-point value `a' is a signaling
168
| NaN; otherwise returns 0.
169
*----------------------------------------------------------------------------*/
170
 
171
flag float64_is_signaling_nan( float64 a )
172
{
173
 
174
    return
175
           ( ( ( a.high>>19 ) & 0xFFF ) == 0xFFE )
176
        && ( a.low || ( a.high & 0x0007FFFF ) );
177
 
178
}
179
 
180
/*----------------------------------------------------------------------------
181
| Returns the result of converting the double-precision floating-point NaN
182
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
183
| exception is raised.
184
*----------------------------------------------------------------------------*/
185
 
186
static commonNaNT float64ToCommonNaN( float64 a )
187
{
188
    commonNaNT z;
189
 
190
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
191
    z.sign = a.high>>31;
192
    shortShift64Left( a.high, a.low, 12, &z.high, &z.low );
193
    return z;
194
 
195
}
196
 
197
/*----------------------------------------------------------------------------
198
| Returns the result of converting the canonical NaN `a' to the double-
199
| precision floating-point format.
200
*----------------------------------------------------------------------------*/
201
 
202
static float64 commonNaNToFloat64( commonNaNT a )
203
{
204
    float64 z;
205
 
206
    shift64Right( a.high, a.low, 12, &z.high, &z.low );
207
    z.high |= ( ( (bits32) a.sign )<<31 ) | 0x7FF80000;
208
    return z;
209
 
210
}
211
 
212
/*----------------------------------------------------------------------------
213
| Takes two double-precision floating-point values `a' and `b', one of which
214
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
215
| signaling NaN, the invalid exception is raised.
216
*----------------------------------------------------------------------------*/
217
 
218
static float64 propagateFloat64NaN( float64 a, float64 b )
219
{
220
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
221
 
222
    aIsNaN = float64_is_nan( a );
223
    aIsSignalingNaN = float64_is_signaling_nan( a );
224
    bIsNaN = float64_is_nan( b );
225
    bIsSignalingNaN = float64_is_signaling_nan( b );
226
    a.high |= 0x00080000;
227
    b.high |= 0x00080000;
228
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
229
    return bIsSignalingNaN ? b : aIsSignalingNaN ? a : bIsNaN ? b : a;
230
 
231
}
232
 

powered by: WebSVN 2.1.0

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