1 | // |
---|
2 | // $Id$ |
---|
3 | // |
---|
4 | // decbin.sa 3.3 12/19/90 |
---|
5 | // |
---|
6 | // Description: Converts normalized packed bcd value pointed to by |
---|
7 | // register A6 to extended-precision value in FP0. |
---|
8 | // |
---|
9 | // Input: Normalized packed bcd value in ETEMP(a6). |
---|
10 | // |
---|
11 | // Output: Exact floating-point representation of the packed bcd value. |
---|
12 | // |
---|
13 | // Saves and Modifies: D2-D5 |
---|
14 | // |
---|
15 | // Speed: The program decbin takes ??? cycles to execute. |
---|
16 | // |
---|
17 | // Object Size: |
---|
18 | // |
---|
19 | // External Reference(s): None. |
---|
20 | // |
---|
21 | // Algorithm: |
---|
22 | // Expected is a normal bcd (i.e. non-exceptional; all inf, zero, |
---|
23 | // and NaN operands are dispatched without entering this routine) |
---|
24 | // value in 68881/882 format at location ETEMP(A6). |
---|
25 | // |
---|
26 | // A1. Convert the bcd exponent to binary by successive adds and muls. |
---|
27 | // Set the sign according to SE. Subtract 16 to compensate |
---|
28 | // for the mantissa which is to be interpreted as 17 integer |
---|
29 | // digits, rather than 1 integer and 16 fraction digits. |
---|
30 | // Note: this operation can never overflow. |
---|
31 | // |
---|
32 | // A2. Convert the bcd mantissa to binary by successive |
---|
33 | // adds and muls in FP0. Set the sign according to SM. |
---|
34 | // The mantissa digits will be converted with the decimal point |
---|
35 | // assumed following the least-significant digit. |
---|
36 | // Note: this operation can never overflow. |
---|
37 | // |
---|
38 | // A3. Count the number of leading/trailing zeros in the |
---|
39 | // bcd string. If SE is positive, count the leading zeros; |
---|
40 | // if negative, count the trailing zeros. Set the adjusted |
---|
41 | // exponent equal to the exponent from A1 and the zero count |
---|
42 | // added if SM = 1 and subtracted if SM = 0. Scale the |
---|
43 | // mantissa the equivalent of forcing in the bcd value: |
---|
44 | // |
---|
45 | // SM = 0 a non-zero digit in the integer position |
---|
46 | // SM = 1 a non-zero digit in Mant0, lsd of the fraction |
---|
47 | // |
---|
48 | // this will insure that any value, regardless of its |
---|
49 | // representation (ex. 0.1E2, 1E1, 10E0, 100E-1), is converted |
---|
50 | // consistently. |
---|
51 | // |
---|
52 | // A4. Calculate the factor 10^exp in FP1 using a table of |
---|
53 | // 10^(2^n) values. To reduce the error in forming factors |
---|
54 | // greater than 10^27, a directed rounding scheme is used with |
---|
55 | // tables rounded to RN, RM, and RP, according to the table |
---|
56 | // in the comments of the pwrten section. |
---|
57 | // |
---|
58 | // A5. Form the final binary number by scaling the mantissa by |
---|
59 | // the exponent factor. This is done by multiplying the |
---|
60 | // mantissa in FP0 by the factor in FP1 if the adjusted |
---|
61 | // exponent sign is positive, and dividing FP0 by FP1 if |
---|
62 | // it is negative. |
---|
63 | // |
---|
64 | // Clean up and return. Check if the final mul or div resulted |
---|
65 | // in an inex2 exception. If so, set inex1 in the fpsr and |
---|
66 | // check if the inex1 exception is enabled. If so, set d7 upper |
---|
67 | // word to $0100. This will signal unimp.sa that an enabled inex1 |
---|
68 | // exception occurred. Unimp will fix the stack. |
---|
69 | // |
---|
70 | |
---|
71 | // Copyright (C) Motorola, Inc. 1990 |
---|
72 | // All Rights Reserved |
---|
73 | // |
---|
74 | // THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA |
---|
75 | // The copyright notice above does not evidence any |
---|
76 | // actual or intended publication of such source code. |
---|
77 | |
---|
78 | //DECBIN idnt 2,1 | Motorola 040 Floating Point Software Package |
---|
79 | |
---|
80 | |section 8 |
---|
81 | |
---|
82 | #include "fpsp.defs" |
---|
83 | |
---|
84 | // |
---|
85 | // PTENRN, PTENRM, and PTENRP are arrays of powers of 10 rounded |
---|
86 | // to nearest, minus, and plus, respectively. The tables include |
---|
87 | // 10**{1,2,4,8,16,32,64,128,256,512,1024,2048,4096}. No rounding |
---|
88 | // is required until the power is greater than 27, however, all |
---|
89 | // tables include the first 5 for ease of indexing. |
---|
90 | // |
---|
91 | |xref PTENRN |
---|
92 | |xref PTENRM |
---|
93 | |xref PTENRP |
---|
94 | |
---|
95 | RTABLE: .byte 0,0,0,0 |
---|
96 | .byte 2,3,2,3 |
---|
97 | .byte 2,3,3,2 |
---|
98 | .byte 3,2,2,3 |
---|
99 | |
---|
100 | .global decbin |
---|
101 | .global calc_e |
---|
102 | .global pwrten |
---|
103 | .global calc_m |
---|
104 | .global norm |
---|
105 | .global ap_st_z |
---|
106 | .global ap_st_n |
---|
107 | // |
---|
108 | .set FNIBS,7 |
---|
109 | .set FSTRT,0 |
---|
110 | // |
---|
111 | .set ESTRT,4 |
---|
112 | .set EDIGITS,2 // |
---|
113 | // |
---|
114 | // Constants in single precision |
---|
115 | FZERO: .long 0x00000000 |
---|
116 | FONE: .long 0x3F800000 |
---|
117 | FTEN: .long 0x41200000 |
---|
118 | |
---|
119 | .set TEN,10 |
---|
120 | |
---|
121 | // |
---|
122 | decbin: |
---|
123 | | fmovel #0,FPCR ;clr real fpcr |
---|
124 | moveml %d2-%d5,-(%a7) |
---|
125 | // |
---|
126 | // Calculate exponent: |
---|
127 | // 1. Copy bcd value in memory for use as a working copy. |
---|
128 | // 2. Calculate absolute value of exponent in d1 by mul and add. |
---|
129 | // 3. Correct for exponent sign. |
---|
130 | // 4. Subtract 16 to compensate for interpreting the mant as all integer digits. |
---|
131 | // (i.e., all digits assumed left of the decimal point.) |
---|
132 | // |
---|
133 | // Register usage: |
---|
134 | // |
---|
135 | // calc_e: |
---|
136 | // (*) d0: temp digit storage |
---|
137 | // (*) d1: accumulator for binary exponent |
---|
138 | // (*) d2: digit count |
---|
139 | // (*) d3: offset pointer |
---|
140 | // ( ) d4: first word of bcd |
---|
141 | // ( ) a0: pointer to working bcd value |
---|
142 | // ( ) a6: pointer to original bcd value |
---|
143 | // (*) FP_SCR1: working copy of original bcd value |
---|
144 | // (*) L_SCR1: copy of original exponent word |
---|
145 | // |
---|
146 | calc_e: |
---|
147 | movel #EDIGITS,%d2 //# of nibbles (digits) in fraction part |
---|
148 | moveql #ESTRT,%d3 //counter to pick up digits |
---|
149 | leal FP_SCR1(%a6),%a0 //load tmp bcd storage address |
---|
150 | movel ETEMP(%a6),(%a0) //save input bcd value |
---|
151 | movel ETEMP_HI(%a6),4(%a0) //save words 2 and 3 |
---|
152 | movel ETEMP_LO(%a6),8(%a0) //and work with these |
---|
153 | movel (%a0),%d4 //get first word of bcd |
---|
154 | clrl %d1 //zero d1 for accumulator |
---|
155 | e_gd: |
---|
156 | mulul #TEN,%d1 //mul partial product by one digit place |
---|
157 | bfextu %d4{%d3:#4},%d0 //get the digit and zero extend into d0 |
---|
158 | addl %d0,%d1 //d1 = d1 + d0 |
---|
159 | addqb #4,%d3 //advance d3 to the next digit |
---|
160 | dbf %d2,e_gd //if we have used all 3 digits, exit loop |
---|
161 | btst #30,%d4 //get SE |
---|
162 | beqs e_pos //don't negate if pos |
---|
163 | negl %d1 //negate before subtracting |
---|
164 | e_pos: |
---|
165 | subl #16,%d1 //sub to compensate for shift of mant |
---|
166 | bges e_save //if still pos, do not neg |
---|
167 | negl %d1 //now negative, make pos and set SE |
---|
168 | orl #0x40000000,%d4 //set SE in d4, |
---|
169 | orl #0x40000000,(%a0) //and in working bcd |
---|
170 | e_save: |
---|
171 | movel %d1,L_SCR1(%a6) //save exp in memory |
---|
172 | // |
---|
173 | // |
---|
174 | // Calculate mantissa: |
---|
175 | // 1. Calculate absolute value of mantissa in fp0 by mul and add. |
---|
176 | // 2. Correct for mantissa sign. |
---|
177 | // (i.e., all digits assumed left of the decimal point.) |
---|
178 | // |
---|
179 | // Register usage: |
---|
180 | // |
---|
181 | // calc_m: |
---|
182 | // (*) d0: temp digit storage |
---|
183 | // (*) d1: lword counter |
---|
184 | // (*) d2: digit count |
---|
185 | // (*) d3: offset pointer |
---|
186 | // ( ) d4: words 2 and 3 of bcd |
---|
187 | // ( ) a0: pointer to working bcd value |
---|
188 | // ( ) a6: pointer to original bcd value |
---|
189 | // (*) fp0: mantissa accumulator |
---|
190 | // ( ) FP_SCR1: working copy of original bcd value |
---|
191 | // ( ) L_SCR1: copy of original exponent word |
---|
192 | // |
---|
193 | calc_m: |
---|
194 | moveql #1,%d1 //word counter, init to 1 |
---|
195 | fmoves FZERO,%fp0 //accumulator |
---|
196 | // |
---|
197 | // |
---|
198 | // Since the packed number has a long word between the first & second parts, |
---|
199 | // get the integer digit then skip down & get the rest of the |
---|
200 | // mantissa. We will unroll the loop once. |
---|
201 | // |
---|
202 | bfextu (%a0){#28:#4},%d0 //integer part is ls digit in long word |
---|
203 | faddb %d0,%fp0 //add digit to sum in fp0 |
---|
204 | // |
---|
205 | // |
---|
206 | // Get the rest of the mantissa. |
---|
207 | // |
---|
208 | loadlw: |
---|
209 | movel (%a0,%d1.L*4),%d4 //load mantissa longword into d4 |
---|
210 | moveql #FSTRT,%d3 //counter to pick up digits |
---|
211 | moveql #FNIBS,%d2 //reset number of digits per a0 ptr |
---|
212 | md2b: |
---|
213 | fmuls FTEN,%fp0 //fp0 = fp0 * 10 |
---|
214 | bfextu %d4{%d3:#4},%d0 //get the digit and zero extend |
---|
215 | faddb %d0,%fp0 //fp0 = fp0 + digit |
---|
216 | // |
---|
217 | // |
---|
218 | // If all the digits (8) in that long word have been converted (d2=0), |
---|
219 | // then inc d1 (=2) to point to the next long word and reset d3 to 0 |
---|
220 | // to initialize the digit offset, and set d2 to 7 for the digit count; |
---|
221 | // else continue with this long word. |
---|
222 | // |
---|
223 | addqb #4,%d3 //advance d3 to the next digit |
---|
224 | dbf %d2,md2b //check for last digit in this lw |
---|
225 | nextlw: |
---|
226 | addql #1,%d1 //inc lw pointer in mantissa |
---|
227 | cmpl #2,%d1 //test for last lw |
---|
228 | ble loadlw //if not, get last one |
---|
229 | |
---|
230 | // |
---|
231 | // Check the sign of the mant and make the value in fp0 the same sign. |
---|
232 | // |
---|
233 | m_sign: |
---|
234 | btst #31,(%a0) //test sign of the mantissa |
---|
235 | beq ap_st_z //if clear, go to append/strip zeros |
---|
236 | fnegx %fp0 //if set, negate fp0 |
---|
237 | |
---|
238 | // |
---|
239 | // Append/strip zeros: |
---|
240 | // |
---|
241 | // For adjusted exponents which have an absolute value greater than 27*, |
---|
242 | // this routine calculates the amount needed to normalize the mantissa |
---|
243 | // for the adjusted exponent. That number is subtracted from the exp |
---|
244 | // if the exp was positive, and added if it was negative. The purpose |
---|
245 | // of this is to reduce the value of the exponent and the possibility |
---|
246 | // of error in calculation of pwrten. |
---|
247 | // |
---|
248 | // 1. Branch on the sign of the adjusted exponent. |
---|
249 | // 2p.(positive exp) |
---|
250 | // 2. Check M16 and the digits in lwords 2 and 3 in descending order. |
---|
251 | // 3. Add one for each zero encountered until a non-zero digit. |
---|
252 | // 4. Subtract the count from the exp. |
---|
253 | // 5. Check if the exp has crossed zero in #3 above; make the exp abs |
---|
254 | // and set SE. |
---|
255 | // 6. Multiply the mantissa by 10**count. |
---|
256 | // 2n.(negative exp) |
---|
257 | // 2. Check the digits in lwords 3 and 2 in descending order. |
---|
258 | // 3. Add one for each zero encountered until a non-zero digit. |
---|
259 | // 4. Add the count to the exp. |
---|
260 | // 5. Check if the exp has crossed zero in #3 above; clear SE. |
---|
261 | // 6. Divide the mantissa by 10**count. |
---|
262 | // |
---|
263 | // *Why 27? If the adjusted exponent is within -28 < expA < 28, than |
---|
264 | // any adjustment due to append/strip zeros will drive the resultant |
---|
265 | // exponent towards zero. Since all pwrten constants with a power |
---|
266 | // of 27 or less are exact, there is no need to use this routine to |
---|
267 | // attempt to lessen the resultant exponent. |
---|
268 | // |
---|
269 | // Register usage: |
---|
270 | // |
---|
271 | // ap_st_z: |
---|
272 | // (*) d0: temp digit storage |
---|
273 | // (*) d1: zero count |
---|
274 | // (*) d2: digit count |
---|
275 | // (*) d3: offset pointer |
---|
276 | // ( ) d4: first word of bcd |
---|
277 | // (*) d5: lword counter |
---|
278 | // ( ) a0: pointer to working bcd value |
---|
279 | // ( ) FP_SCR1: working copy of original bcd value |
---|
280 | // ( ) L_SCR1: copy of original exponent word |
---|
281 | // |
---|
282 | // |
---|
283 | // First check the absolute value of the exponent to see if this |
---|
284 | // routine is necessary. If so, then check the sign of the exponent |
---|
285 | // and do append (+) or strip (-) zeros accordingly. |
---|
286 | // This section handles a positive adjusted exponent. |
---|
287 | // |
---|
288 | ap_st_z: |
---|
289 | movel L_SCR1(%a6),%d1 //load expA for range test |
---|
290 | cmpl #27,%d1 //test is with 27 |
---|
291 | ble pwrten //if abs(expA) <28, skip ap/st zeros |
---|
292 | btst #30,(%a0) //check sign of exp |
---|
293 | bne ap_st_n //if neg, go to neg side |
---|
294 | clrl %d1 //zero count reg |
---|
295 | movel (%a0),%d4 //load lword 1 to d4 |
---|
296 | bfextu %d4{#28:#4},%d0 //get M16 in d0 |
---|
297 | bnes ap_p_fx //if M16 is non-zero, go fix exp |
---|
298 | addql #1,%d1 //inc zero count |
---|
299 | moveql #1,%d5 //init lword counter |
---|
300 | movel (%a0,%d5.L*4),%d4 //get lword 2 to d4 |
---|
301 | bnes ap_p_cl //if lw 2 is zero, skip it |
---|
302 | addql #8,%d1 //and inc count by 8 |
---|
303 | addql #1,%d5 //inc lword counter |
---|
304 | movel (%a0,%d5.L*4),%d4 //get lword 3 to d4 |
---|
305 | ap_p_cl: |
---|
306 | clrl %d3 //init offset reg |
---|
307 | moveql #7,%d2 //init digit counter |
---|
308 | ap_p_gd: |
---|
309 | bfextu %d4{%d3:#4},%d0 //get digit |
---|
310 | bnes ap_p_fx //if non-zero, go to fix exp |
---|
311 | addql #4,%d3 //point to next digit |
---|
312 | addql #1,%d1 //inc digit counter |
---|
313 | dbf %d2,ap_p_gd //get next digit |
---|
314 | ap_p_fx: |
---|
315 | movel %d1,%d0 //copy counter to d2 |
---|
316 | movel L_SCR1(%a6),%d1 //get adjusted exp from memory |
---|
317 | subl %d0,%d1 //subtract count from exp |
---|
318 | bges ap_p_fm //if still pos, go to pwrten |
---|
319 | negl %d1 //now its neg; get abs |
---|
320 | movel (%a0),%d4 //load lword 1 to d4 |
---|
321 | orl #0x40000000,%d4 // and set SE in d4 |
---|
322 | orl #0x40000000,(%a0) // and in memory |
---|
323 | // |
---|
324 | // Calculate the mantissa multiplier to compensate for the striping of |
---|
325 | // zeros from the mantissa. |
---|
326 | // |
---|
327 | ap_p_fm: |
---|
328 | movel #PTENRN,%a1 //get address of power-of-ten table |
---|
329 | clrl %d3 //init table index |
---|
330 | fmoves FONE,%fp1 //init fp1 to 1 |
---|
331 | moveql #3,%d2 //init d2 to count bits in counter |
---|
332 | ap_p_el: |
---|
333 | asrl #1,%d0 //shift lsb into carry |
---|
334 | bccs ap_p_en //if 1, mul fp1 by pwrten factor |
---|
335 | fmulx (%a1,%d3),%fp1 //mul by 10**(d3_bit_no) |
---|
336 | ap_p_en: |
---|
337 | addl #12,%d3 //inc d3 to next rtable entry |
---|
338 | tstl %d0 //check if d0 is zero |
---|
339 | bnes ap_p_el //if not, get next bit |
---|
340 | fmulx %fp1,%fp0 //mul mantissa by 10**(no_bits_shifted) |
---|
341 | bra pwrten //go calc pwrten |
---|
342 | // |
---|
343 | // This section handles a negative adjusted exponent. |
---|
344 | // |
---|
345 | ap_st_n: |
---|
346 | clrl %d1 //clr counter |
---|
347 | moveql #2,%d5 //set up d5 to point to lword 3 |
---|
348 | movel (%a0,%d5.L*4),%d4 //get lword 3 |
---|
349 | bnes ap_n_cl //if not zero, check digits |
---|
350 | subl #1,%d5 //dec d5 to point to lword 2 |
---|
351 | addql #8,%d1 //inc counter by 8 |
---|
352 | movel (%a0,%d5.L*4),%d4 //get lword 2 |
---|
353 | ap_n_cl: |
---|
354 | movel #28,%d3 //point to last digit |
---|
355 | moveql #7,%d2 //init digit counter |
---|
356 | ap_n_gd: |
---|
357 | bfextu %d4{%d3:#4},%d0 //get digit |
---|
358 | bnes ap_n_fx //if non-zero, go to exp fix |
---|
359 | subql #4,%d3 //point to previous digit |
---|
360 | addql #1,%d1 //inc digit counter |
---|
361 | dbf %d2,ap_n_gd //get next digit |
---|
362 | ap_n_fx: |
---|
363 | movel %d1,%d0 //copy counter to d0 |
---|
364 | movel L_SCR1(%a6),%d1 //get adjusted exp from memory |
---|
365 | subl %d0,%d1 //subtract count from exp |
---|
366 | bgts ap_n_fm //if still pos, go fix mantissa |
---|
367 | negl %d1 //take abs of exp and clr SE |
---|
368 | movel (%a0),%d4 //load lword 1 to d4 |
---|
369 | andl #0xbfffffff,%d4 // and clr SE in d4 |
---|
370 | andl #0xbfffffff,(%a0) // and in memory |
---|
371 | // |
---|
372 | // Calculate the mantissa multiplier to compensate for the appending of |
---|
373 | // zeros to the mantissa. |
---|
374 | // |
---|
375 | ap_n_fm: |
---|
376 | movel #PTENRN,%a1 //get address of power-of-ten table |
---|
377 | clrl %d3 //init table index |
---|
378 | fmoves FONE,%fp1 //init fp1 to 1 |
---|
379 | moveql #3,%d2 //init d2 to count bits in counter |
---|
380 | ap_n_el: |
---|
381 | asrl #1,%d0 //shift lsb into carry |
---|
382 | bccs ap_n_en //if 1, mul fp1 by pwrten factor |
---|
383 | fmulx (%a1,%d3),%fp1 //mul by 10**(d3_bit_no) |
---|
384 | ap_n_en: |
---|
385 | addl #12,%d3 //inc d3 to next rtable entry |
---|
386 | tstl %d0 //check if d0 is zero |
---|
387 | bnes ap_n_el //if not, get next bit |
---|
388 | fdivx %fp1,%fp0 //div mantissa by 10**(no_bits_shifted) |
---|
389 | // |
---|
390 | // |
---|
391 | // Calculate power-of-ten factor from adjusted and shifted exponent. |
---|
392 | // |
---|
393 | // Register usage: |
---|
394 | // |
---|
395 | // pwrten: |
---|
396 | // (*) d0: temp |
---|
397 | // ( ) d1: exponent |
---|
398 | // (*) d2: {FPCR[6:5],SM,SE} as index in RTABLE; temp |
---|
399 | // (*) d3: FPCR work copy |
---|
400 | // ( ) d4: first word of bcd |
---|
401 | // (*) a1: RTABLE pointer |
---|
402 | // calc_p: |
---|
403 | // (*) d0: temp |
---|
404 | // ( ) d1: exponent |
---|
405 | // (*) d3: PWRTxx table index |
---|
406 | // ( ) a0: pointer to working copy of bcd |
---|
407 | // (*) a1: PWRTxx pointer |
---|
408 | // (*) fp1: power-of-ten accumulator |
---|
409 | // |
---|
410 | // Pwrten calculates the exponent factor in the selected rounding mode |
---|
411 | // according to the following table: |
---|
412 | // |
---|
413 | // Sign of Mant Sign of Exp Rounding Mode PWRTEN Rounding Mode |
---|
414 | // |
---|
415 | // ANY ANY RN RN |
---|
416 | // |
---|
417 | // + + RP RP |
---|
418 | // - + RP RM |
---|
419 | // + - RP RM |
---|
420 | // - - RP RP |
---|
421 | // |
---|
422 | // + + RM RM |
---|
423 | // - + RM RP |
---|
424 | // + - RM RP |
---|
425 | // - - RM RM |
---|
426 | // |
---|
427 | // + + RZ RM |
---|
428 | // - + RZ RM |
---|
429 | // + - RZ RP |
---|
430 | // - - RZ RP |
---|
431 | // |
---|
432 | // |
---|
433 | pwrten: |
---|
434 | movel USER_FPCR(%a6),%d3 //get user's FPCR |
---|
435 | bfextu %d3{#26:#2},%d2 //isolate rounding mode bits |
---|
436 | movel (%a0),%d4 //reload 1st bcd word to d4 |
---|
437 | asll #2,%d2 //format d2 to be |
---|
438 | bfextu %d4{#0:#2},%d0 // {FPCR[6],FPCR[5],SM,SE} |
---|
439 | addl %d0,%d2 //in d2 as index into RTABLE |
---|
440 | leal RTABLE,%a1 //load rtable base |
---|
441 | moveb (%a1,%d2),%d0 //load new rounding bits from table |
---|
442 | clrl %d3 //clear d3 to force no exc and extended |
---|
443 | bfins %d0,%d3{#26:#2} //stuff new rounding bits in FPCR |
---|
444 | fmovel %d3,%FPCR //write new FPCR |
---|
445 | asrl #1,%d0 //write correct PTENxx table |
---|
446 | bccs not_rp //to a1 |
---|
447 | leal PTENRP,%a1 //it is RP |
---|
448 | bras calc_p //go to init section |
---|
449 | not_rp: |
---|
450 | asrl #1,%d0 //keep checking |
---|
451 | bccs not_rm |
---|
452 | leal PTENRM,%a1 //it is RM |
---|
453 | bras calc_p //go to init section |
---|
454 | not_rm: |
---|
455 | leal PTENRN,%a1 //it is RN |
---|
456 | calc_p: |
---|
457 | movel %d1,%d0 //copy exp to d0;use d0 |
---|
458 | bpls no_neg //if exp is negative, |
---|
459 | negl %d0 //invert it |
---|
460 | orl #0x40000000,(%a0) //and set SE bit |
---|
461 | no_neg: |
---|
462 | clrl %d3 //table index |
---|
463 | fmoves FONE,%fp1 //init fp1 to 1 |
---|
464 | e_loop: |
---|
465 | asrl #1,%d0 //shift next bit into carry |
---|
466 | bccs e_next //if zero, skip the mul |
---|
467 | fmulx (%a1,%d3),%fp1 //mul by 10**(d3_bit_no) |
---|
468 | e_next: |
---|
469 | addl #12,%d3 //inc d3 to next rtable entry |
---|
470 | tstl %d0 //check if d0 is zero |
---|
471 | bnes e_loop //not zero, continue shifting |
---|
472 | // |
---|
473 | // |
---|
474 | // Check the sign of the adjusted exp and make the value in fp0 the |
---|
475 | // same sign. If the exp was pos then multiply fp1*fp0; |
---|
476 | // else divide fp0/fp1. |
---|
477 | // |
---|
478 | // Register Usage: |
---|
479 | // norm: |
---|
480 | // ( ) a0: pointer to working bcd value |
---|
481 | // (*) fp0: mantissa accumulator |
---|
482 | // ( ) fp1: scaling factor - 10**(abs(exp)) |
---|
483 | // |
---|
484 | norm: |
---|
485 | btst #30,(%a0) //test the sign of the exponent |
---|
486 | beqs mul //if clear, go to multiply |
---|
487 | div: |
---|
488 | fdivx %fp1,%fp0 //exp is negative, so divide mant by exp |
---|
489 | bras end_dec |
---|
490 | mul: |
---|
491 | fmulx %fp1,%fp0 //exp is positive, so multiply by exp |
---|
492 | // |
---|
493 | // |
---|
494 | // Clean up and return with result in fp0. |
---|
495 | // |
---|
496 | // If the final mul/div in decbin incurred an inex exception, |
---|
497 | // it will be inex2, but will be reported as inex1 by get_op. |
---|
498 | // |
---|
499 | end_dec: |
---|
500 | fmovel %FPSR,%d0 //get status register |
---|
501 | bclrl #inex2_bit+8,%d0 //test for inex2 and clear it |
---|
502 | fmovel %d0,%FPSR //return status reg w/o inex2 |
---|
503 | beqs no_exc //skip this if no exc |
---|
504 | orl #inx1a_mask,USER_FPSR(%a6) //set inex1/ainex |
---|
505 | no_exc: |
---|
506 | moveml (%a7)+,%d2-%d5 |
---|
507 | rts |
---|
508 | |end |
---|