|
|
1.1.1.2 ! root 1: /* $NetBSD: fpu_explode.c,v 1.16 2021/03/08 14:37:55 isaki Exp $ */ 1.1 root 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: case FTYPE_LNG: 322: s = fpu_itof(fp, s); 323: break; 324: 325: case FTYPE_SNG: 326: s = fpu_stof(fp, s); 327: break; 328: 329: case FTYPE_DBL: 330: s = fpu_dtof(fp, s, space[1]); 331: break; 332: 333: case FTYPE_EXT: 334: s = fpu_xtof(fp, s, space[1], space[2]); 335: break; 336: 337: #if defined(XM6i_FPE) 338: case FTYPE_BCD: 339: s = fpu_ptof(fe, fp, space); 340: break; 341: #endif 342: 1.1.1.2 ! root 343: case FTYPE_BYT: ! 344: case FTYPE_WRD: ! 345: /* Caller must cast it to signed LNG instead of calling this */ ! 346: /* FALLTHROUGH */ 1.1 root 347: default: 348: #if defined(XM6i_FPE) 349: /* 何も出来ることがない */ 350: break; 351: #else 352: panic("fpu_explode"); 353: #endif 354: } 355: if (s == FPC_QNAN && (fp->fp_mant[0] & FP_QUIETBIT) == 0) { 356: /* 357: * Input is a signalling NaN. All operations that return 358: * an input NaN operand put it through a ``NaN conversion'', 359: * which basically just means ``turn on the quiet bit''. 360: * We do this here so that all NaNs internally look quiet 361: * (we can tell signalling ones by their class). 362: */ 363: fp->fp_mant[0] |= FP_QUIETBIT; 364: fe->fe_fpsr |= FPSR_SNAN; /* assert SNAN exception */ 365: s = FPC_SNAN; 366: } 367: fp->fp_class = s; 368: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.