|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982 Regents of the University of California ! 3: */ ! 4: #ifndef lint ! 5: static char sccsid[] = "@(#)bignum1.c 4.4 6/30/83"; ! 6: #endif not lint ! 7: ! 8: #include <errno.h> ! 9: #include <stdio.h> ! 10: #include "as.h" ! 11: ! 12: /* ! 13: * Construct a floating point number ! 14: */ ! 15: Bignum as_atof(numbuf, radix, ovfp) ! 16: char *numbuf; ! 17: int radix; ! 18: Ovf *ovfp; ! 19: { ! 20: Bignum number; ! 21: extern int errno; ! 22: double atof(); ! 23: ! 24: number = Znumber; ! 25: errno = 0; ! 26: switch(radix){ ! 27: case TYPF: ! 28: case TYPD: ! 29: number.num_tag = TYPD; ! 30: *ovfp = 0; ! 31: number.num_num.numFd_float.Fd_value = atof(numbuf); ! 32: break; ! 33: case TYPG: ! 34: case TYPH: ! 35: number = bigatof(numbuf, radix); ! 36: break; ! 37: } ! 38: if (errno == ERANGE && passno == 2){ ! 39: yywarning("Floating conversion over/underflowed\n"); ! 40: } ! 41: return(number); ! 42: } ! 43: ! 44: /* ! 45: * Construct an integer. ! 46: */ ! 47: ! 48: Bignum as_atoi(ccp, radix, ovfp) ! 49: reg char *ccp; /* character cp */ ! 50: int radix; ! 51: Ovf *ovfp; ! 52: { ! 53: reg chptr bcp; ! 54: chptr tcp; ! 55: reg int i; ! 56: int val; ! 57: Bignum n_n; ! 58: Bignum t_n; ! 59: int sign; ! 60: Ovf ovf; ! 61: ! 62: ovf = 0; ! 63: sign = 0; ! 64: for (; *ccp; ccp++){ ! 65: switch(*ccp){ ! 66: case '0': ! 67: case '+': continue; ! 68: case '-': sign ^= 1; ! 69: continue; ! 70: } ! 71: break; ! 72: } ! 73: ! 74: n_n = Znumber; ! 75: t_n = Znumber; ! 76: bcp = CH_FIELD(n_n); (void)numclear(bcp); ! 77: tcp = CH_FIELD(t_n); (void)numclear(tcp); ! 78: for (; *ccp; ccp++){ ! 79: switch(*ccp){ ! 80: case '8': case '9': ! 81: if (radix < 10) ! 82: goto done; ! 83: /*FALLTHROUGH*/ ! 84: case '0': case '1': case '2': case '3': case '4': ! 85: case '5': case '6': case '7': ! 86: val = *ccp - '0'; ! 87: break; ! 88: case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': ! 89: if (radix < 16) ! 90: goto done; ! 91: val = *ccp - 'A' + 10; ! 92: break; ! 93: case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': ! 94: if (radix < 16) ! 95: goto done; ! 96: val = *ccp - 'a' + 10; ! 97: break; ! 98: default: ! 99: goto done; ! 100: } ! 101: switch(radix){ ! 102: case 8: ! 103: ovf |= numshift(3, bcp, bcp); ! 104: break; ! 105: case 16: ! 106: ovf |= numshift(4, bcp, bcp); ! 107: break; ! 108: case 10: ! 109: ovf |= numshift(1, tcp, bcp); ! 110: ovf |= numshift(3, bcp, bcp); ! 111: ovf |= numaddv(bcp, tcp, bcp); ! 112: break; ! 113: } ! 114: ovf |= numaddd(bcp, bcp, val); ! 115: } ! 116: done: ; ! 117: ovf |= posovf(bcp); ! 118: if (sign){ ! 119: if (ovf & OVF_MAXINT) { ! 120: ovf &= ~(OVF_MAXINT | OVF_POSOVF); ! 121: } else { ! 122: ovf |= numnegate(bcp, bcp); ! 123: } ! 124: } ! 125: /* ! 126: * find the highest set unit of the number ! 127: */ ! 128: val = sign ? -1 : 0; ! 129: for (i = 0; i < CH_N; i++){ ! 130: if (bcp[i] == val) ! 131: break; ! 132: } ! 133: { ! 134: static u_char tagtab[4][16] = { ! 135: { TYPB, ! 136: TYPW, ! 137: TYPL, TYPL, ! 138: TYPQ, TYPQ, TYPQ, TYPQ, ! 139: TYPO, TYPO, TYPO, TYPO, TYPO, TYPO, TYPO, TYPO}, ! 140: { TYPW, ! 141: TYPL, ! 142: TYPQ, TYPQ, ! 143: TYPO, TYPO, TYPO, TYPO}, ! 144: { 0 }, ! 145: { TYPL, ! 146: TYPQ, ! 147: TYPO, TYPO } ! 148: }; ! 149: /* ! 150: * i indexes to the null chunk; make it point to the ! 151: * last non null chunk ! 152: */ ! 153: i -= 1; ! 154: if (i < 0) ! 155: i = 0; ! 156: n_n.num_tag = tagtab[HOC][i]; ! 157: assert(n_n.num_tag != 0, "Botch width computation"); ! 158: } ! 159: *ovfp = ovf; ! 160: return(n_n); ! 161: } ! 162: ! 163: Ovf posovf(src) ! 164: reg chptr src; ! 165: { ! 166: reg int i; ! 167: Ovf overflow = 0; ! 168: ! 169: if (src[HOC] & SIGNBIT) ! 170: overflow = OVF_POSOVF; ! 171: if (src[HOC] == SIGNBIT){ ! 172: for (i = HOC - 1; i >= 0; --i){ ! 173: if (src[i] != 0) ! 174: return(overflow); ! 175: } ! 176: overflow |= OVF_MAXINT; ! 177: } ! 178: return(overflow); ! 179: } ! 180: ! 181: /* ! 182: * check if the number is clear ! 183: */ ! 184: int isclear(dst) ! 185: reg chptr dst; ! 186: { ! 187: return(!isunequal(dst, CH_FIELD(Znumber))); ! 188: } ! 189: ! 190: int isunequal(src1, src2) ! 191: reg chptr src1, src2; ! 192: { ! 193: reg int i; ! 194: ! 195: i = CH_N; ! 196: do{ ! 197: if (*src1++ != *src2++) ! 198: return(i); ! 199: }while(--i); ! 200: return(0); ! 201: } ! 202: ! 203: Ovf numclear(dst) ! 204: reg chptr dst; ! 205: { ! 206: reg int i; ! 207: i = CH_N; ! 208: do{ ! 209: *dst++ = 0; ! 210: }while(--i); ! 211: return(0); ! 212: } ! 213: ! 214: Ovf numshift(n, dst, src) ! 215: int n; ! 216: reg chptr dst, src; ! 217: { ! 218: reg int i; ! 219: reg u_int carryi, carryo; ! 220: reg u_int mask; ! 221: reg u_int value; ! 222: ! 223: i = CH_N; ! 224: if (n == 0){ ! 225: do{ ! 226: *dst++ = *src++; ! 227: } while(--i); ! 228: return(0); ! 229: } ! 230: ! 231: carryi = 0; ! 232: mask = ONES(n); ! 233: ! 234: if (n > 0){ ! 235: do{ ! 236: value = *src++; ! 237: carryo = (value >> (CH_BITS - n)) & mask; ! 238: value <<= n; ! 239: value &= ~mask; ! 240: *dst++ = value | carryi; ! 241: carryi = carryo; ! 242: } while (--i); ! 243: return(carryi ? OVF_LSHIFT : 0); ! 244: } else { ! 245: n = -n; ! 246: src += CH_N; ! 247: dst += CH_N; ! 248: do{ ! 249: value = *--src; ! 250: carryo = value & mask; ! 251: value >>= n; ! 252: value &= ONES(CH_BITS - n); ! 253: *--dst = value | carryi; ! 254: carryi = carryo << (CH_BITS - n); ! 255: } while (--i); ! 256: return(carryi ? OVF_LSHIFT : 0); ! 257: } ! 258: } ! 259: ! 260: Ovf numaddd(dst, src1, val) ! 261: chptr dst, src1; ! 262: int val; ! 263: { ! 264: static Bignum work; ! 265: ! 266: work.num_uchar[0] = val; ! 267: return (numaddv(dst, src1, CH_FIELD(work))); ! 268: } ! 269: ! 270: Ovf numaddv(dst, src1, src2) ! 271: reg chptr dst, src1, src2; ! 272: { ! 273: reg int i; ! 274: reg int carry; ! 275: reg u_int A,B,value; ! 276: ! 277: carry = 0; ! 278: i = CH_N; ! 279: do{ ! 280: A = *src1++; ! 281: B = *src2++; ! 282: value = A + B + carry; ! 283: *dst++ = value; ! 284: carry = 0; ! 285: if (value < A || value < B) ! 286: carry = 1; ! 287: } while (--i); ! 288: return(carry ? OVF_ADDV : 0); ! 289: } ! 290: ! 291: Ovf numnegate(dst, src) ! 292: chptr dst, src; ! 293: { ! 294: Ovf ovf; ! 295: ! 296: ovf = num1comp(dst, src) ; ! 297: ovf |= numaddd(dst, dst, 1); ! 298: return(ovf); ! 299: } ! 300: ! 301: Ovf num1comp(dst, src) ! 302: reg chptr dst, src; ! 303: { ! 304: reg int i; ! 305: i = CH_N; ! 306: do{ ! 307: *dst++ = ~ *src++; ! 308: }while (--i); ! 309: return(0); ! 310: } ! 311: ! 312: /* ! 313: * Determine if floating point numbers are ! 314: * capable of being represented as a one byte immediate literal constant ! 315: * If it is, then stuff the value into *valuep. ! 316: * argtype is how the instruction will interpret the number. ! 317: */ ! 318: int slitflt(number, argtype, valuep) ! 319: Bignum number; /* number presented */ ! 320: int argtype; /* what the instruction expects */ ! 321: int *valuep; ! 322: { ! 323: #define EXPPREC 3 ! 324: #define MANTPREC 3 ! 325: ! 326: int mask; ! 327: reg int i; ! 328: Bignum unpacked; ! 329: Ovf ovf; ! 330: ! 331: *valuep = 0; ! 332: if (!ty_float[argtype]) ! 333: return(0); ! 334: unpacked = bignumunpack(number, &ovf); ! 335: assert(ovf == 0, "overflow in unpacking floating #!?"); ! 336: if (unpacked.num_sign) ! 337: return(0); ! 338: if (unpacked.num_exponent < 0) ! 339: return(0); ! 340: if (unpacked.num_exponent > ONES(EXPPREC)) ! 341: return(0); ! 342: for (i = 0; i < HOC; i++){ ! 343: if (CH_FIELD(unpacked)[i]) ! 344: return(0); ! 345: } ! 346: if ((CH_FIELD(unpacked)[HOC]) & ONES(CH_BITS - MANTPREC)) ! 347: return(0); ! 348: *valuep = (unpacked.num_exponent & ONES(EXPPREC)) << MANTPREC; ! 349: mask = (CH_FIELD(unpacked)[HOC]) >> (CH_BITS - MANTPREC); ! 350: mask &= ONES(MANTPREC); ! 351: *valuep |= mask; ! 352: *valuep &= ONES(MANTPREC + EXPPREC); ! 353: return(1); ! 354: } ! 355: ! 356: #ifndef STANDALONE ! 357: /* ! 358: * Output a big number to txtfil ! 359: * Called only when passno == 2 ! 360: * ! 361: * The conversion specifies the width of the number to be written out. ! 362: * The width is supplied from either an initialized data directive ! 363: * (for example .float, .double), or from the operand size ! 364: * defined by an operator. ! 365: * If the number is of type quad or octal, ! 366: * we just write it out; this allows one to specify bit ! 367: * patterns for floating point numbers. ! 368: * If the number is one of the floating types and the conversion ! 369: * is not the same type, then we complain, but do the conversion anyway. ! 370: * The conversion is strict. ! 371: */ ! 372: bignumwrite(number, toconv) ! 373: Bignum number; ! 374: int toconv; /* one of TYP[QO FDGH] */ ! 375: { ! 376: reg u_int *bp; ! 377: ! 378: if (passno != 2) ! 379: return; ! 380: ! 381: bp = &number.num_uint[0]; ! 382: switch(number.num_tag){ ! 383: case TYPB: ! 384: case TYPW: ! 385: case TYPL: ! 386: case TYPQ: ! 387: case TYPO: ! 388: number = intconvert(number, toconv); ! 389: break; ! 390: default: ! 391: number = floatconvert(number, toconv); ! 392: break; ! 393: } ! 394: bwrite((char *)bp, ty_nbyte[toconv], txtfil); ! 395: } ! 396: #endif STANDALONE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.