* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratory.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* @(#)fpu_subr.c 8.1 (Berkeley) 6/11/93
* from: $Header: fpu_subr.c,v 1.4 92/12/01 08:46:52 torek Exp $
#include <sparc/fpu/fpu_arith.h>
#include <sparc/fpu/fpu_emu.h>
* Shift the given number right rsh bits. Any bits that `fall off' will get
* shoved into the sticky field; we return the resulting sticky. Note that
* shifting NaNs is legal (this will never shift all bits out); a NaN's
* sticky field is ignored anyway.
fpu_shr(register struct fpn
*fp
, register int rsh
)
register u_int m0
, m1
, m2
, m3
, s
;
if (rsh
<= 0 || (fp
->fp_class
!= FPC_NUM
&& !ISNAN(fp
)))
panic("fpu_rightshift 1");
/* If shifting all the bits out, take a shortcut. */
if ((m0
| m1
| m2
| m3
) == 0)
panic("fpu_rightshift 2");
if ((m0
| m1
| m2
| m3
) == 0)
/* Squish out full words. */
m3
= m0
, m2
= 0, m1
= 0, m0
= 0;
} else if (rsh
>= 32 * 2) {
m3
= m1
, m2
= m0
, m1
= 0, m0
= 0;
m3
= m2
, m2
= m1
, m1
= m0
, m0
= 0;
/* Handle any remaining partial word. */
m3
= (m3
>> rsh
) | (m2
<< lsh
);
m2
= (m2
>> rsh
) | (m1
<< lsh
);
m1
= (m1
>> rsh
) | (m0
<< lsh
);
* Force a number to be normal, i.e., make its fraction have all zero
* bits before FP_1, then FP_1, then all 1 bits. This is used for denorms
* and (sometimes) for intermediate results.
* Internally, this may use a `supernormal' -- a number whose fp_mant
* is greater than or equal to 2.0 -- so as a side effect you can hand it
* a supernormal and it will fix it (provided fp->fp_mant[3] == 0).
fpu_norm(register struct fpn
*fp
)
register u_int m0
, m1
, m2
, m3
, top
, sup
, nrm
;
register int lsh
, rsh
, exp
;
/* Handle severe subnormals with 32-bit moves. */
m0
= m1
, m1
= m2
, m2
= m3
, m3
= 0, exp
-= 32;
m0
= m2
, m1
= m3
, m2
= 0, m3
= 0, exp
-= 2 * 32;
m0
= m3
, m1
= 0, m2
= 0, m3
= 0, exp
-= 3 * 32;
/* Now fix any supernormal or remaining subnormal. */
* We have a supernormal number. We need to shift it right.
for (rsh
= 1, top
= m0
>> 1; top
>= sup
; rsh
++) /* XXX slow */
m2
= (m2
>> rsh
) | (m1
<< lsh
);
m1
= (m1
>> rsh
) | (m0
<< lsh
);
* We have a regular denorm (a subnormal number), and need
for (lsh
= 1, top
= m0
<< 1; top
< nrm
; lsh
++) /* XXX slow */
m1
= (m1
<< lsh
) | (m2
>> rsh
);
m2
= (m2
<< lsh
) | (m3
>> rsh
);
* Concoct a `fresh' Quiet NaN per Appendix N.
* As a side effect, we set NV (invalid) for the current exceptions.
fpu_newnan(register struct fpemu
*fe
)
fp
->fp_mant
[0] = FP_1
- 1;
fp
->fp_mant
[1] = fp
->fp_mant
[2] = fp
->fp_mant
[3] = ~0;