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