1: /* 2: * Copyright (c) 1982 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: static char sccsid[] = "@(#)bignum2.c 5.1 (Berkeley) 4/30/85"; 9: #endif not lint 10: 11: #include <stdio.h> 12: #include "as.h" 13: Bignum Znumber; /* zero reference */ 14: #define MINEXP -32768 /* never generate; reserved for id 0 */ 15: 16: Bignum intconvert(number, convto) 17: Bignum number; 18: int convto; 19: { 20: reg int i; 21: if (number.num_tag == convto) 22: return(number); 23: if (ty_nbyte[number.num_tag] > ty_nbyte[convto] && (passno == 2)){ 24: yywarning("Conversion between %s and %s looses significance", 25: ty_string[number.num_tag], 26: ty_string[convto]); 27: } 28: for (i = ty_nbyte[convto]; i < ty_nbyte[TYPO]; i++) 29: number.num_uchar[i] = 0; 30: return(number); 31: } 32: 33: #define CONV(src, dst) (((src) << TYPLG) + (dst)) 34: 35: Bignum floatconvert(number, convto) 36: Bignum number; 37: int convto; 38: { 39: reg u_int *bp; /* r11 */ 40: int loss = 0; 41: int gain = 0; 42: int mixs = 0; 43: Ovf ovf; 44: 45: if (number.num_tag == convto) 46: return(number); 47: bp = &number.num_uint[0]; 48: #ifdef lint 49: *bp = *bp; 50: #endif lint 51: 52: switch(CONV(number.num_tag, convto)){ 53: 54: case CONV(TYPF, TYPD): asm("cvtfd (r11), (r11)"); break; 55: case CONV(TYPF, TYPG): mixs++; break; 56: case CONV(TYPF, TYPH): mixs++; break; 57: 58: case CONV(TYPD, TYPF): asm("cvtdf (r11), (r11)"); break; 59: case CONV(TYPD, TYPG): mixs++; break; 60: case CONV(TYPD, TYPH): mixs++; break; 61: 62: case CONV(TYPG, TYPF): mixs++; break; 63: case CONV(TYPG, TYPD): mixs++; break; 64: case CONV(TYPG, TYPH): mixs++; break; 65: 66: case CONV(TYPH, TYPF): mixs++; break; 67: case CONV(TYPH, TYPD): mixs++; break; 68: case CONV(TYPH, TYPG): mixs++; break; 69: default: panic("Bad floating point conversion?"); 70: } 71: if ((gain || mixs || loss) && (passno == 2)){ 72: yywarning("Converting from %s to %s: %s ", 73: ty_string[number.num_tag], 74: ty_string[convto], 75: gain ? "gains significance" : 76: (loss ? "looses significance" : "mixs exponent formats") 77: ); 78: } 79: if (mixs){ 80: number = bignumconvert(number, convto, &ovf); 81: if (ovf && passno == 2){ 82: yywarning("Floating conversion over/underflowed\n"); 83: } 84: } else { 85: number.num_tag = convto; 86: } 87: return(number); 88: } 89: 90: /* 91: * Convert a big number between various representations 92: */ 93: Bignum bignumconvert(number, toconv, ovfp) 94: Bignum number; 95: int toconv; 96: Ovf *ovfp; 97: { 98: int tag; 99: 100: *ovfp = 0; 101: tag = number.num_tag; 102: if (tag == toconv) 103: return(number); 104: if (tag == TYPUNPACKED){ 105: return(bignumpack(number, toconv, ovfp)); 106: } 107: if (toconv == TYPUNPACKED){ 108: return(bignumunpack(number, ovfp)); 109: } 110: return(bignumpack(bignumunpack(number, ovfp), toconv, ovfp)); 111: } 112: 113: Bignum bignumunpack(Packed, ovfp) 114: Bignum Packed; 115: Ovf *ovfp; 116: { 117: Bignum Mantissa; 118: Bignum Enumber; 119: reg int i; 120: int j; 121: int k; 122: reg struct ty_bigdesc *p; 123: reg chptr packed; 124: reg chptr mantissa; 125: reg chptr enumber; 126: u_short exponent; 127: int sign; 128: int mask; 129: 130: p = &ty_bigdesc[Packed.num_tag]; 131: 132: *ovfp = 0; 133: Mantissa = Znumber; 134: sign = 0; 135: exponent = 0; 136: mantissa = CH_FIELD(Mantissa); 137: enumber = CH_FIELD(Enumber); 138: packed = CH_FIELD(Packed); 139: 140: if (isclear(packed)){ 141: Mantissa.num_tag = TYPUNPACKED; 142: Mantissa.num_exponent = MINEXP; 143: return(Mantissa); 144: } 145: /* 146: * map the packed number into the mantissa, using 147: * the unpacking map 148: */ 149: mapnumber(mantissa, packed, 16, p->b_upmmap); 150: /* 151: * perform the mantissa shifting. 152: * This may appear to overflow; all that is lost 153: * is low order bits of the exponent. 154: */ 155: (void)numshift(p->b_mlshift, mantissa, mantissa); 156: /* 157: * handle sign and exponent 158: */ 159: switch(Packed.num_tag){ 160: case TYPB: 161: case TYPW: 162: case TYPL: 163: case TYPO: 164: case TYPQ: 165: sign = 0; 166: exponent = p->b_eexcess; 167: if (mantissa[HOC] & SIGNBIT){ 168: sign = -1; 169: *ovfp |= numnegate(mantissa, mantissa); 170: } 171: /* 172: * Normalize the packed by left shifting, 173: * adjusting the exponent as we go. 174: * Do a binary weighted left shift for some speed. 175: */ 176: k = 0; 177: for (j = 4; j >= 0; --j){ 178: i = 1 << j; /* 16, 8, 4, 2, 1 */ 179: while(1){ 180: if (k >= p->b_msigbits) 181: break; 182: mask = ONES(i) << (CH_BITS - i); 183: if (mantissa[HOC] & mask) 184: break; 185: (void)numshift(i, mantissa, mantissa); 186: k += i; 187: exponent -= i; 188: } 189: } 190: assert(mantissa[HOC] & SIGNBIT, "integer <<ing"); 191: /* 192: * now, kick the most significant bit off the top 193: */ 194: (void)numshift(1, mantissa, mantissa); 195: break; 196: default: 197: /* 198: * map the exponent into the local area. 199: */ 200: Enumber = Znumber; 201: mapnumber(enumber, packed, 2, p->b_upemap); 202: /* 203: * Extract the exponent, and get rid 204: * of the sign bit 205: */ 206: exponent = Enumber.num_ushort[0] & ONES(15); 207: /* 208: * shift the exponent, and get rid of high order 209: * trash 210: */ 211: exponent >>= p->b_ershift; 212: exponent &= ONES(p->b_esigbits); 213: /* 214: * un excess the exponent 215: */ 216: exponent -= p->b_eexcess; 217: /* 218: * extract and extend the sign bit 219: */ 220: sign = (Enumber.num_ushort[0] & ~ONES(15)) ? -1 : 0; 221: } 222: /* 223: * Assemble the pieces, and return the number 224: */ 225: Mantissa.num_tag = TYPUNPACKED; 226: Mantissa.num_sign = sign; 227: Mantissa.num_exponent = exponent; 228: return(Mantissa); 229: } 230: 231: Bignum bignumpack(Unpacked, toconv, ovfp) 232: Bignum Unpacked; 233: int toconv; 234: Ovf *ovfp; 235: { 236: Bignum Back; 237: Bignum Enumber; 238: Bignum Temp; 239: 240: short exponent; 241: char sign; 242: reg struct ty_bigdesc *p; 243: reg chptr back; 244: reg chptr enumber; 245: reg chptr temp; 246: reg chptr unpacked; 247: 248: int i,j; 249: 250: if (Unpacked.num_tag != TYPUNPACKED) 251: panic("Argument to bignumpack is not unpacked"); 252: 253: *ovfp = 0; 254: Back = Znumber; 255: Temp = Znumber; 256: Back.num_tag = toconv; 257: 258: back = CH_FIELD(Back); 259: temp = CH_FIELD(Temp); 260: enumber = CH_FIELD(Enumber); 261: unpacked = CH_FIELD(Unpacked); 262: p = &ty_bigdesc[toconv]; 263: 264: exponent = Unpacked.num_exponent; 265: sign = Unpacked.num_sign; 266: if (exponent == MINEXP) 267: return(Back); /* identically zero */ 268: 269: switch(toconv){ 270: case TYPB: 271: case TYPW: 272: case TYPL: 273: case TYPQ: 274: case TYPO: 275: /* 276: * Put back in the assumed high order fraction 277: * bit that is always a 1. 278: */ 279: (void)numshift(-1, temp, unpacked); 280: temp[HOC] |= SIGNBIT; 281: if (exponent > p->b_eexcess){ 282: /* 283: * Construct the largest positive integer 284: */ 285: (void)numclear(temp); 286: (void)num1comp(temp, temp); 287: temp[HOC] &= ~SIGNBIT; 288: sign = sign; 289: *ovfp |= OVF_OVERFLOW; 290: } else 291: if (exponent <= 0){ 292: /* 293: * chop the temp; underflow to integer 0 294: */ 295: (void)numclear(temp); 296: sign = 0; 297: *ovfp |= OVF_UNDERFLOW; 298: } else { 299: /* 300: * denormalize the temp. 301: * This will again chop, by shifting 302: * bits off the right end into oblivion. 303: */ 304: for (j = 4; j >= 0; --j){ 305: i = 1 << j; /* 16, 8, 4, 2, 1 */ 306: while(exponent + i <= p->b_eexcess){ 307: numshift(-i, temp, temp); 308: exponent += i; 309: } 310: } 311: } 312: /* 313: * negate the temp if the sign is set 314: */ 315: if (sign) 316: *ovfp |= numnegate(temp, temp); 317: /* 318: * Stuff the temp number into the return area 319: */ 320: mapnumber(back, temp, 16, p->b_pmmap); 321: return(Back); 322: default: 323: /* 324: * Shift the mantissa to the right, filling in zeroes on 325: * the left. This aligns the least significant bit 326: * on the bottom of a byte, something that upround 327: * will use. 328: * Put the result into a temporary. 329: * Even though the shift may be zero, there 330: * is still a copy involved here. 331: */ 332: (void)numshift(-(p->b_mlshift), temp, unpacked); 333: /* 334: * Perform the rounding by adding in 0.5 ulp's 335: */ 336: exponent = upround(&Temp, p, exponent); 337: /* 338: * Do a range check on the exponent, in preparation 339: * to stuffing it in. 340: */ 341: if ((short)(exponent + p->b_eexcess) == 0){ 342: /* 343: * Sorry, no gradual underflow on the 344: * VAX. Chop this beasty totally to zero 345: */ 346: goto zeroret; 347: } else 348: if ((short)(exponent + p->b_eexcess) < 0){ 349: /* 350: * True underflow will happen; 351: * Chop everything to positive zero 352: */ 353: zeroret: 354: (void)numclear(temp); 355: exponent = 0; 356: sign = 0; /* avoid reserved operand! */ 357: *ovfp |= OVF_UNDERFLOW; 358: } else 359: if ((unsigned)(exponent + p->b_eexcess) 360: >= (unsigned)(1 << p->b_esigbits)){ 361: /* 362: * Construct the largest magnitude possible 363: * floating point unpacked: 0.{1}111111111 364: */ 365: (void)numclear(temp); 366: (void)num1comp(temp, temp); 367: exponent = ONES(p->b_esigbits); 368: sign = sign; 369: *ovfp |= OVF_OVERFLOW; 370: } else { 371: /* 372: * The exponent will fit. 373: * Bias it up, and the common code will stuff it. 374: */ 375: exponent += p->b_eexcess; 376: } 377: exponent <<= p->b_ershift; 378: /* 379: * mask out trash for the sign, and put in the sign. 380: */ 381: exponent &= ONES(15); 382: if (sign) 383: exponent |= ~ONES(15); 384: Enumber.num_ushort[0] = exponent; 385: /* 386: * Map the unpacked exponent into the value going back 387: */ 388: mapnumber(back, enumber, 2, p->b_pemap); 389: /* 390: * Stuff the unpacked mantissa into the return area 391: */ 392: mapnumber(back, temp, 16, p->b_pmmap); 393: return(Back); 394: } 395: /*NOTREACHED*/ 396: } 397: 398: mapnumber(chp1, chp2, nbytes, themap) 399: chptr chp1, chp2; 400: int nbytes; 401: char *themap; 402: { 403: reg int i; 404: reg u_char *p1, *p2; 405: 406: p1 = (u_char *)chp1; 407: p2 = (u_char *)chp2; 408: for (i = 0; i < nbytes; i++){ 409: switch(themap[i]){ 410: case NOTAKE: 411: break; 412: default: 413: p1[themap[i]] |= p2[i]; 414: break; 415: } 416: } 417: } 418: 419: #define UPSHIFT 2 420: /* 421: * round in 1/2 ulp in the number, possibly modifying 422: * the binary exponent if there was total carry out. 423: * Return the modified exponent 424: */ 425: int upround(numberp, p, exponent) 426: reg Bignum *numberp; 427: reg struct ty_bigdesc *p; 428: int exponent; 429: { 430: reg u_char *bytep; 431: int nbytes; 432: int byteindex; 433: int hofractionbit; 434: int ovffractionbit; 435: reg int ovfbitindex; 436: reg chptr number; 437: static Bignum ulp; 438: 439: /* 440: * Find out the byte index of the byte containing the ulp 441: */ 442: number = CH_FIELD(numberp[0]); 443: bytep = numberp->num_uchar; 444: 445: nbytes = (p->b_msigbits - 1) + p->b_mlshift; 446: assert((nbytes % 8) == 0, "mantissa sig bits"); 447: nbytes /= 8; 448: byteindex = 15 - nbytes; 449: assert(byteindex >= 0, "ulp in outer space"); 450: /* 451: * Shift the number to the right by two places, 452: * so that we can do full arithmetic without overflowing 453: * to the left. 454: */ 455: numshift(-UPSHIFT, number, number); 456: /* 457: * Construct the missing high order fraction bit 458: */ 459: ovfbitindex = 8 - (p->b_mlshift + UPSHIFT); 460: assert(ovfbitindex >= 0, "Shifted byte 15 into byte 14"); 461: hofractionbit = (0x01 << ovfbitindex); 462: ovffractionbit = (0x02 << ovfbitindex); 463: bytep[15] |= hofractionbit; 464: /* 465: * construct the unit in the last place, and it 466: * to the fraction 467: */ 468: ulp.num_uchar[byteindex] |= (0x80 >> UPSHIFT); 469: numaddv(number, number, CH_FIELD(ulp)); 470: ulp.num_uchar[byteindex] &= ~(0x80 >> UPSHIFT); 471: /* 472: * Check if there was an overflow, 473: * and adjust by shifting. 474: * Also, bring the number back into canonical 475: * unpacked form by left shifting by two to undeo 476: * what we did before. 477: */ 478: if (bytep[15] & ovffractionbit){ 479: exponent += 1; 480: numshift(UPSHIFT - 1, number, number); 481: } else { 482: numshift(UPSHIFT, number, number); 483: } 484: /* 485: * Clear off trash in the unused bits of the high 486: * order byte of the number 487: */ 488: bytep[15] &= ONES(8 - p->b_mlshift); 489: return(exponent); 490: } 491: #ifdef DEBUG 492: bignumprint(number) 493: Bignum number; 494: { 495: printf("Bignum: %s (exp: %d, sign: %d) 0x%08x%08x%08x%08x", 496: ty_string[number.num_tag], 497: number.num_exponent, 498: number.num_sign, 499: number.num_uint[3], 500: number.num_uint[2], 501: number.num_uint[1], 502: number.num_uint[0]); 503: switch(number.num_tag){ 504: case TYPB: 505: case TYPW: 506: case TYPL: 507: case TYPQ: 508: case TYPO: 509: case TYPUNPACKED: 510: break; 511: case TYPF: 512: printf(" == %10.8e", number.num_num.numFf_float.Ff_value); 513: break; 514: case TYPD: 515: printf(" == %20.17e", number.num_num.numFd_float.Fd_value); 516: break; 517: case TYPG: 518: case TYPH: 519: break; 520: } 521: } 522: 523: numprintovf(ovf) 524: Ovf ovf; 525: { 526: int i; 527: static struct ovftab{ 528: Ovf which; 529: char *print; 530: } ovftab[] = { 531: OVF_POSOVF, "posovf", 532: OVF_MAXINT, "maxint", 533: OVF_ADDV, "addv", 534: OVF_LSHIFT, "lshift", 535: OVF_F, "F float", 536: OVF_D, "D float", 537: OVF_G, "G float", 538: OVF_H, "H float", 539: OVF_OVERFLOW, "cvt overflow", 540: OVF_UNDERFLOW, "cvt underflow", 541: 0, 0 542: }; 543: for(i = 0; ovftab[i].which; i++){ 544: if (ovf & ovftab[i].which) 545: printf("Overflow(%s) ", ovftab[i].print); 546: } 547: } 548: #endif DEBUG