|
|
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.