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

Defined functions

bignumconvert defined in line 93; used 2 times
bignumpack defined in line 231; used 4 times
bignumprint defined in line 492; used 5 times
bignumunpack defined in line 113; used 5 times
floatconvert defined in line 35; used 2 times
intconvert defined in line 16; used 2 times
mapnumber defined in line 398; used 5 times
numprintovf defined in line 523; never used
upround defined in line 425; used 1 times

Defined variables

Znumber defined in line 13; used 14 times
sccsid defined in line 8; never used

Defined struct's

ovftab defined in line 527; never used

Defined macros

CONV defined in line 33; used 13 times
MINEXP defined in line 14; used 2 times
UPSHIFT defined in line 419; used 6 times
Last modified: 1985-04-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1623
Valid CSS Valid XHTML 1.0 Strict