|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #if defined(LIBC_SCCS) && !defined(lint) ! 21: .asciz "@(#)atof.s 5.3 (Berkeley) 6/1/90" ! 22: #endif /* LIBC_SCCS and not lint */ ! 23: ! 24: #include "DEFS.h" ! 25: ! 26: /* ! 27: * atof: convert ascii to floating ! 28: * ! 29: * C usage: ! 30: * ! 31: * double atof (s) ! 32: * char *s; ! 33: * ! 34: * Register usage: ! 35: * ! 36: * r0-1: value being developed ! 37: * r2: first section: pointer to the next character ! 38: * second section: binary exponent ! 39: * r3: flags ! 40: * r4: first section: the current character ! 41: * second section: scratch ! 42: * r5: the decimal exponent ! 43: * r6-7: scratch ! 44: */ ! 45: .set msign,0 # mantissa has negative sign ! 46: .set esign,1 # exponent has negative sign ! 47: .set decpt,2 # decimal point encountered ! 48: ! 49: ENTRY(atof, R6|R7) ! 50: /* ! 51: * Initialization ! 52: */ ! 53: clrl r3 # All flags start out false ! 54: movl 4(fp),r2 # Address the first character ! 55: clrl r5 # Clear starting exponent ! 56: /* ! 57: * Skip leading white space ! 58: */ ! 59: sk0: movzbl (r2),r4 # Fetch the next (first) character ! 60: incl r2 ! 61: cmpb $' ,r4 # Is it blank? ! 62: beql sk0 # ...yes ! 63: cmpb r4,$8 # 8 is lowest of white-space group ! 64: blss sk1 # Jump if char too low to be white space ! 65: cmpb r4,$13 # 13 is highest of white-space group ! 66: bleq sk0 # Jump if character is white space ! 67: sk1: ! 68: /* ! 69: * Check for a sign ! 70: */ ! 71: cmpb $'+,r4 # Positive sign? ! 72: beql cs1 # ... yes ! 73: cmpb $'-,r4 # Negative sign? ! 74: bneq cs2 # ... no ! 75: orb2 $1<msign,r3 # Indicate a negative mantissa ! 76: cs1: movzbl (r2),r4 # Skip the character ! 77: incl r2 ! 78: cs2: ! 79: /* ! 80: * Accumulate digits, keeping track of the exponent ! 81: */ ! 82: clrl r1 ! 83: clrl r0 # Clear the accumulator ! 84: ad0: cmpb r4,$'0 # Do we have a digit? ! 85: blss ad4 # ... no, too small ! 86: cmpb r4,$'9 ! 87: bgtr ad4 # ... no, too large ! 88: /* ! 89: * We got a digit. Accumulate it ! 90: */ ! 91: cmpl r0,$214748364 # Would this digit cause overflow? ! 92: bgeq ad1 # ... yes ! 93: /* ! 94: * Multiply (r0,r1) by 10. This is done by developing ! 95: * (r0,r1)*2 in (r6,r7), shifting (r0,r1) left three bits, ! 96: * and adding the two quadwords. ! 97: */ ! 98: shlq $1,r0,r6 # (r6,r7)=(r0,r1)*2 ! 99: shlq $3,r0,r0 # (r0,r1)=(r0,r1)*8 ! 100: addl2 r7,r1 # Add low halves ! 101: adwc r6,r0 # Add high halves ! 102: /* ! 103: * Add in the digit ! 104: */ ! 105: subl2 $'0,r4 # Get the digit value ! 106: addl2 r4,r1 # Add it into the accumulator ! 107: adwc $0,r0 # Possible carry into high half ! 108: brb ad2 # Join common code ! 109: /* ! 110: * Here when the digit won't fit in the accumulator ! 111: */ ! 112: ad1: incl r5 # Ignore the digit, bump exponent ! 113: /* ! 114: * If we have seen a decimal point, decrease the exponent by 1 ! 115: */ ! 116: ad2: bbc $decpt,r3,ad3 # Jump if decimal point not seen ! 117: decl r5 # Decrease exponent ! 118: ad3: ! 119: /* ! 120: * Fetch the next character, back for more ! 121: */ ! 122: movzbl (r2),r4 # Fetch ! 123: incl r2 ! 124: brb ad0 # Try again ! 125: /* ! 126: * Not a digit. Could it be a decimal point? ! 127: */ ! 128: ad4: cmpb r4,$'. # If it's not a decimal point, either it's ! 129: bneq ad5 # the end of the number or the start of ! 130: # the exponent. ! 131: bbs $decpt,r3,ad5 ! 132: orb2 $1<decpt,r3 # If it IS a decimal point, we record that ! 133: brb ad3 # we've seen one, and keep collecting ! 134: # digits if it is the first one. ! 135: ! 136: /* ! 137: * Check for an exponent ! 138: */ ! 139: ad5: clrl r6 # Initialize the exponent accumulator ! 140: ! 141: cmpb r4,$'e # We allow both lower case e ! 142: beql ex1 # ... and ... ! 143: cmpb r4,$'E # upper-case E ! 144: bneq ex7 ! 145: /* ! 146: * Does the exponent have a sign? ! 147: */ ! 148: ex1: movzbl (r2),r4 # Get next character ! 149: incl r2 ! 150: cmpb r4,$'+ # Positive sign? ! 151: beql ex2 # ... yes ... ! 152: cmpb r4,$'- # Negative sign? ! 153: bneq ex3 # ... no ... ! 154: orb2 $1<esign,r3 # Indicate exponent is negative ! 155: ex2: movzbl (r2),r4 # Grab the next character ! 156: incl r2 ! 157: /* ! 158: * Accumulate exponent digits in r6 ! 159: */ ! 160: ex3: cmpb r4,$'0 # A digit is within the range ! 161: blss ex4 # '0' through ! 162: cmpb r4,$'9 # '9', ! 163: bgtr ex4 # inclusive. ! 164: cmpl r6,$214748364 # Exponent outrageously large already? ! 165: bgeq ex2 # ... yes ! 166: moval (r6)[r6],r6 # r6 *= 5 ! 167: movaw -'0(r4)[r6],r6 # r6 = r6 * 2 + r4 - '0' ! 168: brb ex2 # Go 'round again ! 169: ex4: ! 170: /* ! 171: * Now get the final exponent and force it within a reasonable ! 172: * range so our scaling loops don't take forever for values ! 173: * that will ultimately cause overflow or underflow anyway. ! 174: * A tight check on over/underflow will be done by ldexp. ! 175: */ ! 176: bbc $esign,r3,ex5 # Jump if exponent not negative ! 177: mnegl r6,r6 # If sign, negate exponent ! 178: ex5: addl2 r6,r5 # Add given exponent to calculated exponent ! 179: cmpl r5,$-100 # Absurdly small? ! 180: bgtr ex6 # ... no ! 181: movl $-100,r5 # ... yes, force within limit ! 182: ex6: cmpl r5,$100 # Absurdly large? ! 183: blss ex7 # ... no ! 184: movl $100,r5 # ... yes, force within bounds ! 185: ex7: ! 186: /* ! 187: * Our number has now been reduced to a mantissa and an exponent. ! 188: * The mantissa is a 63-bit positive binary integer in r0,r1, ! 189: * and the exponent is a signed power of 10 in r5. The msign ! 190: * bit in r3 will be on if the mantissa should ultimately be ! 191: * considered negative. ! 192: * ! 193: * We now have to convert it to a standard format floating point ! 194: * number. This will be done by accumulating a binary exponent ! 195: * in r2, as we progressively get r5 closer to zero. ! 196: * ! 197: * Don't bother scaling if the mantissa is zero ! 198: */ ! 199: tstl r1 ! 200: bneq 1f ! 201: tstl r0 # Mantissa zero? ! 202: jeql exit # ... yes ! 203: ! 204: 1: clrl r2 # Initialize binary exponent ! 205: tstl r5 # Which way to scale? ! 206: bleq sd0 # Scale down if decimal exponent <= 0 ! 207: /* ! 208: * Scale up by "multiplying" r0,r1 by 10 as many times as necessary, ! 209: * as follows: ! 210: * ! 211: * Step 1: Shift r0,r1 right as necessary to ensure that no ! 212: * overflow can occur when multiplying. ! 213: */ ! 214: su0: cmpl r0,$429496729 # Compare high word to (2**31)/5 ! 215: blss su1 # Jump out if guaranteed safe ! 216: shrq $1,r0,r0 # Else shift right one bit ! 217: incl r2 # bump exponent to compensate ! 218: brb su0 # and go back to test again. ! 219: /* ! 220: * Step 2: Multiply r0,r1 by 5, by appropriate shifting and ! 221: * double-precision addition ! 222: */ ! 223: su1: shlq $2,r0,r6 # (r6,r7) := (r0,r1) * 4 ! 224: addl2 r7,r1 # Add low-order halves ! 225: adwc r6,r0 # and high-order halves ! 226: /* ! 227: * Step 3: Increment the binary exponent to take care of the final ! 228: * factor of 2, and go back if we still need to scale more. ! 229: */ ! 230: incl r2 # Increment the exponent ! 231: decl r5 # ...sobgtr r5,su0 ! 232: bgtr su0 # and back for more (maybe) ! 233: ! 234: brb cm0 # Merge to build final value ! 235: ! 236: /* ! 237: * Scale down. We must "divide" r0,r1 by 10 as many times ! 238: * as needed, as follows: ! 239: * ! 240: * Step 0: Right now, the condition codes reflect the state ! 241: * of r5. If it's zero, we are done. ! 242: */ ! 243: sd0: beql cm0 # If finished, build final number ! 244: /* ! 245: * Step 1: Shift r0,r1 left until the high-order bit (not counting ! 246: * the sign bit) is nonzero, so that the division will preserve ! 247: * as much precision as possible. ! 248: */ ! 249: tstl r0 # Is the entire high-order half zero? ! 250: bneq sd2 # ...no, go shift one bit at a time ! 251: shlq $30,r0,r0 # ...yes, shift left 30, ! 252: subl2 $30,r2 # decrement the exponent to compensate, ! 253: # and now it's known to be safe to shift ! 254: # at least once more. ! 255: sd1: shlq $1,r0,r0 # Shift (r0,r1) left one, and ! 256: decl r2 # decrement the exponent to compensate ! 257: sd2: bbc $30,r0,sd1 # If the high-order bit is off, go shift ! 258: /* ! 259: * Step 2: Divide the high-order part of (r0,r1) by 5, ! 260: * giving a quotient in r1 and a remainder in r7. ! 261: */ ! 262: sd3: movl r0,r7 # Copy the high-order part ! 263: clrl r6 # Zero-extend to 64 bits ! 264: ediv $5,r6,r0,r6 # Divide (cannot overflow) ! 265: /* ! 266: * Step 3: Divide the low-order part of (r0,r1) by 5, ! 267: * using the remainder from step 2 for rounding. ! 268: * Note that the result of this computation is unsigned, ! 269: * so we have to allow for the fact that an ordinary division ! 270: * by 5 could overflow. We make allowance by dividing by 10, ! 271: * multiplying the quotient by 2, and using the remainder ! 272: * to adjust the modified quotient. ! 273: */ ! 274: addl3 $2,r1,r7 # Dividend is low part of (r0,r1) plus ! 275: adwc $0,r6 # 2 for rounding plus ! 276: # (2**32) * previous remainder ! 277: ediv $10,r6,r1,r7 # r1 := quotient, r7 := remainder. ! 278: addl2 r1,r1 # Make r1 result of dividing by 5 ! 279: cmpl r7,$5 # If remainder is 5 or greater, ! 280: blss sd4 # increment the adjustted quotient. ! 281: incl r1 ! 282: /* ! 283: * Step 4: Increment the decimal exponent, decrement the binary ! 284: * exponent (to make the division by 5 into a division by 10), ! 285: * and back for another iteration. ! 286: */ ! 287: sd4: decl r2 # Binary exponent ! 288: aoblss $0,r5,sd2 ! 289: /* ! 290: * We now have the following: ! 291: * ! 292: * r0: high-order half of a 64-bit integer ! 293: * r1: load-order half of the same 64-bit integer ! 294: * r2: a binary exponent ! 295: * ! 296: * Our final result is the integer represented by (r0,r1) ! 297: * multiplied by 2 to the power contained in r2. ! 298: * We will transform (r0,r1) into a floating-point value, ! 299: * set the sign appropriately, and let ldexp do the ! 300: * rest of the work. ! 301: * ! 302: * Step 1: if the high-order bit (excluding the sign) of ! 303: * the high-order half (r0) is 1, then we have 63 bits of ! 304: * fraction, too many to convert easily. However, we also ! 305: * know we won't need them all, so we will just throw the ! 306: * low-order bit away (and adjust the exponent appropriately). ! 307: */ ! 308: cm0: bbc $30,r0,cm1 # jump if no adjustment needed ! 309: shrq $1,r0,r0 # lose the low-order bit ! 310: incl r2 # increase the exponent to compensate ! 311: /* ! 312: * Step 2: split the 62-bit number in (r0,r1) into two ! 313: * 31-bit positive quantities ! 314: */ ! 315: cm1: shlq $1,r0,r0 # put the high-order bits in r0 ! 316: # and a 0 in the bottom of r1 ! 317: shrl $1,r1,r1 # right-justify the bits in r1 ! 318: # moving 0 into the sign bit. ! 319: /* ! 320: * Step 3: convert both halves to floating point ! 321: */ ! 322: cvld r1 ! 323: std r6 # low-order part in r6-r7 ! 324: cvld r0 ! 325: std r0 # high-order part in r0-r1 ! 326: /* ! 327: * Step 4: multiply the high order part by 2**31 and combine them ! 328: */ ! 329: ldd two31 ! 330: muld r0 # multiply ! 331: addd r6 # combine ! 332: /* ! 333: * Step 5: if appropriate, negate the floating value ! 334: */ ! 335: bbc $msign,r3,cm2 # Jump if mantissa not signed ! 336: negd # If negative, make it so ! 337: /* ! 338: * Step 6: call ldexp to complete the job ! 339: */ ! 340: cm2: pushl r2 # Put exponent in parameter list ! 341: pushd # and also mantissa ! 342: calls $3,_ldexp # go combine them ! 343: ! 344: exit: ! 345: ret ! 346: ! 347: .align 2 ! 348: two31: .long 0x50000000 # (=2147483648) 2 ** 31 in floating-point ! 349: .long 0 # so atof doesn't have to convert it
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.