1 /* libgcc1 routines for 68000 w/o floating-point hardware. */
2 /* Copyright (C) 1994 Free Software Foundation, Inc.
4 This file is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
9 In addition to the permissions in the GNU General Public License, the
10 Free Software Foundation gives you unlimited permission to link the
11 compiled version of this file with other programs, and to distribute
12 those programs without any restriction coming from the use of this
13 file. (The General Public License restrictions do apply in other
14 respects; for example, they cover modification of the file, and
15 distribution when not linked into another program.)
17 This file is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; see the file COPYING. If not, write to
24 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
26 /* As a special exception, if you link this library with files
27 compiled with GCC to produce an executable, this does not cause
28 the resulting executable to be covered by the GNU General Public License.
29 This exception does not however invalidate any other reasons why
30 the executable file might be covered by the GNU General Public License. */
32 /* Use this one for any 680x0; assumes no floating point hardware.
33 The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk.
34 Some of this code comes from MINIX, via the folks at ericsson.
35 D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
38 /* These are predefined by new versions of GNU cpp. */
40 #ifndef __USER_LABEL_PREFIX__
41 #define __USER_LABEL_PREFIX__ _
44 #ifndef __REGISTER_PREFIX__
45 #define __REGISTER_PREFIX__
48 /* ANSI concatenation macros. */
50 #define CONCAT1(a, b) CONCAT2(a, b)
51 #define CONCAT2(a, b) a ## b
53 /* Use the right prefix for global labels. */
55 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
57 /* Use the right prefix for registers. */
59 #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
81 | This is an attempt at a decent floating point (single, double and
82 | extended double) code for the GNU C compiler. It should be easy to
83 | adapt to other compilers (but beware of the local labels!).
85 | Starting date: 21 October, 1990
87 | It is convenient to introduce the notation (s,e,f) for a floating point
88 | number, where s=sign, e=exponent, f=fraction. We will call a floating
89 | point number fpn to abbreviate, independently of the precision.
90 | Let MAX_EXP be in each case the maximum exponent (255 for floats, 1023
91 | for doubles and 16383 for long doubles). We then have the following
93 | 1. Normalized fpns have 0 < e < MAX_EXP. They correspond to
94 | (-1)^s x 1.f x 2^(e-bias-1).
95 | 2. Denormalized fpns have e=0. They correspond to numbers of the form
96 | (-1)^s x 0.f x 2^(-bias).
97 | 3. +/-INFINITY have e=MAX_EXP, f=0.
98 | 4. Quiet NaN (Not a Number) have all bits set.
99 | 5. Signaling NaN (Not a Number) have s=0, e=MAX_EXP, f=1.
101 |=============================================================================
103 |=============================================================================
105 | This is the floating point condition code register (_fpCCR):
108 | short _exception_bits;
109 | short _trap_enable_bits;
110 | short _sticky_bits;
111 | short _rounding_mode;
113 | short _last_operation;
137 .word ROUND_TO_NEAREST
150 EBITS = __exception_bits - SYM (_fpCCR)
151 TRAPE = __trap_enable_bits - SYM (_fpCCR)
152 STICK = __sticky_bits - SYM (_fpCCR)
153 ROUND = __rounding_mode - SYM (_fpCCR)
154 FORMT = __format - SYM (_fpCCR)
155 LASTO = __last_operation - SYM (_fpCCR)
156 OPER1 = __operand1 - SYM (_fpCCR)
157 OPER2 = __operand2 - SYM (_fpCCR)
159 | The following exception types are supported:
160 INEXACT_RESULT = 0x0001
163 DIVIDE_BY_ZERO = 0x0008
164 INVALID_OPERATION = 0x0010
166 | The allowed rounding modes are:
168 ROUND_TO_NEAREST = 0 | round result to nearest representable value
169 ROUND_TO_ZERO = 1 | round result towards zero
170 ROUND_TO_PLUS = 2 | round result towards plus infinity
171 ROUND_TO_MINUS = 3 | round result towards minus infinity
173 | The allowed values of format are:
179 | The allowed values for the last operation are:
189 |=============================================================================
190 | __clear_sticky_bits
191 |=============================================================================
193 | The sticky bits are normally not cleared (thus the name), whereas the
194 | exception type and exception value reflect the last computation.
195 | This routine is provided to clear them (you can also write to _fpCCR,
196 | since it is globally visible).
198 .globl SYM (__clear_sticky_bit)
203 | void __clear_sticky_bits(void);
204 SYM (__clear_sticky_bit):
209 |=============================================================================
210 | $_exception_handler
211 |=============================================================================
213 .globl $_exception_handler
218 | This is the common exit point if an exception occurs.
219 | NOTE: it is NOT callable from C!
220 | It expects the exception type in d7, the format (SINGLE_FLOAT,
221 | DOUBLE_FLOAT or LONG_FLOAT) in d6, and the last operation code in d5.
222 | It sets the corresponding exception and sticky bits, and the format.
223 | Depending on the format if fills the corresponding slots for the
224 | operands which produced the exception (all this information is provided
225 | so if you write your own exception handlers you have enough information
226 | to deal with the problem).
227 | Then checks to see if the corresponding exception is trap-enabled,
228 | in which case it pushes the address of _fpCCR and traps through
229 | trap FPTRAP (15 for the moment).
235 movew d7,a0@(EBITS) | set __exception_bits
236 orw d7,a0@(STICK) | and __sticky_bits
237 movew d6,a0@(FORMT) | and __format
238 movew d5,a0@(LASTO) | and __last_operation
240 | Now put the operands in place:
241 cmpw #SINGLE_FLOAT,d6
243 movel a6@(8),a0@(OPER1)
244 movel a6@(12),a0@(OPER1+4)
245 movel a6@(16),a0@(OPER2)
246 movel a6@(20),a0@(OPER2+4)
248 1: movel a6@(8),a0@(OPER1)
249 movel a6@(12),a0@(OPER2)
251 | And check whether the exception is trap-enabled:
252 andw a0@(TRAPE),d7 | is exception trap-enabled?
254 pea SYM (_fpCCR) | yes, push address of _fpCCR
255 trap #FPTRAP | and trap
256 1: moveml sp@+,d2-d7 | restore data registers
259 #endif /* L_floatex */
265 .globl SYM (__mulsi3)
272 movew a6@(0x8), d0 /* x0 -> d0 */
273 muluw a6@(0xe), d0 /* x0*y1 */
274 movew a6@(0xa), d1 /* x1 -> d1 */
275 muluw a6@(0xc), d1 /* x1*y0 */
279 movew a6@(0xa), d1 /* x1 -> d1 */
280 muluw a6@(0xe), d1 /* x1*y1 */
290 LS14 = 0x0002 /* d1 will be saved and restored */
294 #endif /* L_mulsi3 */
300 .globl SYM (__udivsi3)
307 movel a6@(0xc), d0 /* d0 = divisor */
308 movel a6@(0x8), d1 /* d1 = dividend */
312 cmpl #0x10000, d0 /* divisor >= 2 ^ 16 ? */
313 bge l4 /* then try next algorithm */
315 lsrl #8, d2 /* get high dividend */
317 divu d0, d2 /* high quotient in lower word */
318 movew d2, d1 /* save high quotient */
320 movew d3, d2 /* get low dividend + high rest */
321 divu d0, d2 /* low quotient */
325 l4: movel d0, d2 /* use d2 as divisor backup */
326 l4a: lsrl #1, d0 /* shift divisor */
327 lsrl #1, d1 /* shift dividend */
328 cmpl #0x10000, d0 /* still divisor >= 2 ^ 16 ? */
330 divu d0, d1 /* now we have 16bit divisor => compute remainder */
332 movel d1, sp@- /* multiply divisor with */
333 movel d2, sp@- /* remainder */
334 jbsr SYM (__umulsi3) /* and */
336 cmpl d0, d3 /* compare the result with the dividend */
337 bge l5 /* if dividend >= result => nofix */
350 LS14 = 0x000e /* d1-d3 will be saved and restored */
354 #endif /* L_udivsi3 */
360 .globl SYM (__umulsi3)
367 movew a6@(0x8), d0 /* x0 -> d0 */
368 muluw a6@(0xe), d0 /* x0*y1 */
369 movew a6@(0xa), d1 /* x1 -> d1 */
370 muluw a6@(0xc), d1 /* x1*y0 */
374 movew a6@(0xa), d1 /* x1 -> d1 */
375 muluw a6@(0xe), d1 /* x1*y1 */
385 LS14 = 0x0002 /* d1 will be saved and restored */
389 #endif /* L_umulsi3 */
395 .globl SYM (__divsi3)
402 moveb #1, d4 /* sign of result stored in d4 (=1 or =-1) */
403 movel a6@(0xc), d0 /* d0 = divisor */
406 negb d4 /* change sign because divisor <0 */
407 l1: movel a6@(0x8), d1 /* d1 = dividend */
414 cmpl #0x10000, d0 /* divisor >= 2 ^ 16 ? */
415 bge l4 /* then try next algorithm */
417 lsrl #8, d2 /* get high dividend */
419 divu d0, d2 /* high quotient in lower word */
420 movew d2, d1 /* save high quotient */
422 movew d3, d2 /* get low dividend + high rest */
423 divu d0, d2 /* low quotient */
427 l4: movel d0, d2 /* use d2 as divisor backup */
428 l4a: lsrl #1, d0 /* shift divisor */
429 lsrl #1, d1 /* shift dividend */
430 cmpl #0x10000, d0 /* still divisor >= 2 ^ 16 ? */
432 divu d0, d1 /* now we have 16bit divisor => compute remainder */
434 movel d1, sp@- /* multiply divisor with */
435 movel d2, sp@- /* remainder */
436 jbsr SYM (__umulsi3) /* and */
438 cmpl d0, d3 /* compare the result with the dividend */
439 bge l5 /* if dividend >= result => nofix */
455 LS14 = 0x001e /* d1-d4 will be saved and restored */
459 #endif /* L_divsi3 */
465 .globl SYM (__umodsi3)
472 movel a6@(0xc),d1 /* divisor */
473 movel a6@(0x8),d2 /* dividend */
476 jbsr SYM (__udivsi3) /* d0 = a/b */
480 jbsr SYM (__umulsi3) /* d0 = (a/b)*b */
483 addl d2, d0 /* d0 = a - (a/b)*b */
492 LS14 = 0x006 /* d1-d2 will be saved and restored */
496 #endif /* L_umodsi3 */
502 .globl SYM (__modsi3)
509 movel a6@(0xc),d1 /* divisor */
510 movel a6@(0x8),d2 /* dividend */
513 jbsr SYM (__divsi3) /* d0 = a/b */
517 jbsr SYM (__mulsi3) /* d0 = (a/b)*b */
520 addl d2, d0 /* d0 = a - (a/b)*b */
529 LS14 = 0x006 /* d1-d2 will be saved and restored */
533 #endif /* L_modsi3 */
545 .globl SYM (__lshrsi3)
557 #endif /* L_lshrsi3 */
569 .globl SYM (__lshlsi3)
581 #endif /* L_lshlsi3 */
593 .globl SYM (__ashrsi3)
605 #endif /* L_ashrsi3 */
617 .globl SYM (__ashlsi3)
629 #endif /* L_ashlsi3 */
634 .globl $_exception_handler
636 QUIET_NaN = 0xffffffff
640 DBL_MAX_EXP = D_MAX_EXP - D_BIAS
641 DBL_MIN_EXP = 1 - D_BIAS
644 INEXACT_RESULT = 0x0001
647 DIVIDE_BY_ZERO = 0x0008
648 INVALID_OPERATION = 0x0010
662 ROUND_TO_NEAREST = 0 | round result to nearest representable value
663 ROUND_TO_ZERO = 1 | round result towards zero
664 ROUND_TO_PLUS = 2 | round result towards plus infinity
665 ROUND_TO_MINUS = 3 | round result towards minus infinity
669 .globl SYM (__adddf3)
670 .globl SYM (__subdf3)
671 .globl SYM (__muldf3)
672 .globl SYM (__divdf3)
673 .globl SYM (__negdf2)
674 .globl SYM (__cmpdf2)
679 | These are common routines to return and signal exceptions.
682 | Return and signal a denormalized number
685 orw #INEXACT_RESULT,d7
686 movew #DOUBLE_FLOAT,d6
687 jmp $_exception_handler
691 | Return a properly signed INFINITY and set the exception flags
696 orw #INEXACT_RESULT,d7
697 movew #DOUBLE_FLOAT,d6
698 jmp $_exception_handler
701 | Return 0 and set the exception flags
705 orw #INEXACT_RESULT,d7
706 movew #DOUBLE_FLOAT,d6
707 jmp $_exception_handler
710 | Return a quiet NaN and set the exception flags
713 movew #INVALID_OPERATION,d7
714 orw #INEXACT_RESULT,d7
715 movew #DOUBLE_FLOAT,d6
716 jmp $_exception_handler
719 | Return a properly signed INFINITY and set the exception flags
723 movew #DIVIDE_BY_ZERO,d7
724 orw #INEXACT_RESULT,d7
725 movew #DOUBLE_FLOAT,d6
726 jmp $_exception_handler
728 |=============================================================================
729 |=============================================================================
730 | double precision routines
731 |=============================================================================
732 |=============================================================================
734 | A double precision floating point number (double) has the format:
737 | unsigned int sign : 1; /* sign bit */
738 | unsigned int exponent : 11; /* exponent, shifted by 126 */
739 | unsigned int fraction : 52; /* fraction */
742 | Thus sizeof(double) = 8 (64 bits).
744 | All the routines are callable from C programs, and return the result
745 | in the register pair d0-d1. They also preserve all registers except
748 |=============================================================================
750 |=============================================================================
752 | double __subdf3(double, double);
754 bchg #31,sp@(12) | change sign of second operand
755 | and fall through, so we always add
756 |=============================================================================
758 |=============================================================================
760 | double __adddf3(double, double);
762 link a6,#0 | everything will be done in registers
763 moveml d2-d7,sp@- | save all data registers and a2 (but d0-d1)
764 movel a6@(8),d0 | get first operand
766 movel a6@(16),d2 | get second operand
769 movel d0,d7 | get d0's sign bit in d7 '
770 addl d1,d1 | check and clear sign bit of a, and gain one
771 addxl d0,d0 | bit of extra precision
772 beq Ladddf$b | if zero return second operand
774 movel d2,d6 | save sign in d6
775 addl d3,d3 | get rid of sign bit and gain one bit of
776 addxl d2,d2 | extra precision
777 beq Ladddf$a | if zero return first operand
779 andl #0x80000000,d7 | isolate a's sign bit '
780 swap d6 | and also b's sign bit '
782 orw d6,d7 | and combine them into d7, so that a's sign '
783 | bit is in the high word and b's is in the '
784 | low word, so d6 is free to be used
785 movel d7,a0 | now save d7 into a0, so d7 is free to
788 | Get the exponents and check for denormalized and/or infinity.
790 movel #0x001fffff,d6 | mask for the fraction
791 movel #0x00200000,d7 | mask to put hidden bit back
794 andl d6,d0 | get fraction in d0
795 notl d6 | make d6 into mask for the exponent
796 andl d6,d4 | get exponent in d4
797 beq Ladddf$a$den | branch if a is denormalized
798 cmpl d6,d4 | check for INFINITY or NaN
800 orl d7,d0 | and put hidden bit back
802 swap d4 | shift right exponent so that it starts
803 lsrw #5,d4 | in bit 0 and not bit 20
804 | Now we have a's exponent in d4 and fraction in d0-d1 '
805 movel d2,d5 | save b to get exponent
806 andl d6,d5 | get exponent in d5
807 beq Ladddf$b$den | branch if b is denormalized
808 cmpl d6,d5 | check for INFINITY or NaN
810 notl d6 | make d6 into mask for the fraction again
811 andl d6,d2 | and get fraction in d2
812 orl d7,d2 | and put hidden bit back
814 swap d5 | shift right exponent so that it starts
815 lsrw #5,d5 | in bit 0 and not bit 20
817 | Now we have b's exponent in d5 and fraction in d2-d3. '
819 | The situation now is as follows: the signs are combined in a0, the
820 | numbers are in d0-d1 (a) and d2-d3 (b), and the exponents in d4 (a)
821 | and d5 (b). To do the rounding correctly we need to keep all the
822 | bits until the end, so we need to use d0-d1-d2-d3 for the first number
823 | and d4-d5-d6-d7 for the second. To do this we store (temporarily) the
824 | exponents in a2-a3.
826 moveml a2-a3,sp@- | save the address registers
828 movel d4,a2 | save the exponents
831 movel #0,d7 | and move the numbers around
838 | Here we shift the numbers until the exponents are the same, and put
839 | the largest exponent in a2.
840 exg d4,a2 | get exponents back
842 cmpw d4,d5 | compare the exponents
843 beq Ladddf$3 | if equal don't shift '
844 bhi 9f | branch if second exponent is higher
846 | Here we have a's exponent larger than b's, so we have to shift b. We do
847 | this by using as counter d2:
848 1: movew d4,d2 | move largest exponent to d2
849 subw d5,d2 | and substract second exponent
850 exg d4,a2 | get back the longs we saved
852 | if difference is too large we don't shift (actually, we can just exit) '
853 cmpw #DBL_MANT_DIG+2,d2
855 cmpw #32,d2 | if difference >= 32, shift by longs
857 2: cmpw #16,d2 | if difference >= 16, shift by words
859 bra 3f | enter dbra loop
890 subw d5,d6 | keep d5 (largest exponent) in d4
893 | if difference is too large we don't shift (actually, we can just exit) '
894 cmpw #DBL_MANT_DIG+2,d6
896 cmpw #32,d6 | if difference >= 32, shift by longs
898 2: cmpw #16,d6 | if difference >= 16, shift by words
900 bra 3f | enter dbra loop
932 | Now we have the numbers in d0--d3 and d4--d7, the exponent in a2, and
935 | Here we have to decide whether to add or substract the numbers:
936 exg d7,a0 | get the signs
937 exg d6,a3 | a3 is free to be used
939 movew #0,d7 | get a's sign in d7 '
941 movew #0,d6 | and b's sign in d6 '
942 eorl d7,d6 | compare the signs
943 bmi Lsubdf$0 | if the signs are different we have
945 exg d7,a0 | else we add the numbers
952 movel a2,d4 | return exponent to d4
954 andl #0x80000000,d7 | d7 now has the sign
958 | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
959 | the case of denormalized numbers in the rounding routine itself).
960 | As in the addition (not in the substraction!) we could have set
961 | one more bit we check this:
962 btst #DBL_MANT_DIG+1,d0
970 lea Ladddf$5,a0 | to return from rounding routine
971 lea SYM (_fpCCR),a1 | check the rounding mode
972 movew a1@(6),d6 | rounding mode in d6
973 beq Lround$to$nearest
974 cmpw #ROUND_TO_PLUS,d6
979 | Put back the exponent and check for overflow
980 cmpw #0x7ff,d4 | is the exponent big?
982 bclr #DBL_MANT_DIG-1,d0
983 lslw #4,d4 | put exponent back into position
993 | Here we do the substraction.
994 exg d7,a0 | put sign back in a0
1000 beq Ladddf$ret$1 | if zero just exit
1001 bpl 1f | if positive skip the following
1003 bchg #31,d7 | change sign bit in d7
1007 negxl d1 | and negate result
1010 movel a2,d4 | return exponent to d4
1012 andl #0x80000000,d7 | isolate sign bit
1015 | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
1016 | the case of denormalized numbers in the rounding routine itself).
1017 | As in the addition (not in the substraction!) we could have set
1018 | one more bit we check this:
1019 btst #DBL_MANT_DIG+1,d0
1027 lea Lsubdf$1,a0 | to return from rounding routine
1028 lea SYM (_fpCCR),a1 | check the rounding mode
1029 movew a1@(6),d6 | rounding mode in d6
1030 beq Lround$to$nearest
1031 cmpw #ROUND_TO_PLUS,d6
1036 | Put back the exponent and sign (we don't have overflow). '
1037 bclr #DBL_MANT_DIG-1,d0
1038 lslw #4,d4 | put exponent back into position
1044 | If one of the numbers was too small (difference of exponents >=
1045 | DBL_MANT_DIG+1) we return the other (and now we don't have to '
1046 | check for finiteness or zero).
1053 moveml sp@+,d2-d7 | restore data registers
1054 unlk a6 | and return
1063 moveml sp@+,d2-d7 | restore data registers
1064 unlk a6 | and return
1068 movel d7,d4 | d7 contains 0x00200000
1072 movel d7,d5 | d7 contains 0x00200000
1077 | Return b (if a is zero)
1086 | Check for NaN and +/-INFINITY.
1088 andl #0x80000000,d7 |
1090 cmpl #0x7ff00000,d0 |
1092 movel d0,d0 | check for zero, since we don't '
1093 bne Ladddf$ret | want to return -0 by mistake
1097 andl #0x000fffff,d0 | check for NaN (nonzero fraction)
1103 moveml sp@+,a2-a3 | restore regs and exit
1109 orl d7,d0 | put sign bit back
1115 | Return a denormalized number.
1116 lsrl #1,d0 | shift right once more
1122 | This could be faster but it is not worth the effort, since it is not
1123 | executed very often. We sacrifice speed for clarity here.
1124 movel a6@(8),d0 | get the numbers back (remember that we
1125 movel a6@(12),d1 | did some processing already)
1128 movel #0x7ff00000,d4 | useful constant (INFINITY)
1129 movel d0,d7 | save sign bits
1131 bclr #31,d0 | clear sign bits
1133 | We know that one of them is either NaN of +/-INFINITY
1134 | Check for NaN (if either one is NaN return NaN)
1135 cmpl d4,d0 | check first a (d0)
1136 bhi Ld$inop | if d0 > 0x7ff00000 or equal and
1138 tstl d1 | d1 > 0, a is NaN
1140 2: cmpl d4,d2 | check now b (d1)
1146 | Now comes the check for +/-INFINITY. We know that both are (maybe not
1147 | finite) numbers, but we have to check if both are infinite whether we
1148 | are adding or substracting them.
1149 eorl d7,d6 | to check sign bits
1151 andl #0x80000000,d7 | get (common) sign bit
1154 | We know one (or both) are infinite, so we test for equality between the
1155 | two numbers (if they are equal they have to be infinite both, so we
1157 cmpl d2,d0 | are both infinite?
1158 bne 1f | if d0 <> d2 they are not equal
1159 cmpl d3,d1 | if d0 == d2 test d3 and d1
1160 beq Ld$inop | if equal return NaN
1162 andl #0x80000000,d7 | get a's sign bit '
1163 cmpl d4,d0 | test now for infinity
1164 beq Ld$infty | if a is INFINITY return with this sign
1165 bchg #31,d7 | else we know b is INFINITY and has
1166 bra Ld$infty | the opposite sign
1168 |=============================================================================
1170 |=============================================================================
1172 | double __muldf3(double, double);
1176 movel a6@(8),d0 | get a into d0-d1
1178 movel a6@(16),d2 | and b into d2-d3
1180 movel d0,d7 | d7 will hold the sign of the product
1182 andl #0x80000000,d7 |
1183 movel d7,a0 | save sign bit into a0
1184 movel #0x7ff00000,d7 | useful constant (+INFINITY)
1185 movel d7,d6 | another (mask for fraction)
1187 bclr #31,d0 | get rid of a's sign bit '
1190 beq Lmuldf$a$0 | branch if a is zero
1192 bclr #31,d2 | get rid of b's sign bit '
1195 beq Lmuldf$b$0 | branch if b is zero
1197 cmpl d7,d0 | is a big?
1198 bhi Lmuldf$inop | if a is NaN return NaN
1199 beq Lmuldf$a$nf | we still have to check d1 and b ...
1200 cmpl d7,d2 | now compare b with INFINITY
1201 bhi Lmuldf$inop | is b NaN?
1202 beq Lmuldf$b$nf | we still have to check d3 ...
1203 | Here we have both numbers finite and nonzero (and with no sign bit).
1204 | Now we get the exponents into d4 and d5.
1205 andl d7,d4 | isolate exponent in d4
1206 beq Lmuldf$a$den | if exponent is zero we have a denormalized
1207 andl d6,d0 | isolate fraction
1208 orl #0x00100000,d0 | and put hidden bit back
1209 swap d4 | I like exponents in the first byte
1215 orl #0x00100000,d2 | and put hidden bit back
1219 addw d5,d4 | add exponents
1220 subw #D_BIAS+1,d4 | and substract bias (plus one)
1222 | We are now ready to do the multiplication. The situation is as follows:
1223 | both a and b have bit 52 ( bit 20 of d0 and d2) set (even if they were
1224 | denormalized to start with!), which means that in the product bit 104
1225 | (which will correspond to bit 8 of the fourth long) is set.
1227 | Here we have to do the product.
1228 | To do it we have to juggle the registers back and forth, as there are not
1229 | enough to keep everything in them. So we use the address registers to keep
1230 | some intermediate data.
1232 moveml a2-a3,sp@- | save a2 and a3 for temporary use
1233 movel #0,a2 | a2 is a null register
1234 movel d4,a3 | and a3 will preserve the exponent
1236 | First, shift d2-d3 so bit 20 becomes bit 31:
1237 rorl #5,d2 | rotate d2 5 places right
1238 swap d2 | and swap it
1239 rorl #5,d3 | do the same thing with d3
1241 movew d3,d6 | get the rightmost 11 bits of d3
1243 orw d6,d2 | and put them into d2
1244 andw #0xf800,d3 | clear those bits in d3
1246 movel d2,d6 | move b into d6-d7
1247 movel d3,d7 | move a into d4-d5
1248 movel d0,d4 | and clear d0-d1-d2-d3 (to put result)
1255 | We use a1 as counter:
1256 movel #DBL_MANT_DIG-1,a1
1259 1: exg d7,a1 | put counter back in a1
1260 addl d3,d3 | shift sum once left
1266 bcc 2f | if bit clear skip the following
1268 addl d5,d3 | else add a to the sum
1273 2: exg d7,a1 | put counter in d7
1274 dbf d7,1b | decrement and branch
1276 movel a3,d4 | restore exponent
1279 | Now we have the product in d0-d1-d2-d3, with bit 8 of d0 set. The
1280 | first thing to do now is to normalize it so bit 8 becomes bit
1281 | DBL_MANT_DIG-32 (to do the rounding); later we will shift right.
1303 | Now round, check for over- and underflow, and exit.
1304 movel a0,d7 | get sign bit back into d7
1307 btst #DBL_MANT_DIG+1-32,d0
1320 movel a0,d7 | get sign bit back into d7
1321 tstl d3 | we know d2 == 0x7ff00000, so check d3
1322 bne Ld$inop | if d3 <> 0 b is NaN
1323 bra Ld$overflow | else we have overflow (since a is finite)
1327 movel a0,d7 | get sign bit back into d7
1328 tstl d1 | we know d0 == 0x7ff00000, so check d1
1329 bne Ld$inop | if d1 <> 0 a is NaN
1330 bra Ld$overflow | else signal overflow
1332 | If either number is zero return zero, unless the other is +/-INFINITY or
1333 | NaN, in which case we return NaN.
1336 exg d2,d0 | put b (==0) into d0-d1
1337 exg d3,d1 | and a (with sign bit cleared) into d2-d3
1340 movel a6@(16),d2 | put b into d2-d3 again
1342 bclr #31,d2 | clear sign bit
1343 1: cmpl #0x7ff00000,d2 | check for non-finiteness
1344 bge Ld$inop | in case NaN or +/-INFINITY return NaN
1351 | If a number is denormalized we put an exponent of 1 but do not put the
1352 | hidden bit back into the fraction; instead we shift left until bit 21
1353 | (the hidden bit) is set, adjusting the exponent accordingly. We do this
1354 | to ensure that the product of the fractions is close to 1.
1358 1: addl d1,d1 | shift a left until bit 20 is set
1360 subw #1,d4 | and adjust exponent
1368 1: addl d3,d3 | shift b left until bit 20 is set
1370 subw #1,d5 | and adjust exponent
1376 |=============================================================================
1378 |=============================================================================
1380 | double __divdf3(double, double);
1384 movel a6@(8),d0 | get a into d0-d1
1386 movel a6@(16),d2 | and b into d2-d3
1388 movel d0,d7 | d7 will hold the sign of the result
1390 andl #0x80000000,d7 |
1391 movel d7,a0 | save sign into a0
1392 movel #0x7ff00000,d7 | useful constant (+INFINITY)
1393 movel d7,d6 | another (mask for fraction)
1395 bclr #31,d0 | get rid of a's sign bit '
1398 beq Ldivdf$a$0 | branch if a is zero
1400 bclr #31,d2 | get rid of b's sign bit '
1403 beq Ldivdf$b$0 | branch if b is zero
1405 cmpl d7,d0 | is a big?
1406 bhi Ldivdf$inop | if a is NaN return NaN
1407 beq Ldivdf$a$nf | if d0 == 0x7ff00000 we check d1
1408 cmpl d7,d2 | now compare b with INFINITY
1409 bhi Ldivdf$inop | if b is NaN return NaN
1410 beq Ldivdf$b$nf | if d2 == 0x7ff00000 we check d3
1411 | Here we have both numbers finite and nonzero (and with no sign bit).
1412 | Now we get the exponents into d4 and d5 and normalize the numbers to
1413 | ensure that the ratio of the fractions is around 1. We do this by
1414 | making sure that both numbers have bit #DBL_MANT_DIG-32-1 (hidden bit)
1415 | set, even if they were denormalized to start with.
1416 | Thus, the result will satisfy: 2 > result > 1/2.
1417 andl d7,d4 | and isolate exponent in d4
1418 beq Ldivdf$a$den | if exponent is zero we have a denormalized
1419 andl d6,d0 | and isolate fraction
1420 orl #0x00100000,d0 | and put hidden bit back
1421 swap d4 | I like exponents in the first byte
1427 orl #0x00100000,d2 |
1431 subw d5,d4 | substract exponents
1432 addw #D_BIAS,d4 | and add bias
1434 | We are now ready to do the division. We have prepared things in such a way
1435 | that the ratio of the fractions will be less than 2 but greater than 1/2.
1436 | At this point the registers in use are:
1437 | d0-d1 hold a (first operand, bit DBL_MANT_DIG-32=0, bit
1438 | DBL_MANT_DIG-1-32=1)
1439 | d2-d3 hold b (second operand, bit DBL_MANT_DIG-32=1)
1440 | d4 holds the difference of the exponents, corrected by the bias
1441 | a0 holds the sign of the ratio
1443 | To do the rounding correctly we need to keep information about the
1444 | nonsignificant bits. One way to do this would be to do the division
1445 | using four registers; another is to use two registers (as originally
1446 | I did), but use a sticky bit to preserve information about the
1447 | fractional part. Note that we can keep that info in a1, which is not
1449 movel #0,d6 | d6-d7 will hold the result
1451 movel #0,a1 | and a1 will hold the sticky bit
1453 movel #DBL_MANT_DIG-32+1,d5
1455 1: cmpl d0,d2 | is a < b?
1456 bhi 3f | if b > a skip the following
1457 beq 4f | if d0==d2 check d1 and d3
1459 subxl d2,d0 | a <-- a - b
1460 bset d5,d6 | set the corresponding bit in d6
1461 3: addl d1,d1 | shift a by 1
1463 dbra d5,1b | and branch back
1465 4: cmpl d1,d3 | here d0==d2, so check d1 and d3
1466 bhi 3b | if d1 > d2 skip the substraction
1467 bra 2b | else go do it
1469 | Here we have to start setting the bits in the second long.
1470 movel #31,d5 | again d5 is counter
1472 1: cmpl d0,d2 | is a < b?
1473 bhi 3f | if b > a skip the following
1474 beq 4f | if d0==d2 check d1 and d3
1476 subxl d2,d0 | a <-- a - b
1477 bset d5,d7 | set the corresponding bit in d7
1478 3: addl d1,d1 | shift a by 1
1480 dbra d5,1b | and branch back
1482 4: cmpl d1,d3 | here d0==d2, so check d1 and d3
1483 bhi 3b | if d1 > d2 skip the substraction
1484 bra 2b | else go do it
1486 | Now go ahead checking until we hit a one, which we store in d2.
1487 movel #DBL_MANT_DIG,d5
1488 1: cmpl d2,d0 | is a < b?
1489 bhi 4f | if b < a, exit
1490 beq 3f | if d0==d2 check d1 and d3
1491 2: addl d1,d1 | shift a by 1
1493 dbra d5,1b | and branch back
1494 movel #0,d2 | here no sticky bit was found
1497 3: cmpl d1,d3 | here d0==d2, so check d1 and d3
1498 bhi 2b | if d1 > d2 go back
1500 | Here put the sticky bit in d2-d3 (in the position which actually corresponds
1501 | to it; if you don't do this the algorithm loses in some cases). '
1504 subw #DBL_MANT_DIG,d5
1513 | Finally we are finished! Move the longs in the address registers to
1514 | their final destination:
1519 | Here we have finished the division, with the result in d0-d1-d2-d3, with
1520 | 2^21 <= d6 < 2^23. Thus bit 23 is not set, but bit 22 could be set.
1521 | If it is not, then definitely bit 21 is set. Normalize so bit 22 is
1523 btst #DBL_MANT_DIG-32+1,d0
1531 | Now round, check for over- and underflow, and exit.
1532 movel a0,d7 | restore sign bit to d7
1541 | If a is zero check to see whether b is zero also. In that case return
1542 | NaN; then check if b is NaN, and return NaN also in that case. Else
1548 beq Ld$inop | if b is also zero return NaN
1549 cmpl #0x7ff00000,d2 | check for NaN
1554 1: movel #0,d0 | else return zero
1556 lea SYM (_fpCCR),a0 | clear exception flags
1564 | If we got here a is not zero. Check if a is NaN; in that case return NaN,
1565 | else return +/-INFINITY. Remember that a is in d0 with the sign bit
1567 movel a0,d7 | put a's sign bit back in d7 '
1568 cmpl #0x7ff00000,d0 | compare d0 with INFINITY
1569 bhi Ld$inop | if larger it is NaN
1572 bra Ld$div$0 | else signal DIVIDE_BY_ZERO
1576 | If d2 == 0x7ff00000 we have to check d3.
1578 bne Ld$inop | if d3 <> 0, b is NaN
1579 bra Ld$underflow | else b is +/-INFINITY, so signal underflow
1583 | If d0 == 0x7ff00000 we have to check d1.
1585 bne Ld$inop | if d1 <> 0, a is NaN
1586 | If a is INFINITY we have to check b
1587 cmpl d7,d2 | compare b with INFINITY
1588 bge Ld$inop | if b is NaN or INFINITY return NaN
1591 bra Ld$overflow | else return overflow
1593 | If a number is denormalized we put an exponent of 1 but do not put the
1594 | bit back into the fraction.
1598 1: addl d1,d1 | shift a left until bit 20 is set
1600 subw #1,d4 | and adjust exponent
1601 btst #DBL_MANT_DIG-32-1,d0
1608 1: addl d3,d3 | shift b left until bit 20 is set
1610 subw #1,d5 | and adjust exponent
1611 btst #DBL_MANT_DIG-32-1,d2
1616 | This is a common exit point for __muldf3 and __divdf3. When they enter
1617 | this point the sign of the result is in d7, the result in d0-d1, normalized
1618 | so that 2^21 <= d0 < 2^22, and the exponent is in the lower byte of d4.
1620 | First check for underlow in the exponent:
1621 cmpw #-DBL_MANT_DIG-1,d4
1623 | It could happen that the exponent is less than 1, in which case the
1624 | number is denormalized. In this case we shift right and adjust the
1625 | exponent until it becomes 1 or the fraction is zero (in the latter case
1626 | we signal underflow and return zero).
1628 movel #0,d6 | use d6-d7 to collect bits flushed right
1629 movel d6,d7 | use d6-d7 to collect bits flushed right
1630 cmpw #1,d4 | if the exponent is less than 1 we
1631 bge 2f | have to shift right (denormalize)
1632 1: addw #1,d4 | adjust the exponent
1633 lsrl #1,d0 | shift right once
1639 cmpw #1,d4 | is the exponent 1 already?
1640 beq 2f | if not loop back
1642 bra Ld$underflow | safety check, shouldn't execute '
1643 2: orl d6,d2 | this is a trick so we don't lose '
1644 orl d7,d3 | the bits which were flushed right
1645 movel a0,d7 | get back sign bit into d7
1646 | Now call the rounding routine (which takes care of denormalized numbers):
1647 lea Lround$0,a0 | to return from rounding routine
1648 lea SYM (_fpCCR),a1 | check the rounding mode
1649 movew a1@(6),d6 | rounding mode in d6
1650 beq Lround$to$nearest
1651 cmpw #ROUND_TO_PLUS,d6
1656 | Here we have a correctly rounded result (either normalized or denormalized).
1658 | Here we should have either a normalized number or a denormalized one, and
1659 | the exponent is necessarily larger or equal to 1 (so we don't have to '
1660 | check again for underflow!). We have to check for overflow or for a
1661 | denormalized number (which also signals underflow).
1662 | Check for overflow (i.e., exponent >= 0x7ff).
1665 | Now check for a denormalized number (exponent==0):
1669 | Put back the exponents and sign and return.
1670 lslw #4,d4 | exponent back to fourth byte
1671 bclr #DBL_MANT_DIG-32-1,d0
1672 swap d0 | and put back exponent
1675 orl d7,d0 | and sign also
1683 |=============================================================================
1685 |=============================================================================
1687 | double __negdf2(double, double);
1692 movel a6@(8),d0 | get number to negate in d0-d1
1694 bchg #31,d0 | negate
1695 movel d0,d2 | make a positive copy (for the tests)
1697 movel d2,d4 | check for zero
1699 beq 2f | if zero (either sign) return +zero
1700 cmpl #0x7ff00000,d2 | compare to +INFINITY
1701 blt 1f | if finite, return
1702 bhi Ld$inop | if larger (fraction not zero) is NaN
1703 tstl d1 | if d2 == 0x7ff00000 check d1
1705 movel d0,d7 | else get sign and return INFINITY
1708 1: lea SYM (_fpCCR),a0
1716 |=============================================================================
1718 |=============================================================================
1724 | int __cmpdf2(double, double);
1727 moveml d2-d7,sp@- | save registers
1729 movel a6@(8),d0 | get first operand
1731 movel a6@(16),d2 | get second operand
1733 | First check if a and/or b are (+/-) zero and in that case clear
1735 movel d0,d6 | copy signs into d6 (a) and d7(b)
1736 bclr #31,d0 | and clear signs in d0 and d2
1739 cmpl #0x7fff0000,d0 | check for a == NaN
1740 bhi Ld$inop | if d0 > 0x7ff00000, a is NaN
1741 beq Lcmpdf$a$nf | if equal can be INFINITY, so check d1
1742 movel d0,d4 | copy into d4 to test for zero
1746 cmpl #0x7fff0000,d2 | check for b == NaN
1747 bhi Ld$inop | if d2 > 0x7ff00000, b is NaN
1748 beq Lcmpdf$b$nf | if equal can be INFINITY, so check d3
1756 | If the signs are not equal check if a >= 0
1758 bpl Lcmpdf$a$gt$b | if (a >= 0 && b < 0) => a > b
1759 bmi Lcmpdf$b$gt$a | if (a < 0 && b >= 0) => a < b
1761 | If the signs are equal check for < 0
1764 | If both are negative exchange them
1768 | Now that they are positive we just compare them as longs (does this also
1769 | work for denormalized numbers?).
1771 bhi Lcmpdf$b$gt$a | |b| > |a|
1772 bne Lcmpdf$a$gt$b | |b| < |a|
1773 | If we got here d0 == d2, so we compare d1 and d3.
1775 bhi Lcmpdf$b$gt$a | |b| > |a|
1776 bne Lcmpdf$a$gt$b | |b| < |a|
1777 | If we got here a == b.
1779 moveml sp@+,d2-d7 | put back the registers
1784 moveml sp@+,d2-d7 | put back the registers
1789 moveml sp@+,d2-d7 | put back the registers
1810 |=============================================================================
1812 |=============================================================================
1814 | The rounding routines expect the number to be normalized in registers
1815 | d0-d1-d2-d3, with the exponent in register d4. They assume that the
1816 | exponent is larger or equal to 1. They return a properly normalized number
1817 | if possible, and a denormalized number otherwise. The exponent is returned
1821 | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
1822 | Here we assume that the exponent is not too small (this should be checked
1823 | before entering the rounding routine), but the number could be denormalized.
1825 | Check for denormalized numbers:
1826 1: btst #DBL_MANT_DIG-32,d0
1827 bne 2f | if set the number is normalized
1828 | Normalize shifting left until bit #DBL_MANT_DIG-32 is set or the exponent
1829 | is one (remember that a denormalized number corresponds to an
1830 | exponent of -D_BIAS+1).
1831 cmpw #1,d4 | remember that the exponent is at least one
1832 beq 2f | an exponent of one means denormalized
1833 addl d3,d3 | else shift and adjust the exponent
1839 | Now round: we do it as follows: after the shifting we can write the
1840 | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
1841 | If delta < 1, do nothing. If delta > 1, add 1 to f.
1842 | If delta == 1, we make sure the rounded number will be even (odd?)
1844 btst #0,d1 | is delta < 1?
1845 beq 2f | if so, do not do anything
1846 orl d2,d3 | is delta == 1?
1847 bne 1f | if so round to even
1849 andl #2,d3 | bit 1 is the last significant bit
1854 1: movel #1,d3 | else add 1
1858 | Shift right once (because we used bit #DBL_MANT_DIG-32!).
1862 | Now check again bit #DBL_MANT_DIG-32 (rounding could have produced a
1863 | 'fraction overflow' ...).
1864 btst #DBL_MANT_DIG-32,d0
1870 | If bit #DBL_MANT_DIG-32-1 is clear we have a denormalized number, so we
1871 | have to put the exponent to zero and return a denormalized number.
1872 btst #DBL_MANT_DIG-32-1,d0
1882 #endif /* L_double */
1887 .globl $_exception_handler
1889 QUIET_NaN = 0xffffffff
1890 SIGNL_NaN = 0x7f800001
1891 INFINITY = 0x7f800000
1895 FLT_MAX_EXP = F_MAX_EXP - F_BIAS
1896 FLT_MIN_EXP = 1 - F_BIAS
1899 INEXACT_RESULT = 0x0001
1902 DIVIDE_BY_ZERO = 0x0008
1903 INVALID_OPERATION = 0x0010
1917 ROUND_TO_NEAREST = 0 | round result to nearest representable value
1918 ROUND_TO_ZERO = 1 | round result towards zero
1919 ROUND_TO_PLUS = 2 | round result towards plus infinity
1920 ROUND_TO_MINUS = 3 | round result towards minus infinity
1924 .globl SYM (__addsf3)
1925 .globl SYM (__subsf3)
1926 .globl SYM (__mulsf3)
1927 .globl SYM (__divsf3)
1928 .globl SYM (__negsf2)
1929 .globl SYM (__cmpsf2)
1931 | These are common routines to return and signal exceptions.
1937 | Return and signal a denormalized number
1940 orw #INEXACT_RESULT,d7
1941 movew #SINGLE_FLOAT,d6
1942 jmp $_exception_handler
1946 | Return a properly signed INFINITY and set the exception flags
1950 orw #INEXACT_RESULT,d7
1951 movew #SINGLE_FLOAT,d6
1952 jmp $_exception_handler
1955 | Return 0 and set the exception flags
1958 orw #INEXACT_RESULT,d7
1959 movew #SINGLE_FLOAT,d6
1960 jmp $_exception_handler
1963 | Return a quiet NaN and set the exception flags
1965 movew #INVALID_OPERATION,d7
1966 orw #INEXACT_RESULT,d7
1967 movew #SINGLE_FLOAT,d6
1968 jmp $_exception_handler
1971 | Return a properly signed INFINITY and set the exception flags
1974 movew #DIVIDE_BY_ZERO,d7
1975 orw #INEXACT_RESULT,d7
1976 movew #SINGLE_FLOAT,d6
1977 jmp $_exception_handler
1979 |=============================================================================
1980 |=============================================================================
1981 | single precision routines
1982 |=============================================================================
1983 |=============================================================================
1985 | A single precision floating point number (float) has the format:
1988 | unsigned int sign : 1; /* sign bit */
1989 | unsigned int exponent : 8; /* exponent, shifted by 126 */
1990 | unsigned int fraction : 23; /* fraction */
1993 | Thus sizeof(float) = 4 (32 bits).
1995 | All the routines are callable from C programs, and return the result
1996 | in the single register d0. They also preserve all registers except
1999 |=============================================================================
2001 |=============================================================================
2003 | float __subsf3(float, float);
2005 bchg #31,sp@(8) | change sign of second operand
2007 |=============================================================================
2009 |=============================================================================
2011 | float __addsf3(float, float);
2013 link a6,#0 | everything will be done in registers
2014 moveml d2-d7,sp@- | save all data registers but d0-d1
2015 movel a6@(8),d0 | get first operand
2016 movel a6@(12),d1 | get second operand
2017 movel d0,d6 | get d0's sign bit '
2018 addl d0,d0 | check and clear sign bit of a
2019 beq Laddsf$b | if zero return second operand
2020 movel d1,d7 | save b's sign bit '
2021 addl d1,d1 | get rid of sign bit
2022 beq Laddsf$a | if zero return first operand
2024 movel d6,a0 | save signs in address registers
2025 movel d7,a1 | so we can use d6 and d7
2027 | Get the exponents and check for denormalized and/or infinity.
2029 movel #0x00ffffff,d4 | mask to get fraction
2030 movel #0x01000000,d5 | mask to put hidden bit back
2032 movel d0,d6 | save a to get exponent
2033 andl d4,d0 | get fraction in d0
2034 notl d4 | make d4 into a mask for the exponent
2035 andl d4,d6 | get exponent in d6
2036 beq Laddsf$a$den | branch if a is denormalized
2037 cmpl d4,d6 | check for INFINITY or NaN
2039 swap d6 | put exponent into first word
2040 orl d5,d0 | and put hidden bit back
2042 | Now we have a's exponent in d6 (second byte) and the mantissa in d0. '
2043 movel d1,d7 | get exponent in d7
2045 beq Laddsf$b$den | branch if b is denormalized
2046 cmpl d4,d7 | check for INFINITY or NaN
2048 swap d7 | put exponent into first word
2049 notl d4 | make d4 into a mask for the fraction
2050 andl d4,d1 | get fraction in d1
2051 orl d5,d1 | and put hidden bit back
2053 | Now we have b's exponent in d7 (second byte) and the mantissa in d1. '
2055 | Note that the hidden bit corresponds to bit #FLT_MANT_DIG-1, and we
2056 | shifted right once, so bit #FLT_MANT_DIG is set (so we have one extra
2059 movel d1,d2 | move b to d2, since we want to use
2060 | two registers to do the sum
2061 movel #0,d1 | and clear the new ones
2064 | Here we shift the numbers in registers d0 and d1 so the exponents are the
2065 | same, and put the largest exponent in d6. Note that we are using two
2066 | registers for each number (see the discussion by D. Knuth in "Seminumerical
2068 cmpw d6,d7 | compare exponents
2069 beq Laddsf$3 | if equal don't shift '
2070 bhi 5f | branch if second exponent largest
2072 subl d6,d7 | keep the largest exponent
2074 lsrw #8,d7 | put difference in lower byte
2075 | if difference is too large we don't shift (actually, we can just exit) '
2076 cmpw #FLT_MANT_DIG+2,d7
2078 cmpw #16,d7 | if difference >= 16 swap
2082 3: lsrl #1,d2 | shift right second operand
2092 bne 2b | if still more bits, go back to normal case
2095 exg d6,d7 | exchange the exponents
2096 subl d6,d7 | keep the largest exponent
2098 lsrw #8,d7 | put difference in lower byte
2099 | if difference is too large we don't shift (and exit!) '
2100 cmpw #FLT_MANT_DIG+2,d7
2102 cmpw #16,d7 | if difference >= 16 swap
2106 7: lsrl #1,d0 | shift right first operand
2116 bne 6b | if still more bits, go back to normal case
2117 | otherwise we fall through
2119 | Now we have a in d0-d1, b in d2-d3, and the largest exponent in d6 (the
2120 | signs are stored in a0 and a1).
2123 | Here we have to decide whether to add or substract the numbers
2124 exg d6,a0 | get signs back
2125 exg d7,a1 | and save the exponents
2126 eorl d6,d7 | combine sign bits
2127 bmi Lsubsf$0 | if negative a and b have opposite
2128 | sign so we actually substract the
2131 | Here we have both positive or both negative
2132 exg d6,a0 | now we have the exponent in d6
2133 movel a0,d7 | and sign in d7
2134 andl #0x80000000,d7 |
2135 | Here we do the addition.
2138 | Note: now we have d2, d3, d4 and d5 to play with!
2140 | Put the exponent, in the first byte, in d2, to use the "standard" rounding
2145 | Before rounding normalize so bit #FLT_MANT_DIG is set (we will consider
2146 | the case of denormalized numbers in the rounding routine itself).
2147 | As in the addition (not in the substraction!) we could have set
2148 | one more bit we check this:
2149 btst #FLT_MANT_DIG+1,d0
2155 lea Laddsf$4,a0 | to return from rounding routine
2156 lea SYM (_fpCCR),a1 | check the rounding mode
2157 movew a1@(6),d6 | rounding mode in d6
2158 beq Lround$to$nearest
2159 cmpw #ROUND_TO_PLUS,d6
2164 | Put back the exponent, but check for overflow.
2167 bclr #FLT_MANT_DIG-1,d0
2177 | We are here if a > 0 and b < 0 (sign bits cleared).
2178 | Here we do the substraction.
2179 movel d6,d7 | put sign in d7
2180 andl #0x80000000,d7 |
2182 subl d3,d1 | result in d0-d1
2184 beq Laddsf$ret | if zero just exit
2185 bpl 1f | if positive skip the following
2186 bchg #31,d7 | change sign bit in d7
2190 exg d2,a0 | now we have the exponent in d2
2191 lsrw #8,d2 | put it in the first byte
2193 | Now d0-d1 is positive and the sign bit is in d7.
2195 | Note that we do not have to normalize, since in the substraction bit
2196 | #FLT_MANT_DIG+1 is never set, and denormalized numbers are handled by
2197 | the rounding routines themselves.
2198 lea Lsubsf$1,a0 | to return from rounding routine
2199 lea SYM (_fpCCR),a1 | check the rounding mode
2200 movew a1@(6),d6 | rounding mode in d6
2201 beq Lround$to$nearest
2202 cmpw #ROUND_TO_PLUS,d6
2207 | Put back the exponent (we can't have overflow!). '
2208 bclr #FLT_MANT_DIG-1,d0
2214 | If one of the numbers was too small (difference of exponents >=
2215 | FLT_MANT_DIG+2) we return the other (and now we don't have to '
2216 | check for finiteness or zero).
2221 moveml sp@+,d2-d7 | restore data registers
2222 unlk a6 | and return
2229 moveml sp@+,d2-d7 | restore data registers
2230 unlk a6 | and return
2233 | If the numbers are denormalized remember to put exponent equal to 1.
2236 movel d5,d6 | d5 contains 0x01000000
2243 notl d4 | make d4 into a mask for the fraction
2244 | (this was not executed after the jump)
2247 | The rest is mainly code for the different results which can be
2248 | returned (checking always for +/-INFINITY and NaN).
2251 | Return b (if a is zero).
2255 | Return a (if b is zero).
2259 | We have to check for NaN and +/-infty.
2261 andl #0x80000000,d7 | put sign in d7
2262 bclr #31,d0 | clear sign
2263 cmpl #INFINITY,d0 | check for infty or NaN
2265 movel d0,d0 | check for zero (we do this because we don't '
2266 bne Laddsf$ret | want to return -0 by mistake
2267 bclr #31,d7 | if zero be sure to clear sign
2268 bra Laddsf$ret | if everything OK just return
2270 | The value to be returned is either +/-infty or NaN
2271 andl #0x007fffff,d0 | check for NaN
2272 bne Lf$inop | if mantissa not zero is NaN
2276 | Normal exit (a and b nonzero, result is not NaN nor +/-infty).
2277 | We have to clear the exception flags (just the exception type).
2280 orl d7,d0 | put sign bit
2281 moveml sp@+,d2-d7 | restore data registers
2282 unlk a6 | and return
2286 | Return a denormalized number (for addition we don't signal underflow) '
2287 lsrl #1,d0 | remember to shift right back once
2288 bra Laddsf$ret | and return
2290 | Note: when adding two floats of the same sign if either one is
2291 | NaN we return NaN without regard to whether the other is finite or
2292 | not. When substracting them (i.e., when adding two numbers of
2293 | opposite signs) things are more complicated: if both are INFINITY
2294 | we return NaN, if only one is INFINITY and the other is NaN we return
2295 | NaN, but if it is finite we return INFINITY with the corresponding sign.
2299 | This could be faster but it is not worth the effort, since it is not
2300 | executed very often. We sacrifice speed for clarity here.
2301 movel a6@(8),d0 | get the numbers back (remember that we
2302 movel a6@(12),d1 | did some processing already)
2303 movel #INFINITY,d4 | useful constant (INFINITY)
2304 movel d0,d2 | save sign bits
2306 bclr #31,d0 | clear sign bits
2308 | We know that one of them is either NaN of +/-INFINITY
2309 | Check for NaN (if either one is NaN return NaN)
2310 cmpl d4,d0 | check first a (d0)
2312 cmpl d4,d1 | check now b (d1)
2314 | Now comes the check for +/-INFINITY. We know that both are (maybe not
2315 | finite) numbers, but we have to check if both are infinite whether we
2316 | are adding or substracting them.
2317 eorl d3,d2 | to check sign bits
2320 andl #0x80000000,d7 | get (common) sign bit
2323 | We know one (or both) are infinite, so we test for equality between the
2324 | two numbers (if they are equal they have to be infinite both, so we
2326 cmpl d1,d0 | are both infinite?
2327 beq Lf$inop | if so return NaN
2330 andl #0x80000000,d7 | get a's sign bit '
2331 cmpl d4,d0 | test now for infinity
2332 beq Lf$infty | if a is INFINITY return with this sign
2333 bchg #31,d7 | else we know b is INFINITY and has
2334 bra Lf$infty | the opposite sign
2336 |=============================================================================
2338 |=============================================================================
2340 | float __mulsf3(float, float);
2344 movel a6@(8),d0 | get a into d0
2345 movel a6@(12),d1 | and b into d1
2346 movel d0,d7 | d7 will hold the sign of the product
2348 andl #0x80000000,d7 |
2349 movel #INFINITY,d6 | useful constant (+INFINITY)
2350 movel d6,d5 | another (mask for fraction)
2352 movel #0x00800000,d4 | this is to put hidden bit back
2353 bclr #31,d0 | get rid of a's sign bit '
2355 beq Lmulsf$a$0 | branch if a is zero
2356 bclr #31,d1 | get rid of b's sign bit '
2358 beq Lmulsf$b$0 | branch if b is zero
2359 cmpl d6,d0 | is a big?
2360 bhi Lmulsf$inop | if a is NaN return NaN
2361 beq Lmulsf$inf | if a is INFINITY we have to check b
2362 cmpl d6,d1 | now compare b with INFINITY
2363 bhi Lmulsf$inop | is b NaN?
2364 beq Lmulsf$overflow | is b INFINITY?
2365 | Here we have both numbers finite and nonzero (and with no sign bit).
2366 | Now we get the exponents into d2 and d3.
2367 andl d6,d2 | and isolate exponent in d2
2368 beq Lmulsf$a$den | if exponent is zero we have a denormalized
2369 andl d5,d0 | and isolate fraction
2370 orl d4,d0 | and put hidden bit back
2371 swap d2 | I like exponents in the first byte
2381 addw d3,d2 | add exponents
2382 subw #F_BIAS+1,d2 | and substract bias (plus one)
2384 | We are now ready to do the multiplication. The situation is as follows:
2385 | both a and b have bit FLT_MANT_DIG-1 set (even if they were
2386 | denormalized to start with!), which means that in the product
2387 | bit 2*(FLT_MANT_DIG-1) (that is, bit 2*FLT_MANT_DIG-2-32 of the
2388 | high long) is set.
2390 | To do the multiplication let us move the number a little bit around ...
2391 movel d1,d6 | second operand in d6
2392 movel d0,d5 | first operand in d4-d5
2394 movel d4,d1 | the sums will go in d0-d1
2397 | now bit FLT_MANT_DIG-1 becomes bit 31:
2398 lsll #31-FLT_MANT_DIG+1,d6
2400 | Start the loop (we loop #FLT_MANT_DIG times):
2401 movew #FLT_MANT_DIG-1,d3
2402 1: addl d1,d1 | shift sum
2404 lsll #1,d6 | get bit bn
2405 bcc 2f | if not set skip sum
2408 2: dbf d3,1b | loop back
2410 | Now we have the product in d0-d1, with bit (FLT_MANT_DIG - 1) + FLT_MANT_DIG
2411 | (mod 32) of d0 set. The first thing to do now is to normalize it so bit
2412 | FLT_MANT_DIG is set (to do the rounding).
2425 btst #FLT_MANT_DIG+1,d0
2442 | If either is NaN return NaN; else both are (maybe infinite) numbers, so
2443 | return INFINITY with the correct sign (which is in d7).
2444 cmpl d6,d1 | is b NaN?
2445 bhi Lf$inop | if so return NaN
2446 bra Lf$overflow | else return +/-INFINITY
2448 | If either number is zero return zero, unless the other is +/-INFINITY,
2449 | or NaN, in which case we return NaN.
2451 | Here d1 (==b) is zero.
2452 movel d1,d0 | put b into d0 (just a zero)
2453 movel a6@(8),d1 | get a again to check for non-finiteness
2456 movel a6@(12),d1 | get b again to check for non-finiteness
2457 1: bclr #31,d1 | clear sign bit
2458 cmpl #INFINITY,d1 | and check for a large exponent
2459 bge Lf$inop | if b is +/-INFINITY or NaN return NaN
2460 lea SYM (_fpCCR),a0 | else return zero
2466 | If a number is denormalized we put an exponent of 1 but do not put the
2467 | hidden bit back into the fraction; instead we shift left until bit 23
2468 | (the hidden bit) is set, adjusting the exponent accordingly. We do this
2469 | to ensure that the product of the fractions is close to 1.
2473 1: addl d0,d0 | shift a left (until bit 23 is set)
2474 subw #1,d2 | and adjust exponent
2475 btst #FLT_MANT_DIG-1,d0
2477 bra 1b | else loop back
2482 1: addl d1,d1 | shift b left until bit 23 is set
2483 subw #1,d3 | and adjust exponent
2484 btst #FLT_MANT_DIG-1,d1
2486 bra 1b | else loop back
2488 |=============================================================================
2490 |=============================================================================
2492 | float __divsf3(float, float);
2496 movel a6@(8),d0 | get a into d0
2497 movel a6@(12),d1 | and b into d1
2498 movel d0,d7 | d7 will hold the sign of the result
2500 andl #0x80000000,d7 |
2501 movel #INFINITY,d6 | useful constant (+INFINITY)
2502 movel d6,d5 | another (mask for fraction)
2504 movel #0x00800000,d4 | this is to put hidden bit back
2505 bclr #31,d0 | get rid of a's sign bit '
2507 beq Ldivsf$a$0 | branch if a is zero
2508 bclr #31,d1 | get rid of b's sign bit '
2510 beq Ldivsf$b$0 | branch if b is zero
2511 cmpl d6,d0 | is a big?
2512 bhi Ldivsf$inop | if a is NaN return NaN
2513 beq Ldivsf$inf | if a is INIFINITY we have to check b
2514 cmpl d6,d1 | now compare b with INFINITY
2515 bhi Ldivsf$inop | if b is NaN return NaN
2516 beq Ldivsf$underflow
2517 | Here we have both numbers finite and nonzero (and with no sign bit).
2518 | Now we get the exponents into d2 and d3 and normalize the numbers to
2519 | ensure that the ratio of the fractions is close to 1. We do this by
2520 | making sure that bit #FLT_MANT_DIG-1 (hidden bit) is set.
2521 andl d6,d2 | and isolate exponent in d2
2522 beq Ldivsf$a$den | if exponent is zero we have a denormalized
2523 andl d5,d0 | and isolate fraction
2524 orl d4,d0 | and put hidden bit back
2525 swap d2 | I like exponents in the first byte
2535 subw d3,d2 | substract exponents
2536 addw #F_BIAS,d2 | and add bias
2538 | We are now ready to do the division. We have prepared things in such a way
2539 | that the ratio of the fractions will be less than 2 but greater than 1/2.
2540 | At this point the registers in use are:
2541 | d0 holds a (first operand, bit FLT_MANT_DIG=0, bit FLT_MANT_DIG-1=1)
2542 | d1 holds b (second operand, bit FLT_MANT_DIG=1)
2543 | d2 holds the difference of the exponents, corrected by the bias
2544 | d7 holds the sign of the ratio
2545 | d4, d5, d6 hold some constants
2546 movel d7,a0 | d6-d7 will hold the ratio of the fractions
2550 movew #FLT_MANT_DIG+1,d3
2551 1: cmpl d0,d1 | is a < b?
2553 bset d3,d6 | set a bit in d6
2554 subl d1,d0 | if a >= b a <-- a-b
2555 beq 3f | if a is zero, exit
2556 2: addl d0,d0 | multiply a by 2
2559 | Now we keep going to set the sticky bit ...
2560 movew #FLT_MANT_DIG,d3
2568 subw #FLT_MANT_DIG,d3
2572 movel d6,d0 | put the ratio in d0-d1
2573 movel a0,d7 | get sign back
2575 | Because of the normalization we did before we are guaranteed that
2576 | d0 is smaller than 2^26 but larger than 2^24. Thus bit 26 is not set,
2577 | bit 25 could be set, and if it is not set then bit 24 is necessarily set.
2578 btst #FLT_MANT_DIG+1,d0
2579 beq 1f | if it is not set, then bit 24 is set
2583 | Now round, check for over- and underflow, and exit.
2601 | If a is zero check to see whether b is zero also. In that case return
2602 | NaN; then check if b is NaN, and return NaN also in that case. Else
2604 andl #0x7fffffff,d1 | clear sign bit and test b
2605 beq Lf$inop | if b is also zero return NaN
2606 cmpl #INFINITY,d1 | check for NaN
2608 movel #0,d0 | else return zero
2609 lea SYM (_fpCCR),a0 |
2617 | If we got here a is not zero. Check if a is NaN; in that case return NaN,
2618 | else return +/-INFINITY. Remember that a is in d0 with the sign bit
2620 cmpl #INFINITY,d0 | compare d0 with INFINITY
2621 bhi Lf$inop | if larger it is NaN
2622 bra Lf$div$0 | else signal DIVIDE_BY_ZERO
2626 | If a is INFINITY we have to check b
2627 cmpl #INFINITY,d1 | compare b with INFINITY
2628 bge Lf$inop | if b is NaN or INFINITY return NaN
2629 bra Lf$overflow | else return overflow
2631 | If a number is denormalized we put an exponent of 1 but do not put the
2632 | bit back into the fraction.
2636 1: addl d0,d0 | shift a left until bit FLT_MANT_DIG-1 is set
2637 subw #1,d2 | and adjust exponent
2638 btst #FLT_MANT_DIG-1,d0
2645 1: addl d1,d1 | shift b left until bit FLT_MANT_DIG is set
2646 subw #1,d3 | and adjust exponent
2647 btst #FLT_MANT_DIG-1,d1
2652 | This is a common exit point for __mulsf3 and __divsf3.
2654 | First check for underlow in the exponent:
2655 cmpw #-FLT_MANT_DIG-1,d2
2657 | It could happen that the exponent is less than 1, in which case the
2658 | number is denormalized. In this case we shift right and adjust the
2659 | exponent until it becomes 1 or the fraction is zero (in the latter case
2660 | we signal underflow and return zero).
2661 movel #0,d6 | d6 is used temporarily
2662 cmpw #1,d2 | if the exponent is less than 1 we
2663 bge 2f | have to shift right (denormalize)
2664 1: addw #1,d2 | adjust the exponent
2665 lsrl #1,d0 | shift right once
2667 roxrl #1,d6 | d6 collect bits we would lose otherwise
2668 cmpw #1,d2 | is the exponent 1 already?
2669 beq 2f | if not loop back
2671 bra Lf$underflow | safety check, shouldn't execute '
2672 2: orl d6,d1 | this is a trick so we don't lose '
2673 | the extra bits which were flushed right
2674 | Now call the rounding routine (which takes care of denormalized numbers):
2675 lea Lround$0,a0 | to return from rounding routine
2676 lea SYM (_fpCCR),a1 | check the rounding mode
2677 movew a1@(6),d6 | rounding mode in d6
2678 beq Lround$to$nearest
2679 cmpw #ROUND_TO_PLUS,d6
2684 | Here we have a correctly rounded result (either normalized or denormalized).
2686 | Here we should have either a normalized number or a denormalized one, and
2687 | the exponent is necessarily larger or equal to 1 (so we don't have to '
2688 | check again for underflow!). We have to check for overflow or for a
2689 | denormalized number (which also signals underflow).
2690 | Check for overflow (i.e., exponent >= 255).
2693 | Now check for a denormalized number (exponent==0).
2697 | Put back the exponents and sign and return.
2698 lslw #7,d2 | exponent back to fourth byte
2699 bclr #FLT_MANT_DIG-1,d0
2700 swap d0 | and put back exponent
2703 orl d7,d0 | and sign also
2711 |=============================================================================
2713 |=============================================================================
2715 | This is trivial and could be shorter if we didn't bother checking for NaN '
2718 | float __negsf2(float);
2723 movel a6@(8),d0 | get number to negate in d0
2724 bchg #31,d0 | negate
2725 movel d0,d1 | make a positive copy
2727 tstl d1 | check for zero
2728 beq 2f | if zero (either sign) return +zero
2729 cmpl #INFINITY,d1 | compare to +INFINITY
2731 bhi Lf$inop | if larger (fraction not zero) is NaN
2732 movel d0,d7 | else get sign and return INFINITY
2735 1: lea SYM (_fpCCR),a0
2743 |=============================================================================
2745 |=============================================================================
2751 | int __cmpsf2(float, float);
2754 moveml d2-d7,sp@- | save registers
2756 movel a6@(8),d0 | get first operand
2757 movel a6@(12),d1 | get second operand
2758 | Check if either is NaN, and in that case return garbage and signal
2759 | INVALID_OPERATION. Check also if either is zero, and clear the signs
2776 | If the signs are not equal check if a >= 0
2778 bpl Lcmpsf$a$gt$b | if (a >= 0 && b < 0) => a > b
2779 bmi Lcmpsf$b$gt$a | if (a < 0 && b >= 0) => a < b
2781 | If the signs are equal check for < 0
2784 | If both are negative exchange them
2787 | Now that they are positive we just compare them as longs (does this also
2788 | work for denormalized numbers?).
2790 bhi Lcmpsf$b$gt$a | |b| > |a|
2791 bne Lcmpsf$a$gt$b | |b| < |a|
2792 | If we got here a == b.
2794 moveml sp@+,d2-d7 | put back the registers
2799 moveml sp@+,d2-d7 | put back the registers
2804 moveml sp@+,d2-d7 | put back the registers
2815 |=============================================================================
2817 |=============================================================================
2819 | The rounding routines expect the number to be normalized in registers
2820 | d0-d1, with the exponent in register d2. They assume that the
2821 | exponent is larger or equal to 1. They return a properly normalized number
2822 | if possible, and a denormalized number otherwise. The exponent is returned
2826 | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
2827 | Here we assume that the exponent is not too small (this should be checked
2828 | before entering the rounding routine), but the number could be denormalized.
2830 | Check for denormalized numbers:
2831 1: btst #FLT_MANT_DIG,d0
2832 bne 2f | if set the number is normalized
2833 | Normalize shifting left until bit #FLT_MANT_DIG is set or the exponent
2834 | is one (remember that a denormalized number corresponds to an
2835 | exponent of -F_BIAS+1).
2836 cmpw #1,d2 | remember that the exponent is at least one
2837 beq 2f | an exponent of one means denormalized
2838 addl d1,d1 | else shift and adjust the exponent
2842 | Now round: we do it as follows: after the shifting we can write the
2843 | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
2844 | If delta < 1, do nothing. If delta > 1, add 1 to f.
2845 | If delta == 1, we make sure the rounded number will be even (odd?)
2847 btst #0,d0 | is delta < 1?
2848 beq 2f | if so, do not do anything
2849 tstl d1 | is delta == 1?
2850 bne 1f | if so round to even
2852 andl #2,d1 | bit 1 is the last significant bit
2855 1: movel #1,d1 | else add 1
2857 | Shift right once (because we used bit #FLT_MANT_DIG!).
2859 | Now check again bit #FLT_MANT_DIG (rounding could have produced a
2860 | 'fraction overflow' ...).
2861 btst #FLT_MANT_DIG,d0
2866 | If bit #FLT_MANT_DIG-1 is clear we have a denormalized number, so we
2867 | have to put the exponent to zero and return a denormalized number.
2868 btst #FLT_MANT_DIG-1,d0
2878 #endif /* L_float */
2880 | gcc expects the routines __eqdf2, __nedf2, __gtdf2, __gedf2,
2881 | __ledf2, __ltdf2 to all return the same value as a direct call to
2882 | __cmpdf2 would. In this implementation, each of these routines
2883 | simply calls __cmpdf2. It would be more efficient to give the
2884 | __cmpdf2 routine several names, but separating them out will make it
2885 | easier to write efficient versions of these routines someday.
2898 .globl SYM (__eqdf2)
2912 #endif /* L_eqdf2 */
2925 .globl SYM (__nedf2)
2939 #endif /* L_nedf2 */
2951 .globl SYM (__gtdf2)
2965 #endif /* L_gtdf2 */
2978 .globl SYM (__gedf2)
2992 #endif /* L_gedf2 */
3005 .globl SYM (__ltdf2)
3019 #endif /* L_ltdf2 */
3031 .globl SYM (__ledf2)
3045 #endif /* L_ledf2 */
3047 | The comments above about __eqdf2, et. al., also apply to __eqsf2,
3048 | et. al., except that the latter call __cmpsf2 rather than __cmpdf2.
3060 .globl SYM (__eqsf2)
3072 #endif /* L_eqsf2 */
3084 .globl SYM (__nesf2)
3096 #endif /* L_nesf2 */
3108 .globl SYM (__gtsf2)
3120 #endif /* L_gtsf2 */
3132 .globl SYM (__gesf2)
3144 #endif /* L_gesf2 */
3156 .globl SYM (__ltsf2)
3168 #endif /* L_ltsf2 */
3180 .globl SYM (__lesf2)
3192 #endif /* L_lesf2 */