~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to target-arm/nwfpe/softfloat-specialize

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno, Aurelien Jarno
  • Date: 2008-08-25 04:38:35 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20080825043835-8e3tftavy8bujdch
Tags: 0.9.1-6
[ Aurelien Jarno ]
* debian/control: 
  - Update list of supported targets (Closes: bug#488339).
* debian/qemu-make-debian-root:
  - Use mktemp instead of $$ to create temporary directories (Closes: 
    bug#496394).
* debian/links:
  - Add missing links to manpages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/*
3
 
===============================================================================
4
 
 
5
 
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
6
 
Arithmetic Package, Release 2.
7
 
 
8
 
Written by John R. Hauser.  This work was made possible in part by the
9
 
International Computer Science Institute, located at Suite 600, 1947 Center
10
 
Street, Berkeley, California 94704.  Funding was partially provided by the
11
 
National Science Foundation under grant MIP-9311980.  The original version
12
 
of this code was written as part of a project to build a fixed-point vector
13
 
processor in collaboration with the University of California at Berkeley,
14
 
overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
15
 
is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
16
 
arithmetic/softfloat.html'.
17
 
 
18
 
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
19
 
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
20
 
TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
21
 
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
22
 
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
23
 
 
24
 
Derivative works are acceptable, even for commercial purposes, so long as
25
 
(1) they include prominent notice that the work is derivative, and (2) they
26
 
include prominent notice akin to these three paragraphs for those parts of
27
 
this code that are retained.
28
 
 
29
 
===============================================================================
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
 
*/
38
 
int8 float_detect_tininess = float_tininess_after_rounding;
39
 
 
40
 
/*
41
 
-------------------------------------------------------------------------------
42
 
Raises the exceptions specified by `flags'.  Floating-point traps can be
43
 
defined here if desired.  It is currently not possible for such a trap to
44
 
substitute a result value.  If traps are not implemented, this routine
45
 
should be simply `float_exception_flags |= flags;'.
46
 
 
47
 
ScottB:  November 4, 1998
48
 
Moved this function out of softfloat-specialize into fpmodule.c.
49
 
This effectively isolates all the changes required for integrating with the
50
 
Linux kernel into fpmodule.c.  Porting to NetBSD should only require modifying
51
 
fpmodule.c to integrate with the NetBSD kernel (I hope!).
52
 
-------------------------------------------------------------------------------
53
 
*/
54
 
void float_raise( int8 flags )
55
 
{
56
 
    float_exception_flags |= flags;
57
 
}
58
 
 
59
 
/*
60
 
-------------------------------------------------------------------------------
61
 
Internal canonical NaN format.
62
 
-------------------------------------------------------------------------------
63
 
*/
64
 
typedef struct {
65
 
    flag sign;
66
 
    bits64 high, low;
67
 
} commonNaNT;
68
 
 
69
 
/*
70
 
-------------------------------------------------------------------------------
71
 
The pattern for a default generated single-precision NaN.
72
 
-------------------------------------------------------------------------------
73
 
*/
74
 
#define float32_default_nan 0xFFFFFFFF
75
 
 
76
 
/*
77
 
-------------------------------------------------------------------------------
78
 
Returns 1 if the single-precision floating-point value `a' is a NaN;
79
 
otherwise returns 0.
80
 
-------------------------------------------------------------------------------
81
 
*/
82
 
flag float32_is_nan( float32 a )
83
 
{
84
 
 
85
 
    return ( 0xFF000000 < (bits32) ( a<<1 ) );
86
 
 
87
 
}
88
 
 
89
 
/*
90
 
-------------------------------------------------------------------------------
91
 
Returns 1 if the single-precision floating-point value `a' is a signaling
92
 
NaN; otherwise returns 0.
93
 
-------------------------------------------------------------------------------
94
 
*/
95
 
flag float32_is_signaling_nan( float32 a )
96
 
{
97
 
 
98
 
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
99
 
 
100
 
}
101
 
 
102
 
/*
103
 
-------------------------------------------------------------------------------
104
 
Returns the result of converting the single-precision floating-point NaN
105
 
`a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
106
 
exception is raised.
107
 
-------------------------------------------------------------------------------
108
 
*/
109
 
static commonNaNT float32ToCommonNaN( float32 a )
110
 
{
111
 
    commonNaNT z;
112
 
 
113
 
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
114
 
    z.sign = a>>31;
115
 
    z.low = 0;
116
 
    z.high = ( (bits64) a )<<41;
117
 
    return z;
118
 
 
119
 
}
120
 
 
121
 
/*
122
 
-------------------------------------------------------------------------------
123
 
Returns the result of converting the canonical NaN `a' to the single-
124
 
precision floating-point format.
125
 
-------------------------------------------------------------------------------
126
 
*/
127
 
static float32 commonNaNToFloat32( commonNaNT a )
128
 
{
129
 
 
130
 
    return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
131
 
 
132
 
}
133
 
 
134
 
/*
135
 
-------------------------------------------------------------------------------
136
 
Takes two single-precision floating-point values `a' and `b', one of which
137
 
is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
138
 
signaling NaN, the invalid exception is raised.
139
 
-------------------------------------------------------------------------------
140
 
*/
141
 
static float32 propagateFloat32NaN( float32 a, float32 b )
142
 
{
143
 
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
144
 
 
145
 
    aIsNaN = float32_is_nan( a );
146
 
    aIsSignalingNaN = float32_is_signaling_nan( a );
147
 
    bIsNaN = float32_is_nan( b );
148
 
    bIsSignalingNaN = float32_is_signaling_nan( b );
149
 
    a |= 0x00400000;
150
 
    b |= 0x00400000;
151
 
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
152
 
    if ( aIsNaN ) {
153
 
        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
154
 
    }
155
 
    else {
156
 
        return b;
157
 
    }
158
 
 
159
 
}
160
 
 
161
 
/*
162
 
-------------------------------------------------------------------------------
163
 
The pattern for a default generated double-precision NaN.
164
 
-------------------------------------------------------------------------------
165
 
*/
166
 
#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
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 ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
178
 
 
179
 
}
180
 
 
181
 
/*
182
 
-------------------------------------------------------------------------------
183
 
Returns 1 if the double-precision floating-point value `a' is a signaling
184
 
NaN; otherwise returns 0.
185
 
-------------------------------------------------------------------------------
186
 
*/
187
 
flag float64_is_signaling_nan( float64 a )
188
 
{
189
 
 
190
 
    return
191
 
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
192
 
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
193
 
 
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>>63;
209
 
    z.low = 0;
210
 
    z.high = a<<12;
211
 
    return z;
212
 
 
213
 
}
214
 
 
215
 
/*
216
 
-------------------------------------------------------------------------------
217
 
Returns the result of converting the canonical NaN `a' to the double-
218
 
precision floating-point format.
219
 
-------------------------------------------------------------------------------
220
 
*/
221
 
static float64 commonNaNToFloat64( commonNaNT a )
222
 
{
223
 
 
224
 
    return
225
 
          ( ( (bits64) a.sign )<<63 )
226
 
        | LIT64( 0x7FF8000000000000 )
227
 
        | ( a.high>>12 );
228
 
 
229
 
}
230
 
 
231
 
/*
232
 
-------------------------------------------------------------------------------
233
 
Takes two double-precision floating-point values `a' and `b', one of which
234
 
is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
235
 
signaling NaN, the invalid exception is raised.
236
 
-------------------------------------------------------------------------------
237
 
*/
238
 
static float64 propagateFloat64NaN( float64 a, float64 b )
239
 
{
240
 
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
241
 
 
242
 
    aIsNaN = float64_is_nan( a );
243
 
    aIsSignalingNaN = float64_is_signaling_nan( a );
244
 
    bIsNaN = float64_is_nan( b );
245
 
    bIsSignalingNaN = float64_is_signaling_nan( b );
246
 
    a |= LIT64( 0x0008000000000000 );
247
 
    b |= LIT64( 0x0008000000000000 );
248
 
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
249
 
    if ( aIsNaN ) {
250
 
        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
251
 
    }
252
 
    else {
253
 
        return b;
254
 
    }
255
 
 
256
 
}
257
 
 
258
 
#ifdef FLOATX80
259
 
 
260
 
/*
261
 
-------------------------------------------------------------------------------
262
 
The pattern for a default generated extended double-precision NaN.  The
263
 
`high' and `low' values hold the most- and least-significant bits,
264
 
respectively.
265
 
-------------------------------------------------------------------------------
266
 
*/
267
 
#define floatx80_default_nan_high 0xFFFF
268
 
#define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
269
 
 
270
 
/*
271
 
-------------------------------------------------------------------------------
272
 
Returns 1 if the extended double-precision floating-point value `a' is a
273
 
NaN; otherwise returns 0.
274
 
-------------------------------------------------------------------------------
275
 
*/
276
 
flag floatx80_is_nan( floatx80 a )
277
 
{
278
 
 
279
 
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
280
 
 
281
 
}
282
 
 
283
 
/*
284
 
-------------------------------------------------------------------------------
285
 
Returns 1 if the extended double-precision floating-point value `a' is a
286
 
signaling NaN; otherwise returns 0.
287
 
-------------------------------------------------------------------------------
288
 
*/
289
 
flag floatx80_is_signaling_nan( floatx80 a )
290
 
{
291
 
    //register int lr;
292
 
    bits64 aLow;
293
 
 
294
 
    //__asm__("mov %0, lr" : : "g" (lr));
295
 
    //fp_printk("floatx80_is_signalling_nan() called from 0x%08x\n",lr);
296
 
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
297
 
    return
298
 
           ( ( a.high & 0x7FFF ) == 0x7FFF )
299
 
        && (bits64) ( aLow<<1 )
300
 
        && ( a.low == aLow );
301
 
 
302
 
}
303
 
 
304
 
/*
305
 
-------------------------------------------------------------------------------
306
 
Returns the result of converting the extended double-precision floating-
307
 
point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
308
 
invalid exception is raised.
309
 
-------------------------------------------------------------------------------
310
 
*/
311
 
static commonNaNT floatx80ToCommonNaN( floatx80 a )
312
 
{
313
 
    commonNaNT z;
314
 
 
315
 
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
316
 
    z.sign = a.high>>15;
317
 
    z.low = 0;
318
 
    z.high = a.low<<1;
319
 
    return z;
320
 
 
321
 
}
322
 
 
323
 
/*
324
 
-------------------------------------------------------------------------------
325
 
Returns the result of converting the canonical NaN `a' to the extended
326
 
double-precision floating-point format.
327
 
-------------------------------------------------------------------------------
328
 
*/
329
 
static floatx80 commonNaNToFloatx80( commonNaNT a )
330
 
{
331
 
    floatx80 z;
332
 
 
333
 
    z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
334
 
    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
335
 
    return z;
336
 
 
337
 
}
338
 
 
339
 
/*
340
 
-------------------------------------------------------------------------------
341
 
Takes two extended double-precision floating-point values `a' and `b', one
342
 
of which is a NaN, and returns the appropriate NaN result.  If either `a' or
343
 
`b' is a signaling NaN, the invalid exception is raised.
344
 
-------------------------------------------------------------------------------
345
 
*/
346
 
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
347
 
{
348
 
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
349
 
 
350
 
    aIsNaN = floatx80_is_nan( a );
351
 
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
352
 
    bIsNaN = floatx80_is_nan( b );
353
 
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
354
 
    a.low |= LIT64( 0xC000000000000000 );
355
 
    b.low |= LIT64( 0xC000000000000000 );
356
 
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
357
 
    if ( aIsNaN ) {
358
 
        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
359
 
    }
360
 
    else {
361
 
        return b;
362
 
    }
363
 
 
364
 
}
365
 
 
366
 
#endif