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/fcnvuf.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/fcnvuf.c')
-rw-r--r-- | arch/parisc/math-emu/fcnvuf.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/arch/parisc/math-emu/fcnvuf.c b/arch/parisc/math-emu/fcnvuf.c new file mode 100644 index 000000000000..5e68189fee22 --- /dev/null +++ b/arch/parisc/math-emu/fcnvuf.c | |||
@@ -0,0 +1,318 @@ | |||
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 | * File: | ||
25 | * @(#) pa/spmath/fcnvuf.c $Revision: 1.1 $ | ||
26 | * | ||
27 | * Purpose: | ||
28 | * Fixed point to Floating-point Converts | ||
29 | * | ||
30 | * External Interfaces: | ||
31 | * dbl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status) | ||
32 | * dbl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status) | ||
33 | * sgl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status) | ||
34 | * sgl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status) | ||
35 | * | ||
36 | * Internal Interfaces: | ||
37 | * | ||
38 | * Theory: | ||
39 | * <<please update with a overview of the operation of this file>> | ||
40 | * | ||
41 | * END_DESC | ||
42 | */ | ||
43 | |||
44 | |||
45 | #include "float.h" | ||
46 | #include "sgl_float.h" | ||
47 | #include "dbl_float.h" | ||
48 | #include "cnv_float.h" | ||
49 | |||
50 | /************************************************************************ | ||
51 | * Fixed point to Floating-point Converts * | ||
52 | ************************************************************************/ | ||
53 | |||
54 | /* | ||
55 | * Convert Single Unsigned Fixed to Single Floating-point format | ||
56 | */ | ||
57 | |||
58 | int | ||
59 | sgl_to_sgl_fcnvuf( | ||
60 | unsigned int *srcptr, | ||
61 | unsigned int *nullptr, | ||
62 | sgl_floating_point *dstptr, | ||
63 | unsigned int *status) | ||
64 | { | ||
65 | register unsigned int src, result = 0; | ||
66 | register int dst_exponent; | ||
67 | |||
68 | src = *srcptr; | ||
69 | |||
70 | /* Check for zero */ | ||
71 | if (src == 0) { | ||
72 | Sgl_setzero(result); | ||
73 | *dstptr = result; | ||
74 | return(NOEXCEPTION); | ||
75 | } | ||
76 | /* | ||
77 | * Generate exponent and normalized mantissa | ||
78 | */ | ||
79 | dst_exponent = 16; /* initialize for normalization */ | ||
80 | /* | ||
81 | * Check word for most significant bit set. Returns | ||
82 | * a value in dst_exponent indicating the bit position, | ||
83 | * between -1 and 30. | ||
84 | */ | ||
85 | Find_ms_one_bit(src,dst_exponent); | ||
86 | /* left justify source, with msb at bit position 0 */ | ||
87 | src <<= dst_exponent+1; | ||
88 | Sgl_set_mantissa(result, src >> SGL_EXP_LENGTH); | ||
89 | Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent); | ||
90 | |||
91 | /* check for inexact */ | ||
92 | if (Suint_isinexact_to_sgl(src)) { | ||
93 | switch (Rounding_mode()) { | ||
94 | case ROUNDPLUS: | ||
95 | Sgl_increment(result); | ||
96 | break; | ||
97 | case ROUNDMINUS: /* never negative */ | ||
98 | break; | ||
99 | case ROUNDNEAREST: | ||
100 | Sgl_roundnearest_from_suint(src,result); | ||
101 | break; | ||
102 | } | ||
103 | if (Is_inexacttrap_enabled()) { | ||
104 | *dstptr = result; | ||
105 | return(INEXACTEXCEPTION); | ||
106 | } | ||
107 | else Set_inexactflag(); | ||
108 | } | ||
109 | *dstptr = result; | ||
110 | return(NOEXCEPTION); | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * Single Unsigned Fixed to Double Floating-point | ||
115 | */ | ||
116 | |||
117 | int | ||
118 | sgl_to_dbl_fcnvuf( | ||
119 | unsigned int *srcptr, | ||
120 | unsigned int *nullptr, | ||
121 | dbl_floating_point *dstptr, | ||
122 | unsigned int *status) | ||
123 | { | ||
124 | register int dst_exponent; | ||
125 | register unsigned int src, resultp1 = 0, resultp2 = 0; | ||
126 | |||
127 | src = *srcptr; | ||
128 | |||
129 | /* Check for zero */ | ||
130 | if (src == 0) { | ||
131 | Dbl_setzero(resultp1,resultp2); | ||
132 | Dbl_copytoptr(resultp1,resultp2,dstptr); | ||
133 | return(NOEXCEPTION); | ||
134 | } | ||
135 | /* | ||
136 | * Generate exponent and normalized mantissa | ||
137 | */ | ||
138 | dst_exponent = 16; /* initialize for normalization */ | ||
139 | /* | ||
140 | * Check word for most significant bit set. Returns | ||
141 | * a value in dst_exponent indicating the bit position, | ||
142 | * between -1 and 30. | ||
143 | */ | ||
144 | Find_ms_one_bit(src,dst_exponent); | ||
145 | /* left justify source, with msb at bit position 0 */ | ||
146 | src <<= dst_exponent+1; | ||
147 | Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH); | ||
148 | Dbl_set_mantissap2(resultp2, src << (32-DBL_EXP_LENGTH)); | ||
149 | Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent); | ||
150 | Dbl_copytoptr(resultp1,resultp2,dstptr); | ||
151 | return(NOEXCEPTION); | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Double Unsigned Fixed to Single Floating-point | ||
156 | */ | ||
157 | |||
158 | int | ||
159 | dbl_to_sgl_fcnvuf( | ||
160 | dbl_unsigned *srcptr, | ||
161 | unsigned int *nullptr, | ||
162 | sgl_floating_point *dstptr, | ||
163 | unsigned int *status) | ||
164 | { | ||
165 | int dst_exponent; | ||
166 | unsigned int srcp1, srcp2, result = 0; | ||
167 | |||
168 | Duint_copyfromptr(srcptr,srcp1,srcp2); | ||
169 | |||
170 | /* Check for zero */ | ||
171 | if (srcp1 == 0 && srcp2 == 0) { | ||
172 | Sgl_setzero(result); | ||
173 | *dstptr = result; | ||
174 | return(NOEXCEPTION); | ||
175 | } | ||
176 | /* | ||
177 | * Generate exponent and normalized mantissa | ||
178 | */ | ||
179 | dst_exponent = 16; /* initialize for normalization */ | ||
180 | if (srcp1 == 0) { | ||
181 | /* | ||
182 | * Check word for most significant bit set. Returns | ||
183 | * a value in dst_exponent indicating the bit position, | ||
184 | * between -1 and 30. | ||
185 | */ | ||
186 | Find_ms_one_bit(srcp2,dst_exponent); | ||
187 | /* left justify source, with msb at bit position 0 */ | ||
188 | srcp1 = srcp2 << dst_exponent+1; | ||
189 | srcp2 = 0; | ||
190 | /* | ||
191 | * since msb set is in second word, need to | ||
192 | * adjust bit position count | ||
193 | */ | ||
194 | dst_exponent += 32; | ||
195 | } | ||
196 | else { | ||
197 | /* | ||
198 | * Check word for most significant bit set. Returns | ||
199 | * a value in dst_exponent indicating the bit position, | ||
200 | * between -1 and 30. | ||
201 | * | ||
202 | */ | ||
203 | Find_ms_one_bit(srcp1,dst_exponent); | ||
204 | /* left justify source, with msb at bit position 0 */ | ||
205 | if (dst_exponent >= 0) { | ||
206 | Variable_shift_double(srcp1,srcp2,(31-dst_exponent), | ||
207 | srcp1); | ||
208 | srcp2 <<= dst_exponent+1; | ||
209 | } | ||
210 | } | ||
211 | Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH); | ||
212 | Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent); | ||
213 | |||
214 | /* check for inexact */ | ||
215 | if (Duint_isinexact_to_sgl(srcp1,srcp2)) { | ||
216 | switch (Rounding_mode()) { | ||
217 | case ROUNDPLUS: | ||
218 | Sgl_increment(result); | ||
219 | break; | ||
220 | case ROUNDMINUS: /* never negative */ | ||
221 | break; | ||
222 | case ROUNDNEAREST: | ||
223 | Sgl_roundnearest_from_duint(srcp1,srcp2,result); | ||
224 | break; | ||
225 | } | ||
226 | if (Is_inexacttrap_enabled()) { | ||
227 | *dstptr = result; | ||
228 | return(INEXACTEXCEPTION); | ||
229 | } | ||
230 | else Set_inexactflag(); | ||
231 | } | ||
232 | *dstptr = result; | ||
233 | return(NOEXCEPTION); | ||
234 | } | ||
235 | |||
236 | /* | ||
237 | * Double Unsigned Fixed to Double Floating-point | ||
238 | */ | ||
239 | |||
240 | int | ||
241 | dbl_to_dbl_fcnvuf( | ||
242 | dbl_unsigned *srcptr, | ||
243 | unsigned int *nullptr, | ||
244 | dbl_floating_point *dstptr, | ||
245 | unsigned int *status) | ||
246 | { | ||
247 | register int dst_exponent; | ||
248 | register unsigned int srcp1, srcp2, resultp1 = 0, resultp2 = 0; | ||
249 | |||
250 | Duint_copyfromptr(srcptr,srcp1,srcp2); | ||
251 | |||
252 | /* Check for zero */ | ||
253 | if (srcp1 == 0 && srcp2 ==0) { | ||
254 | Dbl_setzero(resultp1,resultp2); | ||
255 | Dbl_copytoptr(resultp1,resultp2,dstptr); | ||
256 | return(NOEXCEPTION); | ||
257 | } | ||
258 | /* | ||
259 | * Generate exponent and normalized mantissa | ||
260 | */ | ||
261 | dst_exponent = 16; /* initialize for normalization */ | ||
262 | if (srcp1 == 0) { | ||
263 | /* | ||
264 | * Check word for most significant bit set. Returns | ||
265 | * a value in dst_exponent indicating the bit position, | ||
266 | * between -1 and 30. | ||
267 | */ | ||
268 | Find_ms_one_bit(srcp2,dst_exponent); | ||
269 | /* left justify source, with msb at bit position 0 */ | ||
270 | srcp1 = srcp2 << dst_exponent+1; | ||
271 | srcp2 = 0; | ||
272 | /* | ||
273 | * since msb set is in second word, need to | ||
274 | * adjust bit position count | ||
275 | */ | ||
276 | dst_exponent += 32; | ||
277 | } | ||
278 | else { | ||
279 | /* | ||
280 | * Check word for most significant bit set. Returns | ||
281 | * a value in dst_exponent indicating the bit position, | ||
282 | * between -1 and 30. | ||
283 | */ | ||
284 | Find_ms_one_bit(srcp1,dst_exponent); | ||
285 | /* left justify source, with msb at bit position 0 */ | ||
286 | if (dst_exponent >= 0) { | ||
287 | Variable_shift_double(srcp1,srcp2,(31-dst_exponent), | ||
288 | srcp1); | ||
289 | srcp2 <<= dst_exponent+1; | ||
290 | } | ||
291 | } | ||
292 | Dbl_set_mantissap1(resultp1, srcp1 >> DBL_EXP_LENGTH); | ||
293 | Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH,resultp2); | ||
294 | Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent); | ||
295 | |||
296 | /* check for inexact */ | ||
297 | if (Duint_isinexact_to_dbl(srcp2)) { | ||
298 | switch (Rounding_mode()) { | ||
299 | case ROUNDPLUS: | ||
300 | Dbl_increment(resultp1,resultp2); | ||
301 | break; | ||
302 | case ROUNDMINUS: /* never negative */ | ||
303 | break; | ||
304 | case ROUNDNEAREST: | ||
305 | Dbl_roundnearest_from_duint(srcp2,resultp1, | ||
306 | resultp2); | ||
307 | break; | ||
308 | } | ||
309 | if (Is_inexacttrap_enabled()) { | ||
310 | Dbl_copytoptr(resultp1,resultp2,dstptr); | ||
311 | return(INEXACTEXCEPTION); | ||
312 | } | ||
313 | else Set_inexactflag(); | ||
314 | } | ||
315 | Dbl_copytoptr(resultp1,resultp2,dstptr); | ||
316 | return(NOEXCEPTION); | ||
317 | } | ||
318 | |||