1*5805Srrh /* 2*5805Srrh * Copyright (c) 1982 Regents of the University of California 3*5805Srrh */ 4*5805Srrh #ifndef lint 5*5805Srrh static char sccsid[] = "@(#)natof.c 4.1 02/14/82"; 6*5805Srrh #endif not lint 7*5805Srrh 8*5805Srrh #include <stdio.h> 9*5805Srrh #include <ctype.h> 10*5805Srrh #include <errno.h> 11*5805Srrh 12*5805Srrh #include "as.h" 13*5805Srrh 14*5805Srrh Bignum bigatof(str, radix) 15*5805Srrh reg char *str; /* r11 */ 16*5805Srrh int radix; /* TYPF ... TYPH */ 17*5805Srrh { 18*5805Srrh int msign; 19*5805Srrh int esign; 20*5805Srrh int decpt; 21*5805Srrh reg chptr temp; /* r10 */ 22*5805Srrh reg u_int quotient; /* r9 */ /* must be here */ 23*5805Srrh reg u_int remainder; /* r8 */ /* must be here */ 24*5805Srrh reg chptr acc; 25*5805Srrh reg int dividend; /* for doing division */ 26*5805Srrh reg u_int i; 27*5805Srrh short *sptr; /* for doing division */ 28*5805Srrh int ch; 29*5805Srrh int dexponent; /* decimal exponent */ 30*5805Srrh int bexponent; /* binary exponent */ 31*5805Srrh Bignum Acc; 32*5805Srrh Bignum Temp; 33*5805Srrh static Bignum znumber; 34*5805Srrh Ovf ovf; 35*5805Srrh u_int j; 36*5805Srrh extern int errno; 37*5805Srrh u_int ediv(); 38*5805Srrh 39*5805Srrh #ifdef lint 40*5805Srrh quotient = 0; 41*5805Srrh remainder = 0; 42*5805Srrh #endif lint 43*5805Srrh msign = 0; 44*5805Srrh esign = 0; 45*5805Srrh decpt = 0; 46*5805Srrh dexponent = 0; 47*5805Srrh Acc = znumber; 48*5805Srrh Acc.num_tag = radix; 49*5805Srrh acc = CH_FIELD(Acc); 50*5805Srrh temp = CH_FIELD(Temp); 51*5805Srrh 52*5805Srrh do{ 53*5805Srrh ch = *str++; 54*5805Srrh } while(isspace(ch)); 55*5805Srrh 56*5805Srrh switch(ch){ 57*5805Srrh case '-': 58*5805Srrh msign = -1; 59*5805Srrh /* FALLTHROUGH */ 60*5805Srrh case '+': 61*5805Srrh ch = *str++; 62*5805Srrh break; 63*5805Srrh } 64*5805Srrh dofract: 65*5805Srrh for(; isdigit(ch); ch = *str++){ 66*5805Srrh assert(((acc[HOC] & SIGNBIT) == 0), "Negative HOC"); 67*5805Srrh if (acc[HOC] < MAXINT_10){ 68*5805Srrh ovf = numshift(3, temp, acc); 69*5805Srrh ovf |= numshift(1, acc, acc); 70*5805Srrh ovf |= numaddv(acc, temp, acc); 71*5805Srrh ovf |= numaddd(acc, acc, ch - '0'); 72*5805Srrh assert(ovf == 0, "Overflow building mantissa"); 73*5805Srrh } else { 74*5805Srrh /* 75*5805Srrh * Then, the number is too large anyway 76*5805Srrh */ 77*5805Srrh dexponent++; 78*5805Srrh } 79*5805Srrh if (decpt) 80*5805Srrh dexponent--; 81*5805Srrh } 82*5805Srrh switch(ch){ 83*5805Srrh case '.': 84*5805Srrh if (decpt == 0){ 85*5805Srrh decpt++; 86*5805Srrh ch = *str++; 87*5805Srrh goto dofract; 88*5805Srrh } 89*5805Srrh break; 90*5805Srrh /* 91*5805Srrh * only 'e' and 'E' are recognized by atof() 92*5805Srrh */ 93*5805Srrh case 'e': 94*5805Srrh case 'E': 95*5805Srrh /* 96*5805Srrh * we include the remainder for compatability with as formats 97*5805Srrh * in as, the radix actual paramater agrees with the character 98*5805Srrh * we expect; consequently, no checking is done. 99*5805Srrh */ 100*5805Srrh case 'd': 101*5805Srrh case 'D': 102*5805Srrh case 'g': 103*5805Srrh case 'G': 104*5805Srrh case 'h': 105*5805Srrh case 'H': 106*5805Srrh j = 0; 107*5805Srrh ch = *str++; 108*5805Srrh esign = 0; 109*5805Srrh switch(ch){ 110*5805Srrh case '-': 111*5805Srrh esign = 1; 112*5805Srrh /* FALLTHROUGH */ 113*5805Srrh case '+': 114*5805Srrh ch = *str++; 115*5805Srrh } 116*5805Srrh for(; isdigit(ch); ch = *str++){ 117*5805Srrh if (j < MAXINT_10){ 118*5805Srrh j *= 10; 119*5805Srrh j += ch - '0'; 120*5805Srrh } else { 121*5805Srrh /* 122*5805Srrh * outrageously large exponent 123*5805Srrh */ 124*5805Srrh /*VOID*/ 125*5805Srrh } 126*5805Srrh } 127*5805Srrh if (esign) 128*5805Srrh dexponent -= j; 129*5805Srrh else 130*5805Srrh dexponent += j; 131*5805Srrh /* 132*5805Srrh * There should be a range check on dexponent here 133*5805Srrh */ 134*5805Srrh } 135*5805Srrh /* 136*5805Srrh * The number has now been reduced to a mantissa 137*5805Srrh * and an exponent. 138*5805Srrh * The mantissa is an n bit number (to the precision 139*5805Srrh * of the extended words) in the acc. 140*5805Srrh * The exponent is a signed power of 10 in dexponent. 141*5805Srrh * msign is on if the resulting number will eventually 142*5805Srrh * be negative. 143*5805Srrh * 144*5805Srrh * We now must convert the number to standard format floating 145*5805Srrh * number, which will be done by accumulating 146*5805Srrh * a binary exponent in bexponent, as we gradually 147*5805Srrh * drive dexponent towards zero, one count at a time. 148*5805Srrh */ 149*5805Srrh if (isclear(acc)){ 150*5805Srrh return(Acc); 151*5805Srrh } 152*5805Srrh bexponent = 0; 153*5805Srrh 154*5805Srrh /* 155*5805Srrh * Scale the number down. 156*5805Srrh * We must divide acc by 10 as many times as needed. 157*5805Srrh */ 158*5805Srrh for (; dexponent < 0; dexponent++){ 159*5805Srrh /* 160*5805Srrh * Align the number so that the most significant 161*5805Srrh * bits are aligned in the most significant 162*5805Srrh * bits of the accumulator, adjusting the 163*5805Srrh * binary exponent as we shift. 164*5805Srrh * The goal is to get the high order bit (NOT the 165*5805Srrh * sign bit) set. 166*5805Srrh */ 167*5805Srrh assert(((acc[HOC] & SIGNBIT) == 0), "Negative HOC"); 168*5805Srrh ovf = 0; 169*5805Srrh 170*5805Srrh for (j = 5; j >= 1; --j){ 171*5805Srrh i = 1 << (j - 1); /* 16, 8, 4, 2, 1 */ 172*5805Srrh quotient = ONES(i); 173*5805Srrh quotient <<= (CH_BITS - 1) - i; 174*5805Srrh while((acc[HOC] & quotient) == 0){ 175*5805Srrh ovf |= numshift((int)i, acc, acc); 176*5805Srrh bexponent -= i; 177*5805Srrh } 178*5805Srrh } 179*5805Srrh /* 180*5805Srrh * Add 2 to the accumulator to effect rounding, 181*5805Srrh * and get set up to divide by 5. 182*5805Srrh */ 183*5805Srrh ovf = numaddd(acc, acc, 2); 184*5805Srrh assert(ovf == 0, "Carry out of left rounding up by 2"); 185*5805Srrh /* 186*5805Srrh * Divide the high order chunks by 5; 187*5805Srrh * The last chunk will be divided by 10, 188*5805Srrh * (to see what the remainder is, also to effect rounding) 189*5805Srrh * and then multipiled by 2 to effect division by 5. 190*5805Srrh */ 191*5805Srrh remainder = 0; 192*5805Srrh #if DEBUGNATOF 193*5805Srrh printf("Dividing: "); 194*5805Srrh bignumprint(Acc); 195*5805Srrh printf("\n"); 196*5805Srrh #endif DEBUGNATOF 197*5805Srrh sptr = (short *)acc; 198*5805Srrh for (i = (CH_N * 2 - 1); i >= 1; --i){ 199*5805Srrh /* 200*5805Srrh * Divide (remainder:16).(acc[i]:16) 201*5805Srrh * by 5, putting the quotient back 202*5805Srrh * into acc[i]:16, and save the remainder 203*5805Srrh * for the next iteration. 204*5805Srrh */ 205*5805Srrh dividend = (remainder << 16) | (sptr[i] & ONES(16)); 206*5805Srrh assert(dividend >= 0, "dividend < 0"); 207*5805Srrh quotient = dividend / 5; 208*5805Srrh remainder = dividend - (quotient * 5); 209*5805Srrh sptr[i] = quotient; 210*5805Srrh remainder = remainder; 211*5805Srrh } 212*5805Srrh /* 213*5805Srrh * Divide the lowest order chunk by 10, 214*5805Srrh * saving the remainder to decide how to round. 215*5805Srrh * Then, multiply by 2, making it look as 216*5805Srrh * if we divided by 10. 217*5805Srrh * This multiply fills in a 0 on the least sig bit. 218*5805Srrh */ 219*5805Srrh dividend = (remainder << 16) | (sptr[0] & ONES(16)); 220*5805Srrh assert(dividend >= 0, "dividend < 0"); 221*5805Srrh quotient = dividend / 10; 222*5805Srrh remainder = dividend - (quotient * 10); 223*5805Srrh sptr[0] = quotient + quotient; 224*5805Srrh 225*5805Srrh if (remainder >= 5) 226*5805Srrh ovf = numaddd(acc, acc, 1); 227*5805Srrh /* 228*5805Srrh * Now, divide by 2, effecting division by 10, 229*5805Srrh * merely by adjusting the binary exponent. 230*5805Srrh */ 231*5805Srrh bexponent--; 232*5805Srrh } 233*5805Srrh /* 234*5805Srrh * Scale the number up by multiplying by 10 as 235*5805Srrh * many times as necessary 236*5805Srrh */ 237*5805Srrh for (; dexponent > 0; dexponent--){ 238*5805Srrh /* 239*5805Srrh * Compare high word to (2**31)/5, 240*5805Srrh * and scale accordingly 241*5805Srrh */ 242*5805Srrh while ( ((unsigned)acc[HOC]) > MAXINT_5){ 243*5805Srrh (void)numshift(-1, acc, acc); 244*5805Srrh bexponent++; 245*5805Srrh } 246*5805Srrh /* 247*5805Srrh * multiply the mantissa by 5, 248*5805Srrh * and scale the binary exponent by 2 249*5805Srrh */ 250*5805Srrh ovf = numshift(2, temp, acc); 251*5805Srrh ovf |= numaddv(acc, acc, temp); 252*5805Srrh assert(ovf == 0, "Scaling * 10 of manitissa"); 253*5805Srrh bexponent++; 254*5805Srrh } 255*5805Srrh /* 256*5805Srrh * We now have: 257*5805Srrh * a CH_N chunk length binary integer, right 258*5805Srrh * justified (in native format). 259*5805Srrh * a binary exponent. 260*5805Srrh * 261*5805Srrh * Now, we treat this large integer as an octa word 262*5805Srrh * number, and unpack it into standard unpacked 263*5805Srrh * format. That unpacking will give us yet 264*5805Srrh * another binary exponent, which we adjust with 265*5805Srrh * the accumulated binary exponent. 266*5805Srrh */ 267*5805Srrh Acc.num_tag = TYPO; 268*5805Srrh #if DEBUGNATOF 269*5805Srrh printf("Octal number: "); 270*5805Srrh bignumprint(Acc); 271*5805Srrh printf("\n"); 272*5805Srrh #endif DEBUGNATOF 273*5805Srrh Acc = bignumunpack(Acc, &ovf); 274*5805Srrh 275*5805Srrh if (ovf) 276*5805Srrh errno = ERANGE; 277*5805Srrh #if DEBUGNATOF 278*5805Srrh printf("Unpacked octal number: "); 279*5805Srrh bignumprint(Acc); 280*5805Srrh printf("bexponent == %d\n", bexponent); 281*5805Srrh #endif DEBUGNATOF 282*5805Srrh Acc.num_exponent += bexponent; 283*5805Srrh assert(Acc.num_sign == 0, "unpacked integer is < 0"); 284*5805Srrh Acc.num_sign = msign; 285*5805Srrh /* 286*5805Srrh * We now pack the number back into a radix format number. 287*5805Srrh * This checks for overflow, underflow, 288*5805Srrh * and rounds by 1/2 ulp. 289*5805Srrh */ 290*5805Srrh ovf = 0; 291*5805Srrh Acc = bignumpack(Acc, radix, &ovf); 292*5805Srrh if (ovf) 293*5805Srrh errno = ERANGE; 294*5805Srrh #if DEBUGNATOF 295*5805Srrh printf("packed number: "); 296*5805Srrh bignumprint(Acc); 297*5805Srrh printf("\n"); 298*5805Srrh #endif DEBUGNATOF 299*5805Srrh return(Acc); 300*5805Srrh } 301*5805Srrh #if 0 302*5805Srrh /* 303*5805Srrh * Unfortunately, one can't use the ediv instruction to do 304*5805Srrh * division on numbers with > 64 bits. 305*5805Srrh * This is because ediv returns signed quantities; 306*5805Srrh * if the quotient is an unsigned number > 2^31, 307*5805Srrh * ediv sets integer overflow. 308*5805Srrh */ 309*5805Srrh unsigned int ediv(high, low, divisor, qp, i) 310*5805Srrh register unsigned int high; /* r11 */ 311*5805Srrh register unsigned int low; /* r10 */ 312*5805Srrh register unsigned int divisor; /* r9 */ 313*5805Srrh unsigned int *qp; 314*5805Srrh { 315*5805Srrh register unsigned int remainder; /* r8 */ 316*5805Srrh register unsigned int quotient; /* r7 */ 317*5805Srrh 318*5805Srrh asm("ediv r9, r10, r7, r8 # Divide. q->r7, r->r8 (discarded)"); 319*5805Srrh *qp = quotient; 320*5805Srrh return(remainder); 321*5805Srrh } 322*5805Srrh #endif 0 323