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