|
|
1.1 root 1: /* $NetBSD: fpu_explode.c,v 1.15 2015/02/05 12:23:27 isaki Exp $ */
2:
3: /*
4: * Copyright (c) 1992, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
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.
10: *
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.
15: *
16: * Redistribution and use in source and binary forms, with or without
17: * modification, are permitted provided that the following conditions
18: * are met:
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.
27: *
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
38: * SUCH DAMAGE.
39: *
40: * @(#)fpu_explode.c 8.1 (Berkeley) 6/11/93
41: */
42:
43: /*
44: * FPU subroutines: `explode' the machine's `packed binary' format numbers
45: * into our internal format.
46: */
47:
48: #include "fpu_emulate.h"
49:
50:
51: /* Conversion to internal format -- note asymmetry. */
52: static int fpu_itof(struct fpn *fp, uint32_t i);
53: static int fpu_stof(struct fpn *fp, uint32_t i);
54: static int fpu_dtof(struct fpn *fp, uint32_t i, uint32_t j);
55: static int fpu_xtof(struct fpn *fp, uint32_t i, uint32_t j, uint32_t k);
56:
57: /*
58: * N.B.: in all of the following, we assume the FP format is
59: *
60: * ---------------------------
61: * | s | exponent | fraction |
62: * ---------------------------
63: *
64: * (which represents -1**s * 1.fraction * 2**exponent), so that the
65: * sign bit is way at the top (bit 31), the exponent is next, and
66: * then the remaining bits mark the fraction. A zero exponent means
67: * zero or denormalized (0.fraction rather than 1.fraction), and the
68: * maximum possible exponent, 2bias+1, signals inf (fraction==0) or NaN.
69: *
70: * Since the sign bit is always the topmost bit---this holds even for
71: * integers---we set that outside all the *tof functions. Each function
72: * returns the class code for the new number (but note that we use
73: * FPC_QNAN for all NaNs; fpu_explode will fix this if appropriate).
74: */
75:
76: /*
77: * int -> fpn.
78: */
79: static int
80: fpu_itof(struct fpn *fp, uint32_t i)
81: {
82:
83: if (i == 0)
84: return (FPC_ZERO);
85: /*
86: * The value FP_1 represents 2^FP_LG, so set the exponent
87: * there and let normalization fix it up. Convert negative
88: * numbers to sign-and-magnitude. Note that this relies on
89: * fpu_norm()'s handling of `supernormals'; see fpu_subr.c.
90: */
91: fp->fp_exp = FP_LG;
92: fp->fp_mant[0] = (int)i < 0 ? -i : i;
93: fp->fp_mant[1] = 0;
94: fp->fp_mant[2] = 0;
95: fpu_norm(fp);
96: return (FPC_NUM);
97: }
98:
99: #define mask(nbits) ((1 << (nbits)) - 1)
100:
101: /*
102: * All external floating formats convert to internal in the same manner,
103: * as defined here. Note that only normals get an implied 1.0 inserted.
104: */
105: #define FP_TOF(exp, expbias, allfrac, f0, f1, f2, f3) \
106: if (exp == 0) { \
107: if (allfrac == 0) \
108: return (FPC_ZERO); \
109: fp->fp_exp = 1 - expbias; \
110: fp->fp_mant[0] = f0; \
111: fp->fp_mant[1] = f1; \
112: fp->fp_mant[2] = f2; \
113: fpu_norm(fp); \
114: return (FPC_NUM); \
115: } \
116: if (exp == (2 * expbias + 1)) { \
117: if (allfrac == 0) \
118: return (FPC_INF); \
119: fp->fp_mant[0] = f0; \
120: fp->fp_mant[1] = f1; \
121: fp->fp_mant[2] = f2; \
122: return (FPC_QNAN); \
123: } \
124: fp->fp_exp = exp - expbias; \
125: fp->fp_mant[0] = FP_1 | f0; \
126: fp->fp_mant[1] = f1; \
127: fp->fp_mant[2] = f2; \
128: return (FPC_NUM)
129:
130: /*
131: * 32-bit single precision -> fpn.
132: * We assume a single occupies at most (64-FP_LG) bits in the internal
133: * format: i.e., needs at most fp_mant[0] and fp_mant[1].
134: */
135: static int
136: fpu_stof(struct fpn *fp, uint32_t i)
137: {
138: int exp;
139: uint32_t frac, f0, f1;
140: #define SNG_SHIFT (SNG_FRACBITS - FP_LG)
141:
142: exp = (i >> (32 - 1 - SNG_EXPBITS)) & mask(SNG_EXPBITS);
143: frac = i & mask(SNG_FRACBITS);
144: f0 = frac >> SNG_SHIFT;
145: f1 = frac << (32 - SNG_SHIFT);
146: FP_TOF(exp, SNG_EXP_BIAS, frac, f0, f1, 0, 0);
147: }
148:
149: /*
150: * 64-bit double -> fpn.
151: * We assume this uses at most (96-FP_LG) bits.
152: */
153: static int
154: fpu_dtof(struct fpn *fp, uint32_t i, uint32_t j)
155: {
156: int exp;
157: uint32_t frac, f0, f1, f2;
158: #define DBL_SHIFT (DBL_FRACBITS - 32 - FP_LG)
159:
160: exp = (i >> (32 - 1 - DBL_EXPBITS)) & mask(DBL_EXPBITS);
161: frac = i & mask(DBL_FRACBITS - 32);
162: f0 = frac >> DBL_SHIFT;
163: f1 = (frac << (32 - DBL_SHIFT)) | (j >> DBL_SHIFT);
164: f2 = j << (32 - DBL_SHIFT);
165: frac |= j;
166: FP_TOF(exp, DBL_EXP_BIAS, frac, f0, f1, f2, 0);
167: }
168:
169: /*
170: * 96-bit extended -> fpn.
171: */
172: static int
173: fpu_xtof(struct fpn *fp, uint32_t i, uint32_t j, uint32_t k)
174: {
175: int exp;
176: uint32_t f0, f1, f2;
177: #define EXT_SHIFT (EXT_FRACBITS - 1 - 32 - FP_LG)
178:
179: exp = (i >> (32 - 1 - EXT_EXPBITS)) & mask(EXT_EXPBITS);
180: f0 = j >> EXT_SHIFT;
181: f1 = (j << (32 - EXT_SHIFT)) | (k >> EXT_SHIFT);
182: f2 = k << (32 - EXT_SHIFT);
183:
184: /* m68k extended does not imply denormal by exp==0 */
185: if (exp == 0) {
186: if ((j | k) == 0)
187: return (FPC_ZERO);
188: fp->fp_exp = - EXT_EXP_BIAS;
189: fp->fp_mant[0] = f0;
190: fp->fp_mant[1] = f1;
191: fp->fp_mant[2] = f2;
192: fpu_norm(fp);
193: return (FPC_NUM);
194: }
195: if (exp == (2 * EXT_EXP_BIAS + 1)) {
196: /* MSB is an integer part and don't care */
197: if ((j & 0x7fffffff) == 0 && k == 0)
198: return (FPC_INF);
199: fp->fp_mant[0] = f0;
200: fp->fp_mant[1] = f1;
201: fp->fp_mant[2] = f2;
202: return (FPC_QNAN);
203: }
204: fp->fp_exp = exp - EXT_EXP_BIAS;
205: fp->fp_mant[0] = FP_1 | f0;
206: fp->fp_mant[1] = f1;
207: fp->fp_mant[2] = f2;
208: return (FPC_NUM);
209: }
210:
211: #if defined(XM6i_FPE)
212: /*
213: * 96-bit packed BCD -> fpn.
214: */
215: static int
216: fpu_ptof(struct fpemu *fe, struct fpn *fp, const uint32_t *space)
217: {
218: struct fpn frac;
219: struct fpn digit;
220: struct fpn exp;
221: struct fpn *r;
222: uint32_t d;
223: uint32_t d0;
224: uint32_t e;
225: int i;
226: int j;
227:
228: if ((space[0] & 0x7fff0000) == 0x7fff0000) {
229: fp->fp_sign = (space[0] & 0x80000000) ? 1 : 0;
230: if ((space[1] | space[2]) == 0) {
231: /* infinity */
232: return FPC_INF;
233: } else {
234: /* NAN */
235: fp->fp_mant[0] = space[1] >> EXT_SHIFT;
236: fp->fp_mant[1] =
237: (space[1] << (32 - EXT_SHIFT)) | (space[2] >> EXT_SHIFT);
238: fp->fp_mant[2] = space[2] << (32 - EXT_SHIFT);
239:
240: return FPC_QNAN;
241: }
242: }
243:
244: /* 初期化 */
245: fpu_const(&frac, FPU_CONST_0);
246:
247: /* DIGIT 16 を取り出す */
248: d = space[0] & 0x0f;
249: fpu_explode(fe, &frac, FTYPE_LNG, &d);
250:
251: /* DIGIT15..DIGIT0 を取り出す */
252: for (i = 0; i < 2; i++) {
253: d0 = space[i + 1];
254: for (j = 0; j < 8; j++) {
255: /* frac *= 10 */
256: CPYFPN(&fe->fe_f1, &frac);
257: fpu_const(&fe->fe_f2, FPU_CONST_10);
258: r = fpu_mul(fe);
259:
260: d = (d0 & 0xf0000000) >> 28;
261: d0 <<= 4;
262:
263: /* 1桁追加する */
264: fpu_explode(fe, &digit, FTYPE_LNG, &d);
265: CPYFPN(&fe->fe_f1, r);
266: CPYFPN(&fe->fe_f2, &digit);
267: r = fpu_add(fe);
268:
269: CPYFPN(&frac, r);
270: }
271: }
272:
273: /* 仮数部の符号 */
274: if (space[0] & 0x80000000) {
275: frac.fp_sign = 1;
276: }
277:
278: /* (EXP3) は調査していないので未サポート */
279: e = ((space[0] & 0x0f000000) >> 24) * 100
280: + ((space[0] & 0x00f00000) >> 20) * 10
281: + ((space[0] & 0x000f0000) >> 16) * 1;
282:
283: /* 指数部の符号 */
284: if (space[0] & 0x40000000) {
285: e = -e;
286: }
287:
288: /* 小数点位置補正 */
289: e -= 16;
290:
291: /* 10^e を計算 */
292: fpu_explode(fe, &exp, FTYPE_LNG, &e);
293: CPYFPN(&fe->fe_f2, &exp);
294: r = fpu_tentox(fe);
295:
296: /* かけてできあがり */
297: CPYFPN(&fe->fe_f2, r);
298: CPYFPN(&fe->fe_f1, &frac);
299: r = fpu_mul(fe);
300: CPYFPN(fp, r);
301:
302: if (ISZERO(fp)) {
303: return FPC_ZERO;
304: }
305: return FPC_NUM;
306: }
307: #endif /* XM6i_FPE */
308:
309: /*
310: * Explode the contents of a memory operand.
311: */
312: void
313: fpu_explode(struct fpemu *fe, struct fpn *fp, int type, const uint32_t *space)
314: {
315: uint32_t s;
316:
317: s = space[0];
318: fp->fp_sign = s >> 31;
319: fp->fp_sticky = 0;
320: switch (type) {
321:
322: case FTYPE_BYT:
323: s >>= 8;
324: case FTYPE_WRD:
325: s >>= 16;
326: case FTYPE_LNG:
327: s = fpu_itof(fp, s);
328: break;
329:
330: case FTYPE_SNG:
331: s = fpu_stof(fp, s);
332: break;
333:
334: case FTYPE_DBL:
335: s = fpu_dtof(fp, s, space[1]);
336: break;
337:
338: case FTYPE_EXT:
339: s = fpu_xtof(fp, s, space[1], space[2]);
340: break;
341:
342: #if defined(XM6i_FPE)
343: case FTYPE_BCD:
344: s = fpu_ptof(fe, fp, space);
345: break;
346: #endif
347:
348: default:
349: #if defined(XM6i_FPE)
350: /* 何も出来ることがない */
351: break;
352: #else
353: panic("fpu_explode");
354: #endif
355: }
356: if (s == FPC_QNAN && (fp->fp_mant[0] & FP_QUIETBIT) == 0) {
357: /*
358: * Input is a signalling NaN. All operations that return
359: * an input NaN operand put it through a ``NaN conversion'',
360: * which basically just means ``turn on the quiet bit''.
361: * We do this here so that all NaNs internally look quiet
362: * (we can tell signalling ones by their class).
363: */
364: fp->fp_mant[0] |= FP_QUIETBIT;
365: fe->fe_fpsr |= FPSR_SNAN; /* assert SNAN exception */
366: s = FPC_SNAN;
367: }
368: fp->fp_class = s;
369: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.