1 /* libgcc routines for
68000 w
/o floating
-point hardware.
2 Copyright
(C
) 1994, 1996, 1997, 1998 Free Software Foundation
, Inc.
4 This file is part of 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 2, or (at your option) any
11 In addition to the permissions
in the GNU General
Public License
, the
12 Free Software Foundation gives you unlimited permission to link the
13 compiled version of
this file with other programs
, and to distribute
14 those programs without any restriction coming from the use of
this
15 file.
(The General
Public License restrictions do apply
in other
16 respects
; for example, they cover modification of the file, and
17 distribution when
not linked
into another program.
)
19 This file is distributed
in the hope that it will be useful
, but
20 WITHOUT ANY WARRANTY
; without even the implied warranty of
21 MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General
Public License for more details.
24 You should have received a copy of the GNU General
Public License
25 along with
this program
; see the file COPYING. If not, write to
26 the Free Software Foundation
, 51 Franklin Street
, Fifth Floor
,
27 Boston
, MA
02110-1301, USA.
*/
29 /* As a special exception
, if you link
this library with files
30 compiled with GCC to produce an executable
, this does
not cause
31 the resulting executable to be covered by the GNU General
Public License.
32 This exception does
not however invalidate any other reasons why
33 the executable file might be covered by the GNU General
Public License.
*/
35 /* Use
this one for any
680x0
; assumes no floating point hardware.
36 The trailing
" '" appearing on some lines is for ANSI preprocessors. Yuk.
37 Some of
this code comes from MINIX
, via the folks at ericsson.
38 D. V. Henkel
-Wallace
(gumby
@cygnus.com
) Fete Bastille
, 1992
41 /* These are predefined by new versions of GNU cpp.
*/
43 #ifndef __USER_LABEL_PREFIX__
44 #define __USER_LABEL_PREFIX__ _
47 #ifndef __REGISTER_PREFIX__
48 #define __REGISTER_PREFIX__
51 #ifndef __IMMEDIATE_PREFIX__
52 #define __IMMEDIATE_PREFIX__ #
55 /* ANSI concatenation macros.
*/
57 #define CONCAT1
(a
, b
) CONCAT2
(a
, b
)
58 #define CONCAT2
(a
, b
) a ## b
60 /* Use the right prefix for
global labels.
*/
62 #define SYM
(x
) CONCAT1
(__USER_LABEL_PREFIX__
, x
)
64 /* Use the right prefix for registers.
*/
66 #define REG
(x
) CONCAT1
(__REGISTER_PREFIX__
, x
)
68 /* Use the right prefix for immediate values.
*/
70 #define IMM
(x
) CONCAT1
(__IMMEDIATE_PREFIX__
, x
)
91 /* Provide a few macros to allow for PIC code support.
92 * With PIC
, data is stored A5 relative so we
've got to take a bit of special
93 * care to ensure that all loads of global data is via A5. PIC also requires
94 * jumps and subroutine calls to be PC relative rather than absolute. We cheat
95 * a little on this and in the PIC case, we use short offset branches and
96 * hope that the final object code is within range (which it should be).
100 /* Non PIC (absolute/relocatable) versions */
110 .macro PICLEA sym, reg
114 .macro PICPEA sym, areg
120 /* Common for -mid-shared-libary and -msep-data */
130 # if defined(__ID_SHARED_LIBRARY__)
132 /* -mid-shared-library versions */
134 .macro PICLEA sym, reg
135 movel a5@(_current_shared_library_a5_offset_), \reg
136 movel \sym@GOT(\reg), \reg
139 .macro PICPEA sym, areg
140 movel a5@(_current_shared_library_a5_offset_), \areg
141 movel \sym@GOT(\areg), sp@-
144 # else /* !__ID_SHARED_LIBRARY__ */
146 /* Versions for -msep-data */
148 .macro PICLEA sym, reg
149 movel \sym@GOT(a5), \reg
152 .macro PICPEA sym, areg
153 movel \sym@GOT(a5), sp@-
156 # endif /* !__ID_SHARED_LIBRARY__ */
162 | This is an attempt at a decent floating point (single, double and
163 | extended double) code for the GNU C compiler. It should be easy to
164 | adapt to other compilers (but beware of the local labels!).
166 | Starting date: 21 October, 1990
168 | It is convenient to introduce the notation (s,e,f) for a floating point
169 | number, where s=sign, e=exponent, f=fraction. We will call a floating
170 | point number fpn to abbreviate, independently of the precision.
171 | Let MAX_EXP be in each case the maximum exponent (255 for floats, 1023
172 | for doubles and 16383 for long doubles). We then have the following
174 | 1. Normalized fpns have 0 < e < MAX_EXP. They correspond to
175 | (-1)^s x 1.f x 2^(e-bias-1).
176 | 2. Denormalized fpns have e=0. They correspond to numbers of the form
177 | (-1)^s x 0.f x 2^(-bias).
178 | 3. +/-INFINITY have e=MAX_EXP, f=0.
179 | 4. Quiet NaN (Not a Number) have all bits set.
180 | 5. Signaling NaN (Not a Number) have s=0, e=MAX_EXP, f=1.
182 |=============================================================================
184 |=============================================================================
186 | This is the floating point condition code register (_fpCCR):
189 | short _exception_bits;
190 | short _trap_enable_bits;
191 | short _sticky_bits;
192 | short _rounding_mode;
194 | short _last_operation;
218 .word ROUND_TO_NEAREST
231 EBITS = __exception_bits - SYM (_fpCCR)
232 TRAPE = __trap_enable_bits - SYM (_fpCCR)
233 STICK = __sticky_bits - SYM (_fpCCR)
234 ROUND = __rounding_mode - SYM (_fpCCR)
235 FORMT = __format - SYM (_fpCCR)
236 LASTO = __last_operation - SYM (_fpCCR)
237 OPER1 = __operand1 - SYM (_fpCCR)
238 OPER2 = __operand2 - SYM (_fpCCR)
240 | The following exception types are supported:
241 INEXACT_RESULT = 0x0001
244 DIVIDE_BY_ZERO = 0x0008
245 INVALID_OPERATION = 0x0010
247 | The allowed rounding modes are:
249 ROUND_TO_NEAREST = 0 | round result to nearest representable value
250 ROUND_TO_ZERO = 1 | round result towards zero
251 ROUND_TO_PLUS = 2 | round result towards plus infinity
252 ROUND_TO_MINUS = 3 | round result towards minus infinity
254 | The allowed values of format are:
260 | The allowed values for the last operation are:
270 |=============================================================================
271 | __clear_sticky_bits
272 |=============================================================================
274 | The sticky bits are normally not cleared (thus the name), whereas the
275 | exception type and exception value reflect the last computation.
276 | This routine is provided to clear them (you can also write to _fpCCR,
277 | since it is globally visible).
279 .globl SYM (__clear_sticky_bit)
284 | void __clear_sticky_bits(void);
285 SYM (__clear_sticky_bit):
286 PICLEA SYM (_fpCCR),a0
287 #ifndef __mcoldfire__
288 movew IMM (0),a0@(STICK)
294 |=============================================================================
295 | $_exception_handler
296 |=============================================================================
298 .globl $_exception_handler
303 | This is the common exit point if an exception occurs.
304 | NOTE: it is NOT callable from C!
305 | It expects the exception type in d7, the format (SINGLE_FLOAT,
306 | DOUBLE_FLOAT or LONG_FLOAT) in d6, and the last operation code in d5.
307 | It sets the corresponding exception and sticky bits, and the format.
308 | Depending on the format if fills the corresponding slots for the
309 | operands which produced the exception (all this information is provided
310 | so if you write your own exception handlers you have enough information
311 | to deal with the problem).
312 | Then checks to see if the corresponding exception is trap-enabled,
313 | in which case it pushes the address of _fpCCR and traps through
314 | trap FPTRAP (15 for the moment).
319 PICLEA SYM (_fpCCR),a0
320 movew d7,a0@(EBITS) | set __exception_bits
321 #ifndef __mcoldfire__
322 orw d7,a0@(STICK) | and __sticky_bits
328 movew d6,a0@(FORMT) | and __format
329 movew d5,a0@(LASTO) | and __last_operation
331 | Now put the operands in place:
332 #ifndef __mcoldfire__
333 cmpw IMM (SINGLE_FLOAT),d6
335 cmpl IMM (SINGLE_FLOAT),d6
338 movel a6@(8),a0@(OPER1)
339 movel a6@(12),a0@(OPER1+4)
340 movel a6@(16),a0@(OPER2)
341 movel a6@(20),a0@(OPER2+4)
343 1: movel a6@(8),a0@(OPER1)
344 movel a6@(12),a0@(OPER2)
346 | And check whether the exception is trap-enabled:
347 #ifndef __mcoldfire__
348 andw a0@(TRAPE),d7 | is exception trap-enabled?
355 PICPEA SYM (_fpCCR),a1 | yes, push address of _fpCCR
356 trap IMM (FPTRAP) | and trap
357 #ifndef __mcoldfire__
358 1: moveml sp@+,d2-d7 | restore data registers
361 | XXX if frame pointer is ever removed, stack pointer must
366 #endif /* L_floatex */
371 .globl SYM (__mulsi3)
373 movew sp@(4), d0 /* x0 -> d0 */
374 muluw sp@(10), d0 /* x0*y1 */
375 movew sp@(6), d1 /* x1 -> d1 */
376 muluw sp@(8), d1 /* x1*y0 */
377 #ifndef __mcoldfire__
384 movew sp@(6), d1 /* x1 -> d1 */
385 muluw sp@(10), d1 /* x1*y1 */
389 #endif /* L_mulsi3 */
394 .globl SYM (__udivsi3)
396 #ifndef __mcoldfire__
398 movel sp@(12), d1 /* d1 = divisor */
399 movel sp@(8), d0 /* d0 = dividend */
401 cmpl IMM (0x10000), d1 /* divisor >= 2 ^ 16 ? */
402 jcc L3 /* then try next algorithm */
406 divu d1, d2 /* high quotient in lower word */
407 movew d2, d0 /* save high quotient */
409 movew sp@(10), d2 /* get low dividend + high rest */
410 divu d1, d2 /* low quotient */
414 L3: movel d1, d2 /* use d2 as divisor backup */
415 L4: lsrl IMM (1), d1 /* shift divisor */
416 lsrl IMM (1), d0 /* shift dividend */
417 cmpl IMM (0x10000), d1 /* still divisor >= 2 ^ 16 ? */
419 divu d1, d0 /* now we have 16-bit divisor */
420 andl IMM (0xffff), d0 /* mask out divisor, ignore remainder */
422 /* Multiply the 16-bit tentative quotient with the 32-bit divisor. Because of
423 the operand ranges, this might give a 33-bit product. If this product is
424 greater than the dividend, the tentative quotient was too large. */
426 mulu d0, d1 /* low part, 32 bits */
428 mulu d0, d2 /* high part, at most 17 bits */
429 swap d2 /* align high part with low part */
430 tstw d2 /* high part 17 bits? */
431 jne L5 /* if 17 bits, quotient was too large */
432 addl d2, d1 /* add parts */
433 jcs L5 /* if sum is 33 bits, quotient was too large */
434 cmpl sp@(8), d1 /* compare the sum with the dividend */
435 jls L6 /* if sum > dividend, quotient was too large */
436 L5: subql IMM (1), d0 /* adjust quotient */
441 #else /* __mcoldfire__ */
443 /* ColdFire implementation of non-restoring division algorithm from
444 Hennessy & Patterson, Appendix A. */
451 L1: addl d0,d0 | shift reg pair (p,a) one bit left
453 movl d2,d3 | subtract b from p, store in tmp.
455 jcs L2 | if no carry,
456 bset IMM (0),d0 | set the low order bit of a to 1,
457 movl d3,d2 | and store tmp in p.
460 moveml sp@,d2-d4 | restore data registers
463 #endif /* __mcoldfire__ */
465 #endif /* L_udivsi3 */
470 .globl SYM (__divsi3)
474 moveq IMM (1), d2 /* sign of result stored in d2 (=1 or =-1) */
475 movel sp@(12), d1 /* d1 = divisor */
478 #ifndef __mcoldfire__
479 negb d2 /* change sign because divisor <0 */
481 negl d2 /* change sign because divisor <0 */
483 L1: movel sp@(8), d0 /* d0 = dividend */
486 #ifndef __mcoldfire__
494 PICCALL SYM (__udivsi3) /* divide abs(dividend) by abs(divisor) */
503 #endif /* L_divsi3 */
508 .globl SYM (__umodsi3)
510 movel sp@(8), d1 /* d1 = divisor */
511 movel sp@(4), d0 /* d0 = dividend */
514 PICCALL SYM (__udivsi3)
516 movel sp@(8), d1 /* d1 = divisor */
517 #ifndef __mcoldfire__
520 PICCALL SYM (__mulsi3) /* d0 = (a/b)*b */
525 movel sp@(4), d1 /* d1 = dividend */
526 subl d0, d1 /* d1 = a - (a/b)*b */
529 #endif /* L_umodsi3 */
534 .globl SYM (__modsi3)
536 movel sp@(8), d1 /* d1 = divisor */
537 movel sp@(4), d0 /* d0 = dividend */
540 PICCALL SYM (__divsi3)
542 movel sp@(8), d1 /* d1 = divisor */
543 #ifndef __mcoldfire__
546 PICCALL SYM (__mulsi3) /* d0 = (a/b)*b */
551 movel sp@(4), d1 /* d1 = dividend */
552 subl d0, d1 /* d1 = a - (a/b)*b */
555 #endif /* L_modsi3 */
561 .globl $_exception_handler
563 QUIET_NaN = 0xffffffff
567 DBL_MAX_EXP = D_MAX_EXP - D_BIAS
568 DBL_MIN_EXP = 1 - D_BIAS
571 INEXACT_RESULT = 0x0001
574 DIVIDE_BY_ZERO = 0x0008
575 INVALID_OPERATION = 0x0010
589 ROUND_TO_NEAREST = 0 | round result to nearest representable value
590 ROUND_TO_ZERO = 1 | round result towards zero
591 ROUND_TO_PLUS = 2 | round result towards plus infinity
592 ROUND_TO_MINUS = 3 | round result towards minus infinity
596 .globl SYM (__adddf3)
597 .globl SYM (__subdf3)
598 .globl SYM (__muldf3)
599 .globl SYM (__divdf3)
600 .globl SYM (__negdf2)
601 .globl SYM (__cmpdf2)
606 | These are common routines to return and signal exceptions.
609 | Return and signal a denormalized number
611 movew IMM (INEXACT_RESULT+UNDERFLOW),d7
612 moveq IMM (DOUBLE_FLOAT),d6
613 PICJUMP $_exception_handler
617 | Return a properly signed INFINITY and set the exception flags
618 movel IMM (0x7ff00000),d0
621 movew IMM (INEXACT_RESULT+OVERFLOW),d7
622 moveq IMM (DOUBLE_FLOAT),d6
623 PICJUMP $_exception_handler
626 | Return 0 and set the exception flags
629 movew IMM (INEXACT_RESULT+UNDERFLOW),d7
630 moveq IMM (DOUBLE_FLOAT),d6
631 PICJUMP $_exception_handler
634 | Return a quiet NaN and set the exception flags
635 movel IMM (QUIET_NaN),d0
637 movew IMM (INEXACT_RESULT+INVALID_OPERATION),d7
638 moveq IMM (DOUBLE_FLOAT),d6
639 PICJUMP $_exception_handler
642 | Return a properly signed INFINITY and set the exception flags
643 movel IMM (0x7ff00000),d0
646 movew IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7
647 moveq IMM (DOUBLE_FLOAT),d6
648 PICJUMP $_exception_handler
650 |=============================================================================
651 |=============================================================================
652 | double precision routines
653 |=============================================================================
654 |=============================================================================
656 | A double precision floating point number (double) has the format:
659 | unsigned int sign : 1; /* sign bit */
660 | unsigned int exponent : 11; /* exponent, shifted by 126 */
661 | unsigned int fraction : 52; /* fraction */
664 | Thus sizeof(double) = 8 (64 bits).
666 | All the routines are callable from C programs, and return the result
667 | in the register pair d0-d1. They also preserve all registers except
670 |=============================================================================
672 |=============================================================================
674 | double __subdf3(double, double);
676 bchg IMM (31),sp@(12) | change sign of second operand
677 | and fall through, so we always add
678 |=============================================================================
680 |=============================================================================
682 | double __adddf3(double, double);
684 #ifndef __mcoldfire__
685 link a6,IMM (0) | everything will be done in registers
686 moveml d2-d7,sp@- | save all data registers and a2 (but d0-d1)
691 movel a6@(8),d0 | get first operand
693 movel a6@(16),d2 | get second operand
696 movel d0,d7 | get d0's sign bit
in d7
'
697 addl d1,d1 | check and clear sign bit of a, and gain one
698 addxl d0,d0 | bit of extra precision
699 beq Ladddf$b | if zero return second operand
701 movel d2,d6 | save sign in d6
702 addl d3,d3 | get rid of sign bit and gain one bit of
703 addxl d2,d2 | extra precision
704 beq Ladddf$a | if zero return first operand
706 andl IMM (0x80000000),d7 | isolate a's sign bit
'
707 swap d6 | and also b's sign bit
'
708 #ifndef __mcoldfire__
709 andw IMM (0x8000),d6 |
710 orw d6,d7 | and combine them into d7, so that a's sign
'
711 | bit is in the high word and b's is
in the
'
712 | low word, so d6 is free to be used
717 movel d7,a0 | now save d7 into a0, so d7 is free to
720 | Get the exponents and check for denormalized and/or infinity.
722 movel IMM (0x001fffff),d6 | mask for the fraction
723 movel IMM (0x00200000),d7 | mask to put hidden bit back
726 andl d6,d0 | get fraction in d0
727 notl d6 | make d6 into mask for the exponent
728 andl d6,d4 | get exponent in d4
729 beq Ladddf$a$den | branch if a is denormalized
730 cmpl d6,d4 | check for INFINITY or NaN
732 orl d7,d0 | and put hidden bit back
734 swap d4 | shift right exponent so that it starts
735 #ifndef __mcoldfire__
736 lsrw IMM (5),d4 | in bit 0 and not bit 20
738 lsrl IMM (5),d4 | in bit 0 and not bit 20
740 | Now we have a's exponent
in d4
and fraction
in d0
-d1
'
741 movel d2,d5 | save b to get exponent
742 andl d6,d5 | get exponent in d5
743 beq Ladddf$b$den | branch if b is denormalized
744 cmpl d6,d5 | check for INFINITY or NaN
746 notl d6 | make d6 into mask for the fraction again
747 andl d6,d2 | and get fraction in d2
748 orl d7,d2 | and put hidden bit back
750 swap d5 | shift right exponent so that it starts
751 #ifndef __mcoldfire__
752 lsrw IMM (5),d5 | in bit 0 and not bit 20
754 lsrl IMM (5),d5 | in bit 0 and not bit 20
757 | Now we have b's exponent
in d5
and fraction
in d2
-d3.
'
759 | The situation now is as follows: the signs are combined in a0, the
760 | numbers are in d0-d1 (a) and d2-d3 (b), and the exponents in d4 (a)
761 | and d5 (b). To do the rounding correctly we need to keep all the
762 | bits until the end, so we need to use d0-d1-d2-d3 for the first number
763 | and d4-d5-d6-d7 for the second. To do this we store (temporarily) the
764 | exponents in a2-a3.
766 #ifndef __mcoldfire__
767 moveml a2-a3,sp@- | save the address registers
774 movel d4,a2 | save the exponents
777 movel IMM (0),d7 | and move the numbers around
784 | Here we shift the numbers until the exponents are the same, and put
785 | the largest exponent in a2.
786 #ifndef __mcoldfire__
787 exg d4,a2 | get exponents back
789 cmpw d4,d5 | compare the exponents
791 movel d4,a4 | get exponents back
797 cmpl d4,d5 | compare the exponents
799 beq Ladddf$3 | if equal don't shift
'
800 bhi 9f | branch if second exponent is higher
802 | Here we have a's exponent larger than b
's, so we have to shift b. We do
803 | this by using as counter d2:
804 1: movew d4,d2 | move largest exponent to d2
805 #ifndef __mcoldfire__
806 subw d5,d2 | and subtract second exponent
807 exg d4,a2 | get back the longs we saved
810 subl d5,d2 | and subtract second exponent
811 movel d4,a4 | get back the longs we saved
818 | if difference is too large we don't shift
(actually
, we can just exit
) '
819 #ifndef __mcoldfire__
820 cmpw IMM (DBL_MANT_DIG+2),d2
822 cmpl IMM (DBL_MANT_DIG+2),d2
825 #ifndef __mcoldfire__
826 cmpw IMM (32),d2 | if difference >= 32, shift by longs
828 cmpl IMM (32),d2 | if difference >= 32, shift by longs
832 #ifndef __mcoldfire__
833 cmpw IMM (16),d2 | if difference >= 16, shift by words
835 cmpl IMM (16),d2 | if difference >= 16, shift by words
838 bra 3f | enter dbra loop
841 #ifndef __mcoldfire__
862 #ifndef __mcoldfire__
876 #ifndef __mcoldfire__
891 #ifndef __mcoldfire__
899 #ifndef __mcoldfire__
902 subw d5,d6 | keep d5 (largest exponent) in d4
917 | if difference is too large we don't shift
(actually
, we can just exit
) '
918 #ifndef __mcoldfire__
919 cmpw IMM (DBL_MANT_DIG+2),d6
921 cmpl IMM (DBL_MANT_DIG+2),d6
924 #ifndef __mcoldfire__
925 cmpw IMM (32),d6 | if difference >= 32, shift by longs
927 cmpl IMM (32),d6 | if difference >= 32, shift by longs
931 #ifndef __mcoldfire__
932 cmpw IMM (16),d6 | if difference >= 16, shift by words
934 cmpl IMM (16),d6 | if difference >= 16, shift by words
937 bra 3f | enter dbra loop
940 #ifndef __mcoldfire__
961 #ifndef __mcoldfire__
975 #ifndef __mcoldfire__
990 #ifndef __mcoldfire__
997 #ifndef __mcoldfire__
1009 | Now we have the numbers in d0--d3 and d4--d7, the exponent in a2, and
1012 | Here we have to decide whether to add or subtract the numbers:
1013 #ifndef __mcoldfire__
1014 exg d7,a0 | get the signs
1015 exg d6,a3 | a3 is free to be used
1025 movew IMM (0),d7 | get a's sign
in d7
'
1027 movew IMM (0),d6 | and b's sign
in d6
'
1028 eorl d7,d6 | compare the signs
1029 bmi Lsubdf$0 | if the signs are different we have
1031 #ifndef __mcoldfire__
1032 exg d7,a0 | else we add the numbers
1047 movel a2,d4 | return exponent to d4
1049 andl IMM (0x80000000),d7 | d7 now has the sign
1051 #ifndef __mcoldfire__
1059 | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
1060 | the case of denormalized numbers in the rounding routine itself).
1061 | As in the addition (not in the subtraction!) we could have set
1062 | one more bit we check this:
1063 btst IMM (DBL_MANT_DIG+1),d0
1065 #ifndef __mcoldfire__
1088 lea pc@(Ladddf$5),a0 | to return from rounding routine
1089 PICLEA SYM (_fpCCR),a1 | check the rounding mode
1090 #ifdef __mcoldfire__
1093 movew a1@(6),d6 | rounding mode in d6
1094 beq Lround$to$nearest
1095 #ifndef __mcoldfire__
1096 cmpw IMM (ROUND_TO_PLUS),d6
1098 cmpl IMM (ROUND_TO_PLUS),d6
1104 | Put back the exponent and check for overflow
1105 #ifndef __mcoldfire__
1106 cmpw IMM (0x7ff),d4 | is the exponent big?
1108 cmpl IMM (0x7ff),d4 | is the exponent big?
1111 bclr IMM (DBL_MANT_DIG-1),d0
1112 #ifndef __mcoldfire__
1113 lslw IMM (4),d4 | put exponent back into position
1115 lsll IMM (4),d4 | put exponent back into position
1118 #ifndef __mcoldfire__
1130 | Here we do the subtraction.
1131 #ifndef __mcoldfire__
1132 exg d7,a0 | put sign back in a0
1146 beq Ladddf$ret$1 | if zero just exit
1147 bpl 1f | if positive skip the following
1149 bchg IMM (31),d7 | change sign bit in d7
1153 negxl d1 | and negate result
1156 movel a2,d4 | return exponent to d4
1158 andl IMM (0x80000000),d7 | isolate sign bit
1159 #ifndef __mcoldfire__
1167 | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
1168 | the case of denormalized numbers in the rounding routine itself).
1169 | As in the addition (not in the subtraction!) we could have set
1170 | one more bit we check this:
1171 btst IMM (DBL_MANT_DIG+1),d0
1173 #ifndef __mcoldfire__
1196 lea pc@(Lsubdf$1),a0 | to return from rounding routine
1197 PICLEA SYM (_fpCCR),a1 | check the rounding mode
1198 #ifdef __mcoldfire__
1201 movew a1@(6),d6 | rounding mode in d6
1202 beq Lround$to$nearest
1203 #ifndef __mcoldfire__
1204 cmpw IMM (ROUND_TO_PLUS),d6
1206 cmpl IMM (ROUND_TO_PLUS),d6
1212 | Put back the exponent and sign (we don't have overflow
).
'
1213 bclr IMM (DBL_MANT_DIG-1),d0
1214 #ifndef __mcoldfire__
1215 lslw IMM (4),d4 | put exponent back into position
1217 lsll IMM (4),d4 | put exponent back into position
1220 #ifndef __mcoldfire__
1228 | If one of the numbers was too small (difference of exponents >=
1229 | DBL_MANT_DIG+1) we return the other (and now we don't have to
'
1230 | check for finiteness or zero).
1232 #ifndef __mcoldfire__
1241 PICLEA SYM (_fpCCR),a0
1243 #ifndef __mcoldfire__
1244 moveml sp@+,d2-d7 | restore data registers
1247 | XXX if frame pointer is ever removed, stack pointer must
1250 unlk a6 | and return
1254 #ifndef __mcoldfire__
1263 PICLEA SYM (_fpCCR),a0
1265 #ifndef __mcoldfire__
1266 moveml sp@+,d2-d7 | restore data registers
1269 | XXX if frame pointer is ever removed, stack pointer must
1272 unlk a6 | and return
1276 movel d7,d4 | d7 contains 0x00200000
1280 movel d7,d5 | d7 contains 0x00200000
1285 | Return b (if a is zero)
1294 | Check for NaN and +/-INFINITY.
1296 andl IMM (0x80000000),d7 |
1298 cmpl IMM (0x7ff00000),d0 |
1300 movel d0,d0 | check for zero, since we don't
'
1301 bne Ladddf$ret | want to return -0 by mistake
1305 andl IMM (0x000fffff),d0 | check for NaN (nonzero fraction)
1311 #ifndef __mcoldfire__
1312 moveml sp@+,a2-a3 | restore regs and exit
1321 PICLEA SYM (_fpCCR),a0
1323 orl d7,d0 | put sign bit back
1324 #ifndef __mcoldfire__
1328 | XXX if frame pointer is ever removed, stack pointer must
1335 | Return a denormalized number.
1336 #ifndef __mcoldfire__
1337 lsrl IMM (1),d0 | shift right once more
1350 | This could be faster but it is not worth the effort, since it is not
1351 | executed very often. We sacrifice speed for clarity here.
1352 movel a6@(8),d0 | get the numbers back (remember that we
1353 movel a6@(12),d1 | did some processing already)
1356 movel IMM (0x7ff00000),d4 | useful constant (INFINITY)
1357 movel d0,d7 | save sign bits
1359 bclr IMM (31),d0 | clear sign bits
1361 | We know that one of them is either NaN of +/-INFINITY
1362 | Check for NaN (if either one is NaN return NaN)
1363 cmpl d4,d0 | check first a (d0)
1364 bhi Ld$inop | if d0 > 0x7ff00000 or equal and
1366 tstl d1 | d1 > 0, a is NaN
1368 2: cmpl d4,d2 | check now b (d1)
1374 | Now comes the check for +/-INFINITY. We know that both are (maybe not
1375 | finite) numbers, but we have to check if both are infinite whether we
1376 | are adding or subtracting them.
1377 eorl d7,d6 | to check sign bits
1379 andl IMM (0x80000000),d7 | get (common) sign bit
1382 | We know one (or both) are infinite, so we test for equality between the
1383 | two numbers (if they are equal they have to be infinite both, so we
1385 cmpl d2,d0 | are both infinite?
1386 bne 1f | if d0 <> d2 they are not equal
1387 cmpl d3,d1 | if d0 == d2 test d3 and d1
1388 beq Ld$inop | if equal return NaN
1390 andl IMM (0x80000000),d7 | get a's sign bit
'
1391 cmpl d4,d0 | test now for infinity
1392 beq Ld$infty | if a is INFINITY return with this sign
1393 bchg IMM (31),d7 | else we know b is INFINITY and has
1394 bra Ld$infty | the opposite sign
1396 |=============================================================================
1398 |=============================================================================
1400 | double __muldf3(double, double);
1402 #ifndef __mcoldfire__
1409 movel a6@(8),d0 | get a into d0-d1
1411 movel a6@(16),d2 | and b into d2-d3
1413 movel d0,d7 | d7 will hold the sign of the product
1415 andl IMM (0x80000000),d7 |
1416 movel d7,a0 | save sign bit into a0
1417 movel IMM (0x7ff00000),d7 | useful constant (+INFINITY)
1418 movel d7,d6 | another (mask for fraction)
1420 bclr IMM (31),d0 | get rid of a's sign bit
'
1423 beq Lmuldf$a$0 | branch if a is zero
1425 bclr IMM (31),d2 | get rid of b's sign bit
'
1428 beq Lmuldf$b$0 | branch if b is zero
1430 cmpl d7,d0 | is a big?
1431 bhi Lmuldf$inop | if a is NaN return NaN
1432 beq Lmuldf$a$nf | we still have to check d1 and b ...
1433 cmpl d7,d2 | now compare b with INFINITY
1434 bhi Lmuldf$inop | is b NaN?
1435 beq Lmuldf$b$nf | we still have to check d3 ...
1436 | Here we have both numbers finite and nonzero (and with no sign bit).
1437 | Now we get the exponents into d4 and d5.
1438 andl d7,d4 | isolate exponent in d4
1439 beq Lmuldf$a$den | if exponent zero, have denormalized
1440 andl d6,d0 | isolate fraction
1441 orl IMM (0x00100000),d0 | and put hidden bit back
1442 swap d4 | I like exponents in the first byte
1443 #ifndef __mcoldfire__
1452 orl IMM (0x00100000),d2 | and put hidden bit back
1454 #ifndef __mcoldfire__
1460 #ifndef __mcoldfire__
1461 addw d5,d4 | add exponents
1462 subw IMM (D_BIAS+1),d4 | and subtract bias (plus one)
1464 addl d5,d4 | add exponents
1465 subl IMM (D_BIAS+1),d4 | and subtract bias (plus one)
1468 | We are now ready to do the multiplication. The situation is as follows:
1469 | both a and b have bit 52 ( bit 20 of d0 and d2) set (even if they were
1470 | denormalized to start with!), which means that in the product bit 104
1471 | (which will correspond to bit 8 of the fourth long) is set.
1473 | Here we have to do the product.
1474 | To do it we have to juggle the registers back and forth, as there are not
1475 | enough to keep everything in them. So we use the address registers to keep
1476 | some intermediate data.
1478 #ifndef __mcoldfire__
1479 moveml a2-a3,sp@- | save a2 and a3 for temporary use
1485 movel IMM (0),a2 | a2 is a null register
1486 movel d4,a3 | and a3 will preserve the exponent
1488 | First, shift d2-d3 so bit 20 becomes bit 31:
1489 #ifndef __mcoldfire__
1490 rorl IMM (5),d2 | rotate d2 5 places right
1491 swap d2 | and swap it
1492 rorl IMM (5),d3 | do the same thing with d3
1494 movew d3,d6 | get the rightmost 11 bits of d3
1495 andw IMM (0x07ff),d6 |
1496 orw d6,d2 | and put them into d2
1497 andw IMM (0xf800),d3 | clear those bits in d3
1499 moveq IMM (11),d7 | left shift d2 11 bits
1501 movel d3,d6 | get a copy of d3
1502 lsll d7,d3 | left shift d3 11 bits
1503 andl IMM (0xffe00000),d6 | get the top 11 bits of d3
1504 moveq IMM (21),d7 | right shift them 21 bits
1506 orl d6,d2 | stick them at the end of d2
1509 movel d2,d6 | move b into d6-d7
1510 movel d3,d7 | move a into d4-d5
1511 movel d0,d4 | and clear d0-d1-d2-d3 (to put result)
1518 | We use a1 as counter:
1519 movel IMM (DBL_MANT_DIG-1),a1
1520 #ifndef __mcoldfire__
1529 #ifndef __mcoldfire__
1530 exg d7,a1 | put counter back in a1
1536 addl d3,d3 | shift sum once left
1542 bcc 2f | if bit clear skip the following
1543 #ifndef __mcoldfire__
1550 addl d5,d3 | else add a to the sum
1554 #ifndef __mcoldfire__
1562 #ifndef __mcoldfire__
1563 exg d7,a1 | put counter in d7
1564 dbf d7,1b | decrement and branch
1573 movel a3,d4 | restore exponent
1574 #ifndef __mcoldfire__
1582 | Now we have the product in d0-d1-d2-d3, with bit 8 of d0 set. The
1583 | first thing to do now is to normalize it so bit 8 becomes bit
1584 | DBL_MANT_DIG-32 (to do the rounding); later we will shift right.
1593 #ifndef __mcoldfire__
1623 | Now round, check for over- and underflow, and exit.
1624 movel a0,d7 | get sign bit back into d7
1625 moveq IMM (MULTIPLY),d5
1627 btst IMM (DBL_MANT_DIG+1-32),d0
1629 #ifndef __mcoldfire__
1644 moveq IMM (MULTIPLY),d5
1648 moveq IMM (MULTIPLY),d5
1649 movel a0,d7 | get sign bit back into d7
1650 tstl d3 | we know d2 == 0x7ff00000, so check d3
1651 bne Ld$inop | if d3 <> 0 b is NaN
1652 bra Ld$overflow | else we have overflow (since a is finite)
1655 moveq IMM (MULTIPLY),d5
1656 movel a0,d7 | get sign bit back into d7
1657 tstl d1 | we know d0 == 0x7ff00000, so check d1
1658 bne Ld$inop | if d1 <> 0 a is NaN
1659 bra Ld$overflow | else signal overflow
1661 | If either number is zero return zero, unless the other is +/-INFINITY or
1662 | NaN, in which case we return NaN.
1664 moveq IMM (MULTIPLY),d5
1665 #ifndef __mcoldfire__
1666 exg d2,d0 | put b (==0) into d0-d1
1667 exg d3,d1 | and a (with sign bit cleared) into d2-d3
1678 movel a6@(16),d2 | put b into d2-d3 again
1680 bclr IMM (31),d2 | clear sign bit
1681 1: cmpl IMM (0x7ff00000),d2 | check for non-finiteness
1682 bge Ld$inop | in case NaN or +/-INFINITY return NaN
1683 PICLEA SYM (_fpCCR),a0
1685 #ifndef __mcoldfire__
1689 | XXX if frame pointer is ever removed, stack pointer must
1695 | If a number is denormalized we put an exponent of 1 but do not put the
1696 | hidden bit back into the fraction; instead we shift left until bit 21
1697 | (the hidden bit) is set, adjusting the exponent accordingly. We do this
1698 | to ensure that the product of the fractions is close to 1.
1702 1: addl d1,d1 | shift a left until bit 20 is set
1704 #ifndef __mcoldfire__
1705 subw IMM (1),d4 | and adjust exponent
1707 subl IMM (1),d4 | and adjust exponent
1716 1: addl d3,d3 | shift b left until bit 20 is set
1718 #ifndef __mcoldfire__
1719 subw IMM (1),d5 | and adjust exponent
1721 subql IMM (1),d5 | and adjust exponent
1728 |=============================================================================
1730 |=============================================================================
1732 | double __divdf3(double, double);
1734 #ifndef __mcoldfire__
1741 movel a6@(8),d0 | get a into d0-d1
1743 movel a6@(16),d2 | and b into d2-d3
1745 movel d0,d7 | d7 will hold the sign of the result
1747 andl IMM (0x80000000),d7
1748 movel d7,a0 | save sign into a0
1749 movel IMM (0x7ff00000),d7 | useful constant (+INFINITY)
1750 movel d7,d6 | another (mask for fraction)
1752 bclr IMM (31),d0 | get rid of a's sign bit
'
1755 beq Ldivdf$a$0 | branch if a is zero
1757 bclr IMM (31),d2 | get rid of b's sign bit
'
1760 beq Ldivdf$b$0 | branch if b is zero
1762 cmpl d7,d0 | is a big?
1763 bhi Ldivdf$inop | if a is NaN return NaN
1764 beq Ldivdf$a$nf | if d0 == 0x7ff00000 we check d1
1765 cmpl d7,d2 | now compare b with INFINITY
1766 bhi Ldivdf$inop | if b is NaN return NaN
1767 beq Ldivdf$b$nf | if d2 == 0x7ff00000 we check d3
1768 | Here we have both numbers finite and nonzero (and with no sign bit).
1769 | Now we get the exponents into d4 and d5 and normalize the numbers to
1770 | ensure that the ratio of the fractions is around 1. We do this by
1771 | making sure that both numbers have bit #DBL_MANT_DIG-32-1 (hidden bit)
1772 | set, even if they were denormalized to start with.
1773 | Thus, the result will satisfy: 2 > result > 1/2.
1774 andl d7,d4 | and isolate exponent in d4
1775 beq Ldivdf$a$den | if exponent is zero we have a denormalized
1776 andl d6,d0 | and isolate fraction
1777 orl IMM (0x00100000),d0 | and put hidden bit back
1778 swap d4 | I like exponents in the first byte
1779 #ifndef __mcoldfire__
1788 orl IMM (0x00100000),d2
1790 #ifndef __mcoldfire__
1796 #ifndef __mcoldfire__
1797 subw d5,d4 | subtract exponents
1798 addw IMM (D_BIAS),d4 | and add bias
1800 subl d5,d4 | subtract exponents
1801 addl IMM (D_BIAS),d4 | and add bias
1804 | We are now ready to do the division. We have prepared things in such a way
1805 | that the ratio of the fractions will be less than 2 but greater than 1/2.
1806 | At this point the registers in use are:
1807 | d0-d1 hold a (first operand, bit DBL_MANT_DIG-32=0, bit
1808 | DBL_MANT_DIG-1-32=1)
1809 | d2-d3 hold b (second operand, bit DBL_MANT_DIG-32=1)
1810 | d4 holds the difference of the exponents, corrected by the bias
1811 | a0 holds the sign of the ratio
1813 | To do the rounding correctly we need to keep information about the
1814 | nonsignificant bits. One way to do this would be to do the division
1815 | using four registers; another is to use two registers (as originally
1816 | I did), but use a sticky bit to preserve information about the
1817 | fractional part. Note that we can keep that info in a1, which is not
1819 movel IMM (0),d6 | d6-d7 will hold the result
1821 movel IMM (0),a1 | and a1 will hold the sticky bit
1823 movel IMM (DBL_MANT_DIG-32+1),d5
1825 1: cmpl d0,d2 | is a < b?
1826 bhi 3f | if b > a skip the following
1827 beq 4f | if d0==d2 check d1 and d3
1829 subxl d2,d0 | a <-- a - b
1830 bset d5,d6 | set the corresponding bit in d6
1831 3: addl d1,d1 | shift a by 1
1833 #ifndef __mcoldfire__
1834 dbra d5,1b | and branch back
1840 4: cmpl d1,d3 | here d0==d2, so check d1 and d3
1841 bhi 3b | if d1 > d2 skip the subtraction
1842 bra 2b | else go do it
1844 | Here we have to start setting the bits in the second long.
1845 movel IMM (31),d5 | again d5 is counter
1847 1: cmpl d0,d2 | is a < b?
1848 bhi 3f | if b > a skip the following
1849 beq 4f | if d0==d2 check d1 and d3
1851 subxl d2,d0 | a <-- a - b
1852 bset d5,d7 | set the corresponding bit in d7
1853 3: addl d1,d1 | shift a by 1
1855 #ifndef __mcoldfire__
1856 dbra d5,1b | and branch back
1862 4: cmpl d1,d3 | here d0==d2, so check d1 and d3
1863 bhi 3b | if d1 > d2 skip the subtraction
1864 bra 2b | else go do it
1866 | Now go ahead checking until we hit a one, which we store in d2.
1867 movel IMM (DBL_MANT_DIG),d5
1868 1: cmpl d2,d0 | is a < b?
1869 bhi 4f | if b < a, exit
1870 beq 3f | if d0==d2 check d1 and d3
1871 2: addl d1,d1 | shift a by 1
1873 #ifndef __mcoldfire__
1874 dbra d5,1b | and branch back
1879 movel IMM (0),d2 | here no sticky bit was found
1882 3: cmpl d1,d3 | here d0==d2, so check d1 and d3
1883 bhi 2b | if d1 > d2 go back
1885 | Here put the sticky bit in d2-d3 (in the position which actually corresponds
1886 | to it; if you don't do
this the algorithm loses
in some cases
).
'
1889 #ifndef __mcoldfire__
1890 subw IMM (DBL_MANT_DIG),d5
1894 subl IMM (DBL_MANT_DIG),d5
1901 #ifndef __mcoldfire__
1908 | Finally we are finished! Move the longs in the address registers to
1909 | their final destination:
1914 | Here we have finished the division, with the result in d0-d1-d2-d3, with
1915 | 2^21 <= d6 < 2^23. Thus bit 23 is not set, but bit 22 could be set.
1916 | If it is not, then definitely bit 21 is set. Normalize so bit 22 is
1918 btst IMM (DBL_MANT_DIG-32+1),d0
1920 #ifndef __mcoldfire__
1943 | Now round, check for over- and underflow, and exit.
1944 movel a0,d7 | restore sign bit to d7
1945 moveq IMM (DIVIDE),d5
1949 moveq IMM (DIVIDE),d5
1953 | If a is zero check to see whether b is zero also. In that case return
1954 | NaN; then check if b is NaN, and return NaN also in that case. Else
1956 moveq IMM (DIVIDE),d5
1960 beq Ld$inop | if b is also zero return NaN
1961 cmpl IMM (0x7ff00000),d2 | check for NaN
1966 1: movel IMM (0),d0 | else return zero
1968 PICLEA SYM (_fpCCR),a0 | clear exception flags
1970 #ifndef __mcoldfire__
1974 | XXX if frame pointer is ever removed, stack pointer must
1981 moveq IMM (DIVIDE),d5
1982 | If we got here a is not zero. Check if a is NaN; in that case return NaN,
1983 | else return +/-INFINITY. Remember that a is in d0 with the sign bit
1985 movel a0,d7 | put a's sign bit back
in d7
'
1986 cmpl IMM (0x7ff00000),d0 | compare d0 with INFINITY
1987 bhi Ld$inop | if larger it is NaN
1990 bra Ld$div$0 | else signal DIVIDE_BY_ZERO
1993 moveq IMM (DIVIDE),d5
1994 | If d2 == 0x7ff00000 we have to check d3.
1996 bne Ld$inop | if d3 <> 0, b is NaN
1997 bra Ld$underflow | else b is +/-INFINITY, so signal underflow
2000 moveq IMM (DIVIDE),d5
2001 | If d0 == 0x7ff00000 we have to check d1.
2003 bne Ld$inop | if d1 <> 0, a is NaN
2004 | If a is INFINITY we have to check b
2005 cmpl d7,d2 | compare b with INFINITY
2006 bge Ld$inop | if b is NaN or INFINITY return NaN
2009 bra Ld$overflow | else return overflow
2011 | If a number is denormalized we put an exponent of 1 but do not put the
2012 | bit back into the fraction.
2016 1: addl d1,d1 | shift a left until bit 20 is set
2018 #ifndef __mcoldfire__
2019 subw IMM (1),d4 | and adjust exponent
2021 subl IMM (1),d4 | and adjust exponent
2023 btst IMM (DBL_MANT_DIG-32-1),d0
2030 1: addl d3,d3 | shift b left until bit 20 is set
2032 #ifndef __mcoldfire__
2033 subw IMM (1),d5 | and adjust exponent
2035 subql IMM (1),d5 | and adjust exponent
2037 btst IMM (DBL_MANT_DIG-32-1),d2
2042 | This is a common exit point for __muldf3 and __divdf3. When they enter
2043 | this point the sign of the result is in d7, the result in d0-d1, normalized
2044 | so that 2^21 <= d0 < 2^22, and the exponent is in the lower byte of d4.
2046 | First check for underlow in the exponent:
2047 #ifndef __mcoldfire__
2048 cmpw IMM (-DBL_MANT_DIG-1),d4
2050 cmpl IMM (-DBL_MANT_DIG-1),d4
2053 | It could happen that the exponent is less than 1, in which case the
2054 | number is denormalized. In this case we shift right and adjust the
2055 | exponent until it becomes 1 or the fraction is zero (in the latter case
2056 | we signal underflow and return zero).
2058 movel IMM (0),d6 | use d6-d7 to collect bits flushed right
2059 movel d6,d7 | use d6-d7 to collect bits flushed right
2060 #ifndef __mcoldfire__
2061 cmpw IMM (1),d4 | if the exponent is less than 1 we
2063 cmpl IMM (1),d4 | if the exponent is less than 1 we
2065 bge 2f | have to shift right (denormalize)
2067 #ifndef __mcoldfire__
2068 addw IMM (1),d4 | adjust the exponent
2069 lsrl IMM (1),d0 | shift right once
2075 cmpw IMM (1),d4 | is the exponent 1 already?
2077 addl IMM (1),d4 | adjust the exponent
2099 cmpl IMM (1),d4 | is the exponent 1 already?
2101 beq 2f | if not loop back
2103 bra Ld$underflow | safety check, shouldn't execute
'
2104 2: orl d6,d2 | this is a trick so we don't lose
'
2105 orl d7,d3 | the bits which were flushed right
2106 movel a0,d7 | get back sign bit into d7
2107 | Now call the rounding routine (which takes care of denormalized numbers):
2108 lea pc@(Lround$0),a0 | to return from rounding routine
2109 PICLEA SYM (_fpCCR),a1 | check the rounding mode
2110 #ifdef __mcoldfire__
2113 movew a1@(6),d6 | rounding mode in d6
2114 beq Lround$to$nearest
2115 #ifndef __mcoldfire__
2116 cmpw IMM (ROUND_TO_PLUS),d6
2118 cmpl IMM (ROUND_TO_PLUS),d6
2124 | Here we have a correctly rounded result (either normalized or denormalized).
2126 | Here we should have either a normalized number or a denormalized one, and
2127 | the exponent is necessarily larger or equal to 1 (so we don't have to
'
2128 | check again for underflow!). We have to check for overflow or for a
2129 | denormalized number (which also signals underflow).
2130 | Check for overflow (i.e., exponent >= 0x7ff).
2131 #ifndef __mcoldfire__
2132 cmpw IMM (0x07ff),d4
2134 cmpl IMM (0x07ff),d4
2137 | Now check for a denormalized number (exponent==0):
2141 | Put back the exponents and sign and return.
2142 #ifndef __mcoldfire__
2143 lslw IMM (4),d4 | exponent back to fourth byte
2145 lsll IMM (4),d4 | exponent back to fourth byte
2147 bclr IMM (DBL_MANT_DIG-32-1),d0
2148 swap d0 | and put back exponent
2149 #ifndef __mcoldfire__
2155 orl d7,d0 | and sign also
2157 PICLEA SYM (_fpCCR),a0
2159 #ifndef __mcoldfire__
2163 | XXX if frame pointer is ever removed, stack pointer must
2169 |=============================================================================
2171 |=============================================================================
2173 | double __negdf2(double, double);
2175 #ifndef __mcoldfire__
2182 moveq IMM (NEGATE),d5
2183 movel a6@(8),d0 | get number to negate in d0-d1
2185 bchg IMM (31),d0 | negate
2186 movel d0,d2 | make a positive copy (for the tests)
2188 movel d2,d4 | check for zero
2190 beq 2f | if zero (either sign) return +zero
2191 cmpl IMM (0x7ff00000),d2 | compare to +INFINITY
2192 blt 1f | if finite, return
2193 bhi Ld$inop | if larger (fraction not zero) is NaN
2194 tstl d1 | if d2 == 0x7ff00000 check d1
2196 movel d0,d7 | else get sign and return INFINITY
2197 andl IMM (0x80000000),d7
2199 1: PICLEA SYM (_fpCCR),a0
2201 #ifndef __mcoldfire__
2205 | XXX if frame pointer is ever removed, stack pointer must
2213 |=============================================================================
2215 |=============================================================================
2221 | int __cmpdf2(double, double);
2223 #ifndef __mcoldfire__
2225 moveml d2-d7,sp@- | save registers
2230 moveq IMM (COMPARE),d5
2231 movel a6@(8),d0 | get first operand
2233 movel a6@(16),d2 | get second operand
2235 | First check if a and/or b are (+/-) zero and in that case clear
2237 movel d0,d6 | copy signs into d6 (a) and d7(b)
2238 bclr IMM (31),d0 | and clear signs in d0 and d2
2241 cmpl IMM (0x7fff0000),d0 | check for a == NaN
2242 bhi Ld$inop | if d0 > 0x7ff00000, a is NaN
2243 beq Lcmpdf$a$nf | if equal can be INFINITY, so check d1
2244 movel d0,d4 | copy into d4 to test for zero
2248 cmpl IMM (0x7fff0000),d2 | check for b == NaN
2249 bhi Ld$inop | if d2 > 0x7ff00000, b is NaN
2250 beq Lcmpdf$b$nf | if equal can be INFINITY, so check d3
2258 | If the signs are not equal check if a >= 0
2260 bpl Lcmpdf$a$gt$b | if (a >= 0 && b < 0) => a > b
2261 bmi Lcmpdf$b$gt$a | if (a < 0 && b >= 0) => a < b
2263 | If the signs are equal check for < 0
2266 | If both are negative exchange them
2267 #ifndef __mcoldfire__
2279 | Now that they are positive we just compare them as longs (does this also
2280 | work for denormalized numbers?).
2282 bhi Lcmpdf$b$gt$a | |b| > |a|
2283 bne Lcmpdf$a$gt$b | |b| < |a|
2284 | If we got here d0 == d2, so we compare d1 and d3.
2286 bhi Lcmpdf$b$gt$a | |b| > |a|
2287 bne Lcmpdf$a$gt$b | |b| < |a|
2288 | If we got here a == b.
2289 movel IMM (EQUAL),d0
2290 #ifndef __mcoldfire__
2291 moveml sp@+,d2-d7 | put back the registers
2294 | XXX if frame pointer is ever removed, stack pointer must
2300 movel IMM (GREATER),d0
2301 #ifndef __mcoldfire__
2302 moveml sp@+,d2-d7 | put back the registers
2305 | XXX if frame pointer is ever removed, stack pointer must
2312 #ifndef __mcoldfire__
2313 moveml sp@+,d2-d7 | put back the registers
2316 | XXX if frame pointer is ever removed, stack pointer must
2339 |=============================================================================
2341 |=============================================================================
2343 | The rounding routines expect the number to be normalized in registers
2344 | d0-d1-d2-d3, with the exponent in register d4. They assume that the
2345 | exponent is larger or equal to 1. They return a properly normalized number
2346 | if possible, and a denormalized number otherwise. The exponent is returned
2350 | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
2351 | Here we assume that the exponent is not too small (this should be checked
2352 | before entering the rounding routine), but the number could be denormalized.
2354 | Check for denormalized numbers:
2355 1: btst IMM (DBL_MANT_DIG-32),d0
2356 bne 2f | if set the number is normalized
2357 | Normalize shifting left until bit #DBL_MANT_DIG-32 is set or the exponent
2358 | is one (remember that a denormalized number corresponds to an
2359 | exponent of -D_BIAS+1).
2360 #ifndef __mcoldfire__
2361 cmpw IMM (1),d4 | remember that the exponent is at least one
2363 cmpl IMM (1),d4 | remember that the exponent is at least one
2365 beq 2f | an exponent of one means denormalized
2366 addl d3,d3 | else shift and adjust the exponent
2370 #ifndef __mcoldfire__
2377 | Now round: we do it as follows: after the shifting we can write the
2378 | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
2379 | If delta < 1, do nothing. If delta > 1, add 1 to f.
2380 | If delta == 1, we make sure the rounded number will be even (odd?)
2382 btst IMM (0),d1 | is delta < 1?
2383 beq 2f | if so, do not do anything
2384 orl d2,d3 | is delta == 1?
2385 bne 1f | if so round to even
2387 andl IMM (2),d3 | bit 1 is the last significant bit
2392 1: movel IMM (1),d3 | else add 1
2396 | Shift right once (because we used bit #DBL_MANT_DIG-32!).
2398 #ifndef __mcoldfire__
2409 | Now check again bit #DBL_MANT_DIG-32 (rounding could have produced a
2410 | 'fraction overflow
' ...).
2411 btst IMM (DBL_MANT_DIG-32),d0
2413 #ifndef __mcoldfire__
2426 | If bit #DBL_MANT_DIG-32-1 is clear we have a denormalized number, so we
2427 | have to put the exponent to zero and return a denormalized number.
2428 btst IMM (DBL_MANT_DIG-32-1),d0
2438 #endif /* L_double */
2443 .globl $_exception_handler
2445 QUIET_NaN = 0xffffffff
2446 SIGNL_NaN = 0x7f800001
2447 INFINITY = 0x7f800000
2451 FLT_MAX_EXP = F_MAX_EXP - F_BIAS
2452 FLT_MIN_EXP = 1 - F_BIAS
2455 INEXACT_RESULT = 0x0001
2458 DIVIDE_BY_ZERO = 0x0008
2459 INVALID_OPERATION = 0x0010
2473 ROUND_TO_NEAREST = 0 | round result to nearest representable value
2474 ROUND_TO_ZERO = 1 | round result towards zero
2475 ROUND_TO_PLUS = 2 | round result towards plus infinity
2476 ROUND_TO_MINUS = 3 | round result towards minus infinity
2480 .globl SYM (__addsf3)
2481 .globl SYM (__subsf3)
2482 .globl SYM (__mulsf3)
2483 .globl SYM (__divsf3)
2484 .globl SYM (__negsf2)
2485 .globl SYM (__cmpsf2)
2487 | These are common routines to return and signal exceptions.
2493 | Return and signal a denormalized number
2495 moveq IMM (INEXACT_RESULT+UNDERFLOW),d7
2496 moveq IMM (SINGLE_FLOAT),d6
2497 PICJUMP $_exception_handler
2501 | Return a properly signed INFINITY and set the exception flags
2502 movel IMM (INFINITY),d0
2504 moveq IMM (INEXACT_RESULT+OVERFLOW),d7
2505 moveq IMM (SINGLE_FLOAT),d6
2506 PICJUMP $_exception_handler
2509 | Return 0 and set the exception flags
2511 moveq IMM (INEXACT_RESULT+UNDERFLOW),d7
2512 moveq IMM (SINGLE_FLOAT),d6
2513 PICJUMP $_exception_handler
2516 | Return a quiet NaN and set the exception flags
2517 movel IMM (QUIET_NaN),d0
2518 moveq IMM (INEXACT_RESULT+INVALID_OPERATION),d7
2519 moveq IMM (SINGLE_FLOAT),d6
2520 PICJUMP $_exception_handler
2523 | Return a properly signed INFINITY and set the exception flags
2524 movel IMM (INFINITY),d0
2526 moveq IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7
2527 moveq IMM (SINGLE_FLOAT),d6
2528 PICJUMP $_exception_handler
2530 |=============================================================================
2531 |=============================================================================
2532 | single precision routines
2533 |=============================================================================
2534 |=============================================================================
2536 | A single precision floating point number (float) has the format:
2539 | unsigned int sign : 1; /* sign bit */
2540 | unsigned int exponent : 8; /* exponent, shifted by 126 */
2541 | unsigned int fraction : 23; /* fraction */
2544 | Thus sizeof(float) = 4 (32 bits).
2546 | All the routines are callable from C programs, and return the result
2547 | in the single register d0. They also preserve all registers except
2550 |=============================================================================
2552 |=============================================================================
2554 | float __subsf3(float, float);
2556 bchg IMM (31),sp@(8) | change sign of second operand
2558 |=============================================================================
2560 |=============================================================================
2562 | float __addsf3(float, float);
2564 #ifndef __mcoldfire__
2565 link a6,IMM (0) | everything will be done in registers
2566 moveml d2-d7,sp@- | save all data registers but d0-d1
2571 movel a6@(8),d0 | get first operand
2572 movel a6@(12),d1 | get second operand
2573 movel d0,d6 | get d0's sign bit
'
2574 addl d0,d0 | check and clear sign bit of a
2575 beq Laddsf$b | if zero return second operand
2576 movel d1,d7 | save b's sign bit
'
2577 addl d1,d1 | get rid of sign bit
2578 beq Laddsf$a | if zero return first operand
2580 movel d6,a0 | save signs in address registers
2581 movel d7,a1 | so we can use d6 and d7
2583 | Get the exponents and check for denormalized and/or infinity.
2585 movel IMM (0x00ffffff),d4 | mask to get fraction
2586 movel IMM (0x01000000),d5 | mask to put hidden bit back
2588 movel d0,d6 | save a to get exponent
2589 andl d4,d0 | get fraction in d0
2590 notl d4 | make d4 into a mask for the exponent
2591 andl d4,d6 | get exponent in d6
2592 beq Laddsf$a$den | branch if a is denormalized
2593 cmpl d4,d6 | check for INFINITY or NaN
2595 swap d6 | put exponent into first word
2596 orl d5,d0 | and put hidden bit back
2598 | Now we have a's exponent
in d6
(second
byte) and the mantissa
in d0.
'
2599 movel d1,d7 | get exponent in d7
2601 beq Laddsf$b$den | branch if b is denormalized
2602 cmpl d4,d7 | check for INFINITY or NaN
2604 swap d7 | put exponent into first word
2605 notl d4 | make d4 into a mask for the fraction
2606 andl d4,d1 | get fraction in d1
2607 orl d5,d1 | and put hidden bit back
2609 | Now we have b's exponent
in d7
(second
byte) and the mantissa
in d1.
'
2611 | Note that the hidden bit corresponds to bit #FLT_MANT_DIG-1, and we
2612 | shifted right once, so bit #FLT_MANT_DIG is set (so we have one extra
2615 movel d1,d2 | move b to d2, since we want to use
2616 | two registers to do the sum
2617 movel IMM (0),d1 | and clear the new ones
2620 | Here we shift the numbers in registers d0 and d1 so the exponents are the
2621 | same, and put the largest exponent in d6. Note that we are using two
2622 | registers for each number (see the discussion by D. Knuth in "Seminumerical
2624 #ifndef __mcoldfire__
2625 cmpw d6,d7 | compare exponents
2627 cmpl d6,d7 | compare exponents
2629 beq Laddsf$3 | if equal don't shift
'
2630 bhi 5f | branch if second exponent largest
2632 subl d6,d7 | keep the largest exponent
2634 #ifndef __mcoldfire__
2635 lsrw IMM (8),d7 | put difference in lower byte
2637 lsrl IMM (8),d7 | put difference in lower byte
2639 | if difference is too large we don't shift
(actually
, we can just exit
) '
2640 #ifndef __mcoldfire__
2641 cmpw IMM (FLT_MANT_DIG+2),d7
2643 cmpl IMM (FLT_MANT_DIG+2),d7
2646 #ifndef __mcoldfire__
2647 cmpw IMM (16),d7 | if difference >= 16 swap
2649 cmpl IMM (16),d7 | if difference >= 16 swap
2653 #ifndef __mcoldfire__
2659 #ifndef __mcoldfire__
2660 lsrl IMM (1),d2 | shift right second operand
2678 #ifndef __mcoldfire__
2683 bne 2b | if still more bits, go back to normal case
2686 #ifndef __mcoldfire__
2687 exg d6,d7 | exchange the exponents
2693 subl d6,d7 | keep the largest exponent
2695 #ifndef __mcoldfire__
2696 lsrw IMM (8),d7 | put difference in lower byte
2698 lsrl IMM (8),d7 | put difference in lower byte
2700 | if difference is too large we don't shift
(and exit
!) '
2701 #ifndef __mcoldfire__
2702 cmpw IMM (FLT_MANT_DIG+2),d7
2704 cmpl IMM (FLT_MANT_DIG+2),d7
2707 #ifndef __mcoldfire__
2708 cmpw IMM (16),d7 | if difference >= 16 swap
2710 cmpl IMM (16),d7 | if difference >= 16 swap
2714 #ifndef __mcoldfire__
2720 #ifndef __mcoldfire__
2721 lsrl IMM (1),d0 | shift right first operand
2739 #ifndef __mcoldfire__
2744 bne 6b | if still more bits, go back to normal case
2745 | otherwise we fall through
2747 | Now we have a in d0-d1, b in d2-d3, and the largest exponent in d6 (the
2748 | signs are stored in a0 and a1).
2751 | Here we have to decide whether to add or subtract the numbers
2752 #ifndef __mcoldfire__
2753 exg d6,a0 | get signs back
2754 exg d7,a1 | and save the exponents
2763 eorl d6,d7 | combine sign bits
2764 bmi Lsubsf$0 | if negative a and b have opposite
2765 | sign so we actually subtract the
2768 | Here we have both positive or both negative
2769 #ifndef __mcoldfire__
2770 exg d6,a0 | now we have the exponent in d6
2776 movel a0,d7 | and sign in d7
2777 andl IMM (0x80000000),d7
2778 | Here we do the addition.
2781 | Note: now we have d2, d3, d4 and d5 to play with!
2783 | Put the exponent, in the first byte, in d2, to use the "standard" rounding
2786 #ifndef __mcoldfire__
2792 | Before rounding normalize so bit #FLT_MANT_DIG is set (we will consider
2793 | the case of denormalized numbers in the rounding routine itself).
2794 | As in the addition (not in the subtraction!) we could have set
2795 | one more bit we check this:
2796 btst IMM (FLT_MANT_DIG+1),d0
2798 #ifndef __mcoldfire__
2810 lea pc@(Laddsf$4),a0 | to return from rounding routine
2811 PICLEA SYM (_fpCCR),a1 | check the rounding mode
2812 #ifdef __mcoldfire__
2815 movew a1@(6),d6 | rounding mode in d6
2816 beq Lround$to$nearest
2817 #ifndef __mcoldfire__
2818 cmpw IMM (ROUND_TO_PLUS),d6
2820 cmpl IMM (ROUND_TO_PLUS),d6
2826 | Put back the exponent, but check for overflow.
2827 #ifndef __mcoldfire__
2833 bclr IMM (FLT_MANT_DIG-1),d0
2834 #ifndef __mcoldfire__
2847 | We are here if a > 0 and b < 0 (sign bits cleared).
2848 | Here we do the subtraction.
2849 movel d6,d7 | put sign in d7
2850 andl IMM (0x80000000),d7
2852 subl d3,d1 | result in d0-d1
2854 beq Laddsf$ret | if zero just exit
2855 bpl 1f | if positive skip the following
2856 bchg IMM (31),d7 | change sign bit in d7
2860 #ifndef __mcoldfire__
2861 exg d2,a0 | now we have the exponent in d2
2862 lsrw IMM (8),d2 | put it in the first byte
2867 lsrl IMM (8),d2 | put it in the first byte
2870 | Now d0-d1 is positive and the sign bit is in d7.
2872 | Note that we do not have to normalize, since in the subtraction bit
2873 | #FLT_MANT_DIG+1 is never set, and denormalized numbers are handled by
2874 | the rounding routines themselves.
2875 lea pc@(Lsubsf$1),a0 | to return from rounding routine
2876 PICLEA SYM (_fpCCR),a1 | check the rounding mode
2877 #ifdef __mcoldfire__
2880 movew a1@(6),d6 | rounding mode in d6
2881 beq Lround$to$nearest
2882 #ifndef __mcoldfire__
2883 cmpw IMM (ROUND_TO_PLUS),d6
2885 cmpl IMM (ROUND_TO_PLUS),d6
2891 | Put back the exponent (we can't have overflow
!).
'
2892 bclr IMM (FLT_MANT_DIG-1),d0
2893 #ifndef __mcoldfire__
2902 | If one of the numbers was too small (difference of exponents >=
2903 | FLT_MANT_DIG+2) we return the other (and now we don't have to
'
2904 | check for finiteness or zero).
2907 PICLEA SYM (_fpCCR),a0
2909 #ifndef __mcoldfire__
2910 moveml sp@+,d2-d7 | restore data registers
2913 | XXX if frame pointer is ever removed, stack pointer must
2916 unlk a6 | and return
2921 PICLEA SYM (_fpCCR),a0
2923 #ifndef __mcoldfire__
2924 moveml sp@+,d2-d7 | restore data registers
2927 | XXX if frame pointer is ever removed, stack pointer must
2930 unlk a6 | and return
2933 | If the numbers are denormalized remember to put exponent equal to 1.
2936 movel d5,d6 | d5 contains 0x01000000
2943 notl d4 | make d4 into a mask for the fraction
2944 | (this was not executed after the jump)
2947 | The rest is mainly code for the different results which can be
2948 | returned (checking always for +/-INFINITY and NaN).
2951 | Return b (if a is zero).
2955 | Return a (if b is zero).
2959 | We have to check for NaN and +/-infty.
2961 andl IMM (0x80000000),d7 | put sign in d7
2962 bclr IMM (31),d0 | clear sign
2963 cmpl IMM (INFINITY),d0 | check for infty or NaN
2965 movel d0,d0 | check for zero (we do this because we don't
'
2966 bne Laddsf$ret | want to return -0 by mistake
2967 bclr IMM (31),d7 | if zero be sure to clear sign
2968 bra Laddsf$ret | if everything OK just return
2970 | The value to be returned is either +/-infty or NaN
2971 andl IMM (0x007fffff),d0 | check for NaN
2972 bne Lf$inop | if mantissa not zero is NaN
2976 | Normal exit (a and b nonzero, result is not NaN nor +/-infty).
2977 | We have to clear the exception flags (just the exception type).
2978 PICLEA SYM (_fpCCR),a0
2980 orl d7,d0 | put sign bit
2981 #ifndef __mcoldfire__
2982 moveml sp@+,d2-d7 | restore data registers
2985 | XXX if frame pointer is ever removed, stack pointer must
2988 unlk a6 | and return
2992 | Return a denormalized number (for addition we don't signal underflow
) '
2993 lsrl IMM (1),d0 | remember to shift right back once
2994 bra Laddsf$ret | and return
2996 | Note: when adding two floats of the same sign if either one is
2997 | NaN we return NaN without regard to whether the other is finite or
2998 | not. When subtracting them (i.e., when adding two numbers of
2999 | opposite signs) things are more complicated: if both are INFINITY
3000 | we return NaN, if only one is INFINITY and the other is NaN we return
3001 | NaN, but if it is finite we return INFINITY with the corresponding sign.
3005 | This could be faster but it is not worth the effort, since it is not
3006 | executed very often. We sacrifice speed for clarity here.
3007 movel a6@(8),d0 | get the numbers back (remember that we
3008 movel a6@(12),d1 | did some processing already)
3009 movel IMM (INFINITY),d4 | useful constant (INFINITY)
3010 movel d0,d2 | save sign bits
3012 bclr IMM (31),d0 | clear sign bits
3014 | We know that one of them is either NaN of +/-INFINITY
3015 | Check for NaN (if either one is NaN return NaN)
3016 cmpl d4,d0 | check first a (d0)
3018 cmpl d4,d1 | check now b (d1)
3020 | Now comes the check for +/-INFINITY. We know that both are (maybe not
3021 | finite) numbers, but we have to check if both are infinite whether we
3022 | are adding or subtracting them.
3023 eorl d3,d2 | to check sign bits
3026 andl IMM (0x80000000),d7 | get (common) sign bit
3029 | We know one (or both) are infinite, so we test for equality between the
3030 | two numbers (if they are equal they have to be infinite both, so we
3032 cmpl d1,d0 | are both infinite?
3033 beq Lf$inop | if so return NaN
3036 andl IMM (0x80000000),d7 | get a's sign bit
'
3037 cmpl d4,d0 | test now for infinity
3038 beq Lf$infty | if a is INFINITY return with this sign
3039 bchg IMM (31),d7 | else we know b is INFINITY and has
3040 bra Lf$infty | the opposite sign
3042 |=============================================================================
3044 |=============================================================================
3046 | float __mulsf3(float, float);
3048 #ifndef __mcoldfire__
3055 movel a6@(8),d0 | get a into d0
3056 movel a6@(12),d1 | and b into d1
3057 movel d0,d7 | d7 will hold the sign of the product
3059 andl IMM (0x80000000),d7
3060 movel IMM (INFINITY),d6 | useful constant (+INFINITY)
3061 movel d6,d5 | another (mask for fraction)
3063 movel IMM (0x00800000),d4 | this is to put hidden bit back
3064 bclr IMM (31),d0 | get rid of a's sign bit
'
3066 beq Lmulsf$a$0 | branch if a is zero
3067 bclr IMM (31),d1 | get rid of b's sign bit
'
3069 beq Lmulsf$b$0 | branch if b is zero
3070 cmpl d6,d0 | is a big?
3071 bhi Lmulsf$inop | if a is NaN return NaN
3072 beq Lmulsf$inf | if a is INFINITY we have to check b
3073 cmpl d6,d1 | now compare b with INFINITY
3074 bhi Lmulsf$inop | is b NaN?
3075 beq Lmulsf$overflow | is b INFINITY?
3076 | Here we have both numbers finite and nonzero (and with no sign bit).
3077 | Now we get the exponents into d2 and d3.
3078 andl d6,d2 | and isolate exponent in d2
3079 beq Lmulsf$a$den | if exponent is zero we have a denormalized
3080 andl d5,d0 | and isolate fraction
3081 orl d4,d0 | and put hidden bit back
3082 swap d2 | I like exponents in the first byte
3083 #ifndef __mcoldfire__
3094 #ifndef __mcoldfire__
3100 #ifndef __mcoldfire__
3101 addw d3,d2 | add exponents
3102 subw IMM (F_BIAS+1),d2 | and subtract bias (plus one)
3104 addl d3,d2 | add exponents
3105 subl IMM (F_BIAS+1),d2 | and subtract bias (plus one)
3108 | We are now ready to do the multiplication. The situation is as follows:
3109 | both a and b have bit FLT_MANT_DIG-1 set (even if they were
3110 | denormalized to start with!), which means that in the product
3111 | bit 2*(FLT_MANT_DIG-1) (that is, bit 2*FLT_MANT_DIG-2-32 of the
3112 | high long) is set.
3114 | To do the multiplication let us move the number a little bit around ...
3115 movel d1,d6 | second operand in d6
3116 movel d0,d5 | first operand in d4-d5
3118 movel d4,d1 | the sums will go in d0-d1
3121 | now bit FLT_MANT_DIG-1 becomes bit 31:
3122 lsll IMM (31-FLT_MANT_DIG+1),d6
3124 | Start the loop (we loop #FLT_MANT_DIG times):
3125 moveq IMM (FLT_MANT_DIG-1),d3
3126 1: addl d1,d1 | shift sum
3128 lsll IMM (1),d6 | get bit bn
3129 bcc 2f | if not set skip sum
3133 #ifndef __mcoldfire__
3134 dbf d3,1b | loop back
3140 | Now we have the product in d0-d1, with bit (FLT_MANT_DIG - 1) + FLT_MANT_DIG
3141 | (mod 32) of d0 set. The first thing to do now is to normalize it so bit
3142 | FLT_MANT_DIG is set (to do the rounding).
3143 #ifndef __mcoldfire__
3147 andw IMM (0x03ff),d3
3148 andw IMM (0xfd00),d1
3157 andl IMM (0xfffffd00),d1
3162 #ifndef __mcoldfire__
3168 moveq IMM (MULTIPLY),d5
3170 btst IMM (FLT_MANT_DIG+1),d0
3172 #ifndef __mcoldfire__
3187 moveq IMM (MULTIPLY),d5
3191 moveq IMM (MULTIPLY),d5
3195 moveq IMM (MULTIPLY),d5
3196 | If either is NaN return NaN; else both are (maybe infinite) numbers, so
3197 | return INFINITY with the correct sign (which is in d7).
3198 cmpl d6,d1 | is b NaN?
3199 bhi Lf$inop | if so return NaN
3200 bra Lf$overflow | else return +/-INFINITY
3202 | If either number is zero return zero, unless the other is +/-INFINITY,
3203 | or NaN, in which case we return NaN.
3205 | Here d1 (==b) is zero.
3206 movel d1,d0 | put b into d0 (just a zero)
3207 movel a6@(8),d1 | get a again to check for non-finiteness
3210 movel a6@(12),d1 | get b again to check for non-finiteness
3211 1: bclr IMM (31),d1 | clear sign bit
3212 cmpl IMM (INFINITY),d1 | and check for a large exponent
3213 bge Lf$inop | if b is +/-INFINITY or NaN return NaN
3214 PICLEA SYM (_fpCCR),a0 | else return zero
3216 #ifndef __mcoldfire__
3220 | XXX if frame pointer is ever removed, stack pointer must
3226 | If a number is denormalized we put an exponent of 1 but do not put the
3227 | hidden bit back into the fraction; instead we shift left until bit 23
3228 | (the hidden bit) is set, adjusting the exponent accordingly. We do this
3229 | to ensure that the product of the fractions is close to 1.
3233 1: addl d0,d0 | shift a left (until bit 23 is set)
3234 #ifndef __mcoldfire__
3235 subw IMM (1),d2 | and adjust exponent
3237 subql IMM (1),d2 | and adjust exponent
3239 btst IMM (FLT_MANT_DIG-1),d0
3241 bra 1b | else loop back
3246 1: addl d1,d1 | shift b left until bit 23 is set
3247 #ifndef __mcoldfire__
3248 subw IMM (1),d3 | and adjust exponent
3250 subql IMM (1),d3 | and adjust exponent
3252 btst IMM (FLT_MANT_DIG-1),d1
3254 bra 1b | else loop back
3256 |=============================================================================
3258 |=============================================================================
3260 | float __divsf3(float, float);
3262 #ifndef __mcoldfire__
3269 movel a6@(8),d0 | get a into d0
3270 movel a6@(12),d1 | and b into d1
3271 movel d0,d7 | d7 will hold the sign of the result
3273 andl IMM (0x80000000),d7 |
3274 movel IMM (INFINITY),d6 | useful constant (+INFINITY)
3275 movel d6,d5 | another (mask for fraction)
3277 movel IMM (0x00800000),d4 | this is to put hidden bit back
3278 bclr IMM (31),d0 | get rid of a's sign bit
'
3280 beq Ldivsf$a$0 | branch if a is zero
3281 bclr IMM (31),d1 | get rid of b's sign bit
'
3283 beq Ldivsf$b$0 | branch if b is zero
3284 cmpl d6,d0 | is a big?
3285 bhi Ldivsf$inop | if a is NaN return NaN
3286 beq Ldivsf$inf | if a is INFINITY we have to check b
3287 cmpl d6,d1 | now compare b with INFINITY
3288 bhi Ldivsf$inop | if b is NaN return NaN
3289 beq Ldivsf$underflow
3290 | Here we have both numbers finite and nonzero (and with no sign bit).
3291 | Now we get the exponents into d2 and d3 and normalize the numbers to
3292 | ensure that the ratio of the fractions is close to 1. We do this by
3293 | making sure that bit #FLT_MANT_DIG-1 (hidden bit) is set.
3294 andl d6,d2 | and isolate exponent in d2
3295 beq Ldivsf$a$den | if exponent is zero we have a denormalized
3296 andl d5,d0 | and isolate fraction
3297 orl d4,d0 | and put hidden bit back
3298 swap d2 | I like exponents in the first byte
3299 #ifndef __mcoldfire__
3310 #ifndef __mcoldfire__
3316 #ifndef __mcoldfire__
3317 subw d3,d2 | subtract exponents
3318 addw IMM (F_BIAS),d2 | and add bias
3320 subl d3,d2 | subtract exponents
3321 addl IMM (F_BIAS),d2 | and add bias
3324 | We are now ready to do the division. We have prepared things in such a way
3325 | that the ratio of the fractions will be less than 2 but greater than 1/2.
3326 | At this point the registers in use are:
3327 | d0 holds a (first operand, bit FLT_MANT_DIG=0, bit FLT_MANT_DIG-1=1)
3328 | d1 holds b (second operand, bit FLT_MANT_DIG=1)
3329 | d2 holds the difference of the exponents, corrected by the bias
3330 | d7 holds the sign of the ratio
3331 | d4, d5, d6 hold some constants
3332 movel d7,a0 | d6-d7 will hold the ratio of the fractions
3336 moveq IMM (FLT_MANT_DIG+1),d3
3337 1: cmpl d0,d1 | is a < b?
3339 bset d3,d6 | set a bit in d6
3340 subl d1,d0 | if a >= b a <-- a-b
3341 beq 3f | if a is zero, exit
3342 2: addl d0,d0 | multiply a by 2
3343 #ifndef __mcoldfire__
3350 | Now we keep going to set the sticky bit ...
3351 moveq IMM (FLT_MANT_DIG),d3
3355 #ifndef __mcoldfire__
3364 #ifndef __mcoldfire__
3365 subw IMM (FLT_MANT_DIG),d3
3368 subl IMM (FLT_MANT_DIG),d3
3373 movel d6,d0 | put the ratio in d0-d1
3374 movel a0,d7 | get sign back
3376 | Because of the normalization we did before we are guaranteed that
3377 | d0 is smaller than 2^26 but larger than 2^24. Thus bit 26 is not set,
3378 | bit 25 could be set, and if it is not set then bit 24 is necessarily set.
3379 btst IMM (FLT_MANT_DIG+1),d0
3380 beq 1f | if it is not set, then bit 24 is set
3382 #ifndef __mcoldfire__
3388 | Now round, check for over- and underflow, and exit.
3389 moveq IMM (DIVIDE),d5
3393 moveq IMM (DIVIDE),d5
3397 moveq IMM (DIVIDE),d5
3401 moveq IMM (DIVIDE),d5
3405 moveq IMM (DIVIDE),d5
3406 | If a is zero check to see whether b is zero also. In that case return
3407 | NaN; then check if b is NaN, and return NaN also in that case. Else
3409 andl IMM (0x7fffffff),d1 | clear sign bit and test b
3410 beq Lf$inop | if b is also zero return NaN
3411 cmpl IMM (INFINITY),d1 | check for NaN
3413 movel IMM (0),d0 | else return zero
3414 PICLEA SYM (_fpCCR),a0 |
3416 #ifndef __mcoldfire__
3420 | XXX if frame pointer is ever removed, stack pointer must
3427 moveq IMM (DIVIDE),d5
3428 | If we got here a is not zero. Check if a is NaN; in that case return NaN,
3429 | else return +/-INFINITY. Remember that a is in d0 with the sign bit
3431 cmpl IMM (INFINITY),d0 | compare d0 with INFINITY
3432 bhi Lf$inop | if larger it is NaN
3433 bra Lf$div$0 | else signal DIVIDE_BY_ZERO
3436 moveq IMM (DIVIDE),d5
3437 | If a is INFINITY we have to check b
3438 cmpl IMM (INFINITY),d1 | compare b with INFINITY
3439 bge Lf$inop | if b is NaN or INFINITY return NaN
3440 bra Lf$overflow | else return overflow
3442 | If a number is denormalized we put an exponent of 1 but do not put the
3443 | bit back into the fraction.
3447 1: addl d0,d0 | shift a left until bit FLT_MANT_DIG-1 is set
3448 #ifndef __mcoldfire__
3449 subw IMM (1),d2 | and adjust exponent
3451 subl IMM (1),d2 | and adjust exponent
3453 btst IMM (FLT_MANT_DIG-1),d0
3460 1: addl d1,d1 | shift b left until bit FLT_MANT_DIG is set
3461 #ifndef __mcoldfire__
3462 subw IMM (1),d3 | and adjust exponent
3464 subl IMM (1),d3 | and adjust exponent
3466 btst IMM (FLT_MANT_DIG-1),d1
3471 | This is a common exit point for __mulsf3 and __divsf3.
3473 | First check for underlow in the exponent:
3474 #ifndef __mcoldfire__
3475 cmpw IMM (-FLT_MANT_DIG-1),d2
3477 cmpl IMM (-FLT_MANT_DIG-1),d2
3480 | It could happen that the exponent is less than 1, in which case the
3481 | number is denormalized. In this case we shift right and adjust the
3482 | exponent until it becomes 1 or the fraction is zero (in the latter case
3483 | we signal underflow and return zero).
3484 movel IMM (0),d6 | d6 is used temporarily
3485 #ifndef __mcoldfire__
3486 cmpw IMM (1),d2 | if the exponent is less than 1 we
3488 cmpl IMM (1),d2 | if the exponent is less than 1 we
3490 bge 2f | have to shift right (denormalize)
3492 #ifndef __mcoldfire__
3493 addw IMM (1),d2 | adjust the exponent
3494 lsrl IMM (1),d0 | shift right once
3496 roxrl IMM (1),d6 | d6 collect bits we would lose otherwise
3497 cmpw IMM (1),d2 | is the exponent 1 already?
3499 addql IMM (1),d2 | adjust the exponent
3509 cmpl IMM (1),d2 | is the exponent 1 already?
3511 beq 2f | if not loop back
3513 bra Lf$underflow | safety check, shouldn't execute
'
3514 2: orl d6,d1 | this is a trick so we don't lose
'
3515 | the extra bits which were flushed right
3516 | Now call the rounding routine (which takes care of denormalized numbers):
3517 lea pc@(Lround$0),a0 | to return from rounding routine
3518 PICLEA SYM (_fpCCR),a1 | check the rounding mode
3519 #ifdef __mcoldfire__
3522 movew a1@(6),d6 | rounding mode in d6
3523 beq Lround$to$nearest
3524 #ifndef __mcoldfire__
3525 cmpw IMM (ROUND_TO_PLUS),d6
3527 cmpl IMM (ROUND_TO_PLUS),d6
3533 | Here we have a correctly rounded result (either normalized or denormalized).
3535 | Here we should have either a normalized number or a denormalized one, and
3536 | the exponent is necessarily larger or equal to 1 (so we don't have to
'
3537 | check again for underflow!). We have to check for overflow or for a
3538 | denormalized number (which also signals underflow).
3539 | Check for overflow (i.e., exponent >= 255).
3540 #ifndef __mcoldfire__
3541 cmpw IMM (0x00ff),d2
3543 cmpl IMM (0x00ff),d2
3546 | Now check for a denormalized number (exponent==0).
3550 | Put back the exponents and sign and return.
3551 #ifndef __mcoldfire__
3552 lslw IMM (7),d2 | exponent back to fourth byte
3554 lsll IMM (7),d2 | exponent back to fourth byte
3556 bclr IMM (FLT_MANT_DIG-1),d0
3557 swap d0 | and put back exponent
3558 #ifndef __mcoldfire__
3564 orl d7,d0 | and sign also
3566 PICLEA SYM (_fpCCR),a0
3568 #ifndef __mcoldfire__
3572 | XXX if frame pointer is ever removed, stack pointer must
3578 |=============================================================================
3580 |=============================================================================
3582 | This is trivial and could be shorter if we didn't bother checking for NaN
'
3585 | float __negsf2(float);
3587 #ifndef __mcoldfire__
3594 moveq IMM (NEGATE),d5
3595 movel a6@(8),d0 | get number to negate in d0
3596 bchg IMM (31),d0 | negate
3597 movel d0,d1 | make a positive copy
3599 tstl d1 | check for zero
3600 beq 2f | if zero (either sign) return +zero
3601 cmpl IMM (INFINITY),d1 | compare to +INFINITY
3603 bhi Lf$inop | if larger (fraction not zero) is NaN
3604 movel d0,d7 | else get sign and return INFINITY
3605 andl IMM (0x80000000),d7
3607 1: PICLEA SYM (_fpCCR),a0
3609 #ifndef __mcoldfire__
3613 | XXX if frame pointer is ever removed, stack pointer must
3621 |=============================================================================
3623 |=============================================================================
3629 | int __cmpsf2(float, float);
3631 #ifndef __mcoldfire__
3633 moveml d2-d7,sp@- | save registers
3638 moveq IMM (COMPARE),d5
3639 movel a6@(8),d0 | get first operand
3640 movel a6@(12),d1 | get second operand
3641 | Check if either is NaN, and in that case return garbage and signal
3642 | INVALID_OPERATION. Check also if either is zero, and clear the signs
3645 andl IMM (0x7fffffff),d0
3647 cmpl IMM (0x7f800000),d0
3651 andl IMM (0x7fffffff),d1
3653 cmpl IMM (0x7f800000),d1
3659 | If the signs are not equal check if a >= 0
3661 bpl Lcmpsf$a$gt$b | if (a >= 0 && b < 0) => a > b
3662 bmi Lcmpsf$b$gt$a | if (a < 0 && b >= 0) => a < b
3664 | If the signs are equal check for < 0
3667 | If both are negative exchange them
3668 #ifndef __mcoldfire__
3676 | Now that they are positive we just compare them as longs (does this also
3677 | work for denormalized numbers?).
3679 bhi Lcmpsf$b$gt$a | |b| > |a|
3680 bne Lcmpsf$a$gt$b | |b| < |a|
3681 | If we got here a == b.
3682 movel IMM (EQUAL),d0
3683 #ifndef __mcoldfire__
3684 moveml sp@+,d2-d7 | put back the registers
3691 movel IMM (GREATER),d0
3692 #ifndef __mcoldfire__
3693 moveml sp@+,d2-d7 | put back the registers
3696 | XXX if frame pointer is ever removed, stack pointer must
3703 #ifndef __mcoldfire__
3704 moveml sp@+,d2-d7 | put back the registers
3707 | XXX if frame pointer is ever removed, stack pointer must
3720 |=============================================================================
3722 |=============================================================================
3724 | The rounding routines expect the number to be normalized in registers
3725 | d0-d1, with the exponent in register d2. They assume that the
3726 | exponent is larger or equal to 1. They return a properly normalized number
3727 | if possible, and a denormalized number otherwise. The exponent is returned
3731 | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
3732 | Here we assume that the exponent is not too small (this should be checked
3733 | before entering the rounding routine), but the number could be denormalized.
3735 | Check for denormalized numbers:
3736 1: btst IMM (FLT_MANT_DIG),d0
3737 bne 2f | if set the number is normalized
3738 | Normalize shifting left until bit #FLT_MANT_DIG is set or the exponent
3739 | is one (remember that a denormalized number corresponds to an
3740 | exponent of -F_BIAS+1).
3741 #ifndef __mcoldfire__
3742 cmpw IMM (1),d2 | remember that the exponent is at least one
3744 cmpl IMM (1),d2 | remember that the exponent is at least one
3746 beq 2f | an exponent of one means denormalized
3747 addl d1,d1 | else shift and adjust the exponent
3749 #ifndef __mcoldfire__
3756 | Now round: we do it as follows: after the shifting we can write the
3757 | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
3758 | If delta < 1, do nothing. If delta > 1, add 1 to f.
3759 | If delta == 1, we make sure the rounded number will be even (odd?)
3761 btst IMM (0),d0 | is delta < 1?
3762 beq 2f | if so, do not do anything
3763 tstl d1 | is delta == 1?
3764 bne 1f | if so round to even
3766 andl IMM (2),d1 | bit 1 is the last significant bit
3769 1: movel IMM (1),d1 | else add 1
3771 | Shift right once (because we used bit #FLT_MANT_DIG!).
3773 | Now check again bit #FLT_MANT_DIG (rounding could have produced a
3774 | 'fraction overflow
' ...).
3775 btst IMM (FLT_MANT_DIG),d0
3778 #ifndef __mcoldfire__
3784 | If bit #FLT_MANT_DIG-1 is clear we have a denormalized number, so we
3785 | have to put the exponent to zero and return a denormalized number.
3786 btst IMM (FLT_MANT_DIG-1),d0
3796 #endif /* L_float */
3798 | gcc expects the routines __eqdf2, __nedf2, __gtdf2, __gedf2,
3799 | __ledf2, __ltdf2 to all return the same value as a direct call to
3800 | __cmpdf2 would. In this implementation, each of these routines
3801 | simply calls __cmpdf2. It would be more efficient to give the
3802 | __cmpdf2 routine several names, but separating them out will make it
3803 | easier to write efficient versions of these routines someday.
3808 .globl SYM (__eqdf2)
3815 PICCALL SYM (__cmpdf2)
3818 #endif /* L_eqdf2 */
3823 .globl SYM (__nedf2)
3830 PICCALL SYM (__cmpdf2)
3833 #endif /* L_nedf2 */
3838 .globl SYM (__gtdf2)
3845 PICCALL SYM (__cmpdf2)
3848 #endif /* L_gtdf2 */
3853 .globl SYM (__gedf2)
3860 PICCALL SYM (__cmpdf2)
3863 #endif /* L_gedf2 */
3868 .globl SYM (__ltdf2)
3875 PICCALL SYM (__cmpdf2)
3878 #endif /* L_ltdf2 */
3883 .globl SYM (__ledf2)
3890 PICCALL SYM (__cmpdf2)
3893 #endif /* L_ledf2 */
3895 | The comments above about __eqdf2, et. al., also apply to __eqsf2,
3896 | et. al., except that the latter call __cmpsf2 rather than __cmpdf2.
3901 .globl SYM (__eqsf2)
3906 PICCALL SYM (__cmpsf2)
3909 #endif /* L_eqsf2 */
3914 .globl SYM (__nesf2)
3919 PICCALL SYM (__cmpsf2)
3922 #endif /* L_nesf2 */
3927 .globl SYM (__gtsf2)
3932 PICCALL SYM (__cmpsf2)
3935 #endif /* L_gtsf2 */
3940 .globl SYM (__gesf2)
3945 PICCALL SYM (__cmpsf2)
3948 #endif /* L_gesf2 */
3953 .globl SYM (__ltsf2)
3958 PICCALL SYM (__cmpsf2)
3961 #endif /* L_ltsf2 */
3966 .globl SYM (__lesf2)
3971 PICCALL SYM (__cmpsf2)
3974 #endif /* L_lesf2 */