1: /*2: * Copyright (c) 1980 Regents of the University of California.3: * All rights reserved. The Berkeley software License Agreement4: * specifies the terms and conditions for redistribution.5: */6:7: #ifdef LIBC_SCCS8: .asciz "@(#)atof.s 5.3 (Berkeley) 3/9/86"9: #endif LIBC_SCCS10:11: #include "DEFS.h"12:13: /*14: * atof: convert ascii to floating15: *16: * C usage:17: *18: * double atof (s)19: * char *s;20: *21: * Register usage:22: *23: * r0-1: value being developed24: * r2: first section: pointer to the next character25: * second section: binary exponent26: * r3: flags27: * r4: first section: the current character28: * second section: scratch29: * r5: the decimal exponent30: * r6-7: scratch31: */32: .set msign,0 # mantissa has negative sign33: .set esign,1 # exponent has negative sign34: .set decpt,2 # decimal point encountered35:36: ENTRY(atof, R6|R7)37: /*38: * Initialization39: */40: clrl r3 # All flags start out false41: movl 4(ap),r2 # Address the first character42: clrl r5 # Clear starting exponent43: /*44: * Skip leading white space45: */46: sk0: movzbl (r2)+,r4 # Fetch the next (first) character47: cmpb $' ,r4 # Is it blank?48: jeql sk0 # ...yes49: cmpb r4,$8 # 8 is lowest of white-space group50: jlss sk1 # Jump if char too low to be white space51: cmpb r4,$13 # 13 is highest of white-space group52: jleq sk0 # Jump if character is white space53: sk1:54: /*55: * Check for a sign56: */57: cmpb $'+,r4 # Positive sign?58: jeql cs1 # ... yes59: cmpb $'-,r4 # Negative sign?60: jneq cs2 # ... no61: bisb2 $1<msign,r3 # Indicate a negative mantissa62: cs1: movzbl (r2)+,r4 # Skip the character63: cs2:64: /*65: * Accumulate digits, keeping track of the exponent66: */67: clrq r0 # Clear the accumulator68: ad0: cmpb r4,$'0 # Do we have a digit?69: jlss ad4 # ... no, too small70: cmpb r4,$'971: jgtr ad4 # ... no, too large72: /*73: * We got a digit. Accumulate it74: */75: cmpl r1,$214748364 # Would this digit cause overflow?76: jgeq ad1 # ... yes77: /*78: * Multiply (r0,r1) by 10. This is done by developing79: * (r0,r1)*2 in (r6,r7), shifting (r0,r1) left three bits,80: * and adding the two quadwords.81: */82: ashq $1,r0,r6 # (r6,r7)=(r0,r1)*283: ashq $3,r0,r0 # (r0,r1)=(r0,r1)*884: addl2 r6,r0 # Add low halves85: adwc r7,r1 # Add high halves86: /*87: * Add in the digit88: */89: subl2 $'0,r4 # Get the digit value90: addl2 r4,r0 # Add it into the accumulator91: adwc $0,r1 # Possible carry into high half92: jbr ad2 # Join common code93: /*94: * Here when the digit won't fit in the accumulator95: */96: ad1: incl r5 # Ignore the digit, bump exponent97: /*98: * If we have seen a decimal point, decrease the exponent by 199: */100: ad2: jbc $decpt,r3,ad3 # Jump if decimal point not seen101: decl r5 # Decrease exponent102: ad3:103: /*104: * Fetch the next character, back for more105: */106: movzbl (r2)+,r4 # Fetch107: jbr ad0 # Try again108: /*109: * Not a digit. Could it be a decimal point?110: */111: ad4: cmpb r4,$'. # If it's not a decimal point, either it's112: jneq ad5 # the end of the number or the start of113: # the exponent.114: jbcs $decpt,r3,ad3 # If it IS a decimal point, we record that115: # we've seen one, and keep collecting116: # digits if it is the first one.117: /*118: * Check for an exponent119: */120: ad5: clrl r6 # Initialize the exponent accumulator121:122: cmpb r4,$'e # We allow both lower case e123: jeql ex1 # ... and ...124: cmpb r4,$'E # upper-case E125: jneq ex7126: /*127: * Does the exponent have a sign?128: */129: ex1: movzbl (r2)+,r4 # Get next character130: cmpb r4,$'+ # Positive sign?131: jeql ex2 # ... yes ...132: cmpb r4,$'- # Negative sign?133: jneq ex3 # ... no ...134: bisb2 $1<esign,r3 # Indicate exponent is negative135: ex2: movzbl (r2)+,r4 # Grab the next character136: /*137: * Accumulate exponent digits in r6138: */139: ex3: cmpb r4,$'0 # A digit is within the range140: jlss ex4 # '0' through141: cmpb r4,$'9 # '9',142: jgtr ex4 # inclusive.143: cmpl r6,$214748364 # Exponent outrageously large already?144: jgeq ex2 # ... yes145: moval (r6)[r6],r6 # r6 *= 5146: movaw -'0(r4)[r6],r6 # r6 = r6 * 2 + r4 - '0'147: jbr ex2 # Go 'round again148: ex4:149: /*150: * Now get the final exponent and force it within a reasonable151: * range so our scaling loops don't take forever for values152: * that will ultimately cause overflow or underflow anyway.153: * A tight check on over/underflow will be done by ldexp.154: */155: jbc $esign,r3,ex5 # Jump if exponent not negative156: mnegl r6,r6 # If sign, negate exponent157: ex5: addl2 r6,r5 # Add given exponent to calculated exponent158: cmpl r5,$-100 # Absurdly small?159: jgtr ex6 # ... no160: movl $-100,r5 # ... yes, force within limit161: ex6: cmpl r5,$100 # Absurdly large?162: jlss ex7 # ... no163: movl $100,r5 # ... yes, force within bounds164: ex7:165: /*166: * Our number has now been reduced to a mantissa and an exponent.167: * The mantissa is a 63-bit positive binary integer in r0,r1,168: * and the exponent is a signed power of 10 in r5. The msign169: * bit in r3 will be on if the mantissa should ultimately be170: * considered negative.171: *172: * We now have to convert it to a standard format floating point173: * number. This will be done by accumulating a binary exponent174: * in r2, as we progressively get r5 closer to zero.175: *176: * Don't bother scaling if the mantissa is zero177: */178: movq r0,r0 # Mantissa zero?179: jeql exit # ... yes180:181: clrl r2 # Initialize binary exponent182: tstl r5 # Which way to scale?183: jleq sd0 # Scale down if decimal exponent <= 0184: /*185: * Scale up by "multiplying" r0,r1 by 10 as many times as necessary,186: * as follows:187: *188: * Step 1: Shift r0,r1 right as necessary to ensure that no189: * overflow can occur when multiplying.190: */191: su0: cmpl r1,$429496729 # Compare high word to (2**31)/5192: jlss su1 # Jump out if guaranteed safe193: ashq $-1,r0,r0 # Else shift right one bit194: incl r2 # bump exponent to compensate195: jbr su0 # and go back to test again.196: /*197: * Step 2: Multiply r0,r1 by 5, by appropriate shifting and198: * double-precision addition199: */200: su1: ashq $2,r0,r6 # (r6,r7) := (r0,r1) * 4201: addl2 r6,r0 # Add low-order halves202: adwc r7,r1 # and high-order halves203: /*204: * Step 3: Increment the binary exponent to take care of the final205: * factor of 2, and go back if we still need to scale more.206: */207: incl r2 # Increment the exponent208: sobgtr r5,su0 # and back for more (maybe)209:210: jbr cm0 # Merge to build final value211:212: /*213: * Scale down. We must "divide" r0,r1 by 10 as many times214: * as needed, as follows:215: *216: * Step 0: Right now, the condition codes reflect the state217: * of r5. If it's zero, we are done.218: */219: sd0: jeql cm0 # If finished, build final number220: /*221: * Step 1: Shift r0,r1 left until the high-order bit (not counting222: * the sign bit) is nonzero, so that the division will preserve223: * as much precision as possible.224: */225: tstl r1 # Is the entire high-order half zero?226: jneq sd2 # ...no, go shift one bit at a time227: ashq $30,r0,r0 # ...yes, shift left 30,228: subl2 $30,r2 # decrement the exponent to compensate,229: # and now it's known to be safe to shift230: # at least once more.231: sd1: ashq $1,r0,r0 # Shift (r0,r1) left one, and232: decl r2 # decrement the exponent to compensate233: sd2: jbc $30,r1,sd1 # If the high-order bit is off, go shift234: /*235: * Step 2: Divide the high-order part of (r0,r1) by 5,236: * giving a quotient in r1 and a remainder in r7.237: */238: sd3: movl r1,r6 # Copy the high-order part239: clrl r7 # Zero-extend to 64 bits240: ediv $5,r6,r1,r7 # Divide (cannot overflow)241: /*242: * Step 3: Divide the low-order part of (r0,r1) by 5,243: * using the remainder from step 2 for rounding.244: * Note that the result of this computation is unsigned,245: * so we have to allow for the fact that an ordinary division246: * by 5 could overflow. We make allowance by dividing by 10,247: * multiplying the quotient by 2, and using the remainder248: * to adjust the modified quotient.249: */250: addl3 $2,r0,r6 # Dividend is low part of (r0,r1) plus251: adwc $0,r7 # 2 for rounding plus252: # (2**32) * previous remainder253: ediv $10,r6,r0,r6 # r0 := quotient, r6 := remainder.254: addl2 r0,r0 # Make r0 result of dividing by 5255: cmpl r6,$5 # If remainder is 5 or greater,256: jlss sd4 # increment the adjustted quotient.257: incl r0258: /*259: * Step 4: Increment the decimal exponent, decrement the binary260: * exponent (to make the division by 5 into a division by 10),261: * and back for another iteration.262: */263: sd4: decl r2 # Binary exponent264: aoblss $0,r5,sd2265: /*266: * We now have the following:267: *268: * r0: low-order half of a 64-bit integer269: * r1: high-order half of the same 64-bit integer270: * r2: a binary exponent271: *272: * Our final result is the integer represented by (r0,r1)273: * multiplied by 2 to the power contained in r2.274: * We will transform (r0,r1) into a floating-point value,275: * set the sign appropriately, and let ldexp do the276: * rest of the work.277: *278: * Step 1: if the high-order bit (excluding the sign) of279: * the high-order half (r1) is 1, then we have 63 bits of280: * fraction, too many to convert easily. However, we also281: * know we won't need them all, so we will just throw the282: * low-order bit away (and adjust the exponent appropriately).283: */284: cm0: jbc $30,r1,cm1 # jump if no adjustment needed285: ashq $-1,r0,r0 # lose the low-order bit286: incl r2 # increase the exponent to compensate287: /*288: * Step 2: split the 62-bit number in (r0,r1) into two289: * 31-bit positive quantities290: */291: cm1: ashq $1,r0,r0 # put the high-order bits in r1292: # and a 0 in the bottom of r0293: rotl $-1,r0,r0 # right-justify the bits in r0294: # moving the 0 from the ashq295: # into the sign bit.296: /*297: * Step 3: convert both halves to floating point298: */299: cvtld r0,r6 # low-order part in r6-r7300: cvtld r1,r0 # high-order part in r0-r1301: /*302: * Step 4: multiply the high order part by 2**31 and combine them303: */304: muld2 two31,r0 # multiply305: addd2 r6,r0 # combine306: /*307: * Step 5: if appropriate, negate the floating value308: */309: jbc $msign,r3,cm2 # Jump if mantissa not signed310: mnegd r0,r0 # If negative, make it so311: /*312: * Step 6: call ldexp to complete the job313: */314: cm2: pushl r2 # Put exponent in parameter list315: movd r0,-(sp) # and also mantissa316: calls $3,_ldexp # go combine them317:318: exit:319: ret320:321: .align 2322: two31: .word 0x5000 # 2 ** 31323: .word 0 # (=2147483648)324: .word 0 # in floating-point325: .word 0 # (so atof doesn't have to convert it)

