1 /* libgcc routines for 68000 w/o floating-point hardware.
2 Copyright (C) 1994-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC 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 3, or (at your option) any
11 This file is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
25 /* Use this one for any 680x0; assumes no floating point hardware.
26 The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk.
27 Some of this code comes from MINIX, via the folks at ericsson.
28 D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
31 /* These are predefined by new versions of GNU cpp. */
33 #ifndef __USER_LABEL_PREFIX__
34 #define __USER_LABEL_PREFIX__ _
37 #ifndef __REGISTER_PREFIX__
38 #define __REGISTER_PREFIX__
41 #ifndef __IMMEDIATE_PREFIX__
42 #define __IMMEDIATE_PREFIX__ #
45 /* ANSI concatenation macros. */
47 #define CONCAT1(a, b) CONCAT2(a, b)
48 #define CONCAT2(a, b) a ## b
50 /* Use the right prefix for global labels. */
52 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
54 /* Note that X is a function. */
57 #define FUNC(x) .type SYM(x),function
59 /* The .proc pseudo-op is accepted, but ignored, by GAS. We could just
60 define this to the empty string for non-ELF systems, but defining it
61 to .proc means that the information is available to the assembler if
66 /* Use the right prefix for registers. */
68 #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
70 /* Use the right prefix for immediate values. */
72 #define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
93 /* Provide a few macros to allow for PIC code support.
94 * With PIC, data is stored A5 relative so we've got to take a bit of special
95 * care to ensure that all loads of global data is via A5. PIC also requires
96 * jumps and subroutine calls to be PC relative rather than absolute. We cheat
97 * a little on this and in the PIC case, we use short offset branches and
98 * hope that the final object code is within range (which it should be).
102 /* Non PIC (absolute/relocatable) versions */
112 .macro PICLEA sym, reg
116 .macro PICPEA sym, areg
122 # if defined (__uClinux__)
124 /* Versions for uClinux */
126 # if defined(__ID_SHARED_LIBRARY__)
128 /* -mid-shared-library versions */
130 .macro PICLEA sym, reg
131 movel a5@(_current_shared_library_a5_offset_), \reg
132 movel \sym@GOT(\reg), \reg
135 .macro PICPEA sym, areg
136 movel a5@(_current_shared_library_a5_offset_), \areg
137 movel \sym@GOT(\areg), sp@-
150 # else /* !__ID_SHARED_LIBRARY__ */
152 /* Versions for -msep-data */
154 .macro PICLEA sym, reg
155 movel \sym@GOT(a5), \reg
158 .macro PICPEA sym, areg
159 movel \sym@GOT(a5), sp@-
163 #if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
172 /* ISA C has no bra.l instruction, and since this assembly file
173 gets assembled into multiple object files, we avoid the
174 bra instruction entirely. */
175 #if defined (__mcoldfire__) && !defined (__mcfisab__)
185 # else /* !__uClinux__ */
187 /* Versions for Linux */
189 .macro PICLEA sym, reg
190 movel #_GLOBAL_OFFSET_TABLE_@GOTPC, \reg
191 lea (-6, pc, \reg), \reg
192 movel \sym@GOT(\reg), \reg
195 .macro PICPEA sym, areg
196 movel #_GLOBAL_OFFSET_TABLE_@GOTPC, \areg
197 lea (-6, pc, \areg), \areg
198 movel \sym@GOT(\areg), sp@-
202 #if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
211 /* ISA C has no bra.l instruction, and since this assembly file
212 gets assembled into multiple object files, we avoid the
213 bra instruction entirely. */
214 #if defined (__mcoldfire__) && !defined (__mcfisab__)
228 | This is an attempt at a decent floating point (single, double and
229 | extended double) code for the GNU C compiler. It should be easy to
230 | adapt to other compilers (but beware of the local labels!).
232 | Starting date: 21 October, 1990
234 | It is convenient to introduce the notation (s,e,f) for a floating point
235 | number, where s=sign, e=exponent, f=fraction. We will call a floating
236 | point number fpn to abbreviate, independently of the precision.
237 | Let MAX_EXP be in each case the maximum exponent (255 for floats, 1023
238 | for doubles and 16383 for long doubles). We then have the following
240 | 1. Normalized fpns have 0 < e < MAX_EXP. They correspond to
241 | (-1)^s x 1.f x 2^(e-bias-1).
242 | 2. Denormalized fpns have e=0. They correspond to numbers of the form
243 | (-1)^s x 0.f x 2^(-bias).
244 | 3. +/-INFINITY have e=MAX_EXP, f=0.
245 | 4. Quiet NaN (Not a Number) have all bits set.
246 | 5. Signaling NaN (Not a Number) have s=0, e=MAX_EXP, f=1.
248 |=============================================================================
250 |=============================================================================
252 | This is the floating point condition code register (_fpCCR):
255 | short _exception_bits;
256 | short _trap_enable_bits;
257 | short _sticky_bits;
258 | short _rounding_mode;
260 | short _last_operation;
284 .word ROUND_TO_NEAREST
297 EBITS = __exception_bits - SYM (_fpCCR)
298 TRAPE = __trap_enable_bits - SYM (_fpCCR)
299 STICK = __sticky_bits - SYM (_fpCCR)
300 ROUND = __rounding_mode - SYM (_fpCCR)
301 FORMT = __format - SYM (_fpCCR)
302 LASTO = __last_operation - SYM (_fpCCR)
303 OPER1 = __operand1 - SYM (_fpCCR)
304 OPER2 = __operand2 - SYM (_fpCCR)
306 | The following exception types are supported:
307 INEXACT_RESULT = 0x0001
310 DIVIDE_BY_ZERO = 0x0008
311 INVALID_OPERATION = 0x0010
313 | The allowed rounding modes are:
315 ROUND_TO_NEAREST = 0 | round result to nearest representable value
316 ROUND_TO_ZERO = 1 | round result towards zero
317 ROUND_TO_PLUS = 2 | round result towards plus infinity
318 ROUND_TO_MINUS = 3 | round result towards minus infinity
320 | The allowed values of format are:
326 | The allowed values for the last operation are:
336 |=============================================================================
337 | __clear_sticky_bits
338 |=============================================================================
340 | The sticky bits are normally not cleared (thus the name), whereas the
341 | exception type and exception value reflect the last computation.
342 | This routine is provided to clear them (you can also write to _fpCCR,
343 | since it is globally visible).
345 .globl SYM (__clear_sticky_bit)
350 | void __clear_sticky_bits(void);
351 SYM (__clear_sticky_bit):
352 PICLEA SYM (_fpCCR),a0
353 #ifndef __mcoldfire__
354 movew IMM (0),a0@(STICK)
360 |=============================================================================
361 | $_exception_handler
362 |=============================================================================
364 .globl $_exception_handler
369 | This is the common exit point if an exception occurs.
370 | NOTE: it is NOT callable from C!
371 | It expects the exception type in d7, the format (SINGLE_FLOAT,
372 | DOUBLE_FLOAT or LONG_FLOAT) in d6, and the last operation code in d5.
373 | It sets the corresponding exception and sticky bits, and the format.
374 | Depending on the format if fills the corresponding slots for the
375 | operands which produced the exception (all this information is provided
376 | so if you write your own exception handlers you have enough information
377 | to deal with the problem).
378 | Then checks to see if the corresponding exception is trap-enabled,
379 | in which case it pushes the address of _fpCCR and traps through
380 | trap FPTRAP (15 for the moment).
385 PICLEA SYM (_fpCCR),a0
386 movew d7,a0@(EBITS) | set __exception_bits
387 #ifndef __mcoldfire__
388 orw d7,a0@(STICK) | and __sticky_bits
394 movew d6,a0@(FORMT) | and __format
395 movew d5,a0@(LASTO) | and __last_operation
397 | Now put the operands in place:
398 #ifndef __mcoldfire__
399 cmpw IMM (SINGLE_FLOAT),d6
401 cmpl IMM (SINGLE_FLOAT),d6
404 movel a6@(8),a0@(OPER1)
405 movel a6@(12),a0@(OPER1+4)
406 movel a6@(16),a0@(OPER2)
407 movel a6@(20),a0@(OPER2+4)
409 1: movel a6@(8),a0@(OPER1)
410 movel a6@(12),a0@(OPER2)
412 | And check whether the exception is trap-enabled:
413 #ifndef __mcoldfire__
414 andw a0@(TRAPE),d7 | is exception trap-enabled?
421 PICPEA SYM (_fpCCR),a1 | yes, push address of _fpCCR
422 trap IMM (FPTRAP) | and trap
423 #ifndef __mcoldfire__
424 1: moveml sp@+,d2-d7 | restore data registers
427 | XXX if frame pointer is ever removed, stack pointer must
432 #endif /* L_floatex */
437 .globl SYM (__mulsi3)
438 .globl SYM (__mulsi3_internal)
439 .hidden SYM (__mulsi3_internal)
441 SYM (__mulsi3_internal):
442 movew sp@(4), d0 /* x0 -> d0 */
443 muluw sp@(10), d0 /* x0*y1 */
444 movew sp@(6), d1 /* x1 -> d1 */
445 muluw sp@(8), d1 /* x1*y0 */
446 #ifndef __mcoldfire__
453 movew sp@(6), d1 /* x1 -> d1 */
454 muluw sp@(10), d1 /* x1*y1 */
458 #endif /* L_mulsi3 */
463 .globl SYM (__udivsi3)
464 .globl SYM (__udivsi3_internal)
465 .hidden SYM (__udivsi3_internal)
467 SYM (__udivsi3_internal):
468 #ifndef __mcoldfire__
470 movel sp@(12), d1 /* d1 = divisor */
471 movel sp@(8), d0 /* d0 = dividend */
473 cmpl IMM (0x10000), d1 /* divisor >= 2 ^ 16 ? */
474 jcc L3 /* then try next algorithm */
478 divu d1, d2 /* high quotient in lower word */
479 movew d2, d0 /* save high quotient */
481 movew sp@(10), d2 /* get low dividend + high rest */
482 divu d1, d2 /* low quotient */
486 L3: movel d1, d2 /* use d2 as divisor backup */
487 L4: lsrl IMM (1), d1 /* shift divisor */
488 lsrl IMM (1), d0 /* shift dividend */
489 cmpl IMM (0x10000), d1 /* still divisor >= 2 ^ 16 ? */
491 divu d1, d0 /* now we have 16-bit divisor */
492 andl IMM (0xffff), d0 /* mask out divisor, ignore remainder */
494 /* Multiply the 16-bit tentative quotient with the 32-bit divisor. Because of
495 the operand ranges, this might give a 33-bit product. If this product is
496 greater than the dividend, the tentative quotient was too large. */
498 mulu d0, d1 /* low part, 32 bits */
500 mulu d0, d2 /* high part, at most 17 bits */
501 swap d2 /* align high part with low part */
502 tstw d2 /* high part 17 bits? */
503 jne L5 /* if 17 bits, quotient was too large */
504 addl d2, d1 /* add parts */
505 jcs L5 /* if sum is 33 bits, quotient was too large */
506 cmpl sp@(8), d1 /* compare the sum with the dividend */
507 jls L6 /* if sum > dividend, quotient was too large */
508 L5: subql IMM (1), d0 /* adjust quotient */
513 #else /* __mcoldfire__ */
515 /* ColdFire implementation of non-restoring division algorithm from
516 Hennessy & Patterson, Appendix A. */
523 L1: addl d0,d0 | shift reg pair (p,a) one bit left
525 movl d2,d3 | subtract b from p, store in tmp.
527 jcs L2 | if no carry,
528 bset IMM (0),d0 | set the low order bit of a to 1,
529 movl d3,d2 | and store tmp in p.
532 moveml sp@,d2-d4 | restore data registers
535 #endif /* __mcoldfire__ */
537 #endif /* L_udivsi3 */
542 .globl SYM (__divsi3)
543 .globl SYM (__divsi3_internal)
544 .hidden SYM (__divsi3_internal)
546 SYM (__divsi3_internal):
549 moveq IMM (1), d2 /* sign of result stored in d2 (=1 or =-1) */
550 movel sp@(12), d1 /* d1 = divisor */
553 #ifndef __mcoldfire__
554 negb d2 /* change sign because divisor <0 */
556 negl d2 /* change sign because divisor <0 */
558 L1: movel sp@(8), d0 /* d0 = dividend */
561 #ifndef __mcoldfire__
569 PICCALL SYM (__udivsi3_internal) /* divide abs(dividend) by abs(divisor) */
578 #endif /* L_divsi3 */
583 .globl SYM (__umodsi3)
585 movel sp@(8), d1 /* d1 = divisor */
586 movel sp@(4), d0 /* d0 = dividend */
589 PICCALL SYM (__udivsi3_internal)
591 movel sp@(8), d1 /* d1 = divisor */
592 #ifndef __mcoldfire__
595 PICCALL SYM (__mulsi3_internal) /* d0 = (a/b)*b */
600 movel sp@(4), d1 /* d1 = dividend */
601 subl d0, d1 /* d1 = a - (a/b)*b */
604 #endif /* L_umodsi3 */
609 .globl SYM (__modsi3)
611 movel sp@(8), d1 /* d1 = divisor */
612 movel sp@(4), d0 /* d0 = dividend */
615 PICCALL SYM (__divsi3_internal)
617 movel sp@(8), d1 /* d1 = divisor */
618 #ifndef __mcoldfire__
621 PICCALL SYM (__mulsi3_internal) /* d0 = (a/b)*b */
626 movel sp@(4), d1 /* d1 = dividend */
627 subl d0, d1 /* d1 = a - (a/b)*b */
630 #endif /* L_modsi3 */
636 .globl $_exception_handler
638 QUIET_NaN = 0xffffffff
642 DBL_MAX_EXP = D_MAX_EXP - D_BIAS
643 DBL_MIN_EXP = 1 - D_BIAS
646 INEXACT_RESULT = 0x0001
649 DIVIDE_BY_ZERO = 0x0008
650 INVALID_OPERATION = 0x0010
664 ROUND_TO_NEAREST = 0 | round result to nearest representable value
665 ROUND_TO_ZERO = 1 | round result towards zero
666 ROUND_TO_PLUS = 2 | round result towards plus infinity
667 ROUND_TO_MINUS = 3 | round result towards minus infinity
671 .globl SYM (__adddf3)
672 .globl SYM (__subdf3)
673 .globl SYM (__muldf3)
674 .globl SYM (__divdf3)
675 .globl SYM (__negdf2)
676 .globl SYM (__cmpdf2)
677 .globl SYM (__cmpdf2_internal)
678 .hidden SYM (__cmpdf2_internal)
683 | These are common routines to return and signal exceptions.
686 | Return and signal a denormalized number
688 movew IMM (INEXACT_RESULT+UNDERFLOW),d7
689 moveq IMM (DOUBLE_FLOAT),d6
690 PICJUMP $_exception_handler
694 | Return a properly signed INFINITY and set the exception flags
695 movel IMM (0x7ff00000),d0
698 movew IMM (INEXACT_RESULT+OVERFLOW),d7
699 moveq IMM (DOUBLE_FLOAT),d6
700 PICJUMP $_exception_handler
703 | Return 0 and set the exception flags
706 movew IMM (INEXACT_RESULT+UNDERFLOW),d7
707 moveq IMM (DOUBLE_FLOAT),d6
708 PICJUMP $_exception_handler
711 | Return a quiet NaN and set the exception flags
712 movel IMM (QUIET_NaN),d0
714 movew IMM (INEXACT_RESULT+INVALID_OPERATION),d7
715 moveq IMM (DOUBLE_FLOAT),d6
716 PICJUMP $_exception_handler
719 | Return a properly signed INFINITY and set the exception flags
720 movel IMM (0x7ff00000),d0
723 movew IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7
724 moveq IMM (DOUBLE_FLOAT),d6
725 PICJUMP $_exception_handler
727 |=============================================================================
728 |=============================================================================
729 | double precision routines
730 |=============================================================================
731 |=============================================================================
733 | A double precision floating point number (double) has the format:
736 | unsigned int sign : 1; /* sign bit */
737 | unsigned int exponent : 11; /* exponent, shifted by 126 */
738 | unsigned int fraction : 52; /* fraction */
741 | Thus sizeof(double) = 8 (64 bits).
743 | All the routines are callable from C programs, and return the result
744 | in the register pair d0-d1. They also preserve all registers except
747 |=============================================================================
749 |=============================================================================
751 | double __subdf3(double, double);
754 bchg IMM (31),sp@(12) | change sign of second operand
755 | and fall through, so we always add
756 |=============================================================================
758 |=============================================================================
760 | double __adddf3(double, double);
763 #ifndef __mcoldfire__
764 link a6,IMM (0) | everything will be done in registers
765 moveml d2-d7,sp@- | save all data registers and a2 (but d0-d1)
770 movel a6@(8),d0 | get first operand
772 movel a6@(16),d2 | get second operand
775 movel d0,d7 | get d0's sign bit in d7 '
776 addl d1,d1 | check and clear sign bit of a, and gain one
777 addxl d0,d0 | bit of extra precision
778 beq Ladddf$b | if zero return second operand
780 movel d2,d6 | save sign in d6
781 addl d3,d3 | get rid of sign bit and gain one bit of
782 addxl d2,d2 | extra precision
783 beq Ladddf$a | if zero return first operand
785 andl IMM (0x80000000),d7 | isolate a's sign bit '
786 swap d6 | and also b's sign bit '
787 #ifndef __mcoldfire__
788 andw IMM (0x8000),d6 |
789 orw d6,d7 | and combine them into d7, so that a's sign '
790 | bit is in the high word and b's is in the '
791 | low word, so d6 is free to be used
796 movel d7,a0 | now save d7 into a0, so d7 is free to
799 | Get the exponents and check for denormalized and/or infinity.
801 movel IMM (0x001fffff),d6 | mask for the fraction
802 movel IMM (0x00200000),d7 | mask to put hidden bit back
805 andl d6,d0 | get fraction in d0
806 notl d6 | make d6 into mask for the exponent
807 andl d6,d4 | get exponent in d4
808 beq Ladddf$a$den | branch if a is denormalized
809 cmpl d6,d4 | check for INFINITY or NaN
811 orl d7,d0 | and put hidden bit back
813 swap d4 | shift right exponent so that it starts
814 #ifndef __mcoldfire__
815 lsrw IMM (5),d4 | in bit 0 and not bit 20
817 lsrl IMM (5),d4 | in bit 0 and not bit 20
819 | Now we have a's exponent in d4 and fraction in d0-d1 '
820 movel d2,d5 | save b to get exponent
821 andl d6,d5 | get exponent in d5
822 beq Ladddf$b$den | branch if b is denormalized
823 cmpl d6,d5 | check for INFINITY or NaN
825 notl d6 | make d6 into mask for the fraction again
826 andl d6,d2 | and get fraction in d2
827 orl d7,d2 | and put hidden bit back
829 swap d5 | shift right exponent so that it starts
830 #ifndef __mcoldfire__
831 lsrw IMM (5),d5 | in bit 0 and not bit 20
833 lsrl IMM (5),d5 | in bit 0 and not bit 20
836 | Now we have b's exponent in d5 and fraction in d2-d3. '
838 | The situation now is as follows: the signs are combined in a0, the
839 | numbers are in d0-d1 (a) and d2-d3 (b), and the exponents in d4 (a)
840 | and d5 (b). To do the rounding correctly we need to keep all the
841 | bits until the end, so we need to use d0-d1-d2-d3 for the first number
842 | and d4-d5-d6-d7 for the second. To do this we store (temporarily) the
843 | exponents in a2-a3.
845 #ifndef __mcoldfire__
846 moveml a2-a3,sp@- | save the address registers
853 movel d4,a2 | save the exponents
856 movel IMM (0),d7 | and move the numbers around
863 | Here we shift the numbers until the exponents are the same, and put
864 | the largest exponent in a2.
865 #ifndef __mcoldfire__
866 exg d4,a2 | get exponents back
868 cmpw d4,d5 | compare the exponents
870 movel d4,a4 | get exponents back
876 cmpl d4,d5 | compare the exponents
878 beq Ladddf$3 | if equal don't shift '
879 bhi 9f | branch if second exponent is higher
881 | Here we have a's exponent larger than b's, so we have to shift b. We do
882 | this by using as counter d2:
883 1: movew d4,d2 | move largest exponent to d2
884 #ifndef __mcoldfire__
885 subw d5,d2 | and subtract second exponent
886 exg d4,a2 | get back the longs we saved
889 subl d5,d2 | and subtract second exponent
890 movel d4,a4 | get back the longs we saved
897 | if difference is too large we don't shift (actually, we can just exit) '
898 #ifndef __mcoldfire__
899 cmpw IMM (DBL_MANT_DIG+2),d2
901 cmpl IMM (DBL_MANT_DIG+2),d2
904 #ifndef __mcoldfire__
905 cmpw IMM (32),d2 | if difference >= 32, shift by longs
907 cmpl IMM (32),d2 | if difference >= 32, shift by longs
911 #ifndef __mcoldfire__
912 cmpw IMM (16),d2 | if difference >= 16, shift by words
914 cmpl IMM (16),d2 | if difference >= 16, shift by words
917 bra 3f | enter dbra loop
920 #ifndef __mcoldfire__
941 #ifndef __mcoldfire__
955 #ifndef __mcoldfire__
970 #ifndef __mcoldfire__
978 #ifndef __mcoldfire__
981 subw d5,d6 | keep d5 (largest exponent) in d4
996 | if difference is too large we don't shift (actually, we can just exit) '
997 #ifndef __mcoldfire__
998 cmpw IMM (DBL_MANT_DIG+2),d6
1000 cmpl IMM (DBL_MANT_DIG+2),d6
1003 #ifndef __mcoldfire__
1004 cmpw IMM (32),d6 | if difference >= 32, shift by longs
1006 cmpl IMM (32),d6 | if difference >= 32, shift by longs
1010 #ifndef __mcoldfire__
1011 cmpw IMM (16),d6 | if difference >= 16, shift by words
1013 cmpl IMM (16),d6 | if difference >= 16, shift by words
1016 bra 3f | enter dbra loop
1019 #ifndef __mcoldfire__
1040 #ifndef __mcoldfire__
1054 #ifndef __mcoldfire__
1069 #ifndef __mcoldfire__
1076 #ifndef __mcoldfire__
1088 | Now we have the numbers in d0--d3 and d4--d7, the exponent in a2, and
1091 | Here we have to decide whether to add or subtract the numbers:
1092 #ifndef __mcoldfire__
1093 exg d7,a0 | get the signs
1094 exg d6,a3 | a3 is free to be used
1104 movew IMM (0),d7 | get a's sign in d7 '
1106 movew IMM (0),d6 | and b's sign in d6 '
1107 eorl d7,d6 | compare the signs
1108 bmi Lsubdf$0 | if the signs are different we have
1110 #ifndef __mcoldfire__
1111 exg d7,a0 | else we add the numbers
1126 movel a2,d4 | return exponent to d4
1128 andl IMM (0x80000000),d7 | d7 now has the sign
1130 #ifndef __mcoldfire__
1138 | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
1139 | the case of denormalized numbers in the rounding routine itself).
1140 | As in the addition (not in the subtraction!) we could have set
1141 | one more bit we check this:
1142 btst IMM (DBL_MANT_DIG+1),d0
1144 #ifndef __mcoldfire__
1167 lea pc@(Ladddf$5),a0 | to return from rounding routine
1168 PICLEA SYM (_fpCCR),a1 | check the rounding mode
1169 #ifdef __mcoldfire__
1172 movew a1@(6),d6 | rounding mode in d6
1173 beq Lround$to$nearest
1174 #ifndef __mcoldfire__
1175 cmpw IMM (ROUND_TO_PLUS),d6
1177 cmpl IMM (ROUND_TO_PLUS),d6
1183 | Put back the exponent and check for overflow
1184 #ifndef __mcoldfire__
1185 cmpw IMM (0x7ff),d4 | is the exponent big?
1187 cmpl IMM (0x7ff),d4 | is the exponent big?
1190 bclr IMM (DBL_MANT_DIG-1),d0
1191 #ifndef __mcoldfire__
1192 lslw IMM (4),d4 | put exponent back into position
1194 lsll IMM (4),d4 | put exponent back into position
1197 #ifndef __mcoldfire__
1209 | Here we do the subtraction.
1210 #ifndef __mcoldfire__
1211 exg d7,a0 | put sign back in a0
1225 beq Ladddf$ret$1 | if zero just exit
1226 bpl 1f | if positive skip the following
1228 bchg IMM (31),d7 | change sign bit in d7
1232 negxl d1 | and negate result
1235 movel a2,d4 | return exponent to d4
1237 andl IMM (0x80000000),d7 | isolate sign bit
1238 #ifndef __mcoldfire__
1246 | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
1247 | the case of denormalized numbers in the rounding routine itself).
1248 | As in the addition (not in the subtraction!) we could have set
1249 | one more bit we check this:
1250 btst IMM (DBL_MANT_DIG+1),d0
1252 #ifndef __mcoldfire__
1275 lea pc@(Lsubdf$1),a0 | to return from rounding routine
1276 PICLEA SYM (_fpCCR),a1 | check the rounding mode
1277 #ifdef __mcoldfire__
1280 movew a1@(6),d6 | rounding mode in d6
1281 beq Lround$to$nearest
1282 #ifndef __mcoldfire__
1283 cmpw IMM (ROUND_TO_PLUS),d6
1285 cmpl IMM (ROUND_TO_PLUS),d6
1291 | Put back the exponent and sign (we don't have overflow). '
1292 bclr IMM (DBL_MANT_DIG-1),d0
1293 #ifndef __mcoldfire__
1294 lslw IMM (4),d4 | put exponent back into position
1296 lsll IMM (4),d4 | put exponent back into position
1299 #ifndef __mcoldfire__
1307 | If one of the numbers was too small (difference of exponents >=
1308 | DBL_MANT_DIG+1) we return the other (and now we don't have to '
1309 | check for finiteness or zero).
1311 #ifndef __mcoldfire__
1320 PICLEA SYM (_fpCCR),a0
1322 #ifndef __mcoldfire__
1323 moveml sp@+,d2-d7 | restore data registers
1326 | XXX if frame pointer is ever removed, stack pointer must
1329 unlk a6 | and return
1333 #ifndef __mcoldfire__
1342 PICLEA SYM (_fpCCR),a0
1344 #ifndef __mcoldfire__
1345 moveml sp@+,d2-d7 | restore data registers
1348 | XXX if frame pointer is ever removed, stack pointer must
1351 unlk a6 | and return
1355 movel d7,d4 | d7 contains 0x00200000
1359 movel d7,d5 | d7 contains 0x00200000
1364 | Return b (if a is zero)
1367 bne 1f | Check if b is -0
1368 cmpl IMM (0x80000000),d0
1370 andl IMM (0x80000000),d7 | Use the sign of a
1378 | Check for NaN and +/-INFINITY.
1380 andl IMM (0x80000000),d7 |
1382 cmpl IMM (0x7ff00000),d0 |
1384 movel d0,d0 | check for zero, since we don't '
1385 bne Ladddf$ret | want to return -0 by mistake
1391 andl IMM (0x000fffff),d0 | check for NaN (nonzero fraction)
1397 #ifndef __mcoldfire__
1398 moveml sp@+,a2-a3 | restore regs and exit
1407 PICLEA SYM (_fpCCR),a0
1409 orl d7,d0 | put sign bit back
1410 #ifndef __mcoldfire__
1414 | XXX if frame pointer is ever removed, stack pointer must
1421 | Return a denormalized number.
1422 #ifndef __mcoldfire__
1423 lsrl IMM (1),d0 | shift right once more
1436 | This could be faster but it is not worth the effort, since it is not
1437 | executed very often. We sacrifice speed for clarity here.
1438 movel a6@(8),d0 | get the numbers back (remember that we
1439 movel a6@(12),d1 | did some processing already)
1442 movel IMM (0x7ff00000),d4 | useful constant (INFINITY)
1443 movel d0,d7 | save sign bits
1445 bclr IMM (31),d0 | clear sign bits
1447 | We know that one of them is either NaN of +/-INFINITY
1448 | Check for NaN (if either one is NaN return NaN)
1449 cmpl d4,d0 | check first a (d0)
1450 bhi Ld$inop | if d0 > 0x7ff00000 or equal and
1452 tstl d1 | d1 > 0, a is NaN
1454 2: cmpl d4,d2 | check now b (d1)
1460 | Now comes the check for +/-INFINITY. We know that both are (maybe not
1461 | finite) numbers, but we have to check if both are infinite whether we
1462 | are adding or subtracting them.
1463 eorl d7,d6 | to check sign bits
1465 andl IMM (0x80000000),d7 | get (common) sign bit
1468 | We know one (or both) are infinite, so we test for equality between the
1469 | two numbers (if they are equal they have to be infinite both, so we
1471 cmpl d2,d0 | are both infinite?
1472 bne 1f | if d0 <> d2 they are not equal
1473 cmpl d3,d1 | if d0 == d2 test d3 and d1
1474 beq Ld$inop | if equal return NaN
1476 andl IMM (0x80000000),d7 | get a's sign bit '
1477 cmpl d4,d0 | test now for infinity
1478 beq Ld$infty | if a is INFINITY return with this sign
1479 bchg IMM (31),d7 | else we know b is INFINITY and has
1480 bra Ld$infty | the opposite sign
1482 |=============================================================================
1484 |=============================================================================
1486 | double __muldf3(double, double);
1489 #ifndef __mcoldfire__
1496 movel a6@(8),d0 | get a into d0-d1
1498 movel a6@(16),d2 | and b into d2-d3
1500 movel d0,d7 | d7 will hold the sign of the product
1502 andl IMM (0x80000000),d7 |
1503 movel d7,a0 | save sign bit into a0
1504 movel IMM (0x7ff00000),d7 | useful constant (+INFINITY)
1505 movel d7,d6 | another (mask for fraction)
1507 bclr IMM (31),d0 | get rid of a's sign bit '
1510 beq Lmuldf$a$0 | branch if a is zero
1512 bclr IMM (31),d2 | get rid of b's sign bit '
1515 beq Lmuldf$b$0 | branch if b is zero
1517 cmpl d7,d0 | is a big?
1518 bhi Lmuldf$inop | if a is NaN return NaN
1519 beq Lmuldf$a$nf | we still have to check d1 and b ...
1520 cmpl d7,d2 | now compare b with INFINITY
1521 bhi Lmuldf$inop | is b NaN?
1522 beq Lmuldf$b$nf | we still have to check d3 ...
1523 | Here we have both numbers finite and nonzero (and with no sign bit).
1524 | Now we get the exponents into d4 and d5.
1525 andl d7,d4 | isolate exponent in d4
1526 beq Lmuldf$a$den | if exponent zero, have denormalized
1527 andl d6,d0 | isolate fraction
1528 orl IMM (0x00100000),d0 | and put hidden bit back
1529 swap d4 | I like exponents in the first byte
1530 #ifndef __mcoldfire__
1539 orl IMM (0x00100000),d2 | and put hidden bit back
1541 #ifndef __mcoldfire__
1547 #ifndef __mcoldfire__
1548 addw d5,d4 | add exponents
1549 subw IMM (D_BIAS+1),d4 | and subtract bias (plus one)
1551 addl d5,d4 | add exponents
1552 subl IMM (D_BIAS+1),d4 | and subtract bias (plus one)
1555 | We are now ready to do the multiplication. The situation is as follows:
1556 | both a and b have bit 52 ( bit 20 of d0 and d2) set (even if they were
1557 | denormalized to start with!), which means that in the product bit 104
1558 | (which will correspond to bit 8 of the fourth long) is set.
1560 | Here we have to do the product.
1561 | To do it we have to juggle the registers back and forth, as there are not
1562 | enough to keep everything in them. So we use the address registers to keep
1563 | some intermediate data.
1565 #ifndef __mcoldfire__
1566 moveml a2-a3,sp@- | save a2 and a3 for temporary use
1572 movel IMM (0),a2 | a2 is a null register
1573 movel d4,a3 | and a3 will preserve the exponent
1575 | First, shift d2-d3 so bit 20 becomes bit 31:
1576 #ifndef __mcoldfire__
1577 rorl IMM (5),d2 | rotate d2 5 places right
1578 swap d2 | and swap it
1579 rorl IMM (5),d3 | do the same thing with d3
1581 movew d3,d6 | get the rightmost 11 bits of d3
1582 andw IMM (0x07ff),d6 |
1583 orw d6,d2 | and put them into d2
1584 andw IMM (0xf800),d3 | clear those bits in d3
1586 moveq IMM (11),d7 | left shift d2 11 bits
1588 movel d3,d6 | get a copy of d3
1589 lsll d7,d3 | left shift d3 11 bits
1590 andl IMM (0xffe00000),d6 | get the top 11 bits of d3
1591 moveq IMM (21),d7 | right shift them 21 bits
1593 orl d6,d2 | stick them at the end of d2
1596 movel d2,d6 | move b into d6-d7
1597 movel d3,d7 | move a into d4-d5
1598 movel d0,d4 | and clear d0-d1-d2-d3 (to put result)
1605 | We use a1 as counter:
1606 movel IMM (DBL_MANT_DIG-1),a1
1607 #ifndef __mcoldfire__
1616 #ifndef __mcoldfire__
1617 exg d7,a1 | put counter back in a1
1623 addl d3,d3 | shift sum once left
1629 bcc 2f | if bit clear skip the following
1630 #ifndef __mcoldfire__
1637 addl d5,d3 | else add a to the sum
1641 #ifndef __mcoldfire__
1649 #ifndef __mcoldfire__
1650 exg d7,a1 | put counter in d7
1651 dbf d7,1b | decrement and branch
1660 movel a3,d4 | restore exponent
1661 #ifndef __mcoldfire__
1669 | Now we have the product in d0-d1-d2-d3, with bit 8 of d0 set. The
1670 | first thing to do now is to normalize it so bit 8 becomes bit
1671 | DBL_MANT_DIG-32 (to do the rounding); later we will shift right.
1680 #ifndef __mcoldfire__
1710 | Now round, check for over- and underflow, and exit.
1711 movel a0,d7 | get sign bit back into d7
1712 moveq IMM (MULTIPLY),d5
1714 btst IMM (DBL_MANT_DIG+1-32),d0
1716 #ifndef __mcoldfire__
1731 moveq IMM (MULTIPLY),d5
1735 moveq IMM (MULTIPLY),d5
1736 movel a0,d7 | get sign bit back into d7
1737 tstl d3 | we know d2 == 0x7ff00000, so check d3
1738 bne Ld$inop | if d3 <> 0 b is NaN
1739 bra Ld$overflow | else we have overflow (since a is finite)
1742 moveq IMM (MULTIPLY),d5
1743 movel a0,d7 | get sign bit back into d7
1744 tstl d1 | we know d0 == 0x7ff00000, so check d1
1745 bne Ld$inop | if d1 <> 0 a is NaN
1746 bra Ld$overflow | else signal overflow
1748 | If either number is zero return zero, unless the other is +/-INFINITY or
1749 | NaN, in which case we return NaN.
1751 moveq IMM (MULTIPLY),d5
1752 #ifndef __mcoldfire__
1753 exg d2,d0 | put b (==0) into d0-d1
1754 exg d3,d1 | and a (with sign bit cleared) into d2-d3
1755 movel a0,d0 | set result sign
1757 movel d0,d2 | put a into d2-d3
1759 movel a0,d0 | put result zero into d0-d1
1764 movel a0,d0 | set result sign
1765 movel a6@(16),d2 | put b into d2-d3 again
1767 bclr IMM (31),d2 | clear sign bit
1768 1: cmpl IMM (0x7ff00000),d2 | check for non-finiteness
1769 bge Ld$inop | in case NaN or +/-INFINITY return NaN
1770 PICLEA SYM (_fpCCR),a0
1772 #ifndef __mcoldfire__
1776 | XXX if frame pointer is ever removed, stack pointer must
1782 | If a number is denormalized we put an exponent of 1 but do not put the
1783 | hidden bit back into the fraction; instead we shift left until bit 21
1784 | (the hidden bit) is set, adjusting the exponent accordingly. We do this
1785 | to ensure that the product of the fractions is close to 1.
1789 1: addl d1,d1 | shift a left until bit 20 is set
1791 #ifndef __mcoldfire__
1792 subw IMM (1),d4 | and adjust exponent
1794 subl IMM (1),d4 | and adjust exponent
1803 1: addl d3,d3 | shift b left until bit 20 is set
1805 #ifndef __mcoldfire__
1806 subw IMM (1),d5 | and adjust exponent
1808 subql IMM (1),d5 | and adjust exponent
1815 |=============================================================================
1817 |=============================================================================
1819 | double __divdf3(double, double);
1822 #ifndef __mcoldfire__
1829 movel a6@(8),d0 | get a into d0-d1
1831 movel a6@(16),d2 | and b into d2-d3
1833 movel d0,d7 | d7 will hold the sign of the result
1835 andl IMM (0x80000000),d7
1836 movel d7,a0 | save sign into a0
1837 movel IMM (0x7ff00000),d7 | useful constant (+INFINITY)
1838 movel d7,d6 | another (mask for fraction)
1840 bclr IMM (31),d0 | get rid of a's sign bit '
1843 beq Ldivdf$a$0 | branch if a is zero
1845 bclr IMM (31),d2 | get rid of b's sign bit '
1848 beq Ldivdf$b$0 | branch if b is zero
1850 cmpl d7,d0 | is a big?
1851 bhi Ldivdf$inop | if a is NaN return NaN
1852 beq Ldivdf$a$nf | if d0 == 0x7ff00000 we check d1
1853 cmpl d7,d2 | now compare b with INFINITY
1854 bhi Ldivdf$inop | if b is NaN return NaN
1855 beq Ldivdf$b$nf | if d2 == 0x7ff00000 we check d3
1856 | Here we have both numbers finite and nonzero (and with no sign bit).
1857 | Now we get the exponents into d4 and d5 and normalize the numbers to
1858 | ensure that the ratio of the fractions is around 1. We do this by
1859 | making sure that both numbers have bit #DBL_MANT_DIG-32-1 (hidden bit)
1860 | set, even if they were denormalized to start with.
1861 | Thus, the result will satisfy: 2 > result > 1/2.
1862 andl d7,d4 | and isolate exponent in d4
1863 beq Ldivdf$a$den | if exponent is zero we have a denormalized
1864 andl d6,d0 | and isolate fraction
1865 orl IMM (0x00100000),d0 | and put hidden bit back
1866 swap d4 | I like exponents in the first byte
1867 #ifndef __mcoldfire__
1876 orl IMM (0x00100000),d2
1878 #ifndef __mcoldfire__
1884 #ifndef __mcoldfire__
1885 subw d5,d4 | subtract exponents
1886 addw IMM (D_BIAS),d4 | and add bias
1888 subl d5,d4 | subtract exponents
1889 addl IMM (D_BIAS),d4 | and add bias
1892 | We are now ready to do the division. We have prepared things in such a way
1893 | that the ratio of the fractions will be less than 2 but greater than 1/2.
1894 | At this point the registers in use are:
1895 | d0-d1 hold a (first operand, bit DBL_MANT_DIG-32=0, bit
1896 | DBL_MANT_DIG-1-32=1)
1897 | d2-d3 hold b (second operand, bit DBL_MANT_DIG-32=1)
1898 | d4 holds the difference of the exponents, corrected by the bias
1899 | a0 holds the sign of the ratio
1901 | To do the rounding correctly we need to keep information about the
1902 | nonsignificant bits. One way to do this would be to do the division
1903 | using four registers; another is to use two registers (as originally
1904 | I did), but use a sticky bit to preserve information about the
1905 | fractional part. Note that we can keep that info in a1, which is not
1907 movel IMM (0),d6 | d6-d7 will hold the result
1909 movel IMM (0),a1 | and a1 will hold the sticky bit
1911 movel IMM (DBL_MANT_DIG-32+1),d5
1913 1: cmpl d0,d2 | is a < b?
1914 bhi 3f | if b > a skip the following
1915 beq 4f | if d0==d2 check d1 and d3
1917 subxl d2,d0 | a <-- a - b
1918 bset d5,d6 | set the corresponding bit in d6
1919 3: addl d1,d1 | shift a by 1
1921 #ifndef __mcoldfire__
1922 dbra d5,1b | and branch back
1928 4: cmpl d1,d3 | here d0==d2, so check d1 and d3
1929 bhi 3b | if d1 > d2 skip the subtraction
1930 bra 2b | else go do it
1932 | Here we have to start setting the bits in the second long.
1933 movel IMM (31),d5 | again d5 is counter
1935 1: cmpl d0,d2 | is a < b?
1936 bhi 3f | if b > a skip the following
1937 beq 4f | if d0==d2 check d1 and d3
1939 subxl d2,d0 | a <-- a - b
1940 bset d5,d7 | set the corresponding bit in d7
1941 3: addl d1,d1 | shift a by 1
1943 #ifndef __mcoldfire__
1944 dbra d5,1b | and branch back
1950 4: cmpl d1,d3 | here d0==d2, so check d1 and d3
1951 bhi 3b | if d1 > d2 skip the subtraction
1952 bra 2b | else go do it
1954 | Now go ahead checking until we hit a one, which we store in d2.
1955 movel IMM (DBL_MANT_DIG),d5
1956 1: cmpl d2,d0 | is a < b?
1957 bhi 4f | if b < a, exit
1958 beq 3f | if d0==d2 check d1 and d3
1959 2: addl d1,d1 | shift a by 1
1961 #ifndef __mcoldfire__
1962 dbra d5,1b | and branch back
1967 movel IMM (0),d2 | here no sticky bit was found
1970 3: cmpl d1,d3 | here d0==d2, so check d1 and d3
1971 bhi 2b | if d1 > d2 go back
1973 | Here put the sticky bit in d2-d3 (in the position which actually corresponds
1974 | to it; if you don't do this the algorithm loses in some cases). '
1977 #ifndef __mcoldfire__
1978 subw IMM (DBL_MANT_DIG),d5
1982 subl IMM (DBL_MANT_DIG),d5
1989 #ifndef __mcoldfire__
1996 | Finally we are finished! Move the longs in the address registers to
1997 | their final destination:
2002 | Here we have finished the division, with the result in d0-d1-d2-d3, with
2003 | 2^21 <= d6 < 2^23. Thus bit 23 is not set, but bit 22 could be set.
2004 | If it is not, then definitely bit 21 is set. Normalize so bit 22 is
2006 btst IMM (DBL_MANT_DIG-32+1),d0
2008 #ifndef __mcoldfire__
2031 | Now round, check for over- and underflow, and exit.
2032 movel a0,d7 | restore sign bit to d7
2033 moveq IMM (DIVIDE),d5
2037 moveq IMM (DIVIDE),d5
2041 | If a is zero check to see whether b is zero also. In that case return
2042 | NaN; then check if b is NaN, and return NaN also in that case. Else
2043 | return a properly signed zero.
2044 moveq IMM (DIVIDE),d5
2048 beq Ld$inop | if b is also zero return NaN
2049 cmpl IMM (0x7ff00000),d2 | check for NaN
2054 1: movel a0,d0 | else return signed zero
2056 PICLEA SYM (_fpCCR),a0 | clear exception flags
2058 #ifndef __mcoldfire__
2062 | XXX if frame pointer is ever removed, stack pointer must
2069 moveq IMM (DIVIDE),d5
2070 | If we got here a is not zero. Check if a is NaN; in that case return NaN,
2071 | else return +/-INFINITY. Remember that a is in d0 with the sign bit
2073 movel a0,d7 | put a's sign bit back in d7 '
2074 cmpl IMM (0x7ff00000),d0 | compare d0 with INFINITY
2075 bhi Ld$inop | if larger it is NaN
2078 bra Ld$div$0 | else signal DIVIDE_BY_ZERO
2081 moveq IMM (DIVIDE),d5
2082 | If d2 == 0x7ff00000 we have to check d3.
2084 bne Ld$inop | if d3 <> 0, b is NaN
2085 bra Ld$underflow | else b is +/-INFINITY, so signal underflow
2088 moveq IMM (DIVIDE),d5
2089 | If d0 == 0x7ff00000 we have to check d1.
2091 bne Ld$inop | if d1 <> 0, a is NaN
2092 | If a is INFINITY we have to check b
2093 cmpl d7,d2 | compare b with INFINITY
2094 bge Ld$inop | if b is NaN or INFINITY return NaN
2095 movl a0,d7 | restore sign bit to d7
2096 bra Ld$overflow | else return overflow
2098 | If a number is denormalized we put an exponent of 1 but do not put the
2099 | bit back into the fraction.
2103 1: addl d1,d1 | shift a left until bit 20 is set
2105 #ifndef __mcoldfire__
2106 subw IMM (1),d4 | and adjust exponent
2108 subl IMM (1),d4 | and adjust exponent
2110 btst IMM (DBL_MANT_DIG-32-1),d0
2117 1: addl d3,d3 | shift b left until bit 20 is set
2119 #ifndef __mcoldfire__
2120 subw IMM (1),d5 | and adjust exponent
2122 subql IMM (1),d5 | and adjust exponent
2124 btst IMM (DBL_MANT_DIG-32-1),d2
2129 | This is a common exit point for __muldf3 and __divdf3. When they enter
2130 | this point the sign of the result is in d7, the result in d0-d1, normalized
2131 | so that 2^21 <= d0 < 2^22, and the exponent is in the lower byte of d4.
2133 | First check for underlow in the exponent:
2134 #ifndef __mcoldfire__
2135 cmpw IMM (-DBL_MANT_DIG-1),d4
2137 cmpl IMM (-DBL_MANT_DIG-1),d4
2140 | It could happen that the exponent is less than 1, in which case the
2141 | number is denormalized. In this case we shift right and adjust the
2142 | exponent until it becomes 1 or the fraction is zero (in the latter case
2143 | we signal underflow and return zero).
2145 movel IMM (0),d6 | use d6-d7 to collect bits flushed right
2146 movel d6,d7 | use d6-d7 to collect bits flushed right
2147 #ifndef __mcoldfire__
2148 cmpw IMM (1),d4 | if the exponent is less than 1 we
2150 cmpl IMM (1),d4 | if the exponent is less than 1 we
2152 bge 2f | have to shift right (denormalize)
2154 #ifndef __mcoldfire__
2155 addw IMM (1),d4 | adjust the exponent
2156 lsrl IMM (1),d0 | shift right once
2162 cmpw IMM (1),d4 | is the exponent 1 already?
2164 addl IMM (1),d4 | adjust the exponent
2186 cmpl IMM (1),d4 | is the exponent 1 already?
2188 beq 2f | if not loop back
2190 bra Ld$underflow | safety check, shouldn't execute '
2191 2: orl d6,d2 | this is a trick so we don't lose '
2192 orl d7,d3 | the bits which were flushed right
2193 movel a0,d7 | get back sign bit into d7
2194 | Now call the rounding routine (which takes care of denormalized numbers):
2195 lea pc@(Lround$0),a0 | to return from rounding routine
2196 PICLEA SYM (_fpCCR),a1 | check the rounding mode
2197 #ifdef __mcoldfire__
2200 movew a1@(6),d6 | rounding mode in d6
2201 beq Lround$to$nearest
2202 #ifndef __mcoldfire__
2203 cmpw IMM (ROUND_TO_PLUS),d6
2205 cmpl IMM (ROUND_TO_PLUS),d6
2211 | Here we have a correctly rounded result (either normalized or denormalized).
2213 | Here we should have either a normalized number or a denormalized one, and
2214 | the exponent is necessarily larger or equal to 1 (so we don't have to '
2215 | check again for underflow!). We have to check for overflow or for a
2216 | denormalized number (which also signals underflow).
2217 | Check for overflow (i.e., exponent >= 0x7ff).
2218 #ifndef __mcoldfire__
2219 cmpw IMM (0x07ff),d4
2221 cmpl IMM (0x07ff),d4
2224 | Now check for a denormalized number (exponent==0):
2228 | Put back the exponents and sign and return.
2229 #ifndef __mcoldfire__
2230 lslw IMM (4),d4 | exponent back to fourth byte
2232 lsll IMM (4),d4 | exponent back to fourth byte
2234 bclr IMM (DBL_MANT_DIG-32-1),d0
2235 swap d0 | and put back exponent
2236 #ifndef __mcoldfire__
2242 orl d7,d0 | and sign also
2244 PICLEA SYM (_fpCCR),a0
2246 #ifndef __mcoldfire__
2250 | XXX if frame pointer is ever removed, stack pointer must
2256 |=============================================================================
2258 |=============================================================================
2260 | double __negdf2(double, double);
2263 #ifndef __mcoldfire__
2270 moveq IMM (NEGATE),d5
2271 movel a6@(8),d0 | get number to negate in d0-d1
2273 bchg IMM (31),d0 | negate
2274 movel d0,d2 | make a positive copy (for the tests)
2276 movel d2,d4 | check for zero
2278 beq 2f | if zero (either sign) return +zero
2279 cmpl IMM (0x7ff00000),d2 | compare to +INFINITY
2280 blt 1f | if finite, return
2281 bhi Ld$inop | if larger (fraction not zero) is NaN
2282 tstl d1 | if d2 == 0x7ff00000 check d1
2284 movel d0,d7 | else get sign and return INFINITY
2285 andl IMM (0x80000000),d7
2287 1: PICLEA SYM (_fpCCR),a0
2289 #ifndef __mcoldfire__
2293 | XXX if frame pointer is ever removed, stack pointer must
2301 |=============================================================================
2303 |=============================================================================
2309 | int __cmpdf2_internal(double, double, int);
2310 SYM (__cmpdf2_internal):
2311 #ifndef __mcoldfire__
2313 moveml d2-d7,sp@- | save registers
2318 moveq IMM (COMPARE),d5
2319 movel a6@(8),d0 | get first operand
2321 movel a6@(16),d2 | get second operand
2323 | First check if a and/or b are (+/-) zero and in that case clear
2325 movel d0,d6 | copy signs into d6 (a) and d7(b)
2326 bclr IMM (31),d0 | and clear signs in d0 and d2
2329 cmpl IMM (0x7ff00000),d0 | check for a == NaN
2330 bhi Lcmpd$inop | if d0 > 0x7ff00000, a is NaN
2331 beq Lcmpdf$a$nf | if equal can be INFINITY, so check d1
2332 movel d0,d4 | copy into d4 to test for zero
2336 cmpl IMM (0x7ff00000),d2 | check for b == NaN
2337 bhi Lcmpd$inop | if d2 > 0x7ff00000, b is NaN
2338 beq Lcmpdf$b$nf | if equal can be INFINITY, so check d3
2346 | If the signs are not equal check if a >= 0
2348 bpl Lcmpdf$a$gt$b | if (a >= 0 && b < 0) => a > b
2349 bmi Lcmpdf$b$gt$a | if (a < 0 && b >= 0) => a < b
2351 | If the signs are equal check for < 0
2354 | If both are negative exchange them
2355 #ifndef __mcoldfire__
2367 | Now that they are positive we just compare them as longs (does this also
2368 | work for denormalized numbers?).
2370 bhi Lcmpdf$b$gt$a | |b| > |a|
2371 bne Lcmpdf$a$gt$b | |b| < |a|
2372 | If we got here d0 == d2, so we compare d1 and d3.
2374 bhi Lcmpdf$b$gt$a | |b| > |a|
2375 bne Lcmpdf$a$gt$b | |b| < |a|
2376 | If we got here a == b.
2377 movel IMM (EQUAL),d0
2378 #ifndef __mcoldfire__
2379 moveml sp@+,d2-d7 | put back the registers
2382 | XXX if frame pointer is ever removed, stack pointer must
2388 movel IMM (GREATER),d0
2389 #ifndef __mcoldfire__
2390 moveml sp@+,d2-d7 | put back the registers
2393 | XXX if frame pointer is ever removed, stack pointer must
2400 #ifndef __mcoldfire__
2401 moveml sp@+,d2-d7 | put back the registers
2404 | XXX if frame pointer is ever removed, stack pointer must
2429 moveq IMM (INEXACT_RESULT+INVALID_OPERATION),d7
2430 moveq IMM (DOUBLE_FLOAT),d6
2431 PICJUMP $_exception_handler
2433 | int __cmpdf2(double, double);
2442 PICCALL SYM (__cmpdf2_internal)
2446 |=============================================================================
2448 |=============================================================================
2450 | The rounding routines expect the number to be normalized in registers
2451 | d0-d1-d2-d3, with the exponent in register d4. They assume that the
2452 | exponent is larger or equal to 1. They return a properly normalized number
2453 | if possible, and a denormalized number otherwise. The exponent is returned
2457 | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
2458 | Here we assume that the exponent is not too small (this should be checked
2459 | before entering the rounding routine), but the number could be denormalized.
2461 | Check for denormalized numbers:
2462 1: btst IMM (DBL_MANT_DIG-32),d0
2463 bne 2f | if set the number is normalized
2464 | Normalize shifting left until bit #DBL_MANT_DIG-32 is set or the exponent
2465 | is one (remember that a denormalized number corresponds to an
2466 | exponent of -D_BIAS+1).
2467 #ifndef __mcoldfire__
2468 cmpw IMM (1),d4 | remember that the exponent is at least one
2470 cmpl IMM (1),d4 | remember that the exponent is at least one
2472 beq 2f | an exponent of one means denormalized
2473 addl d3,d3 | else shift and adjust the exponent
2477 #ifndef __mcoldfire__
2484 | Now round: we do it as follows: after the shifting we can write the
2485 | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
2486 | If delta < 1, do nothing. If delta > 1, add 1 to f.
2487 | If delta == 1, we make sure the rounded number will be even (odd?)
2489 btst IMM (0),d1 | is delta < 1?
2490 beq 2f | if so, do not do anything
2491 orl d2,d3 | is delta == 1?
2492 bne 1f | if so round to even
2494 andl IMM (2),d3 | bit 1 is the last significant bit
2499 1: movel IMM (1),d3 | else add 1
2503 | Shift right once (because we used bit #DBL_MANT_DIG-32!).
2505 #ifndef __mcoldfire__
2516 | Now check again bit #DBL_MANT_DIG-32 (rounding could have produced a
2517 | 'fraction overflow' ...).
2518 btst IMM (DBL_MANT_DIG-32),d0
2520 #ifndef __mcoldfire__
2533 | If bit #DBL_MANT_DIG-32-1 is clear we have a denormalized number, so we
2534 | have to put the exponent to zero and return a denormalized number.
2535 btst IMM (DBL_MANT_DIG-32-1),d0
2545 #endif /* L_double */
2550 .globl $_exception_handler
2552 QUIET_NaN = 0xffffffff
2553 SIGNL_NaN = 0x7f800001
2554 INFINITY = 0x7f800000
2558 FLT_MAX_EXP = F_MAX_EXP - F_BIAS
2559 FLT_MIN_EXP = 1 - F_BIAS
2562 INEXACT_RESULT = 0x0001
2565 DIVIDE_BY_ZERO = 0x0008
2566 INVALID_OPERATION = 0x0010
2580 ROUND_TO_NEAREST = 0 | round result to nearest representable value
2581 ROUND_TO_ZERO = 1 | round result towards zero
2582 ROUND_TO_PLUS = 2 | round result towards plus infinity
2583 ROUND_TO_MINUS = 3 | round result towards minus infinity
2587 .globl SYM (__addsf3)
2588 .globl SYM (__subsf3)
2589 .globl SYM (__mulsf3)
2590 .globl SYM (__divsf3)
2591 .globl SYM (__negsf2)
2592 .globl SYM (__cmpsf2)
2593 .globl SYM (__cmpsf2_internal)
2594 .hidden SYM (__cmpsf2_internal)
2596 | These are common routines to return and signal exceptions.
2602 | Return and signal a denormalized number
2604 moveq IMM (INEXACT_RESULT+UNDERFLOW),d7
2605 moveq IMM (SINGLE_FLOAT),d6
2606 PICJUMP $_exception_handler
2610 | Return a properly signed INFINITY and set the exception flags
2611 movel IMM (INFINITY),d0
2613 moveq IMM (INEXACT_RESULT+OVERFLOW),d7
2614 moveq IMM (SINGLE_FLOAT),d6
2615 PICJUMP $_exception_handler
2618 | Return 0 and set the exception flags
2620 moveq IMM (INEXACT_RESULT+UNDERFLOW),d7
2621 moveq IMM (SINGLE_FLOAT),d6
2622 PICJUMP $_exception_handler
2625 | Return a quiet NaN and set the exception flags
2626 movel IMM (QUIET_NaN),d0
2627 moveq IMM (INEXACT_RESULT+INVALID_OPERATION),d7
2628 moveq IMM (SINGLE_FLOAT),d6
2629 PICJUMP $_exception_handler
2632 | Return a properly signed INFINITY and set the exception flags
2633 movel IMM (INFINITY),d0
2635 moveq IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7
2636 moveq IMM (SINGLE_FLOAT),d6
2637 PICJUMP $_exception_handler
2639 |=============================================================================
2640 |=============================================================================
2641 | single precision routines
2642 |=============================================================================
2643 |=============================================================================
2645 | A single precision floating point number (float) has the format:
2648 | unsigned int sign : 1; /* sign bit */
2649 | unsigned int exponent : 8; /* exponent, shifted by 126 */
2650 | unsigned int fraction : 23; /* fraction */
2653 | Thus sizeof(float) = 4 (32 bits).
2655 | All the routines are callable from C programs, and return the result
2656 | in the single register d0. They also preserve all registers except
2659 |=============================================================================
2661 |=============================================================================
2663 | float __subsf3(float, float);
2666 bchg IMM (31),sp@(8) | change sign of second operand
2668 |=============================================================================
2670 |=============================================================================
2672 | float __addsf3(float, float);
2675 #ifndef __mcoldfire__
2676 link a6,IMM (0) | everything will be done in registers
2677 moveml d2-d7,sp@- | save all data registers but d0-d1
2682 movel a6@(8),d0 | get first operand
2683 movel a6@(12),d1 | get second operand
2684 movel d0,a0 | get d0's sign bit '
2685 addl d0,d0 | check and clear sign bit of a
2686 beq Laddsf$b | if zero return second operand
2687 movel d1,a1 | save b's sign bit '
2688 addl d1,d1 | get rid of sign bit
2689 beq Laddsf$a | if zero return first operand
2691 | Get the exponents and check for denormalized and/or infinity.
2693 movel IMM (0x00ffffff),d4 | mask to get fraction
2694 movel IMM (0x01000000),d5 | mask to put hidden bit back
2696 movel d0,d6 | save a to get exponent
2697 andl d4,d0 | get fraction in d0
2698 notl d4 | make d4 into a mask for the exponent
2699 andl d4,d6 | get exponent in d6
2700 beq Laddsf$a$den | branch if a is denormalized
2701 cmpl d4,d6 | check for INFINITY or NaN
2703 swap d6 | put exponent into first word
2704 orl d5,d0 | and put hidden bit back
2706 | Now we have a's exponent in d6 (second byte) and the mantissa in d0. '
2707 movel d1,d7 | get exponent in d7
2709 beq Laddsf$b$den | branch if b is denormalized
2710 cmpl d4,d7 | check for INFINITY or NaN
2712 swap d7 | put exponent into first word
2713 notl d4 | make d4 into a mask for the fraction
2714 andl d4,d1 | get fraction in d1
2715 orl d5,d1 | and put hidden bit back
2717 | Now we have b's exponent in d7 (second byte) and the mantissa in d1. '
2719 | Note that the hidden bit corresponds to bit #FLT_MANT_DIG-1, and we
2720 | shifted right once, so bit #FLT_MANT_DIG is set (so we have one extra
2723 movel d1,d2 | move b to d2, since we want to use
2724 | two registers to do the sum
2725 movel IMM (0),d1 | and clear the new ones
2728 | Here we shift the numbers in registers d0 and d1 so the exponents are the
2729 | same, and put the largest exponent in d6. Note that we are using two
2730 | registers for each number (see the discussion by D. Knuth in "Seminumerical
2732 #ifndef __mcoldfire__
2733 cmpw d6,d7 | compare exponents
2735 cmpl d6,d7 | compare exponents
2737 beq Laddsf$3 | if equal don't shift '
2738 bhi 5f | branch if second exponent largest
2740 subl d6,d7 | keep the largest exponent
2742 #ifndef __mcoldfire__
2743 lsrw IMM (8),d7 | put difference in lower byte
2745 lsrl IMM (8),d7 | put difference in lower byte
2747 | if difference is too large we don't shift (actually, we can just exit) '
2748 #ifndef __mcoldfire__
2749 cmpw IMM (FLT_MANT_DIG+2),d7
2751 cmpl IMM (FLT_MANT_DIG+2),d7
2754 #ifndef __mcoldfire__
2755 cmpw IMM (16),d7 | if difference >= 16 swap
2757 cmpl IMM (16),d7 | if difference >= 16 swap
2761 #ifndef __mcoldfire__
2767 #ifndef __mcoldfire__
2768 lsrl IMM (1),d2 | shift right second operand
2786 #ifndef __mcoldfire__
2791 bne 2b | if still more bits, go back to normal case
2794 #ifndef __mcoldfire__
2795 exg d6,d7 | exchange the exponents
2801 subl d6,d7 | keep the largest exponent
2803 #ifndef __mcoldfire__
2804 lsrw IMM (8),d7 | put difference in lower byte
2806 lsrl IMM (8),d7 | put difference in lower byte
2808 | if difference is too large we don't shift (and exit!) '
2809 #ifndef __mcoldfire__
2810 cmpw IMM (FLT_MANT_DIG+2),d7
2812 cmpl IMM (FLT_MANT_DIG+2),d7
2815 #ifndef __mcoldfire__
2816 cmpw IMM (16),d7 | if difference >= 16 swap
2818 cmpl IMM (16),d7 | if difference >= 16 swap
2822 #ifndef __mcoldfire__
2828 #ifndef __mcoldfire__
2829 lsrl IMM (1),d0 | shift right first operand
2847 #ifndef __mcoldfire__
2852 bne 6b | if still more bits, go back to normal case
2853 | otherwise we fall through
2855 | Now we have a in d0-d1, b in d2-d3, and the largest exponent in d6 (the
2856 | signs are stored in a0 and a1).
2859 | Here we have to decide whether to add or subtract the numbers
2860 #ifndef __mcoldfire__
2861 exg d6,a0 | get signs back
2862 exg d7,a1 | and save the exponents
2871 eorl d6,d7 | combine sign bits
2872 bmi Lsubsf$0 | if negative a and b have opposite
2873 | sign so we actually subtract the
2876 | Here we have both positive or both negative
2877 #ifndef __mcoldfire__
2878 exg d6,a0 | now we have the exponent in d6
2884 movel a0,d7 | and sign in d7
2885 andl IMM (0x80000000),d7
2886 | Here we do the addition.
2889 | Note: now we have d2, d3, d4 and d5 to play with!
2891 | Put the exponent, in the first byte, in d2, to use the "standard" rounding
2894 #ifndef __mcoldfire__
2900 | Before rounding normalize so bit #FLT_MANT_DIG is set (we will consider
2901 | the case of denormalized numbers in the rounding routine itself).
2902 | As in the addition (not in the subtraction!) we could have set
2903 | one more bit we check this:
2904 btst IMM (FLT_MANT_DIG+1),d0
2906 #ifndef __mcoldfire__
2918 lea pc@(Laddsf$4),a0 | to return from rounding routine
2919 PICLEA SYM (_fpCCR),a1 | check the rounding mode
2920 #ifdef __mcoldfire__
2923 movew a1@(6),d6 | rounding mode in d6
2924 beq Lround$to$nearest
2925 #ifndef __mcoldfire__
2926 cmpw IMM (ROUND_TO_PLUS),d6
2928 cmpl IMM (ROUND_TO_PLUS),d6
2934 | Put back the exponent, but check for overflow.
2935 #ifndef __mcoldfire__
2941 bclr IMM (FLT_MANT_DIG-1),d0
2942 #ifndef __mcoldfire__
2955 | We are here if a > 0 and b < 0 (sign bits cleared).
2956 | Here we do the subtraction.
2957 movel d6,d7 | put sign in d7
2958 andl IMM (0x80000000),d7
2960 subl d3,d1 | result in d0-d1
2962 beq Laddsf$ret | if zero just exit
2963 bpl 1f | if positive skip the following
2964 bchg IMM (31),d7 | change sign bit in d7
2968 #ifndef __mcoldfire__
2969 exg d2,a0 | now we have the exponent in d2
2970 lsrw IMM (8),d2 | put it in the first byte
2975 lsrl IMM (8),d2 | put it in the first byte
2978 | Now d0-d1 is positive and the sign bit is in d7.
2980 | Note that we do not have to normalize, since in the subtraction bit
2981 | #FLT_MANT_DIG+1 is never set, and denormalized numbers are handled by
2982 | the rounding routines themselves.
2983 lea pc@(Lsubsf$1),a0 | to return from rounding routine
2984 PICLEA SYM (_fpCCR),a1 | check the rounding mode
2985 #ifdef __mcoldfire__
2988 movew a1@(6),d6 | rounding mode in d6
2989 beq Lround$to$nearest
2990 #ifndef __mcoldfire__
2991 cmpw IMM (ROUND_TO_PLUS),d6
2993 cmpl IMM (ROUND_TO_PLUS),d6
2999 | Put back the exponent (we can't have overflow!). '
3000 bclr IMM (FLT_MANT_DIG-1),d0
3001 #ifndef __mcoldfire__
3010 | If one of the numbers was too small (difference of exponents >=
3011 | FLT_MANT_DIG+2) we return the other (and now we don't have to '
3012 | check for finiteness or zero).
3015 PICLEA SYM (_fpCCR),a0
3017 #ifndef __mcoldfire__
3018 moveml sp@+,d2-d7 | restore data registers
3021 | XXX if frame pointer is ever removed, stack pointer must
3024 unlk a6 | and return
3029 PICLEA SYM (_fpCCR),a0
3031 #ifndef __mcoldfire__
3032 moveml sp@+,d2-d7 | restore data registers
3035 | XXX if frame pointer is ever removed, stack pointer must
3038 unlk a6 | and return
3041 | If the numbers are denormalized remember to put exponent equal to 1.
3044 movel d5,d6 | d5 contains 0x01000000
3051 notl d4 | make d4 into a mask for the fraction
3052 | (this was not executed after the jump)
3055 | The rest is mainly code for the different results which can be
3056 | returned (checking always for +/-INFINITY and NaN).
3059 | Return b (if a is zero).
3061 cmpl IMM (0x80000000),d0 | Check if b is -0
3064 andl IMM (0x80000000),d7 | Use the sign of a
3068 | Return a (if b is zero).
3072 | We have to check for NaN and +/-infty.
3074 andl IMM (0x80000000),d7 | put sign in d7
3075 bclr IMM (31),d0 | clear sign
3076 cmpl IMM (INFINITY),d0 | check for infty or NaN
3078 movel d0,d0 | check for zero (we do this because we don't '
3079 bne Laddsf$ret | want to return -0 by mistake
3080 bclr IMM (31),d7 | if zero be sure to clear sign
3081 bra Laddsf$ret | if everything OK just return
3083 | The value to be returned is either +/-infty or NaN
3084 andl IMM (0x007fffff),d0 | check for NaN
3085 bne Lf$inop | if mantissa not zero is NaN
3089 | Normal exit (a and b nonzero, result is not NaN nor +/-infty).
3090 | We have to clear the exception flags (just the exception type).
3091 PICLEA SYM (_fpCCR),a0
3093 orl d7,d0 | put sign bit
3094 #ifndef __mcoldfire__
3095 moveml sp@+,d2-d7 | restore data registers
3098 | XXX if frame pointer is ever removed, stack pointer must
3101 unlk a6 | and return
3105 | Return a denormalized number (for addition we don't signal underflow) '
3106 lsrl IMM (1),d0 | remember to shift right back once
3107 bra Laddsf$ret | and return
3109 | Note: when adding two floats of the same sign if either one is
3110 | NaN we return NaN without regard to whether the other is finite or
3111 | not. When subtracting them (i.e., when adding two numbers of
3112 | opposite signs) things are more complicated: if both are INFINITY
3113 | we return NaN, if only one is INFINITY and the other is NaN we return
3114 | NaN, but if it is finite we return INFINITY with the corresponding sign.
3118 | This could be faster but it is not worth the effort, since it is not
3119 | executed very often. We sacrifice speed for clarity here.
3120 movel a6@(8),d0 | get the numbers back (remember that we
3121 movel a6@(12),d1 | did some processing already)
3122 movel IMM (INFINITY),d4 | useful constant (INFINITY)
3123 movel d0,d2 | save sign bits
3124 movel d0,d7 | into d7 as well as we may need the sign
3125 | bit before jumping to LfSinfty
3127 bclr IMM (31),d0 | clear sign bits
3129 | We know that one of them is either NaN of +/-INFINITY
3130 | Check for NaN (if either one is NaN return NaN)
3131 cmpl d4,d0 | check first a (d0)
3133 cmpl d4,d1 | check now b (d1)
3135 | Now comes the check for +/-INFINITY. We know that both are (maybe not
3136 | finite) numbers, but we have to check if both are infinite whether we
3137 | are adding or subtracting them.
3138 eorl d3,d2 | to check sign bits
3140 andl IMM (0x80000000),d7 | get (common) sign bit
3143 | We know one (or both) are infinite, so we test for equality between the
3144 | two numbers (if they are equal they have to be infinite both, so we
3146 cmpl d1,d0 | are both infinite?
3147 beq Lf$inop | if so return NaN
3149 andl IMM (0x80000000),d7 | get a's sign bit '
3150 cmpl d4,d0 | test now for infinity
3151 beq Lf$infty | if a is INFINITY return with this sign
3152 bchg IMM (31),d7 | else we know b is INFINITY and has
3153 bra Lf$infty | the opposite sign
3155 |=============================================================================
3157 |=============================================================================
3159 | float __mulsf3(float, float);
3162 #ifndef __mcoldfire__
3169 movel a6@(8),d0 | get a into d0
3170 movel a6@(12),d1 | and b into d1
3171 movel d0,d7 | d7 will hold the sign of the product
3173 andl IMM (0x80000000),d7
3174 movel IMM (INFINITY),d6 | useful constant (+INFINITY)
3175 movel d6,d5 | another (mask for fraction)
3177 movel IMM (0x00800000),d4 | this is to put hidden bit back
3178 bclr IMM (31),d0 | get rid of a's sign bit '
3180 beq Lmulsf$a$0 | branch if a is zero
3181 bclr IMM (31),d1 | get rid of b's sign bit '
3183 beq Lmulsf$b$0 | branch if b is zero
3184 cmpl d6,d0 | is a big?
3185 bhi Lmulsf$inop | if a is NaN return NaN
3186 beq Lmulsf$inf | if a is INFINITY we have to check b
3187 cmpl d6,d1 | now compare b with INFINITY
3188 bhi Lmulsf$inop | is b NaN?
3189 beq Lmulsf$overflow | is b INFINITY?
3190 | Here we have both numbers finite and nonzero (and with no sign bit).
3191 | Now we get the exponents into d2 and d3.
3192 andl d6,d2 | and isolate exponent in d2
3193 beq Lmulsf$a$den | if exponent is zero we have a denormalized
3194 andl d5,d0 | and isolate fraction
3195 orl d4,d0 | and put hidden bit back
3196 swap d2 | I like exponents in the first byte
3197 #ifndef __mcoldfire__
3208 #ifndef __mcoldfire__
3214 #ifndef __mcoldfire__
3215 addw d3,d2 | add exponents
3216 subw IMM (F_BIAS+1),d2 | and subtract bias (plus one)
3218 addl d3,d2 | add exponents
3219 subl IMM (F_BIAS+1),d2 | and subtract bias (plus one)
3222 | We are now ready to do the multiplication. The situation is as follows:
3223 | both a and b have bit FLT_MANT_DIG-1 set (even if they were
3224 | denormalized to start with!), which means that in the product
3225 | bit 2*(FLT_MANT_DIG-1) (that is, bit 2*FLT_MANT_DIG-2-32 of the
3226 | high long) is set.
3228 | To do the multiplication let us move the number a little bit around ...
3229 movel d1,d6 | second operand in d6
3230 movel d0,d5 | first operand in d4-d5
3232 movel d4,d1 | the sums will go in d0-d1
3235 | now bit FLT_MANT_DIG-1 becomes bit 31:
3236 lsll IMM (31-FLT_MANT_DIG+1),d6
3238 | Start the loop (we loop #FLT_MANT_DIG times):
3239 moveq IMM (FLT_MANT_DIG-1),d3
3240 1: addl d1,d1 | shift sum
3242 lsll IMM (1),d6 | get bit bn
3243 bcc 2f | if not set skip sum
3247 #ifndef __mcoldfire__
3248 dbf d3,1b | loop back
3254 | Now we have the product in d0-d1, with bit (FLT_MANT_DIG - 1) + FLT_MANT_DIG
3255 | (mod 32) of d0 set. The first thing to do now is to normalize it so bit
3256 | FLT_MANT_DIG is set (to do the rounding).
3257 #ifndef __mcoldfire__
3261 andw IMM (0x03ff),d3
3262 andw IMM (0xfd00),d1
3271 andl IMM (0xfffffd00),d1
3276 #ifndef __mcoldfire__
3282 moveq IMM (MULTIPLY),d5
3284 btst IMM (FLT_MANT_DIG+1),d0
3286 #ifndef __mcoldfire__
3301 moveq IMM (MULTIPLY),d5
3305 moveq IMM (MULTIPLY),d5
3309 moveq IMM (MULTIPLY),d5
3310 | If either is NaN return NaN; else both are (maybe infinite) numbers, so
3311 | return INFINITY with the correct sign (which is in d7).
3312 cmpl d6,d1 | is b NaN?
3313 bhi Lf$inop | if so return NaN
3314 bra Lf$overflow | else return +/-INFINITY
3316 | If either number is zero return zero, unless the other is +/-INFINITY,
3317 | or NaN, in which case we return NaN.
3319 | Here d1 (==b) is zero.
3320 movel a6@(8),d1 | get a again to check for non-finiteness
3323 movel a6@(12),d1 | get b again to check for non-finiteness
3324 1: bclr IMM (31),d1 | clear sign bit
3325 cmpl IMM (INFINITY),d1 | and check for a large exponent
3326 bge Lf$inop | if b is +/-INFINITY or NaN return NaN
3327 movel d7,d0 | else return signed zero
3328 PICLEA SYM (_fpCCR),a0 |
3330 #ifndef __mcoldfire__
3334 | XXX if frame pointer is ever removed, stack pointer must
3340 | If a number is denormalized we put an exponent of 1 but do not put the
3341 | hidden bit back into the fraction; instead we shift left until bit 23
3342 | (the hidden bit) is set, adjusting the exponent accordingly. We do this
3343 | to ensure that the product of the fractions is close to 1.
3347 1: addl d0,d0 | shift a left (until bit 23 is set)
3348 #ifndef __mcoldfire__
3349 subw IMM (1),d2 | and adjust exponent
3351 subql IMM (1),d2 | and adjust exponent
3353 btst IMM (FLT_MANT_DIG-1),d0
3355 bra 1b | else loop back
3360 1: addl d1,d1 | shift b left until bit 23 is set
3361 #ifndef __mcoldfire__
3362 subw IMM (1),d3 | and adjust exponent
3364 subql IMM (1),d3 | and adjust exponent
3366 btst IMM (FLT_MANT_DIG-1),d1
3368 bra 1b | else loop back
3370 |=============================================================================
3372 |=============================================================================
3374 | float __divsf3(float, float);
3377 #ifndef __mcoldfire__
3384 movel a6@(8),d0 | get a into d0
3385 movel a6@(12),d1 | and b into d1
3386 movel d0,d7 | d7 will hold the sign of the result
3388 andl IMM (0x80000000),d7 |
3389 movel IMM (INFINITY),d6 | useful constant (+INFINITY)
3390 movel d6,d5 | another (mask for fraction)
3392 movel IMM (0x00800000),d4 | this is to put hidden bit back
3393 bclr IMM (31),d0 | get rid of a's sign bit '
3395 beq Ldivsf$a$0 | branch if a is zero
3396 bclr IMM (31),d1 | get rid of b's sign bit '
3398 beq Ldivsf$b$0 | branch if b is zero
3399 cmpl d6,d0 | is a big?
3400 bhi Ldivsf$inop | if a is NaN return NaN
3401 beq Ldivsf$inf | if a is INFINITY we have to check b
3402 cmpl d6,d1 | now compare b with INFINITY
3403 bhi Ldivsf$inop | if b is NaN return NaN
3404 beq Ldivsf$underflow
3405 | Here we have both numbers finite and nonzero (and with no sign bit).
3406 | Now we get the exponents into d2 and d3 and normalize the numbers to
3407 | ensure that the ratio of the fractions is close to 1. We do this by
3408 | making sure that bit #FLT_MANT_DIG-1 (hidden bit) is set.
3409 andl d6,d2 | and isolate exponent in d2
3410 beq Ldivsf$a$den | if exponent is zero we have a denormalized
3411 andl d5,d0 | and isolate fraction
3412 orl d4,d0 | and put hidden bit back
3413 swap d2 | I like exponents in the first byte
3414 #ifndef __mcoldfire__
3425 #ifndef __mcoldfire__
3431 #ifndef __mcoldfire__
3432 subw d3,d2 | subtract exponents
3433 addw IMM (F_BIAS),d2 | and add bias
3435 subl d3,d2 | subtract exponents
3436 addl IMM (F_BIAS),d2 | and add bias
3439 | We are now ready to do the division. We have prepared things in such a way
3440 | that the ratio of the fractions will be less than 2 but greater than 1/2.
3441 | At this point the registers in use are:
3442 | d0 holds a (first operand, bit FLT_MANT_DIG=0, bit FLT_MANT_DIG-1=1)
3443 | d1 holds b (second operand, bit FLT_MANT_DIG=1)
3444 | d2 holds the difference of the exponents, corrected by the bias
3445 | d7 holds the sign of the ratio
3446 | d4, d5, d6 hold some constants
3447 movel d7,a0 | d6-d7 will hold the ratio of the fractions
3451 moveq IMM (FLT_MANT_DIG+1),d3
3452 1: cmpl d0,d1 | is a < b?
3454 bset d3,d6 | set a bit in d6
3455 subl d1,d0 | if a >= b a <-- a-b
3456 beq 3f | if a is zero, exit
3457 2: addl d0,d0 | multiply a by 2
3458 #ifndef __mcoldfire__
3465 | Now we keep going to set the sticky bit ...
3466 moveq IMM (FLT_MANT_DIG),d3
3470 #ifndef __mcoldfire__
3479 #ifndef __mcoldfire__
3480 subw IMM (FLT_MANT_DIG),d3
3483 subl IMM (FLT_MANT_DIG),d3
3488 movel d6,d0 | put the ratio in d0-d1
3489 movel a0,d7 | get sign back
3491 | Because of the normalization we did before we are guaranteed that
3492 | d0 is smaller than 2^26 but larger than 2^24. Thus bit 26 is not set,
3493 | bit 25 could be set, and if it is not set then bit 24 is necessarily set.
3494 btst IMM (FLT_MANT_DIG+1),d0
3495 beq 1f | if it is not set, then bit 24 is set
3497 #ifndef __mcoldfire__
3503 | Now round, check for over- and underflow, and exit.
3504 moveq IMM (DIVIDE),d5
3508 moveq IMM (DIVIDE),d5
3512 moveq IMM (DIVIDE),d5
3516 moveq IMM (DIVIDE),d5
3520 moveq IMM (DIVIDE),d5
3521 | If a is zero check to see whether b is zero also. In that case return
3522 | NaN; then check if b is NaN, and return NaN also in that case. Else
3523 | return a properly signed zero.
3524 andl IMM (0x7fffffff),d1 | clear sign bit and test b
3525 beq Lf$inop | if b is also zero return NaN
3526 cmpl IMM (INFINITY),d1 | check for NaN
3528 movel d7,d0 | else return signed zero
3529 PICLEA SYM (_fpCCR),a0 |
3531 #ifndef __mcoldfire__
3535 | XXX if frame pointer is ever removed, stack pointer must
3542 moveq IMM (DIVIDE),d5
3543 | If we got here a is not zero. Check if a is NaN; in that case return NaN,
3544 | else return +/-INFINITY. Remember that a is in d0 with the sign bit
3546 cmpl IMM (INFINITY),d0 | compare d0 with INFINITY
3547 bhi Lf$inop | if larger it is NaN
3548 bra Lf$div$0 | else signal DIVIDE_BY_ZERO
3551 moveq IMM (DIVIDE),d5
3552 | If a is INFINITY we have to check b
3553 cmpl IMM (INFINITY),d1 | compare b with INFINITY
3554 bge Lf$inop | if b is NaN or INFINITY return NaN
3555 bra Lf$overflow | else return overflow
3557 | If a number is denormalized we put an exponent of 1 but do not put the
3558 | bit back into the fraction.
3562 1: addl d0,d0 | shift a left until bit FLT_MANT_DIG-1 is set
3563 #ifndef __mcoldfire__
3564 subw IMM (1),d2 | and adjust exponent
3566 subl IMM (1),d2 | and adjust exponent
3568 btst IMM (FLT_MANT_DIG-1),d0
3575 1: addl d1,d1 | shift b left until bit FLT_MANT_DIG is set
3576 #ifndef __mcoldfire__
3577 subw IMM (1),d3 | and adjust exponent
3579 subl IMM (1),d3 | and adjust exponent
3581 btst IMM (FLT_MANT_DIG-1),d1
3586 | This is a common exit point for __mulsf3 and __divsf3.
3588 | First check for underlow in the exponent:
3589 #ifndef __mcoldfire__
3590 cmpw IMM (-FLT_MANT_DIG-1),d2
3592 cmpl IMM (-FLT_MANT_DIG-1),d2
3595 | It could happen that the exponent is less than 1, in which case the
3596 | number is denormalized. In this case we shift right and adjust the
3597 | exponent until it becomes 1 or the fraction is zero (in the latter case
3598 | we signal underflow and return zero).
3599 movel IMM (0),d6 | d6 is used temporarily
3600 #ifndef __mcoldfire__
3601 cmpw IMM (1),d2 | if the exponent is less than 1 we
3603 cmpl IMM (1),d2 | if the exponent is less than 1 we
3605 bge 2f | have to shift right (denormalize)
3607 #ifndef __mcoldfire__
3608 addw IMM (1),d2 | adjust the exponent
3609 lsrl IMM (1),d0 | shift right once
3611 roxrl IMM (1),d6 | d6 collect bits we would lose otherwise
3612 cmpw IMM (1),d2 | is the exponent 1 already?
3614 addql IMM (1),d2 | adjust the exponent
3624 cmpl IMM (1),d2 | is the exponent 1 already?
3626 beq 2f | if not loop back
3628 bra Lf$underflow | safety check, shouldn't execute '
3629 2: orl d6,d1 | this is a trick so we don't lose '
3630 | the extra bits which were flushed right
3631 | Now call the rounding routine (which takes care of denormalized numbers):
3632 lea pc@(Lround$0),a0 | to return from rounding routine
3633 PICLEA SYM (_fpCCR),a1 | check the rounding mode
3634 #ifdef __mcoldfire__
3637 movew a1@(6),d6 | rounding mode in d6
3638 beq Lround$to$nearest
3639 #ifndef __mcoldfire__
3640 cmpw IMM (ROUND_TO_PLUS),d6
3642 cmpl IMM (ROUND_TO_PLUS),d6
3648 | Here we have a correctly rounded result (either normalized or denormalized).
3650 | Here we should have either a normalized number or a denormalized one, and
3651 | the exponent is necessarily larger or equal to 1 (so we don't have to '
3652 | check again for underflow!). We have to check for overflow or for a
3653 | denormalized number (which also signals underflow).
3654 | Check for overflow (i.e., exponent >= 255).
3655 #ifndef __mcoldfire__
3656 cmpw IMM (0x00ff),d2
3658 cmpl IMM (0x00ff),d2
3661 | Now check for a denormalized number (exponent==0).
3665 | Put back the exponents and sign and return.
3666 #ifndef __mcoldfire__
3667 lslw IMM (7),d2 | exponent back to fourth byte
3669 lsll IMM (7),d2 | exponent back to fourth byte
3671 bclr IMM (FLT_MANT_DIG-1),d0
3672 swap d0 | and put back exponent
3673 #ifndef __mcoldfire__
3679 orl d7,d0 | and sign also
3681 PICLEA SYM (_fpCCR),a0
3683 #ifndef __mcoldfire__
3687 | XXX if frame pointer is ever removed, stack pointer must
3693 |=============================================================================
3695 |=============================================================================
3697 | This is trivial and could be shorter if we didn't bother checking for NaN '
3700 | float __negsf2(float);
3703 #ifndef __mcoldfire__
3710 moveq IMM (NEGATE),d5
3711 movel a6@(8),d0 | get number to negate in d0
3712 bchg IMM (31),d0 | negate
3713 movel d0,d1 | make a positive copy
3715 tstl d1 | check for zero
3716 beq 2f | if zero (either sign) return +zero
3717 cmpl IMM (INFINITY),d1 | compare to +INFINITY
3719 bhi Lf$inop | if larger (fraction not zero) is NaN
3720 movel d0,d7 | else get sign and return INFINITY
3721 andl IMM (0x80000000),d7
3723 1: PICLEA SYM (_fpCCR),a0
3725 #ifndef __mcoldfire__
3729 | XXX if frame pointer is ever removed, stack pointer must
3737 |=============================================================================
3739 |=============================================================================
3745 | int __cmpsf2_internal(float, float, int);
3746 SYM (__cmpsf2_internal):
3747 #ifndef __mcoldfire__
3749 moveml d2-d7,sp@- | save registers
3754 moveq IMM (COMPARE),d5
3755 movel a6@(8),d0 | get first operand
3756 movel a6@(12),d1 | get second operand
3757 | Check if either is NaN, and in that case return garbage and signal
3758 | INVALID_OPERATION. Check also if either is zero, and clear the signs
3761 andl IMM (0x7fffffff),d0
3763 cmpl IMM (0x7f800000),d0
3767 andl IMM (0x7fffffff),d1
3769 cmpl IMM (0x7f800000),d1
3775 | If the signs are not equal check if a >= 0
3777 bpl Lcmpsf$a$gt$b | if (a >= 0 && b < 0) => a > b
3778 bmi Lcmpsf$b$gt$a | if (a < 0 && b >= 0) => a < b
3780 | If the signs are equal check for < 0
3783 | If both are negative exchange them
3784 #ifndef __mcoldfire__
3792 | Now that they are positive we just compare them as longs (does this also
3793 | work for denormalized numbers?).
3795 bhi Lcmpsf$b$gt$a | |b| > |a|
3796 bne Lcmpsf$a$gt$b | |b| < |a|
3797 | If we got here a == b.
3798 movel IMM (EQUAL),d0
3799 #ifndef __mcoldfire__
3800 moveml sp@+,d2-d7 | put back the registers
3807 movel IMM (GREATER),d0
3808 #ifndef __mcoldfire__
3809 moveml sp@+,d2-d7 | put back the registers
3812 | XXX if frame pointer is ever removed, stack pointer must
3819 #ifndef __mcoldfire__
3820 moveml sp@+,d2-d7 | put back the registers
3823 | XXX if frame pointer is ever removed, stack pointer must
3838 moveq IMM (INEXACT_RESULT+INVALID_OPERATION),d7
3839 moveq IMM (SINGLE_FLOAT),d6
3840 PICJUMP $_exception_handler
3842 | int __cmpsf2(float, float);
3849 PICCALL SYM (__cmpsf2_internal)
3853 |=============================================================================
3855 |=============================================================================
3857 | The rounding routines expect the number to be normalized in registers
3858 | d0-d1, with the exponent in register d2. They assume that the
3859 | exponent is larger or equal to 1. They return a properly normalized number
3860 | if possible, and a denormalized number otherwise. The exponent is returned
3864 | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
3865 | Here we assume that the exponent is not too small (this should be checked
3866 | before entering the rounding routine), but the number could be denormalized.
3868 | Check for denormalized numbers:
3869 1: btst IMM (FLT_MANT_DIG),d0
3870 bne 2f | if set the number is normalized
3871 | Normalize shifting left until bit #FLT_MANT_DIG is set or the exponent
3872 | is one (remember that a denormalized number corresponds to an
3873 | exponent of -F_BIAS+1).
3874 #ifndef __mcoldfire__
3875 cmpw IMM (1),d2 | remember that the exponent is at least one
3877 cmpl IMM (1),d2 | remember that the exponent is at least one
3879 beq 2f | an exponent of one means denormalized
3880 addl d1,d1 | else shift and adjust the exponent
3882 #ifndef __mcoldfire__
3889 | Now round: we do it as follows: after the shifting we can write the
3890 | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
3891 | If delta < 1, do nothing. If delta > 1, add 1 to f.
3892 | If delta == 1, we make sure the rounded number will be even (odd?)
3894 btst IMM (0),d0 | is delta < 1?
3895 beq 2f | if so, do not do anything
3896 tstl d1 | is delta == 1?
3897 bne 1f | if so round to even
3899 andl IMM (2),d1 | bit 1 is the last significant bit
3902 1: movel IMM (1),d1 | else add 1
3904 | Shift right once (because we used bit #FLT_MANT_DIG!).
3906 | Now check again bit #FLT_MANT_DIG (rounding could have produced a
3907 | 'fraction overflow' ...).
3908 btst IMM (FLT_MANT_DIG),d0
3911 #ifndef __mcoldfire__
3917 | If bit #FLT_MANT_DIG-1 is clear we have a denormalized number, so we
3918 | have to put the exponent to zero and return a denormalized number.
3919 btst IMM (FLT_MANT_DIG-1),d0
3929 #endif /* L_float */
3931 | gcc expects the routines __eqdf2, __nedf2, __gtdf2, __gedf2,
3932 | __ledf2, __ltdf2 to all return the same value as a direct call to
3933 | __cmpdf2 would. In this implementation, each of these routines
3934 | simply calls __cmpdf2. It would be more efficient to give the
3935 | __cmpdf2 routine several names, but separating them out will make it
3936 | easier to write efficient versions of these routines someday.
3937 | If the operands recompare unordered unordered __gtdf2 and __gedf2 return -1.
3938 | The other routines return 1.
3943 .globl SYM (__eqdf2)
3951 PICCALL SYM (__cmpdf2_internal)
3954 #endif /* L_eqdf2 */
3959 .globl SYM (__nedf2)
3967 PICCALL SYM (__cmpdf2_internal)
3970 #endif /* L_nedf2 */
3975 .globl SYM (__gtdf2)
3983 PICCALL SYM (__cmpdf2_internal)
3986 #endif /* L_gtdf2 */
3991 .globl SYM (__gedf2)
3999 PICCALL SYM (__cmpdf2_internal)
4002 #endif /* L_gedf2 */
4007 .globl SYM (__ltdf2)
4015 PICCALL SYM (__cmpdf2_internal)
4018 #endif /* L_ltdf2 */
4023 .globl SYM (__ledf2)
4031 PICCALL SYM (__cmpdf2_internal)
4034 #endif /* L_ledf2 */
4036 | The comments above about __eqdf2, et. al., also apply to __eqsf2,
4037 | et. al., except that the latter call __cmpsf2 rather than __cmpdf2.
4042 .globl SYM (__eqsf2)
4048 PICCALL SYM (__cmpsf2_internal)
4051 #endif /* L_eqsf2 */
4056 .globl SYM (__nesf2)
4062 PICCALL SYM (__cmpsf2_internal)
4065 #endif /* L_nesf2 */
4070 .globl SYM (__gtsf2)
4076 PICCALL SYM (__cmpsf2_internal)
4079 #endif /* L_gtsf2 */
4084 .globl SYM (__gesf2)
4090 PICCALL SYM (__cmpsf2_internal)
4093 #endif /* L_gesf2 */
4098 .globl SYM (__ltsf2)
4104 PICCALL SYM (__cmpsf2_internal)
4107 #endif /* L_ltsf2 */
4112 .globl SYM (__lesf2)
4118 PICCALL SYM (__cmpsf2_internal)
4121 #endif /* L_lesf2 */
4123 #if defined (__ELF__) && defined (__linux__)
4124 /* Make stack non-executable for ELF linux targets. */
4125 .section .note.GNU-stack,"",@progbits