1 /* $NetBSD: fpu_subr.c,v 1.3.64.3 2004/09/21 13:22:14 skrll 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.3.64.3 2004/09/21 13:22:14 skrll Exp $");
50 #include <sys/types.h>
52 #include <sys/systm.h>
55 #include <machine/reg.h>
56 #include <machine/instr.h>
58 #include <sparc/fpu/fpu_arith.h>
59 #include <sparc/fpu/fpu_emu.h>
60 #include <sparc/fpu/fpu_extern.h>
63 * Shift the given number right rsh bits. Any bits that `fall off' will get
64 * shoved into the sticky field; we return the resulting sticky. Note that
65 * shifting NaNs is legal (this will never shift all bits out); a NaN's
66 * sticky field is ignored anyway.
69 fpu_shr(register struct fpn
*fp
, register int rsh
)
71 register u_int m0
, m1
, m2
, m3
, s
;
75 if (rsh
<= 0 || (fp
->fp_class
!= FPC_NUM
&& !ISNAN(fp
)))
76 panic("fpu_rightshift 1");
84 /* If shifting all the bits out, take a shortcut. */
85 if (rsh
>= FP_NMANT
) {
87 if ((m0
| m1
| m2
| m3
) == 0)
88 panic("fpu_rightshift 2");
95 if ((m0
| m1
| m2
| m3
) == 0)
96 fp
->fp_class
= FPC_ZERO
;
103 /* Squish out full words. */
107 m3
= m0
, m2
= 0, m1
= 0, m0
= 0;
108 } else if (rsh
>= 32 * 2) {
110 m3
= m1
, m2
= m0
, m1
= 0, m0
= 0;
111 } else if (rsh
>= 32) {
113 m3
= m2
, m2
= m1
, m1
= m0
, m0
= 0;
116 /* Handle any remaining partial word. */
117 if ((rsh
&= 31) != 0) {
120 m3
= (m3
>> rsh
) | (m2
<< lsh
);
121 m2
= (m2
>> rsh
) | (m1
<< lsh
);
122 m1
= (m1
>> rsh
) | (m0
<< lsh
);
134 * Force a number to be normal, i.e., make its fraction have all zero
135 * bits before FP_1, then FP_1, then all 1 bits. This is used for denorms
136 * and (sometimes) for intermediate results.
138 * Internally, this may use a `supernormal' -- a number whose fp_mant
139 * is greater than or equal to 2.0 -- so as a side effect you can hand it
140 * a supernormal and it will fix it (provided fp->fp_mant[3] == 0).
143 fpu_norm(register struct fpn
*fp
)
145 register u_int m0
, m1
, m2
, m3
, top
, sup
, nrm
;
146 register int lsh
, rsh
, exp
;
154 /* Handle severe subnormals with 32-bit moves. */
157 m0
= m1
, m1
= m2
, m2
= m3
, m3
= 0, exp
-= 32;
159 m0
= m2
, m1
= m3
, m2
= 0, m3
= 0, exp
-= 2 * 32;
161 m0
= m3
, m1
= 0, m2
= 0, m3
= 0, exp
-= 3 * 32;
163 fp
->fp_class
= FPC_ZERO
;
168 /* Now fix any supernormal or remaining subnormal. */
173 * We have a supernormal number. We need to shift it right.
174 * We may assume m3==0.
176 for (rsh
= 1, top
= m0
>> 1; top
>= sup
; rsh
++) /* XXX slow */
181 m2
= (m2
>> rsh
) | (m1
<< lsh
);
182 m1
= (m1
>> rsh
) | (m0
<< lsh
);
184 } else if (m0
< nrm
) {
186 * We have a regular denorm (a subnormal number), and need
189 for (lsh
= 1, top
= m0
<< 1; top
< nrm
; lsh
++) /* XXX slow */
193 m0
= top
| (m1
>> rsh
);
194 m1
= (m1
<< lsh
) | (m2
>> rsh
);
195 m2
= (m2
<< lsh
) | (m3
>> rsh
);
207 * Concoct a `fresh' Quiet NaN per Appendix N.
208 * As a side effect, we set NV (invalid) for the current exceptions.
211 fpu_newnan(register struct fpemu
*fe
)
213 register struct fpn
*fp
;
217 fp
->fp_class
= FPC_QNAN
;
219 fp
->fp_mant
[0] = FP_1
- 1;
220 fp
->fp_mant
[1] = fp
->fp_mant
[2] = fp
->fp_mant
[3] = ~0;