_atof
defined in line 36; used 80 times

- in /usr/include/math.h line 18
- in /usr/ingres/source/dbu/copy.c line 513
- in /usr/ingres/source/equel/number.c line 105
- in /usr/ingres/source/ovqp/typecheck.c line 124
- in /usr/ingres/source/parser/s_number.c line 83
- in /usr/src/bin/as/bignum1.c line 25, 34
- in /usr/src/bin/awk/awk.def line 57
- in /usr/src/bin/awk/lib.c line 164
- in /usr/src/bin/awk/run.c line 644, 661
- in /usr/src/bin/awk/tran.c line 176
- in /usr/src/bin/csh/sh.func.c line 936-939(2), 952
- in /usr/src/include/math.h line 18
- in /usr/src/lib/libc/stdio/doscan.c line 106, 188-192(2)
- in /usr/src/lib/mip/pass1.h line 196
- in /usr/src/lib/pcc/VMS/filter.c line 201, 208
- in /usr/src/lib/pcc/local.c line 384-387(2)
- in /usr/src/new/X/XMenu/XMenuCreate.c line 61, 272, 314
- in /usr/src/new/X/xpr/xpr.c line 135, 192, 204, 256, 266
- in /usr/src/new/dsh/src/dsh.c line 34, 225
- in /usr/src/old/sdb/docomm.c line 445, 457
- in /usr/src/old/vpr/rvsort.c line 8, 73
- in /usr/src/old/vpr/vpac.c line 140, 149
- in /usr/src/old/vpr/vsort.c line 8, 94
- in /usr/src/ucb/dbx/defs.h line 71
- in /usr/src/ucb/dbx/scanner.c line 552
- in /usr/src/ucb/indent/args.c line 192, 212
- in /usr/src/ucb/pascal/pdx/defs.h line 47
- in /usr/src/ucb/pascal/pdx/library.c line 39
- in /usr/src/ucb/pascal/src/0.h line 703, 711
- in /usr/src/ucb/pascal/src/const.c line 194, 210
- in /usr/src/ucb/pascal/src/rval.c line 1001, 1038-1041(2), 1172, 1188
- in /usr/src/ucb/pascal/src/stkrval.c line 340, 370-373(2)
- in /usr/src/usr.bin/f77/src/f77pass1/misc.c line 303, 314
- in /usr/src/usr.bin/graph/graph.c line 47, 236
- in /usr/src/usr.bin/lint/lint.c line 967
- in /usr/src/usr.bin/spline.c line 232, 263, 329-334(2)
- in /usr/src/usr.bin/uucp/uuq.c line 64, 101
- in /usr/src/usr.lib/libpc/READ8.c line 68, 178
- in /usr/src/usr.lib/lpr/filters/rvsort.c line 19, 84
- in /usr/src/usr.lib/lpr/filters/vsort.c line 19, 105
- in /usr/src/usr.lib/lpr/pac.c line 64, 89, 176