1: /* 2: * Copyright (c) 1980 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: #ifdef LIBC_SCCS 8: .asciz "@(#)atof.s 5.3 (Berkeley) 3/9/86" 9: #endif LIBC_SCCS 10: 11: #include "DEFS.h" 12: 13: /* 14: * atof: convert ascii to floating 15: * 16: * C usage: 17: * 18: * double atof (s) 19: * char *s; 20: * 21: * Register usage: 22: * 23: * r0-1: value being developed 24: * r2: first section: pointer to the next character 25: * second section: binary exponent 26: * r3: flags 27: * r4: first section: the current character 28: * second section: scratch 29: * r5: the decimal exponent 30: * r6-7: scratch 31: */ 32: .set msign,0 # mantissa has negative sign 33: .set esign,1 # exponent has negative sign 34: .set decpt,2 # decimal point encountered 35: 36: ENTRY(atof, R6|R7) 37: /* 38: * Initialization 39: */ 40: clrl r3 # All flags start out false 41: movl 4(ap),r2 # Address the first character 42: clrl r5 # Clear starting exponent 43: /* 44: * Skip leading white space 45: */ 46: sk0: movzbl (r2)+,r4 # Fetch the next (first) character 47: cmpb $' ,r4 # Is it blank? 48: jeql sk0 # ...yes 49: cmpb r4,$8 # 8 is lowest of white-space group 50: jlss sk1 # Jump if char too low to be white space 51: cmpb r4,$13 # 13 is highest of white-space group 52: jleq sk0 # Jump if character is white space 53: sk1: 54: /* 55: * Check for a sign 56: */ 57: cmpb $'+,r4 # Positive sign? 58: jeql cs1 # ... yes 59: cmpb $'-,r4 # Negative sign? 60: jneq cs2 # ... no 61: bisb2 $1<msign,r3 # Indicate a negative mantissa 62: cs1: movzbl (r2)+,r4 # Skip the character 63: cs2: 64: /* 65: * Accumulate digits, keeping track of the exponent 66: */ 67: clrq r0 # Clear the accumulator 68: ad0: cmpb r4,$'0 # Do we have a digit? 69: jlss ad4 # ... no, too small 70: cmpb r4,$'9 71: jgtr ad4 # ... no, too large 72: /* 73: * We got a digit. Accumulate it 74: */ 75: cmpl r1,$214748364 # Would this digit cause overflow? 76: jgeq ad1 # ... yes 77: /* 78: * Multiply (r0,r1) by 10. This is done by developing 79: * (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)*2 83: ashq $3,r0,r0 # (r0,r1)=(r0,r1)*8 84: addl2 r6,r0 # Add low halves 85: adwc r7,r1 # Add high halves 86: /* 87: * Add in the digit 88: */ 89: subl2 $'0,r4 # Get the digit value 90: addl2 r4,r0 # Add it into the accumulator 91: adwc $0,r1 # Possible carry into high half 92: jbr ad2 # Join common code 93: /* 94: * Here when the digit won't fit in the accumulator 95: */ 96: ad1: incl r5 # Ignore the digit, bump exponent 97: /* 98: * If we have seen a decimal point, decrease the exponent by 1 99: */ 100: ad2: jbc $decpt,r3,ad3 # Jump if decimal point not seen 101: decl r5 # Decrease exponent 102: ad3: 103: /* 104: * Fetch the next character, back for more 105: */ 106: movzbl (r2)+,r4 # Fetch 107: jbr ad0 # Try again 108: /* 109: * Not a digit. Could it be a decimal point? 110: */ 111: ad4: cmpb r4,$'. # If it's not a decimal point, either it's 112: jneq ad5 # the end of the number or the start of 113: # the exponent. 114: jbcs $decpt,r3,ad3 # If it IS a decimal point, we record that 115: # we've seen one, and keep collecting 116: # digits if it is the first one. 117: /* 118: * Check for an exponent 119: */ 120: ad5: clrl r6 # Initialize the exponent accumulator 121: 122: cmpb r4,$'e # We allow both lower case e 123: jeql ex1 # ... and ... 124: cmpb r4,$'E # upper-case E 125: jneq ex7 126: /* 127: * Does the exponent have a sign? 128: */ 129: ex1: movzbl (r2)+,r4 # Get next character 130: 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 negative 135: ex2: movzbl (r2)+,r4 # Grab the next character 136: /* 137: * Accumulate exponent digits in r6 138: */ 139: ex3: cmpb r4,$'0 # A digit is within the range 140: jlss ex4 # '0' through 141: cmpb r4,$'9 # '9', 142: jgtr ex4 # inclusive. 143: cmpl r6,$214748364 # Exponent outrageously large already? 144: jgeq ex2 # ... yes 145: moval (r6)[r6],r6 # r6 *= 5 146: movaw -'0(r4)[r6],r6 # r6 = r6 * 2 + r4 - '0' 147: jbr ex2 # Go 'round again 148: ex4: 149: /* 150: * Now get the final exponent and force it within a reasonable 151: * range so our scaling loops don't take forever for values 152: * 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 negative 156: mnegl r6,r6 # If sign, negate exponent 157: ex5: addl2 r6,r5 # Add given exponent to calculated exponent 158: cmpl r5,$-100 # Absurdly small? 159: jgtr ex6 # ... no 160: movl $-100,r5 # ... yes, force within limit 161: ex6: cmpl r5,$100 # Absurdly large? 162: jlss ex7 # ... no 163: movl $100,r5 # ... yes, force within bounds 164: 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 msign 169: * bit in r3 will be on if the mantissa should ultimately be 170: * considered negative. 171: * 172: * We now have to convert it to a standard format floating point 173: * number. This will be done by accumulating a binary exponent 174: * in r2, as we progressively get r5 closer to zero. 175: * 176: * Don't bother scaling if the mantissa is zero 177: */ 178: movq r0,r0 # Mantissa zero? 179: jeql exit # ... yes 180: 181: clrl r2 # Initialize binary exponent 182: tstl r5 # Which way to scale? 183: jleq sd0 # Scale down if decimal exponent <= 0 184: /* 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 no 189: * overflow can occur when multiplying. 190: */ 191: su0: cmpl r1,$429496729 # Compare high word to (2**31)/5 192: jlss su1 # Jump out if guaranteed safe 193: ashq $-1,r0,r0 # Else shift right one bit 194: incl r2 # bump exponent to compensate 195: jbr su0 # and go back to test again. 196: /* 197: * Step 2: Multiply r0,r1 by 5, by appropriate shifting and 198: * double-precision addition 199: */ 200: su1: ashq $2,r0,r6 # (r6,r7) := (r0,r1) * 4 201: addl2 r6,r0 # Add low-order halves 202: adwc r7,r1 # and high-order halves 203: /* 204: * Step 3: Increment the binary exponent to take care of the final 205: * factor of 2, and go back if we still need to scale more. 206: */ 207: incl r2 # Increment the exponent 208: sobgtr r5,su0 # and back for more (maybe) 209: 210: jbr cm0 # Merge to build final value 211: 212: /* 213: * Scale down. We must "divide" r0,r1 by 10 as many times 214: * as needed, as follows: 215: * 216: * Step 0: Right now, the condition codes reflect the state 217: * of r5. If it's zero, we are done. 218: */ 219: sd0: jeql cm0 # If finished, build final number 220: /* 221: * Step 1: Shift r0,r1 left until the high-order bit (not counting 222: * the sign bit) is nonzero, so that the division will preserve 223: * 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 time 227: 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 shift 230: # at least once more. 231: sd1: ashq $1,r0,r0 # Shift (r0,r1) left one, and 232: decl r2 # decrement the exponent to compensate 233: sd2: jbc $30,r1,sd1 # If the high-order bit is off, go shift 234: /* 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 part 239: clrl r7 # Zero-extend to 64 bits 240: 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 division 246: * by 5 could overflow. We make allowance by dividing by 10, 247: * multiplying the quotient by 2, and using the remainder 248: * to adjust the modified quotient. 249: */ 250: addl3 $2,r0,r6 # Dividend is low part of (r0,r1) plus 251: adwc $0,r7 # 2 for rounding plus 252: # (2**32) * previous remainder 253: ediv $10,r6,r0,r6 # r0 := quotient, r6 := remainder. 254: addl2 r0,r0 # Make r0 result of dividing by 5 255: cmpl r6,$5 # If remainder is 5 or greater, 256: jlss sd4 # increment the adjustted quotient. 257: incl r0 258: /* 259: * Step 4: Increment the decimal exponent, decrement the binary 260: * exponent (to make the division by 5 into a division by 10), 261: * and back for another iteration. 262: */ 263: sd4: decl r2 # Binary exponent 264: aoblss $0,r5,sd2 265: /* 266: * We now have the following: 267: * 268: * r0: low-order half of a 64-bit integer 269: * r1: high-order half of the same 64-bit integer 270: * r2: a binary exponent 271: * 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 the 276: * rest of the work. 277: * 278: * Step 1: if the high-order bit (excluding the sign) of 279: * the high-order half (r1) is 1, then we have 63 bits of 280: * fraction, too many to convert easily. However, we also 281: * know we won't need them all, so we will just throw the 282: * low-order bit away (and adjust the exponent appropriately). 283: */ 284: cm0: jbc $30,r1,cm1 # jump if no adjustment needed 285: ashq $-1,r0,r0 # lose the low-order bit 286: incl r2 # increase the exponent to compensate 287: /* 288: * Step 2: split the 62-bit number in (r0,r1) into two 289: * 31-bit positive quantities 290: */ 291: cm1: ashq $1,r0,r0 # put the high-order bits in r1 292: # and a 0 in the bottom of r0 293: rotl $-1,r0,r0 # right-justify the bits in r0 294: # moving the 0 from the ashq 295: # into the sign bit. 296: /* 297: * Step 3: convert both halves to floating point 298: */ 299: cvtld r0,r6 # low-order part in r6-r7 300: cvtld r1,r0 # high-order part in r0-r1 301: /* 302: * Step 4: multiply the high order part by 2**31 and combine them 303: */ 304: muld2 two31,r0 # multiply 305: addd2 r6,r0 # combine 306: /* 307: * Step 5: if appropriate, negate the floating value 308: */ 309: jbc $msign,r3,cm2 # Jump if mantissa not signed 310: mnegd r0,r0 # If negative, make it so 311: /* 312: * Step 6: call ldexp to complete the job 313: */ 314: cm2: pushl r2 # Put exponent in parameter list 315: movd r0,-(sp) # and also mantissa 316: calls $3,_ldexp # go combine them 317: 318: exit: 319: ret 320: 321: .align 2 322: two31: .word 0x5000 # 2 ** 31 323: .word 0 # (=2147483648) 324: .word 0 # in floating-point 325: .word 0 # (so atof doesn't have to convert it)