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