diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/parisc/math-emu/frnd.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/parisc/math-emu/frnd.c')
-rw-r--r-- | arch/parisc/math-emu/frnd.c | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/arch/parisc/math-emu/frnd.c b/arch/parisc/math-emu/frnd.c new file mode 100644 index 000000000000..904b3844bf26 --- /dev/null +++ b/arch/parisc/math-emu/frnd.c | |||
@@ -0,0 +1,252 @@ | |||
1 | /* | ||
2 | * Linux/PA-RISC Project (http://www.parisc-linux.org/) | ||
3 | * | ||
4 | * Floating-point emulation code | ||
5 | * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2, or (at your option) | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | /* | ||
22 | * BEGIN_DESC | ||
23 | * | ||
24 | * Purpose: | ||
25 | * Single Floating-point Round to Integer | ||
26 | * Double Floating-point Round to Integer | ||
27 | * Quad Floating-point Round to Integer (returns unimplemented) | ||
28 | * | ||
29 | * External Interfaces: | ||
30 | * dbl_frnd(srcptr,nullptr,dstptr,status) | ||
31 | * sgl_frnd(srcptr,nullptr,dstptr,status) | ||
32 | * | ||
33 | * END_DESC | ||
34 | */ | ||
35 | |||
36 | |||
37 | #include "float.h" | ||
38 | #include "sgl_float.h" | ||
39 | #include "dbl_float.h" | ||
40 | #include "cnv_float.h" | ||
41 | |||
42 | /* | ||
43 | * Single Floating-point Round to Integer | ||
44 | */ | ||
45 | |||
46 | /*ARGSUSED*/ | ||
47 | int | ||
48 | sgl_frnd(sgl_floating_point *srcptr, | ||
49 | unsigned int *nullptr, | ||
50 | sgl_floating_point *dstptr, | ||
51 | unsigned int *status) | ||
52 | { | ||
53 | register unsigned int src, result; | ||
54 | register int src_exponent; | ||
55 | register boolean inexact = FALSE; | ||
56 | |||
57 | src = *srcptr; | ||
58 | /* | ||
59 | * check source operand for NaN or infinity | ||
60 | */ | ||
61 | if ((src_exponent = Sgl_exponent(src)) == SGL_INFINITY_EXPONENT) { | ||
62 | /* | ||
63 | * is signaling NaN? | ||
64 | */ | ||
65 | if (Sgl_isone_signaling(src)) { | ||
66 | /* trap if INVALIDTRAP enabled */ | ||
67 | if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION); | ||
68 | /* make NaN quiet */ | ||
69 | Set_invalidflag(); | ||
70 | Sgl_set_quiet(src); | ||
71 | } | ||
72 | /* | ||
73 | * return quiet NaN or infinity | ||
74 | */ | ||
75 | *dstptr = src; | ||
76 | return(NOEXCEPTION); | ||
77 | } | ||
78 | /* | ||
79 | * Need to round? | ||
80 | */ | ||
81 | if ((src_exponent -= SGL_BIAS) >= SGL_P - 1) { | ||
82 | *dstptr = src; | ||
83 | return(NOEXCEPTION); | ||
84 | } | ||
85 | /* | ||
86 | * Generate result | ||
87 | */ | ||
88 | if (src_exponent >= 0) { | ||
89 | Sgl_clear_exponent_set_hidden(src); | ||
90 | result = src; | ||
91 | Sgl_rightshift(result,(SGL_P-1) - (src_exponent)); | ||
92 | /* check for inexact */ | ||
93 | if (Sgl_isinexact_to_fix(src,src_exponent)) { | ||
94 | inexact = TRUE; | ||
95 | /* round result */ | ||
96 | switch (Rounding_mode()) { | ||
97 | case ROUNDPLUS: | ||
98 | if (Sgl_iszero_sign(src)) Sgl_increment(result); | ||
99 | break; | ||
100 | case ROUNDMINUS: | ||
101 | if (Sgl_isone_sign(src)) Sgl_increment(result); | ||
102 | break; | ||
103 | case ROUNDNEAREST: | ||
104 | if (Sgl_isone_roundbit(src,src_exponent)) | ||
105 | if (Sgl_isone_stickybit(src,src_exponent) | ||
106 | || (Sgl_isone_lowmantissa(result))) | ||
107 | Sgl_increment(result); | ||
108 | } | ||
109 | } | ||
110 | Sgl_leftshift(result,(SGL_P-1) - (src_exponent)); | ||
111 | if (Sgl_isone_hiddenoverflow(result)) | ||
112 | Sgl_set_exponent(result,src_exponent + (SGL_BIAS+1)); | ||
113 | else Sgl_set_exponent(result,src_exponent + SGL_BIAS); | ||
114 | } | ||
115 | else { | ||
116 | result = src; /* set sign */ | ||
117 | Sgl_setzero_exponentmantissa(result); | ||
118 | /* check for inexact */ | ||
119 | if (Sgl_isnotzero_exponentmantissa(src)) { | ||
120 | inexact = TRUE; | ||
121 | /* round result */ | ||
122 | switch (Rounding_mode()) { | ||
123 | case ROUNDPLUS: | ||
124 | if (Sgl_iszero_sign(src)) | ||
125 | Sgl_set_exponent(result,SGL_BIAS); | ||
126 | break; | ||
127 | case ROUNDMINUS: | ||
128 | if (Sgl_isone_sign(src)) | ||
129 | Sgl_set_exponent(result,SGL_BIAS); | ||
130 | break; | ||
131 | case ROUNDNEAREST: | ||
132 | if (src_exponent == -1) | ||
133 | if (Sgl_isnotzero_mantissa(src)) | ||
134 | Sgl_set_exponent(result,SGL_BIAS); | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | *dstptr = result; | ||
139 | if (inexact) { | ||
140 | if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); | ||
141 | else Set_inexactflag(); | ||
142 | } | ||
143 | return(NOEXCEPTION); | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * Double Floating-point Round to Integer | ||
148 | */ | ||
149 | |||
150 | /*ARGSUSED*/ | ||
151 | int | ||
152 | dbl_frnd( | ||
153 | dbl_floating_point *srcptr, | ||
154 | unsigned int *nullptr, | ||
155 | dbl_floating_point *dstptr, | ||
156 | unsigned int *status) | ||
157 | { | ||
158 | register unsigned int srcp1, srcp2, resultp1, resultp2; | ||
159 | register int src_exponent; | ||
160 | register boolean inexact = FALSE; | ||
161 | |||
162 | Dbl_copyfromptr(srcptr,srcp1,srcp2); | ||
163 | /* | ||
164 | * check source operand for NaN or infinity | ||
165 | */ | ||
166 | if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) { | ||
167 | /* | ||
168 | * is signaling NaN? | ||
169 | */ | ||
170 | if (Dbl_isone_signaling(srcp1)) { | ||
171 | /* trap if INVALIDTRAP enabled */ | ||
172 | if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION); | ||
173 | /* make NaN quiet */ | ||
174 | Set_invalidflag(); | ||
175 | Dbl_set_quiet(srcp1); | ||
176 | } | ||
177 | /* | ||
178 | * return quiet NaN or infinity | ||
179 | */ | ||
180 | Dbl_copytoptr(srcp1,srcp2,dstptr); | ||
181 | return(NOEXCEPTION); | ||
182 | } | ||
183 | /* | ||
184 | * Need to round? | ||
185 | */ | ||
186 | if ((src_exponent -= DBL_BIAS) >= DBL_P - 1) { | ||
187 | Dbl_copytoptr(srcp1,srcp2,dstptr); | ||
188 | return(NOEXCEPTION); | ||
189 | } | ||
190 | /* | ||
191 | * Generate result | ||
192 | */ | ||
193 | if (src_exponent >= 0) { | ||
194 | Dbl_clear_exponent_set_hidden(srcp1); | ||
195 | resultp1 = srcp1; | ||
196 | resultp2 = srcp2; | ||
197 | Dbl_rightshift(resultp1,resultp2,(DBL_P-1) - (src_exponent)); | ||
198 | /* check for inexact */ | ||
199 | if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) { | ||
200 | inexact = TRUE; | ||
201 | /* round result */ | ||
202 | switch (Rounding_mode()) { | ||
203 | case ROUNDPLUS: | ||
204 | if (Dbl_iszero_sign(srcp1)) | ||
205 | Dbl_increment(resultp1,resultp2); | ||
206 | break; | ||
207 | case ROUNDMINUS: | ||
208 | if (Dbl_isone_sign(srcp1)) | ||
209 | Dbl_increment(resultp1,resultp2); | ||
210 | break; | ||
211 | case ROUNDNEAREST: | ||
212 | if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent)) | ||
213 | if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) | ||
214 | || (Dbl_isone_lowmantissap2(resultp2))) | ||
215 | Dbl_increment(resultp1,resultp2); | ||
216 | } | ||
217 | } | ||
218 | Dbl_leftshift(resultp1,resultp2,(DBL_P-1) - (src_exponent)); | ||
219 | if (Dbl_isone_hiddenoverflow(resultp1)) | ||
220 | Dbl_set_exponent(resultp1,src_exponent + (DBL_BIAS+1)); | ||
221 | else Dbl_set_exponent(resultp1,src_exponent + DBL_BIAS); | ||
222 | } | ||
223 | else { | ||
224 | resultp1 = srcp1; /* set sign */ | ||
225 | Dbl_setzero_exponentmantissa(resultp1,resultp2); | ||
226 | /* check for inexact */ | ||
227 | if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { | ||
228 | inexact = TRUE; | ||
229 | /* round result */ | ||
230 | switch (Rounding_mode()) { | ||
231 | case ROUNDPLUS: | ||
232 | if (Dbl_iszero_sign(srcp1)) | ||
233 | Dbl_set_exponent(resultp1,DBL_BIAS); | ||
234 | break; | ||
235 | case ROUNDMINUS: | ||
236 | if (Dbl_isone_sign(srcp1)) | ||
237 | Dbl_set_exponent(resultp1,DBL_BIAS); | ||
238 | break; | ||
239 | case ROUNDNEAREST: | ||
240 | if (src_exponent == -1) | ||
241 | if (Dbl_isnotzero_mantissa(srcp1,srcp2)) | ||
242 | Dbl_set_exponent(resultp1,DBL_BIAS); | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | Dbl_copytoptr(resultp1,resultp2,dstptr); | ||
247 | if (inexact) { | ||
248 | if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); | ||
249 | else Set_inexactflag(); | ||
250 | } | ||
251 | return(NOEXCEPTION); | ||
252 | } | ||