1 /* $NetBSD: fpu_subr.c,v 1.7 2005/12/11 12:17:52 christos Exp $ */
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This software was developed by the Computer Systems Engineering group
8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9 * contributed to Berkeley.
11 * All advertising materials mentioning features or use of this software
12 * must display the following acknowledgement:
13 * This product includes software developed by the University of
14 * California, Lawrence Berkeley Laboratory.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * @(#)fpu_subr.c 8.1 (Berkeley) 6/11/93
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD: fpu_subr.c,v 1.7 2005/12/11 12:17:52 christos Exp $");
50 #include <sys/types.h>
51 #include <sys/systm.h>
53 #include <machine/reg.h>
55 #include "fpu_emulate.h"
56 #include "fpu_arith.h"
59 * Shift the given number right rsh bits. Any bits that `fall off' will get
60 * shoved into the sticky field; we return the resulting sticky. Note that
61 * shifting NaNs is legal (this will never shift all bits out); a NaN's
62 * sticky field is ignored anyway.
65 fpu_shr(register struct fpn
*fp
, register int rsh
)
67 register u_int m0
, m1
, m2
, s
;
71 if (rsh
< 0 || (fp
->fp_class
!= FPC_NUM
&& !ISNAN(fp
)))
72 panic("fpu_rightshift 1");
79 /* If shifting all the bits out, take a shortcut. */
80 if (rsh
>= FP_NMANT
) {
82 if ((m0
| m1
| m2
) == 0)
83 panic("fpu_rightshift 2");
89 if ((m0
| m1
| m2
) == 0)
90 fp
->fp_class
= FPC_ZERO
;
97 /* Squish out full words. */
101 m2
= m0
, m1
= 0, m0
= 0;
102 } else if (rsh
>= 32) {
104 m2
= m1
, m1
= m0
, m0
= 0;
107 /* Handle any remaining partial word. */
108 if ((rsh
&= 31) != 0) {
111 m2
= (m2
>> rsh
) | (m1
<< lsh
);
112 m1
= (m1
>> rsh
) | (m0
<< lsh
);
123 * Force a number to be normal, i.e., make its fraction have all zero
124 * bits before FP_1, then FP_1, then all 1 bits. This is used for denorms
125 * and (sometimes) for intermediate results.
127 * Internally, this may use a `supernormal' -- a number whose fp_mant
128 * is greater than or equal to 2.0 -- so as a side effect you can hand it
129 * a supernormal and it will fix it (provided fp->fp_mant[2] == 0).
132 fpu_norm(register struct fpn
*fp
)
134 register u_int m0
, m1
, m2
, sup
, nrm
;
135 register int lsh
, rsh
, exp
;
142 /* Handle severe subnormals with 32-bit moves. */
155 fp
->fp_class
= FPC_ZERO
;
160 /* Now fix any supernormal or remaining subnormal. */
165 * We have a supernormal number. We need to shift it right.
166 * We may assume m2==0.
168 __asm
volatile("bfffo %1{#0:#32},%0" : "=d"(rsh
) : "g"(m0
));
169 rsh
= 31 - rsh
- FP_LG
;
173 m1
= (m1
>> rsh
) | (m0
<< lsh
);
175 } else if (m0
< nrm
) {
177 * We have a regular denorm (a subnormal number), and need
180 __asm
volatile("bfffo %1{#0:#32},%0" : "=d"(lsh
) : "g"(m0
));
181 lsh
= FP_LG
- 31 + lsh
;
184 m0
= (m0
<< lsh
) | (m1
>> rsh
);
185 m1
= (m1
<< lsh
) | (m2
>> rsh
);
196 * Concoct a `fresh' Quiet NaN per Appendix N.
197 * As a side effect, we set OPERR for the current exceptions.
200 fpu_newnan(register struct fpemu
*fe
)
202 register struct fpn
*fp
;
204 fe
->fe_fpsr
|= FPSR_OPERR
;
206 fp
->fp_class
= FPC_QNAN
;
208 fp
->fp_mant
[0] = FP_1
- 1;
209 fp
->fp_mant
[1] = fp
->fp_mant
[2] = ~0;