1 /* libgcc routines for 68000 w/o floating-point hardware.
2 Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 In addition to the permissions in the GNU General Public License, the
12 Free Software Foundation gives you unlimited permission to link the
13 compiled version of this file with other programs, and to distribute
14 those programs without any restriction coming from the use of this
15 file. (The General Public License restrictions do apply in other
16 respects; for example, they cover modification of the file, and
17 distribution when not linked into another program.)
19 This file is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; see the file COPYING. If not, write to
26 the Free Software Foundation, 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. */
29 /* As a special exception, if you link this library with files
30 compiled with GCC to produce an executable, this does not cause
31 the resulting executable to be covered by the GNU General Public License.
32 This exception does not however invalidate any other reasons why
33 the executable file might be covered by the GNU General Public License. */
35 /* Use this one for any 680x0; assumes no floating point hardware.
36 The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk.
37 Some of this code comes from MINIX, via the folks at ericsson.
38 D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
41 /* These are predefined by new versions of GNU cpp. */
43 #ifndef __USER_LABEL_PREFIX__
44 #define __USER_LABEL_PREFIX__ _
47 #ifndef __REGISTER_PREFIX__
48 #define __REGISTER_PREFIX__
51 #ifndef __IMMEDIATE_PREFIX__
52 #define __IMMEDIATE_PREFIX__ #
55 /* ANSI concatenation macros. */
57 #define CONCAT1(a, b) CONCAT2(a, b)
58 #define CONCAT2(a, b) a ## b
60 /* Use the right prefix for global labels. */
62 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
64 /* Use the right prefix for registers. */
66 #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
68 /* Use the right prefix for immediate values. */
70 #define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
92 | This is an attempt at a decent floating point (single, double and
93 | extended double) code for the GNU C compiler. It should be easy to
94 | adapt to other compilers (but beware of the local labels!).
96 | Starting date: 21 October, 1990
98 | It is convenient to introduce the notation (s,e,f) for a floating point
99 | number, where s=sign, e=exponent, f=fraction. We will call a floating
100 | point number fpn to abbreviate, independently of the precision.
101 | Let MAX_EXP be in each case the maximum exponent (255 for floats, 1023
102 | for doubles and 16383 for long doubles). We then have the following
104 | 1. Normalized fpns have 0 < e < MAX_EXP. They correspond to
105 | (-1)^s x 1.f x 2^(e-bias-1).
106 | 2. Denormalized fpns have e=0. They correspond to numbers of the form
107 | (-1)^s x 0.f x 2^(-bias).
108 | 3. +/-INFINITY have e=MAX_EXP, f=0.
109 | 4. Quiet NaN (Not a Number) have all bits set.
110 | 5. Signaling NaN (Not a Number) have s=0, e=MAX_EXP, f=1.
112 |=============================================================================
114 |=============================================================================
116 | This is the floating point condition code register (_fpCCR):
119 | short _exception_bits;
120 | short _trap_enable_bits;
121 | short _sticky_bits;
122 | short _rounding_mode;
124 | short _last_operation;
148 .word ROUND_TO_NEAREST
161 EBITS = __exception_bits - SYM (_fpCCR)
162 TRAPE = __trap_enable_bits - SYM (_fpCCR)
163 STICK = __sticky_bits - SYM (_fpCCR)
164 ROUND = __rounding_mode - SYM (_fpCCR)
165 FORMT = __format - SYM (_fpCCR)
166 LASTO = __last_operation - SYM (_fpCCR)
167 OPER1 = __operand1 - SYM (_fpCCR)
168 OPER2 = __operand2 - SYM (_fpCCR)
170 | The following exception types are supported:
171 INEXACT_RESULT = 0x0001
174 DIVIDE_BY_ZERO = 0x0008
175 INVALID_OPERATION = 0x0010
177 | The allowed rounding modes are:
179 ROUND_TO_NEAREST = 0 | round result to nearest representable value
180 ROUND_TO_ZERO = 1 | round result towards zero
181 ROUND_TO_PLUS = 2 | round result towards plus infinity
182 ROUND_TO_MINUS = 3 | round result towards minus infinity
184 | The allowed values of format are:
190 | The allowed values for the last operation are:
200 |=============================================================================
201 | __clear_sticky_bits
202 |=============================================================================
204 | The sticky bits are normally not cleared (thus the name), whereas the
205 | exception type and exception value reflect the last computation.
206 | This routine is provided to clear them (you can also write to _fpCCR,
207 | since it is globally visible).
209 .globl SYM (__clear_sticky_bit)
214 | void __clear_sticky_bits(void);
215 SYM (__clear_sticky_bit):
217 #ifndef __mcoldfire__
218 movew IMM (0),a0@(STICK)
224 |=============================================================================
225 | $_exception_handler
226 |=============================================================================
228 .globl $_exception_handler
233 | This is the common exit point if an exception occurs.
234 | NOTE: it is NOT callable from C!
235 | It expects the exception type in d7, the format (SINGLE_FLOAT,
236 | DOUBLE_FLOAT or LONG_FLOAT) in d6, and the last operation code in d5.
237 | It sets the corresponding exception and sticky bits, and the format.
238 | Depending on the format if fills the corresponding slots for the
239 | operands which produced the exception (all this information is provided
240 | so if you write your own exception handlers you have enough information
241 | to deal with the problem).
242 | Then checks to see if the corresponding exception is trap-enabled,
243 | in which case it pushes the address of _fpCCR and traps through
244 | trap FPTRAP (15 for the moment).
250 movew d7,a0@(EBITS) | set __exception_bits
251 #ifndef __mcoldfire__
252 orw d7,a0@(STICK) | and __sticky_bits
258 movew d6,a0@(FORMT) | and __format
259 movew d5,a0@(LASTO) | and __last_operation
261 | Now put the operands in place:
262 #ifndef __mcoldfire__
263 cmpw IMM (SINGLE_FLOAT),d6
265 cmpl IMM (SINGLE_FLOAT),d6
268 movel a6@(8),a0@(OPER1)
269 movel a6@(12),a0@(OPER1+4)
270 movel a6@(16),a0@(OPER2)
271 movel a6@(20),a0@(OPER2+4)
273 1: movel a6@(8),a0@(OPER1)
274 movel a6@(12),a0@(OPER2)
276 | And check whether the exception is trap-enabled:
277 #ifndef __mcoldfire__
278 andw a0@(TRAPE),d7 | is exception trap-enabled?
285 pea SYM (_fpCCR) | yes, push address of _fpCCR
286 trap IMM (FPTRAP) | and trap
287 #ifndef __mcoldfire__
288 1: moveml sp@+,d2-d7 | restore data registers
291 | XXX if frame pointer is ever removed, stack pointer must
296 #endif /* L_floatex */
301 .globl SYM (__mulsi3)
303 movew sp@(4), d0 /* x0 -> d0 */
304 muluw sp@(10), d0 /* x0*y1 */
305 movew sp@(6), d1 /* x1 -> d1 */
306 muluw sp@(8), d1 /* x1*y0 */
307 #ifndef __mcoldfire__
314 movew sp@(6), d1 /* x1 -> d1 */
315 muluw sp@(10), d1 /* x1*y1 */
319 #endif /* L_mulsi3 */
324 .globl SYM (__udivsi3)
326 #ifndef __mcoldfire__
328 movel sp@(12), d1 /* d1 = divisor */
329 movel sp@(8), d0 /* d0 = dividend */
331 cmpl IMM (0x10000), d1 /* divisor >= 2 ^ 16 ? */
332 jcc L3 /* then try next algorithm */
336 divu d1, d2 /* high quotient in lower word */
337 movew d2, d0 /* save high quotient */
339 movew sp@(10), d2 /* get low dividend + high rest */
340 divu d1, d2 /* low quotient */
344 L3: movel d1, d2 /* use d2 as divisor backup */
345 L4: lsrl IMM (1), d1 /* shift divisor */
346 lsrl IMM (1), d0 /* shift dividend */
347 cmpl IMM (0x10000), d1 /* still divisor >= 2 ^ 16 ? */
349 divu d1, d0 /* now we have 16 bit divisor */
350 andl IMM (0xffff), d0 /* mask out divisor, ignore remainder */
352 /* Multiply the 16 bit tentative quotient with the 32 bit divisor. Because of
353 the operand ranges, this might give a 33 bit product. If this product is
354 greater than the dividend, the tentative quotient was too large. */
356 mulu d0, d1 /* low part, 32 bits */
358 mulu d0, d2 /* high part, at most 17 bits */
359 swap d2 /* align high part with low part */
360 tstw d2 /* high part 17 bits? */
361 jne L5 /* if 17 bits, quotient was too large */
362 addl d2, d1 /* add parts */
363 jcs L5 /* if sum is 33 bits, quotient was too large */
364 cmpl sp@(8), d1 /* compare the sum with the dividend */
365 jls L6 /* if sum > dividend, quotient was too large */
366 L5: subql IMM (1), d0 /* adjust quotient */
371 #else /* __mcoldfire__ */
373 /* Coldfire implementation of non-restoring division algorithm from
374 Hennessy & Patterson, Appendix A. */
381 L1: addl d0,d0 | shift reg pair (p,a) one bit left
383 movl d2,d3 | subtract b from p, store in tmp.
385 jcs L2 | if no carry,
386 bset IMM (0),d0 | set the low order bit of a to 1,
387 movl d3,d2 | and store tmp in p.
390 moveml sp@,d2-d4 | restore data registers
393 #endif /* __mcoldfire__ */
395 #endif /* L_udivsi3 */
400 .globl SYM (__divsi3)
404 moveq IMM (1), d2 /* sign of result stored in d2 (=1 or =-1) */
405 movel sp@(12), d1 /* d1 = divisor */
408 #ifndef __mcoldfire__
409 negb d2 /* change sign because divisor <0 */
411 negl d2 /* change sign because divisor <0 */
413 L1: movel sp@(8), d0 /* d0 = dividend */
416 #ifndef __mcoldfire__
424 jbsr SYM (__udivsi3) /* divide abs(dividend) by abs(divisor) */
433 #endif /* L_divsi3 */
438 .globl SYM (__umodsi3)
440 movel sp@(8), d1 /* d1 = divisor */
441 movel sp@(4), d0 /* d0 = dividend */
446 movel sp@(8), d1 /* d1 = divisor */
447 #ifndef __mcoldfire__
450 jbsr SYM (__mulsi3) /* d0 = (a/b)*b */
455 movel sp@(4), d1 /* d1 = dividend */
456 subl d0, d1 /* d1 = a - (a/b)*b */
459 #endif /* L_umodsi3 */
464 .globl SYM (__modsi3)
466 movel sp@(8), d1 /* d1 = divisor */
467 movel sp@(4), d0 /* d0 = dividend */
472 movel sp@(8), d1 /* d1 = divisor */
473 #ifndef __mcoldfire__
476 jbsr SYM (__mulsi3) /* d0 = (a/b)*b */
481 movel sp@(4), d1 /* d1 = dividend */
482 subl d0, d1 /* d1 = a - (a/b)*b */
485 #endif /* L_modsi3 */
491 .globl $_exception_handler
493 QUIET_NaN = 0xffffffff
497 DBL_MAX_EXP = D_MAX_EXP - D_BIAS
498 DBL_MIN_EXP = 1 - D_BIAS
501 INEXACT_RESULT = 0x0001
504 DIVIDE_BY_ZERO = 0x0008
505 INVALID_OPERATION = 0x0010
519 ROUND_TO_NEAREST = 0 | round result to nearest representable value
520 ROUND_TO_ZERO = 1 | round result towards zero
521 ROUND_TO_PLUS = 2 | round result towards plus infinity
522 ROUND_TO_MINUS = 3 | round result towards minus infinity
526 .globl SYM (__adddf3)
527 .globl SYM (__subdf3)
528 .globl SYM (__muldf3)
529 .globl SYM (__divdf3)
530 .globl SYM (__negdf2)
531 .globl SYM (__cmpdf2)
536 | These are common routines to return and signal exceptions.
539 | Return and signal a denormalized number
541 movew IMM (INEXACT_RESULT+UNDERFLOW),d7
542 moveq IMM (DOUBLE_FLOAT),d6
543 jmp $_exception_handler
547 | Return a properly signed INFINITY and set the exception flags
548 movel IMM (0x7ff00000),d0
551 movew IMM (INEXACT_RESULT+OVERFLOW),d7
552 moveq IMM (DOUBLE_FLOAT),d6
553 jmp $_exception_handler
556 | Return 0 and set the exception flags
559 movew IMM (INEXACT_RESULT+UNDERFLOW),d7
560 moveq IMM (DOUBLE_FLOAT),d6
561 jmp $_exception_handler
564 | Return a quiet NaN and set the exception flags
565 movel IMM (QUIET_NaN),d0
567 movew IMM (INEXACT_RESULT+INVALID_OPERATION),d7
568 moveq IMM (DOUBLE_FLOAT),d6
569 jmp $_exception_handler
572 | Return a properly signed INFINITY and set the exception flags
573 movel IMM (0x7ff00000),d0
576 movew IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7
577 moveq IMM (DOUBLE_FLOAT),d6
578 jmp $_exception_handler
580 |=============================================================================
581 |=============================================================================
582 | double precision routines
583 |=============================================================================
584 |=============================================================================
586 | A double precision floating point number (double) has the format:
589 | unsigned int sign : 1; /* sign bit */
590 | unsigned int exponent : 11; /* exponent, shifted by 126 */
591 | unsigned int fraction : 52; /* fraction */
594 | Thus sizeof(double) = 8 (64 bits).
596 | All the routines are callable from C programs, and return the result
597 | in the register pair d0-d1. They also preserve all registers except
600 |=============================================================================
602 |=============================================================================
604 | double __subdf3(double, double);
606 bchg IMM (31),sp@(12) | change sign of second operand
607 | and fall through, so we always add
608 |=============================================================================
610 |=============================================================================
612 | double __adddf3(double, double);
614 #ifndef __mcoldfire__
615 link a6,IMM (0) | everything will be done in registers
616 moveml d2-d7,sp@- | save all data registers and a2 (but d0-d1)
621 movel a6@(8),d0 | get first operand
623 movel a6@(16),d2 | get second operand
626 movel d0,d7 | get d0's sign bit in d7 '
627 addl d1,d1 | check and clear sign bit of a, and gain one
628 addxl d0,d0 | bit of extra precision
629 beq Ladddf$b | if zero return second operand
631 movel d2,d6 | save sign in d6
632 addl d3,d3 | get rid of sign bit and gain one bit of
633 addxl d2,d2 | extra precision
634 beq Ladddf$a | if zero return first operand
636 andl IMM (0x80000000),d7 | isolate a's sign bit '
637 swap d6 | and also b's sign bit '
638 #ifndef __mcoldfire__
639 andw IMM (0x8000),d6 |
640 orw d6,d7 | and combine them into d7, so that a's sign '
641 | bit is in the high word and b's is in the '
642 | low word, so d6 is free to be used
647 movel d7,a0 | now save d7 into a0, so d7 is free to
650 | Get the exponents and check for denormalized and/or infinity.
652 movel IMM (0x001fffff),d6 | mask for the fraction
653 movel IMM (0x00200000),d7 | mask to put hidden bit back
656 andl d6,d0 | get fraction in d0
657 notl d6 | make d6 into mask for the exponent
658 andl d6,d4 | get exponent in d4
659 beq Ladddf$a$den | branch if a is denormalized
660 cmpl d6,d4 | check for INFINITY or NaN
662 orl d7,d0 | and put hidden bit back
664 swap d4 | shift right exponent so that it starts
665 #ifndef __mcoldfire__
666 lsrw IMM (5),d4 | in bit 0 and not bit 20
668 lsrl IMM (5),d4 | in bit 0 and not bit 20
670 | Now we have a's exponent in d4 and fraction in d0-d1 '
671 movel d2,d5 | save b to get exponent
672 andl d6,d5 | get exponent in d5
673 beq Ladddf$b$den | branch if b is denormalized
674 cmpl d6,d5 | check for INFINITY or NaN
676 notl d6 | make d6 into mask for the fraction again
677 andl d6,d2 | and get fraction in d2
678 orl d7,d2 | and put hidden bit back
680 swap d5 | shift right exponent so that it starts
681 #ifndef __mcoldfire__
682 lsrw IMM (5),d5 | in bit 0 and not bit 20
684 lsrl IMM (5),d5 | in bit 0 and not bit 20
687 | Now we have b's exponent in d5 and fraction in d2-d3. '
689 | The situation now is as follows: the signs are combined in a0, the
690 | numbers are in d0-d1 (a) and d2-d3 (b), and the exponents in d4 (a)
691 | and d5 (b). To do the rounding correctly we need to keep all the
692 | bits until the end, so we need to use d0-d1-d2-d3 for the first number
693 | and d4-d5-d6-d7 for the second. To do this we store (temporarily) the
694 | exponents in a2-a3.
696 #ifndef __mcoldfire__
697 moveml a2-a3,sp@- | save the address registers
704 movel d4,a2 | save the exponents
707 movel IMM (0),d7 | and move the numbers around
714 | Here we shift the numbers until the exponents are the same, and put
715 | the largest exponent in a2.
716 #ifndef __mcoldfire__
717 exg d4,a2 | get exponents back
719 cmpw d4,d5 | compare the exponents
721 movel d4,a4 | get exponents back
727 cmpl d4,d5 | compare the exponents
729 beq Ladddf$3 | if equal don't shift '
730 bhi 9f | branch if second exponent is higher
732 | Here we have a's exponent larger than b's, so we have to shift b. We do
733 | this by using as counter d2:
734 1: movew d4,d2 | move largest exponent to d2
735 #ifndef __mcoldfire__
736 subw d5,d2 | and subtract second exponent
737 exg d4,a2 | get back the longs we saved
740 subl d5,d2 | and subtract second exponent
741 movel d4,a4 | get back the longs we saved
748 | if difference is too large we don't shift (actually, we can just exit) '
749 #ifndef __mcoldfire__
750 cmpw IMM (DBL_MANT_DIG+2),d2
752 cmpl IMM (DBL_MANT_DIG+2),d2
755 #ifndef __mcoldfire__
756 cmpw IMM (32),d2 | if difference >= 32, shift by longs
758 cmpl IMM (32),d2 | if difference >= 32, shift by longs
762 #ifndef __mcoldfire__
763 cmpw IMM (16),d2 | if difference >= 16, shift by words
765 cmpl IMM (16),d2 | if difference >= 16, shift by words
768 bra 3f | enter dbra loop
771 #ifndef __mcoldfire__
792 #ifndef __mcoldfire__
806 #ifndef __mcoldfire__
821 #ifndef __mcoldfire__
829 #ifndef __mcoldfire__
832 subw d5,d6 | keep d5 (largest exponent) in d4
847 | if difference is too large we don't shift (actually, we can just exit) '
848 #ifndef __mcoldfire__
849 cmpw IMM (DBL_MANT_DIG+2),d6
851 cmpl IMM (DBL_MANT_DIG+2),d6
854 #ifndef __mcoldfire__
855 cmpw IMM (32),d6 | if difference >= 32, shift by longs
857 cmpl IMM (32),d6 | if difference >= 32, shift by longs
861 #ifndef __mcoldfire__
862 cmpw IMM (16),d6 | if difference >= 16, shift by words
864 cmpl IMM (16),d6 | if difference >= 16, shift by words
867 bra 3f | enter dbra loop
870 #ifndef __mcoldfire__
891 #ifndef __mcoldfire__
905 #ifndef __mcoldfire__
920 #ifndef __mcoldfire__
927 #ifndef __mcoldfire__
939 | Now we have the numbers in d0--d3 and d4--d7, the exponent in a2, and
942 | Here we have to decide whether to add or subtract the numbers:
943 #ifndef __mcoldfire__
944 exg d7,a0 | get the signs
945 exg d6,a3 | a3 is free to be used
955 movew IMM (0),d7 | get a's sign in d7 '
957 movew IMM (0),d6 | and b's sign in d6 '
958 eorl d7,d6 | compare the signs
959 bmi Lsubdf$0 | if the signs are different we have
961 #ifndef __mcoldfire__
962 exg d7,a0 | else we add the numbers
977 movel a2,d4 | return exponent to d4
979 andl IMM (0x80000000),d7 | d7 now has the sign
981 #ifndef __mcoldfire__
989 | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
990 | the case of denormalized numbers in the rounding routine itself).
991 | As in the addition (not in the subtraction!) we could have set
992 | one more bit we check this:
993 btst IMM (DBL_MANT_DIG+1),d0
995 #ifndef __mcoldfire__
1018 lea Ladddf$5,a0 | to return from rounding routine
1019 lea SYM (_fpCCR),a1 | check the rounding mode
1020 #ifdef __mcoldfire__
1023 movew a1@(6),d6 | rounding mode in d6
1024 beq Lround$to$nearest
1025 #ifndef __mcoldfire__
1026 cmpw IMM (ROUND_TO_PLUS),d6
1028 cmpl IMM (ROUND_TO_PLUS),d6
1034 | Put back the exponent and check for overflow
1035 #ifndef __mcoldfire__
1036 cmpw IMM (0x7ff),d4 | is the exponent big?
1038 cmpl IMM (0x7ff),d4 | is the exponent big?
1041 bclr IMM (DBL_MANT_DIG-1),d0
1042 #ifndef __mcoldfire__
1043 lslw IMM (4),d4 | put exponent back into position
1045 lsll IMM (4),d4 | put exponent back into position
1048 #ifndef __mcoldfire__
1060 | Here we do the subtraction.
1061 #ifndef __mcoldfire__
1062 exg d7,a0 | put sign back in a0
1076 beq Ladddf$ret$1 | if zero just exit
1077 bpl 1f | if positive skip the following
1079 bchg IMM (31),d7 | change sign bit in d7
1083 negxl d1 | and negate result
1086 movel a2,d4 | return exponent to d4
1088 andl IMM (0x80000000),d7 | isolate sign bit
1089 #ifndef __mcoldfire__
1097 | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
1098 | the case of denormalized numbers in the rounding routine itself).
1099 | As in the addition (not in the subtraction!) we could have set
1100 | one more bit we check this:
1101 btst IMM (DBL_MANT_DIG+1),d0
1103 #ifndef __mcoldfire__
1126 lea Lsubdf$1,a0 | to return from rounding routine
1127 lea SYM (_fpCCR),a1 | check the rounding mode
1128 #ifdef __mcoldfire__
1131 movew a1@(6),d6 | rounding mode in d6
1132 beq Lround$to$nearest
1133 #ifndef __mcoldfire__
1134 cmpw IMM (ROUND_TO_PLUS),d6
1136 cmpl IMM (ROUND_TO_PLUS),d6
1142 | Put back the exponent and sign (we don't have overflow). '
1143 bclr IMM (DBL_MANT_DIG-1),d0
1144 #ifndef __mcoldfire__
1145 lslw IMM (4),d4 | put exponent back into position
1147 lsll IMM (4),d4 | put exponent back into position
1150 #ifndef __mcoldfire__
1158 | If one of the numbers was too small (difference of exponents >=
1159 | DBL_MANT_DIG+1) we return the other (and now we don't have to '
1160 | check for finiteness or zero).
1162 #ifndef __mcoldfire__
1173 #ifndef __mcoldfire__
1174 moveml sp@+,d2-d7 | restore data registers
1177 | XXX if frame pointer is ever removed, stack pointer must
1180 unlk a6 | and return
1184 #ifndef __mcoldfire__
1195 #ifndef __mcoldfire__
1196 moveml sp@+,d2-d7 | restore data registers
1199 | XXX if frame pointer is ever removed, stack pointer must
1202 unlk a6 | and return
1206 movel d7,d4 | d7 contains 0x00200000
1210 movel d7,d5 | d7 contains 0x00200000
1215 | Return b (if a is zero)
1224 | Check for NaN and +/-INFINITY.
1226 andl IMM (0x80000000),d7 |
1228 cmpl IMM (0x7ff00000),d0 |
1230 movel d0,d0 | check for zero, since we don't '
1231 bne Ladddf$ret | want to return -0 by mistake
1235 andl IMM (0x000fffff),d0 | check for NaN (nonzero fraction)
1241 #ifndef __mcoldfire__
1242 moveml sp@+,a2-a3 | restore regs and exit
1253 orl d7,d0 | put sign bit back
1254 #ifndef __mcoldfire__
1258 | XXX if frame pointer is ever removed, stack pointer must
1265 | Return a denormalized number.
1266 #ifndef __mcoldfire__
1267 lsrl IMM (1),d0 | shift right once more
1280 | This could be faster but it is not worth the effort, since it is not
1281 | executed very often. We sacrifice speed for clarity here.
1282 movel a6@(8),d0 | get the numbers back (remember that we
1283 movel a6@(12),d1 | did some processing already)
1286 movel IMM (0x7ff00000),d4 | useful constant (INFINITY)
1287 movel d0,d7 | save sign bits
1289 bclr IMM (31),d0 | clear sign bits
1291 | We know that one of them is either NaN of +/-INFINITY
1292 | Check for NaN (if either one is NaN return NaN)
1293 cmpl d4,d0 | check first a (d0)
1294 bhi Ld$inop | if d0 > 0x7ff00000 or equal and
1296 tstl d1 | d1 > 0, a is NaN
1298 2: cmpl d4,d2 | check now b (d1)
1304 | Now comes the check for +/-INFINITY. We know that both are (maybe not
1305 | finite) numbers, but we have to check if both are infinite whether we
1306 | are adding or subtracting them.
1307 eorl d7,d6 | to check sign bits
1309 andl IMM (0x80000000),d7 | get (common) sign bit
1312 | We know one (or both) are infinite, so we test for equality between the
1313 | two numbers (if they are equal they have to be infinite both, so we
1315 cmpl d2,d0 | are both infinite?
1316 bne 1f | if d0 <> d2 they are not equal
1317 cmpl d3,d1 | if d0 == d2 test d3 and d1
1318 beq Ld$inop | if equal return NaN
1320 andl IMM (0x80000000),d7 | get a's sign bit '
1321 cmpl d4,d0 | test now for infinity
1322 beq Ld$infty | if a is INFINITY return with this sign
1323 bchg IMM (31),d7 | else we know b is INFINITY and has
1324 bra Ld$infty | the opposite sign
1326 |=============================================================================
1328 |=============================================================================
1330 | double __muldf3(double, double);
1332 #ifndef __mcoldfire__
1339 movel a6@(8),d0 | get a into d0-d1
1341 movel a6@(16),d2 | and b into d2-d3
1343 movel d0,d7 | d7 will hold the sign of the product
1345 andl IMM (0x80000000),d7 |
1346 movel d7,a0 | save sign bit into a0
1347 movel IMM (0x7ff00000),d7 | useful constant (+INFINITY)
1348 movel d7,d6 | another (mask for fraction)
1350 bclr IMM (31),d0 | get rid of a's sign bit '
1353 beq Lmuldf$a$0 | branch if a is zero
1355 bclr IMM (31),d2 | get rid of b's sign bit '
1358 beq Lmuldf$b$0 | branch if b is zero
1360 cmpl d7,d0 | is a big?
1361 bhi Lmuldf$inop | if a is NaN return NaN
1362 beq Lmuldf$a$nf | we still have to check d1 and b ...
1363 cmpl d7,d2 | now compare b with INFINITY
1364 bhi Lmuldf$inop | is b NaN?
1365 beq Lmuldf$b$nf | we still have to check d3 ...
1366 | Here we have both numbers finite and nonzero (and with no sign bit).
1367 | Now we get the exponents into d4 and d5.
1368 andl d7,d4 | isolate exponent in d4
1369 beq Lmuldf$a$den | if exponent zero, have denormalized
1370 andl d6,d0 | isolate fraction
1371 orl IMM (0x00100000),d0 | and put hidden bit back
1372 swap d4 | I like exponents in the first byte
1373 #ifndef __mcoldfire__
1382 orl IMM (0x00100000),d2 | and put hidden bit back
1384 #ifndef __mcoldfire__
1390 #ifndef __mcoldfire__
1391 addw d5,d4 | add exponents
1392 subw IMM (D_BIAS+1),d4 | and subtract bias (plus one)
1394 addl d5,d4 | add exponents
1395 subl IMM (D_BIAS+1),d4 | and subtract bias (plus one)
1398 | We are now ready to do the multiplication. The situation is as follows:
1399 | both a and b have bit 52 ( bit 20 of d0 and d2) set (even if they were
1400 | denormalized to start with!), which means that in the product bit 104
1401 | (which will correspond to bit 8 of the fourth long) is set.
1403 | Here we have to do the product.
1404 | To do it we have to juggle the registers back and forth, as there are not
1405 | enough to keep everything in them. So we use the address registers to keep
1406 | some intermediate data.
1408 #ifndef __mcoldfire__
1409 moveml a2-a3,sp@- | save a2 and a3 for temporary use
1415 movel IMM (0),a2 | a2 is a null register
1416 movel d4,a3 | and a3 will preserve the exponent
1418 | First, shift d2-d3 so bit 20 becomes bit 31:
1419 #ifndef __mcoldfire__
1420 rorl IMM (5),d2 | rotate d2 5 places right
1421 swap d2 | and swap it
1422 rorl IMM (5),d3 | do the same thing with d3
1424 movew d3,d6 | get the rightmost 11 bits of d3
1425 andw IMM (0x07ff),d6 |
1426 orw d6,d2 | and put them into d2
1427 andw IMM (0xf800),d3 | clear those bits in d3
1429 moveq IMM (11),d7 | left shift d2 11 bits
1431 movel d3,d6 | get a copy of d3
1432 lsll d7,d3 | left shift d3 11 bits
1433 andl IMM (0xffe00000),d6 | get the top 11 bits of d3
1434 moveq IMM (21),d7 | right shift them 21 bits
1436 orl d6,d2 | stick them at the end of d2
1439 movel d2,d6 | move b into d6-d7
1440 movel d3,d7 | move a into d4-d5
1441 movel d0,d4 | and clear d0-d1-d2-d3 (to put result)
1448 | We use a1 as counter:
1449 movel IMM (DBL_MANT_DIG-1),a1
1450 #ifndef __mcoldfire__
1459 #ifndef __mcoldfire__
1460 exg d7,a1 | put counter back in a1
1466 addl d3,d3 | shift sum once left
1472 bcc 2f | if bit clear skip the following
1473 #ifndef __mcoldfire__
1480 addl d5,d3 | else add a to the sum
1484 #ifndef __mcoldfire__
1492 #ifndef __mcoldfire__
1493 exg d7,a1 | put counter in d7
1494 dbf d7,1b | decrement and branch
1503 movel a3,d4 | restore exponent
1504 #ifndef __mcoldfire__
1512 | Now we have the product in d0-d1-d2-d3, with bit 8 of d0 set. The
1513 | first thing to do now is to normalize it so bit 8 becomes bit
1514 | DBL_MANT_DIG-32 (to do the rounding); later we will shift right.
1523 #ifndef __mcoldfire__
1553 | Now round, check for over- and underflow, and exit.
1554 movel a0,d7 | get sign bit back into d7
1555 movew IMM (MULTIPLY),d5
1557 btst IMM (DBL_MANT_DIG+1-32),d0
1559 #ifndef __mcoldfire__
1574 movew IMM (MULTIPLY),d5
1578 movew IMM (MULTIPLY),d5
1579 movel a0,d7 | get sign bit back into d7
1580 tstl d3 | we know d2 == 0x7ff00000, so check d3
1581 bne Ld$inop | if d3 <> 0 b is NaN
1582 bra Ld$overflow | else we have overflow (since a is finite)
1585 movew IMM (MULTIPLY),d5
1586 movel a0,d7 | get sign bit back into d7
1587 tstl d1 | we know d0 == 0x7ff00000, so check d1
1588 bne Ld$inop | if d1 <> 0 a is NaN
1589 bra Ld$overflow | else signal overflow
1591 | If either number is zero return zero, unless the other is +/-INFINITY or
1592 | NaN, in which case we return NaN.
1594 movew IMM (MULTIPLY),d5
1595 #ifndef __mcoldfire__
1596 exg d2,d0 | put b (==0) into d0-d1
1597 exg d3,d1 | and a (with sign bit cleared) into d2-d3
1608 movel a6@(16),d2 | put b into d2-d3 again
1610 bclr IMM (31),d2 | clear sign bit
1611 1: cmpl IMM (0x7ff00000),d2 | check for non-finiteness
1612 bge Ld$inop | in case NaN or +/-INFINITY return NaN
1615 #ifndef __mcoldfire__
1619 | XXX if frame pointer is ever removed, stack pointer must
1625 | If a number is denormalized we put an exponent of 1 but do not put the
1626 | hidden bit back into the fraction; instead we shift left until bit 21
1627 | (the hidden bit) is set, adjusting the exponent accordingly. We do this
1628 | to ensure that the product of the fractions is close to 1.
1632 1: addl d1,d1 | shift a left until bit 20 is set
1634 #ifndef __mcoldfire__
1635 subw IMM (1),d4 | and adjust exponent
1637 subl IMM (1),d4 | and adjust exponent
1646 1: addl d3,d3 | shift b left until bit 20 is set
1648 #ifndef __mcoldfire__
1649 subw IMM (1),d5 | and adjust exponent
1651 subql IMM (1),d5 | and adjust exponent
1658 |=============================================================================
1660 |=============================================================================
1662 | double __divdf3(double, double);
1664 #ifndef __mcoldfire__
1671 movel a6@(8),d0 | get a into d0-d1
1673 movel a6@(16),d2 | and b into d2-d3
1675 movel d0,d7 | d7 will hold the sign of the result
1677 andl IMM (0x80000000),d7
1678 movel d7,a0 | save sign into a0
1679 movel IMM (0x7ff00000),d7 | useful constant (+INFINITY)
1680 movel d7,d6 | another (mask for fraction)
1682 bclr IMM (31),d0 | get rid of a's sign bit '
1685 beq Ldivdf$a$0 | branch if a is zero
1687 bclr IMM (31),d2 | get rid of b's sign bit '
1690 beq Ldivdf$b$0 | branch if b is zero
1692 cmpl d7,d0 | is a big?
1693 bhi Ldivdf$inop | if a is NaN return NaN
1694 beq Ldivdf$a$nf | if d0 == 0x7ff00000 we check d1
1695 cmpl d7,d2 | now compare b with INFINITY
1696 bhi Ldivdf$inop | if b is NaN return NaN
1697 beq Ldivdf$b$nf | if d2 == 0x7ff00000 we check d3
1698 | Here we have both numbers finite and nonzero (and with no sign bit).
1699 | Now we get the exponents into d4 and d5 and normalize the numbers to
1700 | ensure that the ratio of the fractions is around 1. We do this by
1701 | making sure that both numbers have bit #DBL_MANT_DIG-32-1 (hidden bit)
1702 | set, even if they were denormalized to start with.
1703 | Thus, the result will satisfy: 2 > result > 1/2.
1704 andl d7,d4 | and isolate exponent in d4
1705 beq Ldivdf$a$den | if exponent is zero we have a denormalized
1706 andl d6,d0 | and isolate fraction
1707 orl IMM (0x00100000),d0 | and put hidden bit back
1708 swap d4 | I like exponents in the first byte
1709 #ifndef __mcoldfire__
1718 orl IMM (0x00100000),d2
1720 #ifndef __mcoldfire__
1726 #ifndef __mcoldfire__
1727 subw d5,d4 | subtract exponents
1728 addw IMM (D_BIAS),d4 | and add bias
1730 subl d5,d4 | subtract exponents
1731 addl IMM (D_BIAS),d4 | and add bias
1734 | We are now ready to do the division. We have prepared things in such a way
1735 | that the ratio of the fractions will be less than 2 but greater than 1/2.
1736 | At this point the registers in use are:
1737 | d0-d1 hold a (first operand, bit DBL_MANT_DIG-32=0, bit
1738 | DBL_MANT_DIG-1-32=1)
1739 | d2-d3 hold b (second operand, bit DBL_MANT_DIG-32=1)
1740 | d4 holds the difference of the exponents, corrected by the bias
1741 | a0 holds the sign of the ratio
1743 | To do the rounding correctly we need to keep information about the
1744 | nonsignificant bits. One way to do this would be to do the division
1745 | using four registers; another is to use two registers (as originally
1746 | I did), but use a sticky bit to preserve information about the
1747 | fractional part. Note that we can keep that info in a1, which is not
1749 movel IMM (0),d6 | d6-d7 will hold the result
1751 movel IMM (0),a1 | and a1 will hold the sticky bit
1753 movel IMM (DBL_MANT_DIG-32+1),d5
1755 1: cmpl d0,d2 | is a < b?
1756 bhi 3f | if b > a skip the following
1757 beq 4f | if d0==d2 check d1 and d3
1759 subxl d2,d0 | a <-- a - b
1760 bset d5,d6 | set the corresponding bit in d6
1761 3: addl d1,d1 | shift a by 1
1763 #ifndef __mcoldfire__
1764 dbra d5,1b | and branch back
1770 4: cmpl d1,d3 | here d0==d2, so check d1 and d3
1771 bhi 3b | if d1 > d2 skip the subtraction
1772 bra 2b | else go do it
1774 | Here we have to start setting the bits in the second long.
1775 movel IMM (31),d5 | again d5 is counter
1777 1: cmpl d0,d2 | is a < b?
1778 bhi 3f | if b > a skip the following
1779 beq 4f | if d0==d2 check d1 and d3
1781 subxl d2,d0 | a <-- a - b
1782 bset d5,d7 | set the corresponding bit in d7
1783 3: addl d1,d1 | shift a by 1
1785 #ifndef __mcoldfire__
1786 dbra d5,1b | and branch back
1792 4: cmpl d1,d3 | here d0==d2, so check d1 and d3
1793 bhi 3b | if d1 > d2 skip the subtraction
1794 bra 2b | else go do it
1796 | Now go ahead checking until we hit a one, which we store in d2.
1797 movel IMM (DBL_MANT_DIG),d5
1798 1: cmpl d2,d0 | is a < b?
1799 bhi 4f | if b < a, exit
1800 beq 3f | if d0==d2 check d1 and d3
1801 2: addl d1,d1 | shift a by 1
1803 #ifndef __mcoldfire__
1804 dbra d5,1b | and branch back
1809 movel IMM (0),d2 | here no sticky bit was found
1812 3: cmpl d1,d3 | here d0==d2, so check d1 and d3
1813 bhi 2b | if d1 > d2 go back
1815 | Here put the sticky bit in d2-d3 (in the position which actually corresponds
1816 | to it; if you don't do this the algorithm loses in some cases). '
1819 #ifndef __mcoldfire__
1820 subw IMM (DBL_MANT_DIG),d5
1824 subl IMM (DBL_MANT_DIG),d5
1831 #ifndef __mcoldfire__
1838 | Finally we are finished! Move the longs in the address registers to
1839 | their final destination:
1844 | Here we have finished the division, with the result in d0-d1-d2-d3, with
1845 | 2^21 <= d6 < 2^23. Thus bit 23 is not set, but bit 22 could be set.
1846 | If it is not, then definitely bit 21 is set. Normalize so bit 22 is
1848 btst IMM (DBL_MANT_DIG-32+1),d0
1850 #ifndef __mcoldfire__
1873 | Now round, check for over- and underflow, and exit.
1874 movel a0,d7 | restore sign bit to d7
1875 movew IMM (DIVIDE),d5
1879 movew IMM (DIVIDE),d5
1883 | If a is zero check to see whether b is zero also. In that case return
1884 | NaN; then check if b is NaN, and return NaN also in that case. Else
1886 movew IMM (DIVIDE),d5
1890 beq Ld$inop | if b is also zero return NaN
1891 cmpl IMM (0x7ff00000),d2 | check for NaN
1896 1: movel IMM (0),d0 | else return zero
1898 lea SYM (_fpCCR),a0 | clear exception flags
1900 #ifndef __mcoldfire__
1904 | XXX if frame pointer is ever removed, stack pointer must
1911 movew IMM (DIVIDE),d5
1912 | If we got here a is not zero. Check if a is NaN; in that case return NaN,
1913 | else return +/-INFINITY. Remember that a is in d0 with the sign bit
1915 movel a0,d7 | put a's sign bit back in d7 '
1916 cmpl IMM (0x7ff00000),d0 | compare d0 with INFINITY
1917 bhi Ld$inop | if larger it is NaN
1920 bra Ld$div$0 | else signal DIVIDE_BY_ZERO
1923 movew IMM (DIVIDE),d5
1924 | If d2 == 0x7ff00000 we have to check d3.
1926 bne Ld$inop | if d3 <> 0, b is NaN
1927 bra Ld$underflow | else b is +/-INFINITY, so signal underflow
1930 movew IMM (DIVIDE),d5
1931 | If d0 == 0x7ff00000 we have to check d1.
1933 bne Ld$inop | if d1 <> 0, a is NaN
1934 | If a is INFINITY we have to check b
1935 cmpl d7,d2 | compare b with INFINITY
1936 bge Ld$inop | if b is NaN or INFINITY return NaN
1939 bra Ld$overflow | else return overflow
1941 | If a number is denormalized we put an exponent of 1 but do not put the
1942 | bit back into the fraction.
1946 1: addl d1,d1 | shift a left until bit 20 is set
1948 #ifndef __mcoldfire__
1949 subw IMM (1),d4 | and adjust exponent
1951 subl IMM (1),d4 | and adjust exponent
1953 btst IMM (DBL_MANT_DIG-32-1),d0
1960 1: addl d3,d3 | shift b left until bit 20 is set
1962 #ifndef __mcoldfire__
1963 subw IMM (1),d5 | and adjust exponent
1965 subql IMM (1),d5 | and adjust exponent
1967 btst IMM (DBL_MANT_DIG-32-1),d2
1972 | This is a common exit point for __muldf3 and __divdf3. When they enter
1973 | this point the sign of the result is in d7, the result in d0-d1, normalized
1974 | so that 2^21 <= d0 < 2^22, and the exponent is in the lower byte of d4.
1976 | First check for underlow in the exponent:
1977 #ifndef __mcoldfire__
1978 cmpw IMM (-DBL_MANT_DIG-1),d4
1980 cmpl IMM (-DBL_MANT_DIG-1),d4
1983 | It could happen that the exponent is less than 1, in which case the
1984 | number is denormalized. In this case we shift right and adjust the
1985 | exponent until it becomes 1 or the fraction is zero (in the latter case
1986 | we signal underflow and return zero).
1988 movel IMM (0),d6 | use d6-d7 to collect bits flushed right
1989 movel d6,d7 | use d6-d7 to collect bits flushed right
1990 #ifndef __mcoldfire__
1991 cmpw IMM (1),d4 | if the exponent is less than 1 we
1993 cmpl IMM (1),d4 | if the exponent is less than 1 we
1995 bge 2f | have to shift right (denormalize)
1997 #ifndef __mcoldfire__
1998 addw IMM (1),d4 | adjust the exponent
1999 lsrl IMM (1),d0 | shift right once
2005 cmpw IMM (1),d4 | is the exponent 1 already?
2007 addl IMM (1),d4 | adjust the exponent
2029 cmpl IMM (1),d4 | is the exponent 1 already?
2031 beq 2f | if not loop back
2033 bra Ld$underflow | safety check, shouldn't execute '
2034 2: orl d6,d2 | this is a trick so we don't lose '
2035 orl d7,d3 | the bits which were flushed right
2036 movel a0,d7 | get back sign bit into d7
2037 | Now call the rounding routine (which takes care of denormalized numbers):
2038 lea Lround$0,a0 | to return from rounding routine
2039 lea SYM (_fpCCR),a1 | check the rounding mode
2040 #ifdef __mcoldfire__
2043 movew a1@(6),d6 | rounding mode in d6
2044 beq Lround$to$nearest
2045 #ifndef __mcoldfire__
2046 cmpw IMM (ROUND_TO_PLUS),d6
2048 cmpl IMM (ROUND_TO_PLUS),d6
2054 | Here we have a correctly rounded result (either normalized or denormalized).
2056 | Here we should have either a normalized number or a denormalized one, and
2057 | the exponent is necessarily larger or equal to 1 (so we don't have to '
2058 | check again for underflow!). We have to check for overflow or for a
2059 | denormalized number (which also signals underflow).
2060 | Check for overflow (i.e., exponent >= 0x7ff).
2061 #ifndef __mcoldfire__
2062 cmpw IMM (0x07ff),d4
2064 cmpl IMM (0x07ff),d4
2067 | Now check for a denormalized number (exponent==0):
2071 | Put back the exponents and sign and return.
2072 #ifndef __mcoldfire__
2073 lslw IMM (4),d4 | exponent back to fourth byte
2075 lsll IMM (4),d4 | exponent back to fourth byte
2077 bclr IMM (DBL_MANT_DIG-32-1),d0
2078 swap d0 | and put back exponent
2079 #ifndef __mcoldfire__
2085 orl d7,d0 | and sign also
2089 #ifndef __mcoldfire__
2093 | XXX if frame pointer is ever removed, stack pointer must
2099 |=============================================================================
2101 |=============================================================================
2103 | double __negdf2(double, double);
2105 #ifndef __mcoldfire__
2112 movew IMM (NEGATE),d5
2113 movel a6@(8),d0 | get number to negate in d0-d1
2115 bchg IMM (31),d0 | negate
2116 movel d0,d2 | make a positive copy (for the tests)
2118 movel d2,d4 | check for zero
2120 beq 2f | if zero (either sign) return +zero
2121 cmpl IMM (0x7ff00000),d2 | compare to +INFINITY
2122 blt 1f | if finite, return
2123 bhi Ld$inop | if larger (fraction not zero) is NaN
2124 tstl d1 | if d2 == 0x7ff00000 check d1
2126 movel d0,d7 | else get sign and return INFINITY
2127 andl IMM (0x80000000),d7
2129 1: lea SYM (_fpCCR),a0
2131 #ifndef __mcoldfire__
2135 | XXX if frame pointer is ever removed, stack pointer must
2143 |=============================================================================
2145 |=============================================================================
2151 | int __cmpdf2(double, double);
2153 #ifndef __mcoldfire__
2155 moveml d2-d7,sp@- | save registers
2160 movew IMM (COMPARE),d5
2161 movel a6@(8),d0 | get first operand
2163 movel a6@(16),d2 | get second operand
2165 | First check if a and/or b are (+/-) zero and in that case clear
2167 movel d0,d6 | copy signs into d6 (a) and d7(b)
2168 bclr IMM (31),d0 | and clear signs in d0 and d2
2171 cmpl IMM (0x7fff0000),d0 | check for a == NaN
2172 bhi Ld$inop | if d0 > 0x7ff00000, a is NaN
2173 beq Lcmpdf$a$nf | if equal can be INFINITY, so check d1
2174 movel d0,d4 | copy into d4 to test for zero
2178 cmpl IMM (0x7fff0000),d2 | check for b == NaN
2179 bhi Ld$inop | if d2 > 0x7ff00000, b is NaN
2180 beq Lcmpdf$b$nf | if equal can be INFINITY, so check d3
2188 | If the signs are not equal check if a >= 0
2190 bpl Lcmpdf$a$gt$b | if (a >= 0 && b < 0) => a > b
2191 bmi Lcmpdf$b$gt$a | if (a < 0 && b >= 0) => a < b
2193 | If the signs are equal check for < 0
2196 | If both are negative exchange them
2197 #ifndef __mcoldfire__
2209 | Now that they are positive we just compare them as longs (does this also
2210 | work for denormalized numbers?).
2212 bhi Lcmpdf$b$gt$a | |b| > |a|
2213 bne Lcmpdf$a$gt$b | |b| < |a|
2214 | If we got here d0 == d2, so we compare d1 and d3.
2216 bhi Lcmpdf$b$gt$a | |b| > |a|
2217 bne Lcmpdf$a$gt$b | |b| < |a|
2218 | If we got here a == b.
2219 movel IMM (EQUAL),d0
2220 #ifndef __mcoldfire__
2221 moveml sp@+,d2-d7 | put back the registers
2224 | XXX if frame pointer is ever removed, stack pointer must
2230 movel IMM (GREATER),d0
2231 #ifndef __mcoldfire__
2232 moveml sp@+,d2-d7 | put back the registers
2235 | XXX if frame pointer is ever removed, stack pointer must
2242 #ifndef __mcoldfire__
2243 moveml sp@+,d2-d7 | put back the registers
2246 | XXX if frame pointer is ever removed, stack pointer must
2269 |=============================================================================
2271 |=============================================================================
2273 | The rounding routines expect the number to be normalized in registers
2274 | d0-d1-d2-d3, with the exponent in register d4. They assume that the
2275 | exponent is larger or equal to 1. They return a properly normalized number
2276 | if possible, and a denormalized number otherwise. The exponent is returned
2280 | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
2281 | Here we assume that the exponent is not too small (this should be checked
2282 | before entering the rounding routine), but the number could be denormalized.
2284 | Check for denormalized numbers:
2285 1: btst IMM (DBL_MANT_DIG-32),d0
2286 bne 2f | if set the number is normalized
2287 | Normalize shifting left until bit #DBL_MANT_DIG-32 is set or the exponent
2288 | is one (remember that a denormalized number corresponds to an
2289 | exponent of -D_BIAS+1).
2290 #ifndef __mcoldfire__
2291 cmpw IMM (1),d4 | remember that the exponent is at least one
2293 cmpl IMM (1),d4 | remember that the exponent is at least one
2295 beq 2f | an exponent of one means denormalized
2296 addl d3,d3 | else shift and adjust the exponent
2300 #ifndef __mcoldfire__
2307 | Now round: we do it as follows: after the shifting we can write the
2308 | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
2309 | If delta < 1, do nothing. If delta > 1, add 1 to f.
2310 | If delta == 1, we make sure the rounded number will be even (odd?)
2312 btst IMM (0),d1 | is delta < 1?
2313 beq 2f | if so, do not do anything
2314 orl d2,d3 | is delta == 1?
2315 bne 1f | if so round to even
2317 andl IMM (2),d3 | bit 1 is the last significant bit
2322 1: movel IMM (1),d3 | else add 1
2326 | Shift right once (because we used bit #DBL_MANT_DIG-32!).
2328 #ifndef __mcoldfire__
2339 | Now check again bit #DBL_MANT_DIG-32 (rounding could have produced a
2340 | 'fraction overflow' ...).
2341 btst IMM (DBL_MANT_DIG-32),d0
2343 #ifndef __mcoldfire__
2356 | If bit #DBL_MANT_DIG-32-1 is clear we have a denormalized number, so we
2357 | have to put the exponent to zero and return a denormalized number.
2358 btst IMM (DBL_MANT_DIG-32-1),d0
2368 #endif /* L_double */
2373 .globl $_exception_handler
2375 QUIET_NaN = 0xffffffff
2376 SIGNL_NaN = 0x7f800001
2377 INFINITY = 0x7f800000
2381 FLT_MAX_EXP = F_MAX_EXP - F_BIAS
2382 FLT_MIN_EXP = 1 - F_BIAS
2385 INEXACT_RESULT = 0x0001
2388 DIVIDE_BY_ZERO = 0x0008
2389 INVALID_OPERATION = 0x0010
2403 ROUND_TO_NEAREST = 0 | round result to nearest representable value
2404 ROUND_TO_ZERO = 1 | round result towards zero
2405 ROUND_TO_PLUS = 2 | round result towards plus infinity
2406 ROUND_TO_MINUS = 3 | round result towards minus infinity
2410 .globl SYM (__addsf3)
2411 .globl SYM (__subsf3)
2412 .globl SYM (__mulsf3)
2413 .globl SYM (__divsf3)
2414 .globl SYM (__negsf2)
2415 .globl SYM (__cmpsf2)
2417 | These are common routines to return and signal exceptions.
2423 | Return and signal a denormalized number
2425 movew IMM (INEXACT_RESULT+UNDERFLOW),d7
2426 moveq IMM (SINGLE_FLOAT),d6
2427 jmp $_exception_handler
2431 | Return a properly signed INFINITY and set the exception flags
2432 movel IMM (INFINITY),d0
2434 movew IMM (INEXACT_RESULT+OVERFLOW),d7
2435 moveq IMM (SINGLE_FLOAT),d6
2436 jmp $_exception_handler
2439 | Return 0 and set the exception flags
2441 movew IMM (INEXACT_RESULT+UNDERFLOW),d7
2442 moveq IMM (SINGLE_FLOAT),d6
2443 jmp $_exception_handler
2446 | Return a quiet NaN and set the exception flags
2447 movel IMM (QUIET_NaN),d0
2448 movew IMM (INEXACT_RESULT+INVALID_OPERATION),d7
2449 moveq IMM (SINGLE_FLOAT),d6
2450 jmp $_exception_handler
2453 | Return a properly signed INFINITY and set the exception flags
2454 movel IMM (INFINITY),d0
2456 movew IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7
2457 moveq IMM (SINGLE_FLOAT),d6
2458 jmp $_exception_handler
2460 |=============================================================================
2461 |=============================================================================
2462 | single precision routines
2463 |=============================================================================
2464 |=============================================================================
2466 | A single precision floating point number (float) has the format:
2469 | unsigned int sign : 1; /* sign bit */
2470 | unsigned int exponent : 8; /* exponent, shifted by 126 */
2471 | unsigned int fraction : 23; /* fraction */
2474 | Thus sizeof(float) = 4 (32 bits).
2476 | All the routines are callable from C programs, and return the result
2477 | in the single register d0. They also preserve all registers except
2480 |=============================================================================
2482 |=============================================================================
2484 | float __subsf3(float, float);
2486 bchg IMM (31),sp@(8) | change sign of second operand
2488 |=============================================================================
2490 |=============================================================================
2492 | float __addsf3(float, float);
2494 #ifndef __mcoldfire__
2495 link a6,IMM (0) | everything will be done in registers
2496 moveml d2-d7,sp@- | save all data registers but d0-d1
2501 movel a6@(8),d0 | get first operand
2502 movel a6@(12),d1 | get second operand
2503 movel d0,d6 | get d0's sign bit '
2504 addl d0,d0 | check and clear sign bit of a
2505 beq Laddsf$b | if zero return second operand
2506 movel d1,d7 | save b's sign bit '
2507 addl d1,d1 | get rid of sign bit
2508 beq Laddsf$a | if zero return first operand
2510 movel d6,a0 | save signs in address registers
2511 movel d7,a1 | so we can use d6 and d7
2513 | Get the exponents and check for denormalized and/or infinity.
2515 movel IMM (0x00ffffff),d4 | mask to get fraction
2516 movel IMM (0x01000000),d5 | mask to put hidden bit back
2518 movel d0,d6 | save a to get exponent
2519 andl d4,d0 | get fraction in d0
2520 notl d4 | make d4 into a mask for the exponent
2521 andl d4,d6 | get exponent in d6
2522 beq Laddsf$a$den | branch if a is denormalized
2523 cmpl d4,d6 | check for INFINITY or NaN
2525 swap d6 | put exponent into first word
2526 orl d5,d0 | and put hidden bit back
2528 | Now we have a's exponent in d6 (second byte) and the mantissa in d0. '
2529 movel d1,d7 | get exponent in d7
2531 beq Laddsf$b$den | branch if b is denormalized
2532 cmpl d4,d7 | check for INFINITY or NaN
2534 swap d7 | put exponent into first word
2535 notl d4 | make d4 into a mask for the fraction
2536 andl d4,d1 | get fraction in d1
2537 orl d5,d1 | and put hidden bit back
2539 | Now we have b's exponent in d7 (second byte) and the mantissa in d1. '
2541 | Note that the hidden bit corresponds to bit #FLT_MANT_DIG-1, and we
2542 | shifted right once, so bit #FLT_MANT_DIG is set (so we have one extra
2545 movel d1,d2 | move b to d2, since we want to use
2546 | two registers to do the sum
2547 movel IMM (0),d1 | and clear the new ones
2550 | Here we shift the numbers in registers d0 and d1 so the exponents are the
2551 | same, and put the largest exponent in d6. Note that we are using two
2552 | registers for each number (see the discussion by D. Knuth in "Seminumerical
2554 #ifndef __mcoldfire__
2555 cmpw d6,d7 | compare exponents
2557 cmpl d6,d7 | compare exponents
2559 beq Laddsf$3 | if equal don't shift '
2560 bhi 5f | branch if second exponent largest
2562 subl d6,d7 | keep the largest exponent
2564 #ifndef __mcoldfire__
2565 lsrw IMM (8),d7 | put difference in lower byte
2567 lsrl IMM (8),d7 | put difference in lower byte
2569 | if difference is too large we don't shift (actually, we can just exit) '
2570 #ifndef __mcoldfire__
2571 cmpw IMM (FLT_MANT_DIG+2),d7
2573 cmpl IMM (FLT_MANT_DIG+2),d7
2576 #ifndef __mcoldfire__
2577 cmpw IMM (16),d7 | if difference >= 16 swap
2579 cmpl IMM (16),d7 | if difference >= 16 swap
2583 #ifndef __mcoldfire__
2589 #ifndef __mcoldfire__
2590 lsrl IMM (1),d2 | shift right second operand
2608 #ifndef __mcoldfire__
2613 bne 2b | if still more bits, go back to normal case
2616 #ifndef __mcoldfire__
2617 exg d6,d7 | exchange the exponents
2623 subl d6,d7 | keep the largest exponent
2625 #ifndef __mcoldfire__
2626 lsrw IMM (8),d7 | put difference in lower byte
2628 lsrl IMM (8),d7 | put difference in lower byte
2630 | if difference is too large we don't shift (and exit!) '
2631 #ifndef __mcoldfire__
2632 cmpw IMM (FLT_MANT_DIG+2),d7
2634 cmpl IMM (FLT_MANT_DIG+2),d7
2637 #ifndef __mcoldfire__
2638 cmpw IMM (16),d7 | if difference >= 16 swap
2640 cmpl IMM (16),d7 | if difference >= 16 swap
2644 #ifndef __mcoldfire__
2650 #ifndef __mcoldfire__
2651 lsrl IMM (1),d0 | shift right first operand
2669 #ifndef __mcoldfire__
2674 bne 6b | if still more bits, go back to normal case
2675 | otherwise we fall through
2677 | Now we have a in d0-d1, b in d2-d3, and the largest exponent in d6 (the
2678 | signs are stored in a0 and a1).
2681 | Here we have to decide whether to add or subtract the numbers
2682 #ifndef __mcoldfire__
2683 exg d6,a0 | get signs back
2684 exg d7,a1 | and save the exponents
2693 eorl d6,d7 | combine sign bits
2694 bmi Lsubsf$0 | if negative a and b have opposite
2695 | sign so we actually subtract the
2698 | Here we have both positive or both negative
2699 #ifndef __mcoldfire__
2700 exg d6,a0 | now we have the exponent in d6
2706 movel a0,d7 | and sign in d7
2707 andl IMM (0x80000000),d7
2708 | Here we do the addition.
2711 | Note: now we have d2, d3, d4 and d5 to play with!
2713 | Put the exponent, in the first byte, in d2, to use the "standard" rounding
2716 #ifndef __mcoldfire__
2722 | Before rounding normalize so bit #FLT_MANT_DIG is set (we will consider
2723 | the case of denormalized numbers in the rounding routine itself).
2724 | As in the addition (not in the subtraction!) we could have set
2725 | one more bit we check this:
2726 btst IMM (FLT_MANT_DIG+1),d0
2728 #ifndef __mcoldfire__
2740 lea Laddsf$4,a0 | to return from rounding routine
2741 lea SYM (_fpCCR),a1 | check the rounding mode
2742 #ifdef __mcoldfire__
2745 movew a1@(6),d6 | rounding mode in d6
2746 beq Lround$to$nearest
2747 #ifndef __mcoldfire__
2748 cmpw IMM (ROUND_TO_PLUS),d6
2750 cmpl IMM (ROUND_TO_PLUS),d6
2756 | Put back the exponent, but check for overflow.
2757 #ifndef __mcoldfire__
2763 bclr IMM (FLT_MANT_DIG-1),d0
2764 #ifndef __mcoldfire__
2777 | We are here if a > 0 and b < 0 (sign bits cleared).
2778 | Here we do the subtraction.
2779 movel d6,d7 | put sign in d7
2780 andl IMM (0x80000000),d7
2782 subl d3,d1 | result in d0-d1
2784 beq Laddsf$ret | if zero just exit
2785 bpl 1f | if positive skip the following
2786 bchg IMM (31),d7 | change sign bit in d7
2790 #ifndef __mcoldfire__
2791 exg d2,a0 | now we have the exponent in d2
2792 lsrw IMM (8),d2 | put it in the first byte
2797 lsrl IMM (8),d2 | put it in the first byte
2800 | Now d0-d1 is positive and the sign bit is in d7.
2802 | Note that we do not have to normalize, since in the subtraction bit
2803 | #FLT_MANT_DIG+1 is never set, and denormalized numbers are handled by
2804 | the rounding routines themselves.
2805 lea Lsubsf$1,a0 | to return from rounding routine
2806 lea SYM (_fpCCR),a1 | check the rounding mode
2807 #ifdef __mcoldfire__
2810 movew a1@(6),d6 | rounding mode in d6
2811 beq Lround$to$nearest
2812 #ifndef __mcoldfire__
2813 cmpw IMM (ROUND_TO_PLUS),d6
2815 cmpl IMM (ROUND_TO_PLUS),d6
2821 | Put back the exponent (we can't have overflow!). '
2822 bclr IMM (FLT_MANT_DIG-1),d0
2823 #ifndef __mcoldfire__
2832 | If one of the numbers was too small (difference of exponents >=
2833 | FLT_MANT_DIG+2) we return the other (and now we don't have to '
2834 | check for finiteness or zero).
2839 #ifndef __mcoldfire__
2840 moveml sp@+,d2-d7 | restore data registers
2843 | XXX if frame pointer is ever removed, stack pointer must
2846 unlk a6 | and return
2853 #ifndef __mcoldfire__
2854 moveml sp@+,d2-d7 | restore data registers
2857 | XXX if frame pointer is ever removed, stack pointer must
2860 unlk a6 | and return
2863 | If the numbers are denormalized remember to put exponent equal to 1.
2866 movel d5,d6 | d5 contains 0x01000000
2873 notl d4 | make d4 into a mask for the fraction
2874 | (this was not executed after the jump)
2877 | The rest is mainly code for the different results which can be
2878 | returned (checking always for +/-INFINITY and NaN).
2881 | Return b (if a is zero).
2885 | Return a (if b is zero).
2889 | We have to check for NaN and +/-infty.
2891 andl IMM (0x80000000),d7 | put sign in d7
2892 bclr IMM (31),d0 | clear sign
2893 cmpl IMM (INFINITY),d0 | check for infty or NaN
2895 movel d0,d0 | check for zero (we do this because we don't '
2896 bne Laddsf$ret | want to return -0 by mistake
2897 bclr IMM (31),d7 | if zero be sure to clear sign
2898 bra Laddsf$ret | if everything OK just return
2900 | The value to be returned is either +/-infty or NaN
2901 andl IMM (0x007fffff),d0 | check for NaN
2902 bne Lf$inop | if mantissa not zero is NaN
2906 | Normal exit (a and b nonzero, result is not NaN nor +/-infty).
2907 | We have to clear the exception flags (just the exception type).
2910 orl d7,d0 | put sign bit
2911 #ifndef __mcoldfire__
2912 moveml sp@+,d2-d7 | restore data registers
2915 | XXX if frame pointer is ever removed, stack pointer must
2918 unlk a6 | and return
2922 | Return a denormalized number (for addition we don't signal underflow) '
2923 lsrl IMM (1),d0 | remember to shift right back once
2924 bra Laddsf$ret | and return
2926 | Note: when adding two floats of the same sign if either one is
2927 | NaN we return NaN without regard to whether the other is finite or
2928 | not. When subtracting them (i.e., when adding two numbers of
2929 | opposite signs) things are more complicated: if both are INFINITY
2930 | we return NaN, if only one is INFINITY and the other is NaN we return
2931 | NaN, but if it is finite we return INFINITY with the corresponding sign.
2935 | This could be faster but it is not worth the effort, since it is not
2936 | executed very often. We sacrifice speed for clarity here.
2937 movel a6@(8),d0 | get the numbers back (remember that we
2938 movel a6@(12),d1 | did some processing already)
2939 movel IMM (INFINITY),d4 | useful constant (INFINITY)
2940 movel d0,d2 | save sign bits
2942 bclr IMM (31),d0 | clear sign bits
2944 | We know that one of them is either NaN of +/-INFINITY
2945 | Check for NaN (if either one is NaN return NaN)
2946 cmpl d4,d0 | check first a (d0)
2948 cmpl d4,d1 | check now b (d1)
2950 | Now comes the check for +/-INFINITY. We know that both are (maybe not
2951 | finite) numbers, but we have to check if both are infinite whether we
2952 | are adding or subtracting them.
2953 eorl d3,d2 | to check sign bits
2956 andl IMM (0x80000000),d7 | get (common) sign bit
2959 | We know one (or both) are infinite, so we test for equality between the
2960 | two numbers (if they are equal they have to be infinite both, so we
2962 cmpl d1,d0 | are both infinite?
2963 beq Lf$inop | if so return NaN
2966 andl IMM (0x80000000),d7 | get a's sign bit '
2967 cmpl d4,d0 | test now for infinity
2968 beq Lf$infty | if a is INFINITY return with this sign
2969 bchg IMM (31),d7 | else we know b is INFINITY and has
2970 bra Lf$infty | the opposite sign
2972 |=============================================================================
2974 |=============================================================================
2976 | float __mulsf3(float, float);
2978 #ifndef __mcoldfire__
2985 movel a6@(8),d0 | get a into d0
2986 movel a6@(12),d1 | and b into d1
2987 movel d0,d7 | d7 will hold the sign of the product
2989 andl IMM (0x80000000),d7
2990 movel IMM (INFINITY),d6 | useful constant (+INFINITY)
2991 movel d6,d5 | another (mask for fraction)
2993 movel IMM (0x00800000),d4 | this is to put hidden bit back
2994 bclr IMM (31),d0 | get rid of a's sign bit '
2996 beq Lmulsf$a$0 | branch if a is zero
2997 bclr IMM (31),d1 | get rid of b's sign bit '
2999 beq Lmulsf$b$0 | branch if b is zero
3000 cmpl d6,d0 | is a big?
3001 bhi Lmulsf$inop | if a is NaN return NaN
3002 beq Lmulsf$inf | if a is INFINITY we have to check b
3003 cmpl d6,d1 | now compare b with INFINITY
3004 bhi Lmulsf$inop | is b NaN?
3005 beq Lmulsf$overflow | is b INFINITY?
3006 | Here we have both numbers finite and nonzero (and with no sign bit).
3007 | Now we get the exponents into d2 and d3.
3008 andl d6,d2 | and isolate exponent in d2
3009 beq Lmulsf$a$den | if exponent is zero we have a denormalized
3010 andl d5,d0 | and isolate fraction
3011 orl d4,d0 | and put hidden bit back
3012 swap d2 | I like exponents in the first byte
3013 #ifndef __mcoldfire__
3024 #ifndef __mcoldfire__
3030 #ifndef __mcoldfire__
3031 addw d3,d2 | add exponents
3032 subw IMM (F_BIAS+1),d2 | and subtract bias (plus one)
3034 addl d3,d2 | add exponents
3035 subl IMM (F_BIAS+1),d2 | and subtract bias (plus one)
3038 | We are now ready to do the multiplication. The situation is as follows:
3039 | both a and b have bit FLT_MANT_DIG-1 set (even if they were
3040 | denormalized to start with!), which means that in the product
3041 | bit 2*(FLT_MANT_DIG-1) (that is, bit 2*FLT_MANT_DIG-2-32 of the
3042 | high long) is set.
3044 | To do the multiplication let us move the number a little bit around ...
3045 movel d1,d6 | second operand in d6
3046 movel d0,d5 | first operand in d4-d5
3048 movel d4,d1 | the sums will go in d0-d1
3051 | now bit FLT_MANT_DIG-1 becomes bit 31:
3052 lsll IMM (31-FLT_MANT_DIG+1),d6
3054 | Start the loop (we loop #FLT_MANT_DIG times):
3055 movew IMM (FLT_MANT_DIG-1),d3
3056 1: addl d1,d1 | shift sum
3058 lsll IMM (1),d6 | get bit bn
3059 bcc 2f | if not set skip sum
3063 #ifndef __mcoldfire__
3064 dbf d3,1b | loop back
3070 | Now we have the product in d0-d1, with bit (FLT_MANT_DIG - 1) + FLT_MANT_DIG
3071 | (mod 32) of d0 set. The first thing to do now is to normalize it so bit
3072 | FLT_MANT_DIG is set (to do the rounding).
3073 #ifndef __mcoldfire__
3077 andw IMM (0x03ff),d3
3078 andw IMM (0xfd00),d1
3087 andl IMM (0xfffffd00),d1
3092 #ifndef __mcoldfire__
3098 movew IMM (MULTIPLY),d5
3100 btst IMM (FLT_MANT_DIG+1),d0
3102 #ifndef __mcoldfire__
3117 movew IMM (MULTIPLY),d5
3121 movew IMM (MULTIPLY),d5
3125 movew IMM (MULTIPLY),d5
3126 | If either is NaN return NaN; else both are (maybe infinite) numbers, so
3127 | return INFINITY with the correct sign (which is in d7).
3128 cmpl d6,d1 | is b NaN?
3129 bhi Lf$inop | if so return NaN
3130 bra Lf$overflow | else return +/-INFINITY
3132 | If either number is zero return zero, unless the other is +/-INFINITY,
3133 | or NaN, in which case we return NaN.
3135 | Here d1 (==b) is zero.
3136 movel d1,d0 | put b into d0 (just a zero)
3137 movel a6@(8),d1 | get a again to check for non-finiteness
3140 movel a6@(12),d1 | get b again to check for non-finiteness
3141 1: bclr IMM (31),d1 | clear sign bit
3142 cmpl IMM (INFINITY),d1 | and check for a large exponent
3143 bge Lf$inop | if b is +/-INFINITY or NaN return NaN
3144 lea SYM (_fpCCR),a0 | else return zero
3146 #ifndef __mcoldfire__
3150 | XXX if frame pointer is ever removed, stack pointer must
3156 | If a number is denormalized we put an exponent of 1 but do not put the
3157 | hidden bit back into the fraction; instead we shift left until bit 23
3158 | (the hidden bit) is set, adjusting the exponent accordingly. We do this
3159 | to ensure that the product of the fractions is close to 1.
3163 1: addl d0,d0 | shift a left (until bit 23 is set)
3164 #ifndef __mcoldfire__
3165 subw IMM (1),d2 | and adjust exponent
3167 subql IMM (1),d2 | and adjust exponent
3169 btst IMM (FLT_MANT_DIG-1),d0
3171 bra 1b | else loop back
3176 1: addl d1,d1 | shift b left until bit 23 is set
3177 #ifndef __mcoldfire__
3178 subw IMM (1),d3 | and adjust exponent
3180 subl IMM (1),d3 | and adjust exponent
3182 btst IMM (FLT_MANT_DIG-1),d1
3184 bra 1b | else loop back
3186 |=============================================================================
3188 |=============================================================================
3190 | float __divsf3(float, float);
3192 #ifndef __mcoldfire__
3199 movel a6@(8),d0 | get a into d0
3200 movel a6@(12),d1 | and b into d1
3201 movel d0,d7 | d7 will hold the sign of the result
3203 andl IMM (0x80000000),d7 |
3204 movel IMM (INFINITY),d6 | useful constant (+INFINITY)
3205 movel d6,d5 | another (mask for fraction)
3207 movel IMM (0x00800000),d4 | this is to put hidden bit back
3208 bclr IMM (31),d0 | get rid of a's sign bit '
3210 beq Ldivsf$a$0 | branch if a is zero
3211 bclr IMM (31),d1 | get rid of b's sign bit '
3213 beq Ldivsf$b$0 | branch if b is zero
3214 cmpl d6,d0 | is a big?
3215 bhi Ldivsf$inop | if a is NaN return NaN
3216 beq Ldivsf$inf | if a is INFINITY we have to check b
3217 cmpl d6,d1 | now compare b with INFINITY
3218 bhi Ldivsf$inop | if b is NaN return NaN
3219 beq Ldivsf$underflow
3220 | Here we have both numbers finite and nonzero (and with no sign bit).
3221 | Now we get the exponents into d2 and d3 and normalize the numbers to
3222 | ensure that the ratio of the fractions is close to 1. We do this by
3223 | making sure that bit #FLT_MANT_DIG-1 (hidden bit) is set.
3224 andl d6,d2 | and isolate exponent in d2
3225 beq Ldivsf$a$den | if exponent is zero we have a denormalized
3226 andl d5,d0 | and isolate fraction
3227 orl d4,d0 | and put hidden bit back
3228 swap d2 | I like exponents in the first byte