OSDN Git Service

* config/alpha/alpha.c (alpha_adjust_cost): Remove set but not
[pf3gnuchains/gcc-fork.git] / gcc / config / m68k / lb1sf68.asm
1 /* libgcc routines for 68000 w/o floating-point hardware.
2    Copyright (C) 1994, 1996, 1997, 1998, 2008, 2009 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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
9 later version.
10
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.
15
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.
19
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/>.  */
24
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
29 */
30
31 /* These are predefined by new versions of GNU cpp.  */
32
33 #ifndef __USER_LABEL_PREFIX__
34 #define __USER_LABEL_PREFIX__ _
35 #endif
36
37 #ifndef __REGISTER_PREFIX__
38 #define __REGISTER_PREFIX__
39 #endif
40
41 #ifndef __IMMEDIATE_PREFIX__
42 #define __IMMEDIATE_PREFIX__ #
43 #endif
44
45 /* ANSI concatenation macros.  */
46
47 #define CONCAT1(a, b) CONCAT2(a, b)
48 #define CONCAT2(a, b) a ## b
49
50 /* Use the right prefix for global labels.  */
51
52 #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
53
54 /* Note that X is a function.  */
55         
56 #ifdef __ELF__
57 #define FUNC(x) .type SYM(x),function
58 #else
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
62    the need arises.  */
63 #define FUNC(x) .proc
64 #endif
65                 
66 /* Use the right prefix for registers.  */
67
68 #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
69
70 /* Use the right prefix for immediate values.  */
71
72 #define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
73
74 #define d0 REG (d0)
75 #define d1 REG (d1)
76 #define d2 REG (d2)
77 #define d3 REG (d3)
78 #define d4 REG (d4)
79 #define d5 REG (d5)
80 #define d6 REG (d6)
81 #define d7 REG (d7)
82 #define a0 REG (a0)
83 #define a1 REG (a1)
84 #define a2 REG (a2)
85 #define a3 REG (a3)
86 #define a4 REG (a4)
87 #define a5 REG (a5)
88 #define a6 REG (a6)
89 #define fp REG (fp)
90 #define sp REG (sp)
91 #define pc REG (pc)
92
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).
99  */
100 #ifndef __PIC__
101
102         /* Non PIC (absolute/relocatable) versions */
103
104         .macro PICCALL addr
105         jbsr    \addr
106         .endm
107
108         .macro PICJUMP addr
109         jmp     \addr
110         .endm
111
112         .macro PICLEA sym, reg
113         lea     \sym, \reg
114         .endm
115
116         .macro PICPEA sym, areg
117         pea     \sym
118         .endm
119
120 #else /* __PIC__ */
121
122 # if defined (__uClinux__)
123
124         /* Versions for uClinux */
125
126 #  if defined(__ID_SHARED_LIBRARY__)
127
128         /* -mid-shared-library versions  */
129
130         .macro PICLEA sym, reg
131         movel   a5@(_current_shared_library_a5_offset_), \reg
132         movel   \sym@GOT(\reg), \reg
133         .endm
134
135         .macro PICPEA sym, areg
136         movel   a5@(_current_shared_library_a5_offset_), \areg
137         movel   \sym@GOT(\areg), sp@-
138         .endm
139
140         .macro PICCALL addr
141         PICLEA  \addr,a0
142         jsr     a0@
143         .endm
144
145         .macro PICJUMP addr
146         PICLEA  \addr,a0
147         jmp     a0@
148         .endm
149
150 #  else /* !__ID_SHARED_LIBRARY__ */
151
152         /* Versions for -msep-data */
153
154         .macro PICLEA sym, reg
155         movel   \sym@GOT(a5), \reg
156         .endm
157
158         .macro PICPEA sym, areg
159         movel   \sym@GOT(a5), sp@-
160         .endm
161
162         .macro PICCALL addr
163 #if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
164         lea     \addr-.-8,a0
165         jsr     pc@(a0)
166 #else
167         jbsr    \addr
168 #endif
169         .endm
170
171         .macro PICJUMP addr
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__)
176         lea     \addr-.-8,a0
177         jmp     pc@(a0)
178 #else
179         bra     \addr
180 #endif
181         .endm
182
183 #  endif
184
185 # else /* !__uClinux__ */
186
187         /* Versions for Linux */
188
189         .macro PICLEA sym, reg
190         movel   #_GLOBAL_OFFSET_TABLE_@GOTPC, \reg
191         lea     (-6, pc, \reg), \reg
192         movel   \sym@GOT(\reg), \reg
193         .endm
194
195         .macro PICPEA sym, areg
196         movel   #_GLOBAL_OFFSET_TABLE_@GOTPC, \areg
197         lea     (-6, pc, \areg), \areg
198         movel   \sym@GOT(\areg), sp@-
199         .endm
200
201         .macro PICCALL addr
202 #if defined (__mcoldfire__) && !defined (__mcfisab__) && !defined (__mcfisac__)
203         lea     \addr-.-8,a0
204         jsr     pc@(a0)
205 #else
206         jbsr    \addr
207 #endif
208         .endm
209
210         .macro PICJUMP addr
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__)
215         lea     \addr-.-8,a0
216         jmp     pc@(a0)
217 #else
218         bra     \addr
219 #endif
220         .endm
221
222 # endif
223 #endif /* __PIC__ */
224
225
226 #ifdef L_floatex
227
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!).
231
232 | Starting date: 21 October, 1990
233
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 
239 | different cases:
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.
247
248 |=============================================================================
249 |                                  exceptions
250 |=============================================================================
251
252 | This is the floating point condition code register (_fpCCR):
253 |
254 | struct {
255 |   short _exception_bits;      
256 |   short _trap_enable_bits;    
257 |   short _sticky_bits;
258 |   short _rounding_mode;
259 |   short _format;
260 |   short _last_operation;
261 |   union {
262 |     float sf;
263 |     double df;
264 |   } _operand1;
265 |   union {
266 |     float sf;
267 |     double df;
268 |   } _operand2;
269 | } _fpCCR;
270
271         .data
272         .even
273
274         .globl  SYM (_fpCCR)
275         
276 SYM (_fpCCR):
277 __exception_bits:
278         .word   0
279 __trap_enable_bits:
280         .word   0
281 __sticky_bits:
282         .word   0
283 __rounding_mode:
284         .word   ROUND_TO_NEAREST
285 __format:
286         .word   NIL
287 __last_operation:
288         .word   NOOP
289 __operand1:
290         .long   0
291         .long   0
292 __operand2:
293         .long   0
294         .long   0
295
296 | Offsets:
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)
305
306 | The following exception types are supported:
307 INEXACT_RESULT          = 0x0001
308 UNDERFLOW               = 0x0002
309 OVERFLOW                = 0x0004
310 DIVIDE_BY_ZERO          = 0x0008
311 INVALID_OPERATION       = 0x0010
312
313 | The allowed rounding modes are:
314 UNKNOWN           = -1
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
319
320 | The allowed values of format are:
321 NIL          = 0
322 SINGLE_FLOAT = 1
323 DOUBLE_FLOAT = 2
324 LONG_FLOAT   = 3
325
326 | The allowed values for the last operation are:
327 NOOP         = 0
328 ADD          = 1
329 MULTIPLY     = 2
330 DIVIDE       = 3
331 NEGATE       = 4
332 COMPARE      = 5
333 EXTENDSFDF   = 6
334 TRUNCDFSF    = 7
335
336 |=============================================================================
337 |                           __clear_sticky_bits
338 |=============================================================================
339
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).
344
345         .globl  SYM (__clear_sticky_bit)
346
347         .text
348         .even
349
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)
355 #else
356         clr.w   a0@(STICK)
357 #endif
358         rts
359
360 |=============================================================================
361 |                           $_exception_handler
362 |=============================================================================
363
364         .globl  $_exception_handler
365
366         .text
367         .even
368
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).
381
382 FPTRAP = 15
383
384 $_exception_handler:
385         PICLEA  SYM (_fpCCR),a0
386         movew   d7,a0@(EBITS)   | set __exception_bits
387 #ifndef __mcoldfire__
388         orw     d7,a0@(STICK)   | and __sticky_bits
389 #else
390         movew   a0@(STICK),d4
391         orl     d7,d4
392         movew   d4,a0@(STICK)
393 #endif
394         movew   d6,a0@(FORMT)   | and __format
395         movew   d5,a0@(LASTO)   | and __last_operation
396
397 | Now put the operands in place:
398 #ifndef __mcoldfire__
399         cmpw    IMM (SINGLE_FLOAT),d6
400 #else
401         cmpl    IMM (SINGLE_FLOAT),d6
402 #endif
403         beq     1f
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)
408         bra     2f
409 1:      movel   a6@(8),a0@(OPER1)
410         movel   a6@(12),a0@(OPER2)
411 2:
412 | And check whether the exception is trap-enabled:
413 #ifndef __mcoldfire__
414         andw    a0@(TRAPE),d7   | is exception trap-enabled?
415 #else
416         clrl    d6
417         movew   a0@(TRAPE),d6
418         andl    d6,d7
419 #endif
420         beq     1f              | no, exit
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
425 #else
426 1:      moveml  sp@,d2-d7
427         | XXX if frame pointer is ever removed, stack pointer must
428         | be adjusted here.
429 #endif
430         unlk    a6              | and return
431         rts
432 #endif /* L_floatex */
433
434 #ifdef  L_mulsi3
435         .text
436         FUNC(__mulsi3)
437         .globl  SYM (__mulsi3)
438 SYM (__mulsi3):
439         movew   sp@(4), d0      /* x0 -> d0 */
440         muluw   sp@(10), d0     /* x0*y1 */
441         movew   sp@(6), d1      /* x1 -> d1 */
442         muluw   sp@(8), d1      /* x1*y0 */
443 #ifndef __mcoldfire__
444         addw    d1, d0
445 #else
446         addl    d1, d0
447 #endif
448         swap    d0
449         clrw    d0
450         movew   sp@(6), d1      /* x1 -> d1 */
451         muluw   sp@(10), d1     /* x1*y1 */
452         addl    d1, d0
453
454         rts
455 #endif /* L_mulsi3 */
456
457 #ifdef  L_udivsi3
458         .text
459         FUNC(__udivsi3)
460         .globl  SYM (__udivsi3)
461 SYM (__udivsi3):
462 #ifndef __mcoldfire__
463         movel   d2, sp@-
464         movel   sp@(12), d1     /* d1 = divisor */
465         movel   sp@(8), d0      /* d0 = dividend */
466
467         cmpl    IMM (0x10000), d1 /* divisor >= 2 ^ 16 ?   */
468         jcc     L3              /* then try next algorithm */
469         movel   d0, d2
470         clrw    d2
471         swap    d2
472         divu    d1, d2          /* high quotient in lower word */
473         movew   d2, d0          /* save high quotient */
474         swap    d0
475         movew   sp@(10), d2     /* get low dividend + high rest */
476         divu    d1, d2          /* low quotient */
477         movew   d2, d0
478         jra     L6
479
480 L3:     movel   d1, d2          /* use d2 as divisor backup */
481 L4:     lsrl    IMM (1), d1     /* shift divisor */
482         lsrl    IMM (1), d0     /* shift dividend */
483         cmpl    IMM (0x10000), d1 /* still divisor >= 2 ^ 16 ?  */
484         jcc     L4
485         divu    d1, d0          /* now we have 16-bit divisor */
486         andl    IMM (0xffff), d0 /* mask out divisor, ignore remainder */
487
488 /* Multiply the 16-bit tentative quotient with the 32-bit divisor.  Because of
489    the operand ranges, this might give a 33-bit product.  If this product is
490    greater than the dividend, the tentative quotient was too large. */
491         movel   d2, d1
492         mulu    d0, d1          /* low part, 32 bits */
493         swap    d2
494         mulu    d0, d2          /* high part, at most 17 bits */
495         swap    d2              /* align high part with low part */
496         tstw    d2              /* high part 17 bits? */
497         jne     L5              /* if 17 bits, quotient was too large */
498         addl    d2, d1          /* add parts */
499         jcs     L5              /* if sum is 33 bits, quotient was too large */
500         cmpl    sp@(8), d1      /* compare the sum with the dividend */
501         jls     L6              /* if sum > dividend, quotient was too large */
502 L5:     subql   IMM (1), d0     /* adjust quotient */
503
504 L6:     movel   sp@+, d2
505         rts
506
507 #else /* __mcoldfire__ */
508
509 /* ColdFire implementation of non-restoring division algorithm from
510    Hennessy & Patterson, Appendix A. */
511         link    a6,IMM (-12)
512         moveml  d2-d4,sp@
513         movel   a6@(8),d0
514         movel   a6@(12),d1
515         clrl    d2              | clear p
516         moveq   IMM (31),d4
517 L1:     addl    d0,d0           | shift reg pair (p,a) one bit left
518         addxl   d2,d2
519         movl    d2,d3           | subtract b from p, store in tmp.
520         subl    d1,d3
521         jcs     L2              | if no carry,
522         bset    IMM (0),d0      | set the low order bit of a to 1,
523         movl    d3,d2           | and store tmp in p.
524 L2:     subql   IMM (1),d4
525         jcc     L1
526         moveml  sp@,d2-d4       | restore data registers
527         unlk    a6              | and return
528         rts
529 #endif /* __mcoldfire__ */
530
531 #endif /* L_udivsi3 */
532
533 #ifdef  L_divsi3
534         .text
535         FUNC(__divsi3)
536         .globl  SYM (__divsi3)
537 SYM (__divsi3):
538         movel   d2, sp@-
539
540         moveq   IMM (1), d2     /* sign of result stored in d2 (=1 or =-1) */
541         movel   sp@(12), d1     /* d1 = divisor */
542         jpl     L1
543         negl    d1
544 #ifndef __mcoldfire__
545         negb    d2              /* change sign because divisor <0  */
546 #else
547         negl    d2              /* change sign because divisor <0  */
548 #endif
549 L1:     movel   sp@(8), d0      /* d0 = dividend */
550         jpl     L2
551         negl    d0
552 #ifndef __mcoldfire__
553         negb    d2
554 #else
555         negl    d2
556 #endif
557
558 L2:     movel   d1, sp@-
559         movel   d0, sp@-
560         PICCALL SYM (__udivsi3) /* divide abs(dividend) by abs(divisor) */
561         addql   IMM (8), sp
562
563         tstb    d2
564         jpl     L3
565         negl    d0
566
567 L3:     movel   sp@+, d2
568         rts
569 #endif /* L_divsi3 */
570
571 #ifdef  L_umodsi3
572         .text
573         FUNC(__umodsi3)
574         .globl  SYM (__umodsi3)
575 SYM (__umodsi3):
576         movel   sp@(8), d1      /* d1 = divisor */
577         movel   sp@(4), d0      /* d0 = dividend */
578         movel   d1, sp@-
579         movel   d0, sp@-
580         PICCALL SYM (__udivsi3)
581         addql   IMM (8), sp
582         movel   sp@(8), d1      /* d1 = divisor */
583 #ifndef __mcoldfire__
584         movel   d1, sp@-
585         movel   d0, sp@-
586         PICCALL SYM (__mulsi3)  /* d0 = (a/b)*b */
587         addql   IMM (8), sp
588 #else
589         mulsl   d1,d0
590 #endif
591         movel   sp@(4), d1      /* d1 = dividend */
592         subl    d0, d1          /* d1 = a - (a/b)*b */
593         movel   d1, d0
594         rts
595 #endif /* L_umodsi3 */
596
597 #ifdef  L_modsi3
598         .text
599         FUNC(__modsi3)
600         .globl  SYM (__modsi3)
601 SYM (__modsi3):
602         movel   sp@(8), d1      /* d1 = divisor */
603         movel   sp@(4), d0      /* d0 = dividend */
604         movel   d1, sp@-
605         movel   d0, sp@-
606         PICCALL SYM (__divsi3)
607         addql   IMM (8), sp
608         movel   sp@(8), d1      /* d1 = divisor */
609 #ifndef __mcoldfire__
610         movel   d1, sp@-
611         movel   d0, sp@-
612         PICCALL SYM (__mulsi3)  /* d0 = (a/b)*b */
613         addql   IMM (8), sp
614 #else
615         mulsl   d1,d0
616 #endif
617         movel   sp@(4), d1      /* d1 = dividend */
618         subl    d0, d1          /* d1 = a - (a/b)*b */
619         movel   d1, d0
620         rts
621 #endif /* L_modsi3 */
622
623
624 #ifdef  L_double
625
626         .globl  SYM (_fpCCR)
627         .globl  $_exception_handler
628
629 QUIET_NaN      = 0xffffffff
630
631 D_MAX_EXP      = 0x07ff
632 D_BIAS         = 1022
633 DBL_MAX_EXP    = D_MAX_EXP - D_BIAS
634 DBL_MIN_EXP    = 1 - D_BIAS
635 DBL_MANT_DIG   = 53
636
637 INEXACT_RESULT          = 0x0001
638 UNDERFLOW               = 0x0002
639 OVERFLOW                = 0x0004
640 DIVIDE_BY_ZERO          = 0x0008
641 INVALID_OPERATION       = 0x0010
642
643 DOUBLE_FLOAT = 2
644
645 NOOP         = 0
646 ADD          = 1
647 MULTIPLY     = 2
648 DIVIDE       = 3
649 NEGATE       = 4
650 COMPARE      = 5
651 EXTENDSFDF   = 6
652 TRUNCDFSF    = 7
653
654 UNKNOWN           = -1
655 ROUND_TO_NEAREST  = 0 | round result to nearest representable value
656 ROUND_TO_ZERO     = 1 | round result towards zero
657 ROUND_TO_PLUS     = 2 | round result towards plus infinity
658 ROUND_TO_MINUS    = 3 | round result towards minus infinity
659
660 | Entry points:
661
662         .globl SYM (__adddf3)
663         .globl SYM (__subdf3)
664         .globl SYM (__muldf3)
665         .globl SYM (__divdf3)
666         .globl SYM (__negdf2)
667         .globl SYM (__cmpdf2)
668         .globl SYM (__cmpdf2_internal)
669         .hidden SYM (__cmpdf2_internal)
670
671         .text
672         .even
673
674 | These are common routines to return and signal exceptions.    
675
676 Ld$den:
677 | Return and signal a denormalized number
678         orl     d7,d0
679         movew   IMM (INEXACT_RESULT+UNDERFLOW),d7
680         moveq   IMM (DOUBLE_FLOAT),d6
681         PICJUMP $_exception_handler
682
683 Ld$infty:
684 Ld$overflow:
685 | Return a properly signed INFINITY and set the exception flags 
686         movel   IMM (0x7ff00000),d0
687         movel   IMM (0),d1
688         orl     d7,d0
689         movew   IMM (INEXACT_RESULT+OVERFLOW),d7
690         moveq   IMM (DOUBLE_FLOAT),d6
691         PICJUMP $_exception_handler
692
693 Ld$underflow:
694 | Return 0 and set the exception flags 
695         movel   IMM (0),d0
696         movel   d0,d1
697         movew   IMM (INEXACT_RESULT+UNDERFLOW),d7
698         moveq   IMM (DOUBLE_FLOAT),d6
699         PICJUMP $_exception_handler
700
701 Ld$inop:
702 | Return a quiet NaN and set the exception flags
703         movel   IMM (QUIET_NaN),d0
704         movel   d0,d1
705         movew   IMM (INEXACT_RESULT+INVALID_OPERATION),d7
706         moveq   IMM (DOUBLE_FLOAT),d6
707         PICJUMP $_exception_handler
708
709 Ld$div$0:
710 | Return a properly signed INFINITY and set the exception flags
711         movel   IMM (0x7ff00000),d0
712         movel   IMM (0),d1
713         orl     d7,d0
714         movew   IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7
715         moveq   IMM (DOUBLE_FLOAT),d6
716         PICJUMP $_exception_handler
717
718 |=============================================================================
719 |=============================================================================
720 |                         double precision routines
721 |=============================================================================
722 |=============================================================================
723
724 | A double precision floating point number (double) has the format:
725 |
726 | struct _double {
727 |  unsigned int sign      : 1;  /* sign bit */ 
728 |  unsigned int exponent  : 11; /* exponent, shifted by 126 */
729 |  unsigned int fraction  : 52; /* fraction */
730 | } double;
731
732 | Thus sizeof(double) = 8 (64 bits). 
733 |
734 | All the routines are callable from C programs, and return the result 
735 | in the register pair d0-d1. They also preserve all registers except 
736 | d0-d1 and a0-a1.
737
738 |=============================================================================
739 |                              __subdf3
740 |=============================================================================
741
742 | double __subdf3(double, double);
743         FUNC(__subdf3)
744 SYM (__subdf3):
745         bchg    IMM (31),sp@(12) | change sign of second operand
746                                 | and fall through, so we always add
747 |=============================================================================
748 |                              __adddf3
749 |=============================================================================
750
751 | double __adddf3(double, double);
752         FUNC(__adddf3)
753 SYM (__adddf3):
754 #ifndef __mcoldfire__
755         link    a6,IMM (0)      | everything will be done in registers
756         moveml  d2-d7,sp@-      | save all data registers and a2 (but d0-d1)
757 #else
758         link    a6,IMM (-24)
759         moveml  d2-d7,sp@
760 #endif
761         movel   a6@(8),d0       | get first operand
762         movel   a6@(12),d1      | 
763         movel   a6@(16),d2      | get second operand
764         movel   a6@(20),d3      | 
765
766         movel   d0,d7           | get d0's sign bit in d7 '
767         addl    d1,d1           | check and clear sign bit of a, and gain one
768         addxl   d0,d0           | bit of extra precision
769         beq     Ladddf$b        | if zero return second operand
770
771         movel   d2,d6           | save sign in d6 
772         addl    d3,d3           | get rid of sign bit and gain one bit of
773         addxl   d2,d2           | extra precision
774         beq     Ladddf$a        | if zero return first operand
775
776         andl    IMM (0x80000000),d7 | isolate a's sign bit '
777         swap    d6              | and also b's sign bit '
778 #ifndef __mcoldfire__
779         andw    IMM (0x8000),d6 |
780         orw     d6,d7           | and combine them into d7, so that a's sign '
781                                 | bit is in the high word and b's is in the '
782                                 | low word, so d6 is free to be used
783 #else
784         andl    IMM (0x8000),d6
785         orl     d6,d7
786 #endif
787         movel   d7,a0           | now save d7 into a0, so d7 is free to
788                                 | be used also
789
790 | Get the exponents and check for denormalized and/or infinity.
791
792         movel   IMM (0x001fffff),d6 | mask for the fraction
793         movel   IMM (0x00200000),d7 | mask to put hidden bit back
794
795         movel   d0,d4           | 
796         andl    d6,d0           | get fraction in d0
797         notl    d6              | make d6 into mask for the exponent
798         andl    d6,d4           | get exponent in d4
799         beq     Ladddf$a$den    | branch if a is denormalized
800         cmpl    d6,d4           | check for INFINITY or NaN
801         beq     Ladddf$nf       | 
802         orl     d7,d0           | and put hidden bit back
803 Ladddf$1:
804         swap    d4              | shift right exponent so that it starts
805 #ifndef __mcoldfire__
806         lsrw    IMM (5),d4      | in bit 0 and not bit 20
807 #else
808         lsrl    IMM (5),d4      | in bit 0 and not bit 20
809 #endif
810 | Now we have a's exponent in d4 and fraction in d0-d1 '
811         movel   d2,d5           | save b to get exponent
812         andl    d6,d5           | get exponent in d5
813         beq     Ladddf$b$den    | branch if b is denormalized
814         cmpl    d6,d5           | check for INFINITY or NaN
815         beq     Ladddf$nf
816         notl    d6              | make d6 into mask for the fraction again
817         andl    d6,d2           | and get fraction in d2
818         orl     d7,d2           | and put hidden bit back
819 Ladddf$2:
820         swap    d5              | shift right exponent so that it starts
821 #ifndef __mcoldfire__
822         lsrw    IMM (5),d5      | in bit 0 and not bit 20
823 #else
824         lsrl    IMM (5),d5      | in bit 0 and not bit 20
825 #endif
826
827 | Now we have b's exponent in d5 and fraction in d2-d3. '
828
829 | The situation now is as follows: the signs are combined in a0, the 
830 | numbers are in d0-d1 (a) and d2-d3 (b), and the exponents in d4 (a)
831 | and d5 (b). To do the rounding correctly we need to keep all the
832 | bits until the end, so we need to use d0-d1-d2-d3 for the first number
833 | and d4-d5-d6-d7 for the second. To do this we store (temporarily) the
834 | exponents in a2-a3.
835
836 #ifndef __mcoldfire__
837         moveml  a2-a3,sp@-      | save the address registers
838 #else
839         movel   a2,sp@- 
840         movel   a3,sp@- 
841         movel   a4,sp@- 
842 #endif
843
844         movel   d4,a2           | save the exponents
845         movel   d5,a3           | 
846
847         movel   IMM (0),d7      | and move the numbers around
848         movel   d7,d6           |
849         movel   d3,d5           |
850         movel   d2,d4           |
851         movel   d7,d3           |
852         movel   d7,d2           |
853
854 | Here we shift the numbers until the exponents are the same, and put 
855 | the largest exponent in a2.
856 #ifndef __mcoldfire__
857         exg     d4,a2           | get exponents back
858         exg     d5,a3           |
859         cmpw    d4,d5           | compare the exponents
860 #else
861         movel   d4,a4           | get exponents back
862         movel   a2,d4
863         movel   a4,a2
864         movel   d5,a4
865         movel   a3,d5
866         movel   a4,a3
867         cmpl    d4,d5           | compare the exponents
868 #endif
869         beq     Ladddf$3        | if equal don't shift '
870         bhi     9f              | branch if second exponent is higher
871
872 | Here we have a's exponent larger than b's, so we have to shift b. We do 
873 | this by using as counter d2:
874 1:      movew   d4,d2           | move largest exponent to d2
875 #ifndef __mcoldfire__
876         subw    d5,d2           | and subtract second exponent
877         exg     d4,a2           | get back the longs we saved
878         exg     d5,a3           |
879 #else
880         subl    d5,d2           | and subtract second exponent
881         movel   d4,a4           | get back the longs we saved
882         movel   a2,d4
883         movel   a4,a2
884         movel   d5,a4
885         movel   a3,d5
886         movel   a4,a3
887 #endif
888 | if difference is too large we don't shift (actually, we can just exit) '
889 #ifndef __mcoldfire__
890         cmpw    IMM (DBL_MANT_DIG+2),d2
891 #else
892         cmpl    IMM (DBL_MANT_DIG+2),d2
893 #endif
894         bge     Ladddf$b$small
895 #ifndef __mcoldfire__
896         cmpw    IMM (32),d2     | if difference >= 32, shift by longs
897 #else
898         cmpl    IMM (32),d2     | if difference >= 32, shift by longs
899 #endif
900         bge     5f
901 2:
902 #ifndef __mcoldfire__
903         cmpw    IMM (16),d2     | if difference >= 16, shift by words   
904 #else
905         cmpl    IMM (16),d2     | if difference >= 16, shift by words   
906 #endif
907         bge     6f
908         bra     3f              | enter dbra loop
909
910 4:
911 #ifndef __mcoldfire__
912         lsrl    IMM (1),d4
913         roxrl   IMM (1),d5
914         roxrl   IMM (1),d6
915         roxrl   IMM (1),d7
916 #else
917         lsrl    IMM (1),d7
918         btst    IMM (0),d6
919         beq     10f
920         bset    IMM (31),d7
921 10:     lsrl    IMM (1),d6
922         btst    IMM (0),d5
923         beq     11f
924         bset    IMM (31),d6
925 11:     lsrl    IMM (1),d5
926         btst    IMM (0),d4
927         beq     12f
928         bset    IMM (31),d5
929 12:     lsrl    IMM (1),d4
930 #endif
931 3:
932 #ifndef __mcoldfire__
933         dbra    d2,4b
934 #else
935         subql   IMM (1),d2
936         bpl     4b      
937 #endif
938         movel   IMM (0),d2
939         movel   d2,d3   
940         bra     Ladddf$4
941 5:
942         movel   d6,d7
943         movel   d5,d6
944         movel   d4,d5
945         movel   IMM (0),d4
946 #ifndef __mcoldfire__
947         subw    IMM (32),d2
948 #else
949         subl    IMM (32),d2
950 #endif
951         bra     2b
952 6:
953         movew   d6,d7
954         swap    d7
955         movew   d5,d6
956         swap    d6
957         movew   d4,d5
958         swap    d5
959         movew   IMM (0),d4
960         swap    d4
961 #ifndef __mcoldfire__
962         subw    IMM (16),d2
963 #else
964         subl    IMM (16),d2
965 #endif
966         bra     3b
967         
968 9:
969 #ifndef __mcoldfire__
970         exg     d4,d5
971         movew   d4,d6
972         subw    d5,d6           | keep d5 (largest exponent) in d4
973         exg     d4,a2
974         exg     d5,a3
975 #else
976         movel   d5,d6
977         movel   d4,d5
978         movel   d6,d4
979         subl    d5,d6
980         movel   d4,a4
981         movel   a2,d4
982         movel   a4,a2
983         movel   d5,a4
984         movel   a3,d5
985         movel   a4,a3
986 #endif
987 | if difference is too large we don't shift (actually, we can just exit) '
988 #ifndef __mcoldfire__
989         cmpw    IMM (DBL_MANT_DIG+2),d6
990 #else
991         cmpl    IMM (DBL_MANT_DIG+2),d6
992 #endif
993         bge     Ladddf$a$small
994 #ifndef __mcoldfire__
995         cmpw    IMM (32),d6     | if difference >= 32, shift by longs
996 #else
997         cmpl    IMM (32),d6     | if difference >= 32, shift by longs
998 #endif
999         bge     5f
1000 2:
1001 #ifndef __mcoldfire__
1002         cmpw    IMM (16),d6     | if difference >= 16, shift by words   
1003 #else
1004         cmpl    IMM (16),d6     | if difference >= 16, shift by words   
1005 #endif
1006         bge     6f
1007         bra     3f              | enter dbra loop
1008
1009 4:
1010 #ifndef __mcoldfire__
1011         lsrl    IMM (1),d0
1012         roxrl   IMM (1),d1
1013         roxrl   IMM (1),d2
1014         roxrl   IMM (1),d3
1015 #else
1016         lsrl    IMM (1),d3
1017         btst    IMM (0),d2
1018         beq     10f
1019         bset    IMM (31),d3
1020 10:     lsrl    IMM (1),d2
1021         btst    IMM (0),d1
1022         beq     11f
1023         bset    IMM (31),d2
1024 11:     lsrl    IMM (1),d1
1025         btst    IMM (0),d0
1026         beq     12f
1027         bset    IMM (31),d1
1028 12:     lsrl    IMM (1),d0
1029 #endif
1030 3:
1031 #ifndef __mcoldfire__
1032         dbra    d6,4b
1033 #else
1034         subql   IMM (1),d6
1035         bpl     4b
1036 #endif
1037         movel   IMM (0),d7
1038         movel   d7,d6
1039         bra     Ladddf$4
1040 5:
1041         movel   d2,d3
1042         movel   d1,d2
1043         movel   d0,d1
1044         movel   IMM (0),d0
1045 #ifndef __mcoldfire__
1046         subw    IMM (32),d6
1047 #else
1048         subl    IMM (32),d6
1049 #endif
1050         bra     2b
1051 6:
1052         movew   d2,d3
1053         swap    d3
1054         movew   d1,d2
1055         swap    d2
1056         movew   d0,d1
1057         swap    d1
1058         movew   IMM (0),d0
1059         swap    d0
1060 #ifndef __mcoldfire__
1061         subw    IMM (16),d6
1062 #else
1063         subl    IMM (16),d6
1064 #endif
1065         bra     3b
1066 Ladddf$3:
1067 #ifndef __mcoldfire__
1068         exg     d4,a2   
1069         exg     d5,a3
1070 #else
1071         movel   d4,a4
1072         movel   a2,d4
1073         movel   a4,a2
1074         movel   d5,a4
1075         movel   a3,d5
1076         movel   a4,a3
1077 #endif
1078 Ladddf$4:       
1079 | Now we have the numbers in d0--d3 and d4--d7, the exponent in a2, and
1080 | the signs in a4.
1081
1082 | Here we have to decide whether to add or subtract the numbers:
1083 #ifndef __mcoldfire__
1084         exg     d7,a0           | get the signs 
1085         exg     d6,a3           | a3 is free to be used
1086 #else
1087         movel   d7,a4
1088         movel   a0,d7
1089         movel   a4,a0
1090         movel   d6,a4
1091         movel   a3,d6
1092         movel   a4,a3
1093 #endif
1094         movel   d7,d6           |
1095         movew   IMM (0),d7      | get a's sign in d7 '
1096         swap    d6              |
1097         movew   IMM (0),d6      | and b's sign in d6 '
1098         eorl    d7,d6           | compare the signs
1099         bmi     Lsubdf$0        | if the signs are different we have 
1100                                 | to subtract
1101 #ifndef __mcoldfire__
1102         exg     d7,a0           | else we add the numbers
1103         exg     d6,a3           |
1104 #else
1105         movel   d7,a4
1106         movel   a0,d7
1107         movel   a4,a0
1108         movel   d6,a4
1109         movel   a3,d6
1110         movel   a4,a3
1111 #endif
1112         addl    d7,d3           |
1113         addxl   d6,d2           |
1114         addxl   d5,d1           | 
1115         addxl   d4,d0           |
1116
1117         movel   a2,d4           | return exponent to d4
1118         movel   a0,d7           | 
1119         andl    IMM (0x80000000),d7 | d7 now has the sign
1120
1121 #ifndef __mcoldfire__
1122         moveml  sp@+,a2-a3      
1123 #else
1124         movel   sp@+,a4 
1125         movel   sp@+,a3 
1126         movel   sp@+,a2 
1127 #endif
1128
1129 | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
1130 | the case of denormalized numbers in the rounding routine itself).
1131 | As in the addition (not in the subtraction!) we could have set 
1132 | one more bit we check this:
1133         btst    IMM (DBL_MANT_DIG+1),d0 
1134         beq     1f
1135 #ifndef __mcoldfire__
1136         lsrl    IMM (1),d0
1137         roxrl   IMM (1),d1
1138         roxrl   IMM (1),d2
1139         roxrl   IMM (1),d3
1140         addw    IMM (1),d4
1141 #else
1142         lsrl    IMM (1),d3
1143         btst    IMM (0),d2
1144         beq     10f
1145         bset    IMM (31),d3
1146 10:     lsrl    IMM (1),d2
1147         btst    IMM (0),d1
1148         beq     11f
1149         bset    IMM (31),d2
1150 11:     lsrl    IMM (1),d1
1151         btst    IMM (0),d0
1152         beq     12f
1153         bset    IMM (31),d1
1154 12:     lsrl    IMM (1),d0
1155         addl    IMM (1),d4
1156 #endif
1157 1:
1158         lea     pc@(Ladddf$5),a0 | to return from rounding routine
1159         PICLEA  SYM (_fpCCR),a1 | check the rounding mode
1160 #ifdef __mcoldfire__
1161         clrl    d6
1162 #endif
1163         movew   a1@(6),d6       | rounding mode in d6
1164         beq     Lround$to$nearest
1165 #ifndef __mcoldfire__
1166         cmpw    IMM (ROUND_TO_PLUS),d6
1167 #else
1168         cmpl    IMM (ROUND_TO_PLUS),d6
1169 #endif
1170         bhi     Lround$to$minus
1171         blt     Lround$to$zero
1172         bra     Lround$to$plus
1173 Ladddf$5:
1174 | Put back the exponent and check for overflow
1175 #ifndef __mcoldfire__
1176         cmpw    IMM (0x7ff),d4  | is the exponent big?
1177 #else
1178         cmpl    IMM (0x7ff),d4  | is the exponent big?
1179 #endif
1180         bge     1f
1181         bclr    IMM (DBL_MANT_DIG-1),d0
1182 #ifndef __mcoldfire__
1183         lslw    IMM (4),d4      | put exponent back into position
1184 #else
1185         lsll    IMM (4),d4      | put exponent back into position
1186 #endif
1187         swap    d0              | 
1188 #ifndef __mcoldfire__
1189         orw     d4,d0           |
1190 #else
1191         orl     d4,d0           |
1192 #endif
1193         swap    d0              |
1194         bra     Ladddf$ret
1195 1:
1196         moveq   IMM (ADD),d5
1197         bra     Ld$overflow
1198
1199 Lsubdf$0:
1200 | Here we do the subtraction.
1201 #ifndef __mcoldfire__
1202         exg     d7,a0           | put sign back in a0
1203         exg     d6,a3           |
1204 #else
1205         movel   d7,a4
1206         movel   a0,d7
1207         movel   a4,a0
1208         movel   d6,a4
1209         movel   a3,d6
1210         movel   a4,a3
1211 #endif
1212         subl    d7,d3           |
1213         subxl   d6,d2           |
1214         subxl   d5,d1           |
1215         subxl   d4,d0           |
1216         beq     Ladddf$ret$1    | if zero just exit
1217         bpl     1f              | if positive skip the following
1218         movel   a0,d7           |
1219         bchg    IMM (31),d7     | change sign bit in d7
1220         movel   d7,a0           |
1221         negl    d3              |
1222         negxl   d2              |
1223         negxl   d1              | and negate result
1224         negxl   d0              |
1225 1:      
1226         movel   a2,d4           | return exponent to d4
1227         movel   a0,d7
1228         andl    IMM (0x80000000),d7 | isolate sign bit
1229 #ifndef __mcoldfire__
1230         moveml  sp@+,a2-a3      |
1231 #else
1232         movel   sp@+,a4
1233         movel   sp@+,a3
1234         movel   sp@+,a2
1235 #endif
1236
1237 | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
1238 | the case of denormalized numbers in the rounding routine itself).
1239 | As in the addition (not in the subtraction!) we could have set 
1240 | one more bit we check this:
1241         btst    IMM (DBL_MANT_DIG+1),d0 
1242         beq     1f
1243 #ifndef __mcoldfire__
1244         lsrl    IMM (1),d0
1245         roxrl   IMM (1),d1
1246         roxrl   IMM (1),d2
1247         roxrl   IMM (1),d3
1248         addw    IMM (1),d4
1249 #else
1250         lsrl    IMM (1),d3
1251         btst    IMM (0),d2
1252         beq     10f
1253         bset    IMM (31),d3
1254 10:     lsrl    IMM (1),d2
1255         btst    IMM (0),d1
1256         beq     11f
1257         bset    IMM (31),d2
1258 11:     lsrl    IMM (1),d1
1259         btst    IMM (0),d0
1260         beq     12f
1261         bset    IMM (31),d1
1262 12:     lsrl    IMM (1),d0
1263         addl    IMM (1),d4
1264 #endif
1265 1:
1266         lea     pc@(Lsubdf$1),a0 | to return from rounding routine
1267         PICLEA  SYM (_fpCCR),a1 | check the rounding mode
1268 #ifdef __mcoldfire__
1269         clrl    d6
1270 #endif
1271         movew   a1@(6),d6       | rounding mode in d6
1272         beq     Lround$to$nearest
1273 #ifndef __mcoldfire__
1274         cmpw    IMM (ROUND_TO_PLUS),d6
1275 #else
1276         cmpl    IMM (ROUND_TO_PLUS),d6
1277 #endif
1278         bhi     Lround$to$minus
1279         blt     Lround$to$zero
1280         bra     Lround$to$plus
1281 Lsubdf$1:
1282 | Put back the exponent and sign (we don't have overflow). '
1283         bclr    IMM (DBL_MANT_DIG-1),d0 
1284 #ifndef __mcoldfire__
1285         lslw    IMM (4),d4      | put exponent back into position
1286 #else
1287         lsll    IMM (4),d4      | put exponent back into position
1288 #endif
1289         swap    d0              | 
1290 #ifndef __mcoldfire__
1291         orw     d4,d0           |
1292 #else
1293         orl     d4,d0           |
1294 #endif
1295         swap    d0              |
1296         bra     Ladddf$ret
1297
1298 | If one of the numbers was too small (difference of exponents >= 
1299 | DBL_MANT_DIG+1) we return the other (and now we don't have to '
1300 | check for finiteness or zero).
1301 Ladddf$a$small:
1302 #ifndef __mcoldfire__
1303         moveml  sp@+,a2-a3      
1304 #else
1305         movel   sp@+,a4
1306         movel   sp@+,a3
1307         movel   sp@+,a2
1308 #endif
1309         movel   a6@(16),d0
1310         movel   a6@(20),d1
1311         PICLEA  SYM (_fpCCR),a0
1312         movew   IMM (0),a0@
1313 #ifndef __mcoldfire__
1314         moveml  sp@+,d2-d7      | restore data registers
1315 #else
1316         moveml  sp@,d2-d7
1317         | XXX if frame pointer is ever removed, stack pointer must
1318         | be adjusted here.
1319 #endif
1320         unlk    a6              | and return
1321         rts
1322
1323 Ladddf$b$small:
1324 #ifndef __mcoldfire__
1325         moveml  sp@+,a2-a3      
1326 #else
1327         movel   sp@+,a4 
1328         movel   sp@+,a3 
1329         movel   sp@+,a2 
1330 #endif
1331         movel   a6@(8),d0
1332         movel   a6@(12),d1
1333         PICLEA  SYM (_fpCCR),a0
1334         movew   IMM (0),a0@
1335 #ifndef __mcoldfire__
1336         moveml  sp@+,d2-d7      | restore data registers
1337 #else
1338         moveml  sp@,d2-d7
1339         | XXX if frame pointer is ever removed, stack pointer must
1340         | be adjusted here.
1341 #endif
1342         unlk    a6              | and return
1343         rts
1344
1345 Ladddf$a$den:
1346         movel   d7,d4           | d7 contains 0x00200000
1347         bra     Ladddf$1
1348
1349 Ladddf$b$den:
1350         movel   d7,d5           | d7 contains 0x00200000
1351         notl    d6
1352         bra     Ladddf$2
1353
1354 Ladddf$b:
1355 | Return b (if a is zero)
1356         movel   d2,d0
1357         movel   d3,d1
1358         bne     1f                      | Check if b is -0
1359         cmpl    IMM (0x80000000),d0
1360         bne     1f
1361         andl    IMM (0x80000000),d7     | Use the sign of a
1362         clrl    d0
1363         bra     Ladddf$ret
1364 Ladddf$a:
1365         movel   a6@(8),d0
1366         movel   a6@(12),d1
1367 1:
1368         moveq   IMM (ADD),d5
1369 | Check for NaN and +/-INFINITY.
1370         movel   d0,d7                   |
1371         andl    IMM (0x80000000),d7     |
1372         bclr    IMM (31),d0             |
1373         cmpl    IMM (0x7ff00000),d0     |
1374         bge     2f                      |
1375         movel   d0,d0                   | check for zero, since we don't  '
1376         bne     Ladddf$ret              | want to return -0 by mistake
1377         bclr    IMM (31),d7             |
1378         bra     Ladddf$ret              |
1379 2:
1380         andl    IMM (0x000fffff),d0     | check for NaN (nonzero fraction)
1381         orl     d1,d0                   |
1382         bne     Ld$inop                 |
1383         bra     Ld$infty                |
1384         
1385 Ladddf$ret$1:
1386 #ifndef __mcoldfire__
1387         moveml  sp@+,a2-a3      | restore regs and exit
1388 #else
1389         movel   sp@+,a4
1390         movel   sp@+,a3
1391         movel   sp@+,a2
1392 #endif
1393
1394 Ladddf$ret:
1395 | Normal exit.
1396         PICLEA  SYM (_fpCCR),a0
1397         movew   IMM (0),a0@
1398         orl     d7,d0           | put sign bit back
1399 #ifndef __mcoldfire__
1400         moveml  sp@+,d2-d7
1401 #else
1402         moveml  sp@,d2-d7
1403         | XXX if frame pointer is ever removed, stack pointer must
1404         | be adjusted here.
1405 #endif
1406         unlk    a6
1407         rts
1408
1409 Ladddf$ret$den:
1410 | Return a denormalized number.
1411 #ifndef __mcoldfire__
1412         lsrl    IMM (1),d0      | shift right once more
1413         roxrl   IMM (1),d1      |
1414 #else
1415         lsrl    IMM (1),d1
1416         btst    IMM (0),d0
1417         beq     10f
1418         bset    IMM (31),d1
1419 10:     lsrl    IMM (1),d0
1420 #endif
1421         bra     Ladddf$ret
1422
1423 Ladddf$nf:
1424         moveq   IMM (ADD),d5
1425 | This could be faster but it is not worth the effort, since it is not
1426 | executed very often. We sacrifice speed for clarity here.
1427         movel   a6@(8),d0       | get the numbers back (remember that we
1428         movel   a6@(12),d1      | did some processing already)
1429         movel   a6@(16),d2      | 
1430         movel   a6@(20),d3      | 
1431         movel   IMM (0x7ff00000),d4 | useful constant (INFINITY)
1432         movel   d0,d7           | save sign bits
1433         movel   d2,d6           | 
1434         bclr    IMM (31),d0     | clear sign bits
1435         bclr    IMM (31),d2     | 
1436 | We know that one of them is either NaN of +/-INFINITY
1437 | Check for NaN (if either one is NaN return NaN)
1438         cmpl    d4,d0           | check first a (d0)
1439         bhi     Ld$inop         | if d0 > 0x7ff00000 or equal and
1440         bne     2f
1441         tstl    d1              | d1 > 0, a is NaN
1442         bne     Ld$inop         | 
1443 2:      cmpl    d4,d2           | check now b (d1)
1444         bhi     Ld$inop         | 
1445         bne     3f
1446         tstl    d3              | 
1447         bne     Ld$inop         | 
1448 3:
1449 | Now comes the check for +/-INFINITY. We know that both are (maybe not
1450 | finite) numbers, but we have to check if both are infinite whether we
1451 | are adding or subtracting them.
1452         eorl    d7,d6           | to check sign bits
1453         bmi     1f
1454         andl    IMM (0x80000000),d7 | get (common) sign bit
1455         bra     Ld$infty
1456 1:
1457 | We know one (or both) are infinite, so we test for equality between the
1458 | two numbers (if they are equal they have to be infinite both, so we
1459 | return NaN).
1460         cmpl    d2,d0           | are both infinite?
1461         bne     1f              | if d0 <> d2 they are not equal
1462         cmpl    d3,d1           | if d0 == d2 test d3 and d1
1463         beq     Ld$inop         | if equal return NaN
1464 1:      
1465         andl    IMM (0x80000000),d7 | get a's sign bit '
1466         cmpl    d4,d0           | test now for infinity
1467         beq     Ld$infty        | if a is INFINITY return with this sign
1468         bchg    IMM (31),d7     | else we know b is INFINITY and has
1469         bra     Ld$infty        | the opposite sign
1470
1471 |=============================================================================
1472 |                              __muldf3
1473 |=============================================================================
1474
1475 | double __muldf3(double, double);
1476         FUNC(__muldf3)
1477 SYM (__muldf3):
1478 #ifndef __mcoldfire__
1479         link    a6,IMM (0)
1480         moveml  d2-d7,sp@-
1481 #else
1482         link    a6,IMM (-24)
1483         moveml  d2-d7,sp@
1484 #endif
1485         movel   a6@(8),d0               | get a into d0-d1
1486         movel   a6@(12),d1              | 
1487         movel   a6@(16),d2              | and b into d2-d3
1488         movel   a6@(20),d3              |
1489         movel   d0,d7                   | d7 will hold the sign of the product
1490         eorl    d2,d7                   |
1491         andl    IMM (0x80000000),d7     |
1492         movel   d7,a0                   | save sign bit into a0 
1493         movel   IMM (0x7ff00000),d7     | useful constant (+INFINITY)
1494         movel   d7,d6                   | another (mask for fraction)
1495         notl    d6                      |
1496         bclr    IMM (31),d0             | get rid of a's sign bit '
1497         movel   d0,d4                   | 
1498         orl     d1,d4                   | 
1499         beq     Lmuldf$a$0              | branch if a is zero
1500         movel   d0,d4                   |
1501         bclr    IMM (31),d2             | get rid of b's sign bit '
1502         movel   d2,d5                   |
1503         orl     d3,d5                   | 
1504         beq     Lmuldf$b$0              | branch if b is zero
1505         movel   d2,d5                   | 
1506         cmpl    d7,d0                   | is a big?
1507         bhi     Lmuldf$inop             | if a is NaN return NaN
1508         beq     Lmuldf$a$nf             | we still have to check d1 and b ...
1509         cmpl    d7,d2                   | now compare b with INFINITY
1510         bhi     Lmuldf$inop             | is b NaN?
1511         beq     Lmuldf$b$nf             | we still have to check d3 ...
1512 | Here we have both numbers finite and nonzero (and with no sign bit).
1513 | Now we get the exponents into d4 and d5.
1514         andl    d7,d4                   | isolate exponent in d4
1515         beq     Lmuldf$a$den            | if exponent zero, have denormalized
1516         andl    d6,d0                   | isolate fraction
1517         orl     IMM (0x00100000),d0     | and put hidden bit back
1518         swap    d4                      | I like exponents in the first byte
1519 #ifndef __mcoldfire__
1520         lsrw    IMM (4),d4              | 
1521 #else
1522         lsrl    IMM (4),d4              | 
1523 #endif
1524 Lmuldf$1:                       
1525         andl    d7,d5                   |
1526         beq     Lmuldf$b$den            |
1527         andl    d6,d2                   |
1528         orl     IMM (0x00100000),d2     | and put hidden bit back
1529         swap    d5                      |
1530 #ifndef __mcoldfire__
1531         lsrw    IMM (4),d5              |
1532 #else
1533         lsrl    IMM (4),d5              |
1534 #endif
1535 Lmuldf$2:                               |
1536 #ifndef __mcoldfire__
1537         addw    d5,d4                   | add exponents
1538         subw    IMM (D_BIAS+1),d4       | and subtract bias (plus one)
1539 #else
1540         addl    d5,d4                   | add exponents
1541         subl    IMM (D_BIAS+1),d4       | and subtract bias (plus one)
1542 #endif
1543
1544 | We are now ready to do the multiplication. The situation is as follows:
1545 | both a and b have bit 52 ( bit 20 of d0 and d2) set (even if they were 
1546 | denormalized to start with!), which means that in the product bit 104 
1547 | (which will correspond to bit 8 of the fourth long) is set.
1548
1549 | Here we have to do the product.
1550 | To do it we have to juggle the registers back and forth, as there are not
1551 | enough to keep everything in them. So we use the address registers to keep
1552 | some intermediate data.
1553
1554 #ifndef __mcoldfire__
1555         moveml  a2-a3,sp@-      | save a2 and a3 for temporary use
1556 #else
1557         movel   a2,sp@-
1558         movel   a3,sp@-
1559         movel   a4,sp@-
1560 #endif
1561         movel   IMM (0),a2      | a2 is a null register
1562         movel   d4,a3           | and a3 will preserve the exponent
1563
1564 | First, shift d2-d3 so bit 20 becomes bit 31:
1565 #ifndef __mcoldfire__
1566         rorl    IMM (5),d2      | rotate d2 5 places right
1567         swap    d2              | and swap it
1568         rorl    IMM (5),d3      | do the same thing with d3
1569         swap    d3              |
1570         movew   d3,d6           | get the rightmost 11 bits of d3
1571         andw    IMM (0x07ff),d6 |
1572         orw     d6,d2           | and put them into d2
1573         andw    IMM (0xf800),d3 | clear those bits in d3
1574 #else
1575         moveq   IMM (11),d7     | left shift d2 11 bits
1576         lsll    d7,d2
1577         movel   d3,d6           | get a copy of d3
1578         lsll    d7,d3           | left shift d3 11 bits
1579         andl    IMM (0xffe00000),d6 | get the top 11 bits of d3
1580         moveq   IMM (21),d7     | right shift them 21 bits
1581         lsrl    d7,d6
1582         orl     d6,d2           | stick them at the end of d2
1583 #endif
1584
1585         movel   d2,d6           | move b into d6-d7
1586         movel   d3,d7           | move a into d4-d5
1587         movel   d0,d4           | and clear d0-d1-d2-d3 (to put result)
1588         movel   d1,d5           |
1589         movel   IMM (0),d3      |
1590         movel   d3,d2           |
1591         movel   d3,d1           |
1592         movel   d3,d0           |
1593
1594 | We use a1 as counter: 
1595         movel   IMM (DBL_MANT_DIG-1),a1         
1596 #ifndef __mcoldfire__
1597         exg     d7,a1
1598 #else
1599         movel   d7,a4
1600         movel   a1,d7
1601         movel   a4,a1
1602 #endif
1603
1604 1:
1605 #ifndef __mcoldfire__
1606         exg     d7,a1           | put counter back in a1
1607 #else
1608         movel   d7,a4
1609         movel   a1,d7
1610         movel   a4,a1
1611 #endif
1612         addl    d3,d3           | shift sum once left
1613         addxl   d2,d2           |
1614         addxl   d1,d1           |
1615         addxl   d0,d0           |
1616         addl    d7,d7           |
1617         addxl   d6,d6           |
1618         bcc     2f              | if bit clear skip the following
1619 #ifndef __mcoldfire__
1620         exg     d7,a2           |
1621 #else
1622         movel   d7,a4
1623         movel   a2,d7
1624         movel   a4,a2
1625 #endif
1626         addl    d5,d3           | else add a to the sum
1627         addxl   d4,d2           |
1628         addxl   d7,d1           |
1629         addxl   d7,d0           |
1630 #ifndef __mcoldfire__
1631         exg     d7,a2           | 
1632 #else
1633         movel   d7,a4
1634         movel   a2,d7
1635         movel   a4,a2
1636 #endif
1637 2:
1638 #ifndef __mcoldfire__
1639         exg     d7,a1           | put counter in d7
1640         dbf     d7,1b           | decrement and branch
1641 #else
1642         movel   d7,a4
1643         movel   a1,d7
1644         movel   a4,a1
1645         subql   IMM (1),d7
1646         bpl     1b
1647 #endif
1648
1649         movel   a3,d4           | restore exponent
1650 #ifndef __mcoldfire__
1651         moveml  sp@+,a2-a3
1652 #else
1653         movel   sp@+,a4
1654         movel   sp@+,a3
1655         movel   sp@+,a2
1656 #endif
1657
1658 | Now we have the product in d0-d1-d2-d3, with bit 8 of d0 set. The 
1659 | first thing to do now is to normalize it so bit 8 becomes bit 
1660 | DBL_MANT_DIG-32 (to do the rounding); later we will shift right.
1661         swap    d0
1662         swap    d1
1663         movew   d1,d0
1664         swap    d2
1665         movew   d2,d1
1666         swap    d3
1667         movew   d3,d2
1668         movew   IMM (0),d3
1669 #ifndef __mcoldfire__
1670         lsrl    IMM (1),d0
1671         roxrl   IMM (1),d1
1672         roxrl   IMM (1),d2
1673         roxrl   IMM (1),d3
1674         lsrl    IMM (1),d0
1675         roxrl   IMM (1),d1
1676         roxrl   IMM (1),d2
1677         roxrl   IMM (1),d3
1678         lsrl    IMM (1),d0
1679         roxrl   IMM (1),d1
1680         roxrl   IMM (1),d2
1681         roxrl   IMM (1),d3
1682 #else
1683         moveq   IMM (29),d6
1684         lsrl    IMM (3),d3
1685         movel   d2,d7
1686         lsll    d6,d7
1687         orl     d7,d3
1688         lsrl    IMM (3),d2
1689         movel   d1,d7
1690         lsll    d6,d7
1691         orl     d7,d2
1692         lsrl    IMM (3),d1
1693         movel   d0,d7
1694         lsll    d6,d7
1695         orl     d7,d1
1696         lsrl    IMM (3),d0
1697 #endif
1698         
1699 | Now round, check for over- and underflow, and exit.
1700         movel   a0,d7           | get sign bit back into d7
1701         moveq   IMM (MULTIPLY),d5
1702
1703         btst    IMM (DBL_MANT_DIG+1-32),d0
1704         beq     Lround$exit
1705 #ifndef __mcoldfire__
1706         lsrl    IMM (1),d0
1707         roxrl   IMM (1),d1
1708         addw    IMM (1),d4
1709 #else
1710         lsrl    IMM (1),d1
1711         btst    IMM (0),d0
1712         beq     10f
1713         bset    IMM (31),d1
1714 10:     lsrl    IMM (1),d0
1715         addl    IMM (1),d4
1716 #endif
1717         bra     Lround$exit
1718
1719 Lmuldf$inop:
1720         moveq   IMM (MULTIPLY),d5
1721         bra     Ld$inop
1722
1723 Lmuldf$b$nf:
1724         moveq   IMM (MULTIPLY),d5
1725         movel   a0,d7           | get sign bit back into d7
1726         tstl    d3              | we know d2 == 0x7ff00000, so check d3
1727         bne     Ld$inop         | if d3 <> 0 b is NaN
1728         bra     Ld$overflow     | else we have overflow (since a is finite)
1729
1730 Lmuldf$a$nf:
1731         moveq   IMM (MULTIPLY),d5
1732         movel   a0,d7           | get sign bit back into d7
1733         tstl    d1              | we know d0 == 0x7ff00000, so check d1
1734         bne     Ld$inop         | if d1 <> 0 a is NaN
1735         bra     Ld$overflow     | else signal overflow
1736
1737 | If either number is zero return zero, unless the other is +/-INFINITY or
1738 | NaN, in which case we return NaN.
1739 Lmuldf$b$0:
1740         moveq   IMM (MULTIPLY),d5
1741 #ifndef __mcoldfire__
1742         exg     d2,d0           | put b (==0) into d0-d1
1743         exg     d3,d1           | and a (with sign bit cleared) into d2-d3
1744         movel   a0,d0           | set result sign
1745 #else
1746         movel   d0,d2           | put a into d2-d3
1747         movel   d1,d3
1748         movel   a0,d0           | put result zero into d0-d1
1749         movq    IMM(0),d1
1750 #endif
1751         bra     1f
1752 Lmuldf$a$0:
1753         movel   a0,d0           | set result sign
1754         movel   a6@(16),d2      | put b into d2-d3 again
1755         movel   a6@(20),d3      |
1756         bclr    IMM (31),d2     | clear sign bit
1757 1:      cmpl    IMM (0x7ff00000),d2 | check for non-finiteness
1758         bge     Ld$inop         | in case NaN or +/-INFINITY return NaN
1759         PICLEA  SYM (_fpCCR),a0
1760         movew   IMM (0),a0@
1761 #ifndef __mcoldfire__
1762         moveml  sp@+,d2-d7
1763 #else
1764         moveml  sp@,d2-d7
1765         | XXX if frame pointer is ever removed, stack pointer must
1766         | be adjusted here.
1767 #endif
1768         unlk    a6
1769         rts
1770
1771 | If a number is denormalized we put an exponent of 1 but do not put the 
1772 | hidden bit back into the fraction; instead we shift left until bit 21
1773 | (the hidden bit) is set, adjusting the exponent accordingly. We do this
1774 | to ensure that the product of the fractions is close to 1.
1775 Lmuldf$a$den:
1776         movel   IMM (1),d4
1777         andl    d6,d0
1778 1:      addl    d1,d1           | shift a left until bit 20 is set
1779         addxl   d0,d0           |
1780 #ifndef __mcoldfire__
1781         subw    IMM (1),d4      | and adjust exponent
1782 #else
1783         subl    IMM (1),d4      | and adjust exponent
1784 #endif
1785         btst    IMM (20),d0     |
1786         bne     Lmuldf$1        |
1787         bra     1b
1788
1789 Lmuldf$b$den:
1790         movel   IMM (1),d5
1791         andl    d6,d2
1792 1:      addl    d3,d3           | shift b left until bit 20 is set
1793         addxl   d2,d2           |
1794 #ifndef __mcoldfire__
1795         subw    IMM (1),d5      | and adjust exponent
1796 #else
1797         subql   IMM (1),d5      | and adjust exponent
1798 #endif
1799         btst    IMM (20),d2     |
1800         bne     Lmuldf$2        |
1801         bra     1b
1802
1803
1804 |=============================================================================
1805 |                              __divdf3
1806 |=============================================================================
1807
1808 | double __divdf3(double, double);
1809         FUNC(__divdf3)
1810 SYM (__divdf3):
1811 #ifndef __mcoldfire__
1812         link    a6,IMM (0)
1813         moveml  d2-d7,sp@-
1814 #else
1815         link    a6,IMM (-24)
1816         moveml  d2-d7,sp@
1817 #endif
1818         movel   a6@(8),d0       | get a into d0-d1
1819         movel   a6@(12),d1      | 
1820         movel   a6@(16),d2      | and b into d2-d3
1821         movel   a6@(20),d3      |
1822         movel   d0,d7           | d7 will hold the sign of the result
1823         eorl    d2,d7           |
1824         andl    IMM (0x80000000),d7
1825         movel   d7,a0           | save sign into a0
1826         movel   IMM (0x7ff00000),d7 | useful constant (+INFINITY)
1827         movel   d7,d6           | another (mask for fraction)
1828         notl    d6              |
1829         bclr    IMM (31),d0     | get rid of a's sign bit '
1830         movel   d0,d4           |
1831         orl     d1,d4           |
1832         beq     Ldivdf$a$0      | branch if a is zero
1833         movel   d0,d4           |
1834         bclr    IMM (31),d2     | get rid of b's sign bit '
1835         movel   d2,d5           |
1836         orl     d3,d5           |
1837         beq     Ldivdf$b$0      | branch if b is zero
1838         movel   d2,d5
1839         cmpl    d7,d0           | is a big?
1840         bhi     Ldivdf$inop     | if a is NaN return NaN
1841         beq     Ldivdf$a$nf     | if d0 == 0x7ff00000 we check d1
1842         cmpl    d7,d2           | now compare b with INFINITY 
1843         bhi     Ldivdf$inop     | if b is NaN return NaN
1844         beq     Ldivdf$b$nf     | if d2 == 0x7ff00000 we check d3
1845 | Here we have both numbers finite and nonzero (and with no sign bit).
1846 | Now we get the exponents into d4 and d5 and normalize the numbers to
1847 | ensure that the ratio of the fractions is around 1. We do this by
1848 | making sure that both numbers have bit #DBL_MANT_DIG-32-1 (hidden bit)
1849 | set, even if they were denormalized to start with.
1850 | Thus, the result will satisfy: 2 > result > 1/2.
1851         andl    d7,d4           | and isolate exponent in d4
1852         beq     Ldivdf$a$den    | if exponent is zero we have a denormalized
1853         andl    d6,d0           | and isolate fraction
1854         orl     IMM (0x00100000),d0 | and put hidden bit back
1855         swap    d4              | I like exponents in the first byte
1856 #ifndef __mcoldfire__
1857         lsrw    IMM (4),d4      | 
1858 #else
1859         lsrl    IMM (4),d4      | 
1860 #endif
1861 Ldivdf$1:                       | 
1862         andl    d7,d5           |
1863         beq     Ldivdf$b$den    |
1864         andl    d6,d2           |
1865         orl     IMM (0x00100000),d2
1866         swap    d5              |
1867 #ifndef __mcoldfire__
1868         lsrw    IMM (4),d5      |
1869 #else
1870         lsrl    IMM (4),d5      |
1871 #endif
1872 Ldivdf$2:                       |
1873 #ifndef __mcoldfire__
1874         subw    d5,d4           | subtract exponents
1875         addw    IMM (D_BIAS),d4 | and add bias
1876 #else
1877         subl    d5,d4           | subtract exponents
1878         addl    IMM (D_BIAS),d4 | and add bias
1879 #endif
1880
1881 | We are now ready to do the division. We have prepared things in such a way
1882 | that the ratio of the fractions will be less than 2 but greater than 1/2.
1883 | At this point the registers in use are:
1884 | d0-d1 hold a (first operand, bit DBL_MANT_DIG-32=0, bit 
1885 | DBL_MANT_DIG-1-32=1)
1886 | d2-d3 hold b (second operand, bit DBL_MANT_DIG-32=1)
1887 | d4    holds the difference of the exponents, corrected by the bias
1888 | a0    holds the sign of the ratio
1889
1890 | To do the rounding correctly we need to keep information about the
1891 | nonsignificant bits. One way to do this would be to do the division
1892 | using four registers; another is to use two registers (as originally
1893 | I did), but use a sticky bit to preserve information about the 
1894 | fractional part. Note that we can keep that info in a1, which is not
1895 | used.
1896         movel   IMM (0),d6      | d6-d7 will hold the result
1897         movel   d6,d7           | 
1898         movel   IMM (0),a1      | and a1 will hold the sticky bit
1899
1900         movel   IMM (DBL_MANT_DIG-32+1),d5      
1901         
1902 1:      cmpl    d0,d2           | is a < b?
1903         bhi     3f              | if b > a skip the following
1904         beq     4f              | if d0==d2 check d1 and d3
1905 2:      subl    d3,d1           | 
1906         subxl   d2,d0           | a <-- a - b
1907         bset    d5,d6           | set the corresponding bit in d6
1908 3:      addl    d1,d1           | shift a by 1
1909         addxl   d0,d0           |
1910 #ifndef __mcoldfire__
1911         dbra    d5,1b           | and branch back
1912 #else
1913         subql   IMM (1), d5
1914         bpl     1b
1915 #endif
1916         bra     5f                      
1917 4:      cmpl    d1,d3           | here d0==d2, so check d1 and d3
1918         bhi     3b              | if d1 > d2 skip the subtraction
1919         bra     2b              | else go do it
1920 5:
1921 | Here we have to start setting the bits in the second long.
1922         movel   IMM (31),d5     | again d5 is counter
1923
1924 1:      cmpl    d0,d2           | is a < b?
1925         bhi     3f              | if b > a skip the following
1926         beq     4f              | if d0==d2 check d1 and d3
1927 2:      subl    d3,d1           | 
1928         subxl   d2,d0           | a <-- a - b
1929         bset    d5,d7           | set the corresponding bit in d7
1930 3:      addl    d1,d1           | shift a by 1
1931         addxl   d0,d0           |
1932 #ifndef __mcoldfire__
1933         dbra    d5,1b           | and branch back
1934 #else
1935         subql   IMM (1), d5
1936         bpl     1b
1937 #endif
1938         bra     5f                      
1939 4:      cmpl    d1,d3           | here d0==d2, so check d1 and d3
1940         bhi     3b              | if d1 > d2 skip the subtraction
1941         bra     2b              | else go do it
1942 5:
1943 | Now go ahead checking until we hit a one, which we store in d2.
1944         movel   IMM (DBL_MANT_DIG),d5
1945 1:      cmpl    d2,d0           | is a < b?
1946         bhi     4f              | if b < a, exit
1947         beq     3f              | if d0==d2 check d1 and d3
1948 2:      addl    d1,d1           | shift a by 1
1949         addxl   d0,d0           |
1950 #ifndef __mcoldfire__
1951         dbra    d5,1b           | and branch back
1952 #else
1953         subql   IMM (1), d5
1954         bpl     1b
1955 #endif
1956         movel   IMM (0),d2      | here no sticky bit was found
1957         movel   d2,d3
1958         bra     5f                      
1959 3:      cmpl    d1,d3           | here d0==d2, so check d1 and d3
1960         bhi     2b              | if d1 > d2 go back
1961 4:
1962 | Here put the sticky bit in d2-d3 (in the position which actually corresponds
1963 | to it; if you don't do this the algorithm loses in some cases). '
1964         movel   IMM (0),d2
1965         movel   d2,d3
1966 #ifndef __mcoldfire__
1967         subw    IMM (DBL_MANT_DIG),d5
1968         addw    IMM (63),d5
1969         cmpw    IMM (31),d5
1970 #else
1971         subl    IMM (DBL_MANT_DIG),d5
1972         addl    IMM (63),d5
1973         cmpl    IMM (31),d5
1974 #endif
1975         bhi     2f
1976 1:      bset    d5,d3
1977         bra     5f
1978 #ifndef __mcoldfire__
1979         subw    IMM (32),d5
1980 #else
1981         subl    IMM (32),d5
1982 #endif
1983 2:      bset    d5,d2
1984 5:
1985 | Finally we are finished! Move the longs in the address registers to
1986 | their final destination:
1987         movel   d6,d0
1988         movel   d7,d1
1989         movel   IMM (0),d3
1990
1991 | Here we have finished the division, with the result in d0-d1-d2-d3, with
1992 | 2^21 <= d6 < 2^23. Thus bit 23 is not set, but bit 22 could be set.
1993 | If it is not, then definitely bit 21 is set. Normalize so bit 22 is
1994 | not set:
1995         btst    IMM (DBL_MANT_DIG-32+1),d0
1996         beq     1f
1997 #ifndef __mcoldfire__
1998         lsrl    IMM (1),d0
1999         roxrl   IMM (1),d1
2000         roxrl   IMM (1),d2
2001         roxrl   IMM (1),d3
2002         addw    IMM (1),d4
2003 #else
2004         lsrl    IMM (1),d3
2005         btst    IMM (0),d2
2006         beq     10f
2007         bset    IMM (31),d3
2008 10:     lsrl    IMM (1),d2
2009         btst    IMM (0),d1
2010         beq     11f
2011         bset    IMM (31),d2
2012 11:     lsrl    IMM (1),d1
2013         btst    IMM (0),d0
2014         beq     12f
2015         bset    IMM (31),d1
2016 12:     lsrl    IMM (1),d0
2017         addl    IMM (1),d4
2018 #endif
2019 1:
2020 | Now round, check for over- and underflow, and exit.
2021         movel   a0,d7           | restore sign bit to d7
2022         moveq   IMM (DIVIDE),d5
2023         bra     Lround$exit
2024
2025 Ldivdf$inop:
2026         moveq   IMM (DIVIDE),d5
2027         bra     Ld$inop
2028
2029 Ldivdf$a$0:
2030 | If a is zero check to see whether b is zero also. In that case return
2031 | NaN; then check if b is NaN, and return NaN also in that case. Else
2032 | return a properly signed zero.
2033         moveq   IMM (DIVIDE),d5
2034         bclr    IMM (31),d2     |
2035         movel   d2,d4           | 
2036         orl     d3,d4           | 
2037         beq     Ld$inop         | if b is also zero return NaN
2038         cmpl    IMM (0x7ff00000),d2 | check for NaN
2039         bhi     Ld$inop         | 
2040         blt     1f              |
2041         tstl    d3              |
2042         bne     Ld$inop         |
2043 1:      movel   a0,d0           | else return signed zero
2044         moveq   IMM(0),d1       | 
2045         PICLEA  SYM (_fpCCR),a0 | clear exception flags
2046         movew   IMM (0),a0@     |
2047 #ifndef __mcoldfire__
2048         moveml  sp@+,d2-d7      | 
2049 #else
2050         moveml  sp@,d2-d7       | 
2051         | XXX if frame pointer is ever removed, stack pointer must
2052         | be adjusted here.
2053 #endif
2054         unlk    a6              | 
2055         rts                     |       
2056
2057 Ldivdf$b$0:
2058         moveq   IMM (DIVIDE),d5
2059 | If we got here a is not zero. Check if a is NaN; in that case return NaN,
2060 | else return +/-INFINITY. Remember that a is in d0 with the sign bit 
2061 | cleared already.
2062         movel   a0,d7           | put a's sign bit back in d7 '
2063         cmpl    IMM (0x7ff00000),d0 | compare d0 with INFINITY
2064         bhi     Ld$inop         | if larger it is NaN
2065         tstl    d1              | 
2066         bne     Ld$inop         | 
2067         bra     Ld$div$0        | else signal DIVIDE_BY_ZERO
2068
2069 Ldivdf$b$nf:
2070         moveq   IMM (DIVIDE),d5
2071 | If d2 == 0x7ff00000 we have to check d3.
2072         tstl    d3              |
2073         bne     Ld$inop         | if d3 <> 0, b is NaN
2074         bra     Ld$underflow    | else b is +/-INFINITY, so signal underflow
2075
2076 Ldivdf$a$nf:
2077         moveq   IMM (DIVIDE),d5
2078 | If d0 == 0x7ff00000 we have to check d1.
2079         tstl    d1              |
2080         bne     Ld$inop         | if d1 <> 0, a is NaN
2081 | If a is INFINITY we have to check b
2082         cmpl    d7,d2           | compare b with INFINITY 
2083         bge     Ld$inop         | if b is NaN or INFINITY return NaN
2084         tstl    d3              |
2085         bne     Ld$inop         | 
2086         bra     Ld$overflow     | else return overflow
2087
2088 | If a number is denormalized we put an exponent of 1 but do not put the 
2089 | bit back into the fraction.
2090 Ldivdf$a$den:
2091         movel   IMM (1),d4
2092         andl    d6,d0
2093 1:      addl    d1,d1           | shift a left until bit 20 is set
2094         addxl   d0,d0
2095 #ifndef __mcoldfire__
2096         subw    IMM (1),d4      | and adjust exponent
2097 #else
2098         subl    IMM (1),d4      | and adjust exponent
2099 #endif
2100         btst    IMM (DBL_MANT_DIG-32-1),d0
2101         bne     Ldivdf$1
2102         bra     1b
2103
2104 Ldivdf$b$den:
2105         movel   IMM (1),d5
2106         andl    d6,d2
2107 1:      addl    d3,d3           | shift b left until bit 20 is set
2108         addxl   d2,d2
2109 #ifndef __mcoldfire__
2110         subw    IMM (1),d5      | and adjust exponent
2111 #else
2112         subql   IMM (1),d5      | and adjust exponent
2113 #endif
2114         btst    IMM (DBL_MANT_DIG-32-1),d2
2115         bne     Ldivdf$2
2116         bra     1b
2117
2118 Lround$exit:
2119 | This is a common exit point for __muldf3 and __divdf3. When they enter
2120 | this point the sign of the result is in d7, the result in d0-d1, normalized
2121 | so that 2^21 <= d0 < 2^22, and the exponent is in the lower byte of d4.
2122
2123 | First check for underlow in the exponent:
2124 #ifndef __mcoldfire__
2125         cmpw    IMM (-DBL_MANT_DIG-1),d4                
2126 #else
2127         cmpl    IMM (-DBL_MANT_DIG-1),d4                
2128 #endif
2129         blt     Ld$underflow    
2130 | It could happen that the exponent is less than 1, in which case the 
2131 | number is denormalized. In this case we shift right and adjust the 
2132 | exponent until it becomes 1 or the fraction is zero (in the latter case 
2133 | we signal underflow and return zero).
2134         movel   d7,a0           |
2135         movel   IMM (0),d6      | use d6-d7 to collect bits flushed right
2136         movel   d6,d7           | use d6-d7 to collect bits flushed right
2137 #ifndef __mcoldfire__
2138         cmpw    IMM (1),d4      | if the exponent is less than 1 we 
2139 #else
2140         cmpl    IMM (1),d4      | if the exponent is less than 1 we 
2141 #endif
2142         bge     2f              | have to shift right (denormalize)
2143 1:
2144 #ifndef __mcoldfire__
2145         addw    IMM (1),d4      | adjust the exponent
2146         lsrl    IMM (1),d0      | shift right once 
2147         roxrl   IMM (1),d1      |
2148         roxrl   IMM (1),d2      |
2149         roxrl   IMM (1),d3      |
2150         roxrl   IMM (1),d6      | 
2151         roxrl   IMM (1),d7      |
2152         cmpw    IMM (1),d4      | is the exponent 1 already?
2153 #else
2154         addl    IMM (1),d4      | adjust the exponent
2155         lsrl    IMM (1),d7
2156         btst    IMM (0),d6
2157         beq     13f
2158         bset    IMM (31),d7
2159 13:     lsrl    IMM (1),d6
2160         btst    IMM (0),d3
2161         beq     14f
2162         bset    IMM (31),d6
2163 14:     lsrl    IMM (1),d3
2164         btst    IMM (0),d2
2165         beq     10f
2166         bset    IMM (31),d3
2167 10:     lsrl    IMM (1),d2
2168         btst    IMM (0),d1
2169         beq     11f
2170         bset    IMM (31),d2
2171 11:     lsrl    IMM (1),d1
2172         btst    IMM (0),d0
2173         beq     12f
2174         bset    IMM (31),d1
2175 12:     lsrl    IMM (1),d0
2176         cmpl    IMM (1),d4      | is the exponent 1 already?
2177 #endif
2178         beq     2f              | if not loop back
2179         bra     1b              |
2180         bra     Ld$underflow    | safety check, shouldn't execute '
2181 2:      orl     d6,d2           | this is a trick so we don't lose  '
2182         orl     d7,d3           | the bits which were flushed right
2183         movel   a0,d7           | get back sign bit into d7
2184 | Now call the rounding routine (which takes care of denormalized numbers):
2185         lea     pc@(Lround$0),a0 | to return from rounding routine
2186         PICLEA  SYM (_fpCCR),a1 | check the rounding mode
2187 #ifdef __mcoldfire__
2188         clrl    d6
2189 #endif
2190         movew   a1@(6),d6       | rounding mode in d6
2191         beq     Lround$to$nearest
2192 #ifndef __mcoldfire__
2193         cmpw    IMM (ROUND_TO_PLUS),d6
2194 #else
2195         cmpl    IMM (ROUND_TO_PLUS),d6
2196 #endif
2197         bhi     Lround$to$minus
2198         blt     Lround$to$zero
2199         bra     Lround$to$plus
2200 Lround$0:
2201 | Here we have a correctly rounded result (either normalized or denormalized).
2202
2203 | Here we should have either a normalized number or a denormalized one, and
2204 | the exponent is necessarily larger or equal to 1 (so we don't have to  '
2205 | check again for underflow!). We have to check for overflow or for a 
2206 | denormalized number (which also signals underflow).
2207 | Check for overflow (i.e., exponent >= 0x7ff).
2208 #ifndef __mcoldfire__
2209         cmpw    IMM (0x07ff),d4
2210 #else
2211         cmpl    IMM (0x07ff),d4
2212 #endif
2213         bge     Ld$overflow
2214 | Now check for a denormalized number (exponent==0):
2215         movew   d4,d4
2216         beq     Ld$den
2217 1:
2218 | Put back the exponents and sign and return.
2219 #ifndef __mcoldfire__
2220         lslw    IMM (4),d4      | exponent back to fourth byte
2221 #else
2222         lsll    IMM (4),d4      | exponent back to fourth byte
2223 #endif
2224         bclr    IMM (DBL_MANT_DIG-32-1),d0
2225         swap    d0              | and put back exponent
2226 #ifndef __mcoldfire__
2227         orw     d4,d0           | 
2228 #else
2229         orl     d4,d0           | 
2230 #endif
2231         swap    d0              |
2232         orl     d7,d0           | and sign also
2233
2234         PICLEA  SYM (_fpCCR),a0
2235         movew   IMM (0),a0@
2236 #ifndef __mcoldfire__
2237         moveml  sp@+,d2-d7
2238 #else
2239         moveml  sp@,d2-d7
2240         | XXX if frame pointer is ever removed, stack pointer must
2241         | be adjusted here.
2242 #endif
2243         unlk    a6
2244         rts
2245
2246 |=============================================================================
2247 |                              __negdf2
2248 |=============================================================================
2249
2250 | double __negdf2(double, double);
2251         FUNC(__negdf2)
2252 SYM (__negdf2):
2253 #ifndef __mcoldfire__
2254         link    a6,IMM (0)
2255         moveml  d2-d7,sp@-
2256 #else
2257         link    a6,IMM (-24)
2258         moveml  d2-d7,sp@
2259 #endif
2260         moveq   IMM (NEGATE),d5
2261         movel   a6@(8),d0       | get number to negate in d0-d1
2262         movel   a6@(12),d1      |
2263         bchg    IMM (31),d0     | negate
2264         movel   d0,d2           | make a positive copy (for the tests)
2265         bclr    IMM (31),d2     |
2266         movel   d2,d4           | check for zero
2267         orl     d1,d4           |
2268         beq     2f              | if zero (either sign) return +zero
2269         cmpl    IMM (0x7ff00000),d2 | compare to +INFINITY
2270         blt     1f              | if finite, return
2271         bhi     Ld$inop         | if larger (fraction not zero) is NaN
2272         tstl    d1              | if d2 == 0x7ff00000 check d1
2273         bne     Ld$inop         |
2274         movel   d0,d7           | else get sign and return INFINITY
2275         andl    IMM (0x80000000),d7
2276         bra     Ld$infty                
2277 1:      PICLEA  SYM (_fpCCR),a0
2278         movew   IMM (0),a0@
2279 #ifndef __mcoldfire__
2280         moveml  sp@+,d2-d7
2281 #else
2282         moveml  sp@,d2-d7
2283         | XXX if frame pointer is ever removed, stack pointer must
2284         | be adjusted here.
2285 #endif
2286         unlk    a6
2287         rts
2288 2:      bclr    IMM (31),d0
2289         bra     1b
2290
2291 |=============================================================================
2292 |                              __cmpdf2
2293 |=============================================================================
2294
2295 GREATER =  1
2296 LESS    = -1
2297 EQUAL   =  0
2298
2299 | int __cmpdf2_internal(double, double, int);
2300 SYM (__cmpdf2_internal):
2301 #ifndef __mcoldfire__
2302         link    a6,IMM (0)
2303         moveml  d2-d7,sp@-      | save registers
2304 #else
2305         link    a6,IMM (-24)
2306         moveml  d2-d7,sp@
2307 #endif
2308         moveq   IMM (COMPARE),d5
2309         movel   a6@(8),d0       | get first operand
2310         movel   a6@(12),d1      |
2311         movel   a6@(16),d2      | get second operand
2312         movel   a6@(20),d3      |
2313 | First check if a and/or b are (+/-) zero and in that case clear
2314 | the sign bit.
2315         movel   d0,d6           | copy signs into d6 (a) and d7(b)
2316         bclr    IMM (31),d0     | and clear signs in d0 and d2
2317         movel   d2,d7           |
2318         bclr    IMM (31),d2     |
2319         cmpl    IMM (0x7ff00000),d0 | check for a == NaN
2320         bhi     Lcmpd$inop              | if d0 > 0x7ff00000, a is NaN
2321         beq     Lcmpdf$a$nf     | if equal can be INFINITY, so check d1
2322         movel   d0,d4           | copy into d4 to test for zero
2323         orl     d1,d4           |
2324         beq     Lcmpdf$a$0      |
2325 Lcmpdf$0:
2326         cmpl    IMM (0x7ff00000),d2 | check for b == NaN
2327         bhi     Lcmpd$inop              | if d2 > 0x7ff00000, b is NaN
2328         beq     Lcmpdf$b$nf     | if equal can be INFINITY, so check d3
2329         movel   d2,d4           |
2330         orl     d3,d4           |
2331         beq     Lcmpdf$b$0      |
2332 Lcmpdf$1:
2333 | Check the signs
2334         eorl    d6,d7
2335         bpl     1f
2336 | If the signs are not equal check if a >= 0
2337         tstl    d6
2338         bpl     Lcmpdf$a$gt$b   | if (a >= 0 && b < 0) => a > b
2339         bmi     Lcmpdf$b$gt$a   | if (a < 0 && b >= 0) => a < b
2340 1:
2341 | If the signs are equal check for < 0
2342         tstl    d6
2343         bpl     1f
2344 | If both are negative exchange them
2345 #ifndef __mcoldfire__
2346         exg     d0,d2
2347         exg     d1,d3
2348 #else
2349         movel   d0,d7
2350         movel   d2,d0
2351         movel   d7,d2
2352         movel   d1,d7
2353         movel   d3,d1
2354         movel   d7,d3
2355 #endif
2356 1:
2357 | Now that they are positive we just compare them as longs (does this also
2358 | work for denormalized numbers?).
2359         cmpl    d0,d2
2360         bhi     Lcmpdf$b$gt$a   | |b| > |a|
2361         bne     Lcmpdf$a$gt$b   | |b| < |a|
2362 | If we got here d0 == d2, so we compare d1 and d3.
2363         cmpl    d1,d3
2364         bhi     Lcmpdf$b$gt$a   | |b| > |a|
2365         bne     Lcmpdf$a$gt$b   | |b| < |a|
2366 | If we got here a == b.
2367         movel   IMM (EQUAL),d0
2368 #ifndef __mcoldfire__
2369         moveml  sp@+,d2-d7      | put back the registers
2370 #else
2371         moveml  sp@,d2-d7
2372         | XXX if frame pointer is ever removed, stack pointer must
2373         | be adjusted here.
2374 #endif
2375         unlk    a6
2376         rts
2377 Lcmpdf$a$gt$b:
2378         movel   IMM (GREATER),d0
2379 #ifndef __mcoldfire__
2380         moveml  sp@+,d2-d7      | put back the registers
2381 #else
2382         moveml  sp@,d2-d7
2383         | XXX if frame pointer is ever removed, stack pointer must
2384         | be adjusted here.
2385 #endif
2386         unlk    a6
2387         rts
2388 Lcmpdf$b$gt$a:
2389         movel   IMM (LESS),d0
2390 #ifndef __mcoldfire__
2391         moveml  sp@+,d2-d7      | put back the registers
2392 #else
2393         moveml  sp@,d2-d7
2394         | XXX if frame pointer is ever removed, stack pointer must
2395         | be adjusted here.
2396 #endif
2397         unlk    a6
2398         rts
2399
2400 Lcmpdf$a$0:     
2401         bclr    IMM (31),d6
2402         bra     Lcmpdf$0
2403 Lcmpdf$b$0:
2404         bclr    IMM (31),d7
2405         bra     Lcmpdf$1
2406
2407 Lcmpdf$a$nf:
2408         tstl    d1
2409         bne     Ld$inop
2410         bra     Lcmpdf$0
2411
2412 Lcmpdf$b$nf:
2413         tstl    d3
2414         bne     Ld$inop
2415         bra     Lcmpdf$1
2416
2417 Lcmpd$inop:
2418         movl    a6@(24),d0
2419         moveq   IMM (INEXACT_RESULT+INVALID_OPERATION),d7
2420         moveq   IMM (DOUBLE_FLOAT),d6
2421         PICJUMP $_exception_handler
2422
2423 | int __cmpdf2(double, double);
2424         FUNC(__cmpdf2)
2425 SYM (__cmpdf2):
2426         link    a6,IMM (0)
2427         pea     1
2428         movl    a6@(20),sp@-
2429         movl    a6@(16),sp@-
2430         movl    a6@(12),sp@-
2431         movl    a6@(8),sp@-
2432         PICCALL SYM (__cmpdf2_internal)
2433         unlk    a6
2434         rts
2435
2436 |=============================================================================
2437 |                           rounding routines
2438 |=============================================================================
2439
2440 | The rounding routines expect the number to be normalized in registers
2441 | d0-d1-d2-d3, with the exponent in register d4. They assume that the 
2442 | exponent is larger or equal to 1. They return a properly normalized number
2443 | if possible, and a denormalized number otherwise. The exponent is returned
2444 | in d4.
2445
2446 Lround$to$nearest:
2447 | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
2448 | Here we assume that the exponent is not too small (this should be checked
2449 | before entering the rounding routine), but the number could be denormalized.
2450
2451 | Check for denormalized numbers:
2452 1:      btst    IMM (DBL_MANT_DIG-32),d0
2453         bne     2f              | if set the number is normalized
2454 | Normalize shifting left until bit #DBL_MANT_DIG-32 is set or the exponent 
2455 | is one (remember that a denormalized number corresponds to an 
2456 | exponent of -D_BIAS+1).
2457 #ifndef __mcoldfire__
2458         cmpw    IMM (1),d4      | remember that the exponent is at least one
2459 #else
2460         cmpl    IMM (1),d4      | remember that the exponent is at least one
2461 #endif
2462         beq     2f              | an exponent of one means denormalized
2463         addl    d3,d3           | else shift and adjust the exponent
2464         addxl   d2,d2           |
2465         addxl   d1,d1           |
2466         addxl   d0,d0           |
2467 #ifndef __mcoldfire__
2468         dbra    d4,1b           |
2469 #else
2470         subql   IMM (1), d4
2471         bpl     1b
2472 #endif
2473 2:
2474 | Now round: we do it as follows: after the shifting we can write the
2475 | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
2476 | If delta < 1, do nothing. If delta > 1, add 1 to f. 
2477 | If delta == 1, we make sure the rounded number will be even (odd?) 
2478 | (after shifting).
2479         btst    IMM (0),d1      | is delta < 1?
2480         beq     2f              | if so, do not do anything
2481         orl     d2,d3           | is delta == 1?
2482         bne     1f              | if so round to even
2483         movel   d1,d3           | 
2484         andl    IMM (2),d3      | bit 1 is the last significant bit
2485         movel   IMM (0),d2      |
2486         addl    d3,d1           |
2487         addxl   d2,d0           |
2488         bra     2f              | 
2489 1:      movel   IMM (1),d3      | else add 1 
2490         movel   IMM (0),d2      |
2491         addl    d3,d1           |
2492         addxl   d2,d0
2493 | Shift right once (because we used bit #DBL_MANT_DIG-32!).
2494 2:
2495 #ifndef __mcoldfire__
2496         lsrl    IMM (1),d0
2497         roxrl   IMM (1),d1              
2498 #else
2499         lsrl    IMM (1),d1
2500         btst    IMM (0),d0
2501         beq     10f
2502         bset    IMM (31),d1
2503 10:     lsrl    IMM (1),d0
2504 #endif
2505
2506 | Now check again bit #DBL_MANT_DIG-32 (rounding could have produced a
2507 | 'fraction overflow' ...).
2508         btst    IMM (DBL_MANT_DIG-32),d0        
2509         beq     1f
2510 #ifndef __mcoldfire__
2511         lsrl    IMM (1),d0
2512         roxrl   IMM (1),d1
2513         addw    IMM (1),d4
2514 #else
2515         lsrl    IMM (1),d1
2516         btst    IMM (0),d0
2517         beq     10f
2518         bset    IMM (31),d1
2519 10:     lsrl    IMM (1),d0
2520         addl    IMM (1),d4
2521 #endif
2522 1:
2523 | If bit #DBL_MANT_DIG-32-1 is clear we have a denormalized number, so we 
2524 | have to put the exponent to zero and return a denormalized number.
2525         btst    IMM (DBL_MANT_DIG-32-1),d0
2526         beq     1f
2527         jmp     a0@
2528 1:      movel   IMM (0),d4
2529         jmp     a0@
2530
2531 Lround$to$zero:
2532 Lround$to$plus:
2533 Lround$to$minus:
2534         jmp     a0@
2535 #endif /* L_double */
2536
2537 #ifdef  L_float
2538
2539         .globl  SYM (_fpCCR)
2540         .globl  $_exception_handler
2541
2542 QUIET_NaN    = 0xffffffff
2543 SIGNL_NaN    = 0x7f800001
2544 INFINITY     = 0x7f800000
2545
2546 F_MAX_EXP      = 0xff
2547 F_BIAS         = 126
2548 FLT_MAX_EXP    = F_MAX_EXP - F_BIAS
2549 FLT_MIN_EXP    = 1 - F_BIAS
2550 FLT_MANT_DIG   = 24
2551
2552 INEXACT_RESULT          = 0x0001
2553 UNDERFLOW               = 0x0002
2554 OVERFLOW                = 0x0004
2555 DIVIDE_BY_ZERO          = 0x0008
2556 INVALID_OPERATION       = 0x0010
2557
2558 SINGLE_FLOAT = 1
2559
2560 NOOP         = 0
2561 ADD          = 1
2562 MULTIPLY     = 2
2563 DIVIDE       = 3
2564 NEGATE       = 4
2565 COMPARE      = 5
2566 EXTENDSFDF   = 6
2567 TRUNCDFSF    = 7
2568
2569 UNKNOWN           = -1
2570 ROUND_TO_NEAREST  = 0 | round result to nearest representable value
2571 ROUND_TO_ZERO     = 1 | round result towards zero
2572 ROUND_TO_PLUS     = 2 | round result towards plus infinity
2573 ROUND_TO_MINUS    = 3 | round result towards minus infinity
2574
2575 | Entry points:
2576
2577         .globl SYM (__addsf3)
2578         .globl SYM (__subsf3)
2579         .globl SYM (__mulsf3)
2580         .globl SYM (__divsf3)
2581         .globl SYM (__negsf2)
2582         .globl SYM (__cmpsf2)
2583         .globl SYM (__cmpsf2_internal)
2584         .hidden SYM (__cmpsf2_internal)
2585
2586 | These are common routines to return and signal exceptions.    
2587
2588         .text
2589         .even
2590
2591 Lf$den:
2592 | Return and signal a denormalized number
2593         orl     d7,d0
2594         moveq   IMM (INEXACT_RESULT+UNDERFLOW),d7
2595         moveq   IMM (SINGLE_FLOAT),d6
2596         PICJUMP $_exception_handler
2597
2598 Lf$infty:
2599 Lf$overflow:
2600 | Return a properly signed INFINITY and set the exception flags 
2601         movel   IMM (INFINITY),d0
2602         orl     d7,d0
2603         moveq   IMM (INEXACT_RESULT+OVERFLOW),d7
2604         moveq   IMM (SINGLE_FLOAT),d6
2605         PICJUMP $_exception_handler
2606
2607 Lf$underflow:
2608 | Return 0 and set the exception flags 
2609         moveq   IMM (0),d0
2610         moveq   IMM (INEXACT_RESULT+UNDERFLOW),d7
2611         moveq   IMM (SINGLE_FLOAT),d6
2612         PICJUMP $_exception_handler
2613
2614 Lf$inop:
2615 | Return a quiet NaN and set the exception flags
2616         movel   IMM (QUIET_NaN),d0
2617         moveq   IMM (INEXACT_RESULT+INVALID_OPERATION),d7
2618         moveq   IMM (SINGLE_FLOAT),d6
2619         PICJUMP $_exception_handler
2620
2621 Lf$div$0:
2622 | Return a properly signed INFINITY and set the exception flags
2623         movel   IMM (INFINITY),d0
2624         orl     d7,d0
2625         moveq   IMM (INEXACT_RESULT+DIVIDE_BY_ZERO),d7
2626         moveq   IMM (SINGLE_FLOAT),d6
2627         PICJUMP $_exception_handler
2628
2629 |=============================================================================
2630 |=============================================================================
2631 |                         single precision routines
2632 |=============================================================================
2633 |=============================================================================
2634
2635 | A single precision floating point number (float) has the format:
2636 |
2637 | struct _float {
2638 |  unsigned int sign      : 1;  /* sign bit */ 
2639 |  unsigned int exponent  : 8;  /* exponent, shifted by 126 */
2640 |  unsigned int fraction  : 23; /* fraction */
2641 | } float;
2642
2643 | Thus sizeof(float) = 4 (32 bits). 
2644 |
2645 | All the routines are callable from C programs, and return the result 
2646 | in the single register d0. They also preserve all registers except 
2647 | d0-d1 and a0-a1.
2648
2649 |=============================================================================
2650 |                              __subsf3
2651 |=============================================================================
2652
2653 | float __subsf3(float, float);
2654         FUNC(__subsf3)
2655 SYM (__subsf3):
2656         bchg    IMM (31),sp@(8) | change sign of second operand
2657                                 | and fall through
2658 |=============================================================================
2659 |                              __addsf3
2660 |=============================================================================
2661
2662 | float __addsf3(float, float);
2663         FUNC(__addsf3)
2664 SYM (__addsf3):
2665 #ifndef __mcoldfire__
2666         link    a6,IMM (0)      | everything will be done in registers
2667         moveml  d2-d7,sp@-      | save all data registers but d0-d1
2668 #else
2669         link    a6,IMM (-24)
2670         moveml  d2-d7,sp@
2671 #endif
2672         movel   a6@(8),d0       | get first operand
2673         movel   a6@(12),d1      | get second operand
2674         movel   d0,a0           | get d0's sign bit '
2675         addl    d0,d0           | check and clear sign bit of a
2676         beq     Laddsf$b        | if zero return second operand
2677         movel   d1,a1           | save b's sign bit '
2678         addl    d1,d1           | get rid of sign bit
2679         beq     Laddsf$a        | if zero return first operand
2680
2681 | Get the exponents and check for denormalized and/or infinity.
2682
2683         movel   IMM (0x00ffffff),d4     | mask to get fraction
2684         movel   IMM (0x01000000),d5     | mask to put hidden bit back
2685
2686         movel   d0,d6           | save a to get exponent
2687         andl    d4,d0           | get fraction in d0
2688         notl    d4              | make d4 into a mask for the exponent
2689         andl    d4,d6           | get exponent in d6
2690         beq     Laddsf$a$den    | branch if a is denormalized
2691         cmpl    d4,d6           | check for INFINITY or NaN
2692         beq     Laddsf$nf
2693         swap    d6              | put exponent into first word
2694         orl     d5,d0           | and put hidden bit back
2695 Laddsf$1:
2696 | Now we have a's exponent in d6 (second byte) and the mantissa in d0. '
2697         movel   d1,d7           | get exponent in d7
2698         andl    d4,d7           | 
2699         beq     Laddsf$b$den    | branch if b is denormalized
2700         cmpl    d4,d7           | check for INFINITY or NaN
2701         beq     Laddsf$nf
2702         swap    d7              | put exponent into first word
2703         notl    d4              | make d4 into a mask for the fraction
2704         andl    d4,d1           | get fraction in d1
2705         orl     d5,d1           | and put hidden bit back
2706 Laddsf$2:
2707 | Now we have b's exponent in d7 (second byte) and the mantissa in d1. '
2708
2709 | Note that the hidden bit corresponds to bit #FLT_MANT_DIG-1, and we 
2710 | shifted right once, so bit #FLT_MANT_DIG is set (so we have one extra
2711 | bit).
2712
2713         movel   d1,d2           | move b to d2, since we want to use
2714                                 | two registers to do the sum
2715         movel   IMM (0),d1      | and clear the new ones
2716         movel   d1,d3           |
2717
2718 | Here we shift the numbers in registers d0 and d1 so the exponents are the
2719 | same, and put the largest exponent in d6. Note that we are using two
2720 | registers for each number (see the discussion by D. Knuth in "Seminumerical 
2721 | Algorithms").
2722 #ifndef __mcoldfire__
2723         cmpw    d6,d7           | compare exponents
2724 #else
2725         cmpl    d6,d7           | compare exponents
2726 #endif
2727         beq     Laddsf$3        | if equal don't shift '
2728         bhi     5f              | branch if second exponent largest
2729 1:
2730         subl    d6,d7           | keep the largest exponent
2731         negl    d7
2732 #ifndef __mcoldfire__
2733         lsrw    IMM (8),d7      | put difference in lower byte
2734 #else
2735         lsrl    IMM (8),d7      | put difference in lower byte
2736 #endif
2737 | if difference is too large we don't shift (actually, we can just exit) '
2738 #ifndef __mcoldfire__
2739         cmpw    IMM (FLT_MANT_DIG+2),d7         
2740 #else
2741         cmpl    IMM (FLT_MANT_DIG+2),d7         
2742 #endif
2743         bge     Laddsf$b$small
2744 #ifndef __mcoldfire__
2745         cmpw    IMM (16),d7     | if difference >= 16 swap
2746 #else
2747         cmpl    IMM (16),d7     | if difference >= 16 swap
2748 #endif
2749         bge     4f
2750 2:
2751 #ifndef __mcoldfire__
2752         subw    IMM (1),d7
2753 #else
2754         subql   IMM (1), d7
2755 #endif
2756 3:
2757 #ifndef __mcoldfire__
2758         lsrl    IMM (1),d2      | shift right second operand
2759         roxrl   IMM (1),d3
2760         dbra    d7,3b
2761 #else
2762         lsrl    IMM (1),d3
2763         btst    IMM (0),d2
2764         beq     10f
2765         bset    IMM (31),d3
2766 10:     lsrl    IMM (1),d2
2767         subql   IMM (1), d7
2768         bpl     3b
2769 #endif
2770         bra     Laddsf$3
2771 4:
2772         movew   d2,d3
2773         swap    d3
2774         movew   d3,d2
2775         swap    d2
2776 #ifndef __mcoldfire__
2777         subw    IMM (16),d7
2778 #else
2779         subl    IMM (16),d7
2780 #endif
2781         bne     2b              | if still more bits, go back to normal case
2782         bra     Laddsf$3
2783 5:
2784 #ifndef __mcoldfire__
2785         exg     d6,d7           | exchange the exponents
2786 #else
2787         eorl    d6,d7
2788         eorl    d7,d6
2789         eorl    d6,d7
2790 #endif
2791         subl    d6,d7           | keep the largest exponent
2792         negl    d7              |
2793 #ifndef __mcoldfire__
2794         lsrw    IMM (8),d7      | put difference in lower byte
2795 #else
2796         lsrl    IMM (8),d7      | put difference in lower byte
2797 #endif
2798 | if difference is too large we don't shift (and exit!) '
2799 #ifndef __mcoldfire__
2800         cmpw    IMM (FLT_MANT_DIG+2),d7         
2801 #else
2802         cmpl    IMM (FLT_MANT_DIG+2),d7         
2803 #endif
2804         bge     Laddsf$a$small
2805 #ifndef __mcoldfire__
2806         cmpw    IMM (16),d7     | if difference >= 16 swap
2807 #else
2808         cmpl    IMM (16),d7     | if difference >= 16 swap
2809 #endif
2810         bge     8f
2811 6:
2812 #ifndef __mcoldfire__
2813         subw    IMM (1),d7
2814 #else
2815         subl    IMM (1),d7
2816 #endif
2817 7:
2818 #ifndef __mcoldfire__
2819         lsrl    IMM (1),d0      | shift right first operand
2820         roxrl   IMM (1),d1
2821         dbra    d7,7b
2822 #else
2823         lsrl    IMM (1),d1
2824         btst    IMM (0),d0
2825         beq     10f
2826         bset    IMM (31),d1
2827 10:     lsrl    IMM (1),d0
2828         subql   IMM (1),d7
2829         bpl     7b
2830 #endif
2831         bra     Laddsf$3
2832 8:
2833         movew   d0,d1
2834         swap    d1
2835         movew   d1,d0
2836         swap    d0
2837 #ifndef __mcoldfire__
2838         subw    IMM (16),d7
2839 #else
2840         subl    IMM (16),d7
2841 #endif
2842         bne     6b              | if still more bits, go back to normal case
2843                                 | otherwise we fall through
2844
2845 | Now we have a in d0-d1, b in d2-d3, and the largest exponent in d6 (the
2846 | signs are stored in a0 and a1).
2847
2848 Laddsf$3:
2849 | Here we have to decide whether to add or subtract the numbers
2850 #ifndef __mcoldfire__
2851         exg     d6,a0           | get signs back
2852         exg     d7,a1           | and save the exponents
2853 #else
2854         movel   d6,d4
2855         movel   a0,d6
2856         movel   d4,a0
2857         movel   d7,d4
2858         movel   a1,d7
2859         movel   d4,a1
2860 #endif
2861         eorl    d6,d7           | combine sign bits
2862         bmi     Lsubsf$0        | if negative a and b have opposite 
2863                                 | sign so we actually subtract the
2864                                 | numbers
2865
2866 | Here we have both positive or both negative
2867 #ifndef __mcoldfire__
2868         exg     d6,a0           | now we have the exponent in d6
2869 #else
2870         movel   d6,d4
2871         movel   a0,d6
2872         movel   d4,a0
2873 #endif
2874         movel   a0,d7           | and sign in d7
2875         andl    IMM (0x80000000),d7
2876 | Here we do the addition.
2877         addl    d3,d1
2878         addxl   d2,d0
2879 | Note: now we have d2, d3, d4 and d5 to play with! 
2880
2881 | Put the exponent, in the first byte, in d2, to use the "standard" rounding
2882 | routines:
2883         movel   d6,d2
2884 #ifndef __mcoldfire__
2885         lsrw    IMM (8),d2
2886 #else
2887         lsrl    IMM (8),d2
2888 #endif
2889
2890 | Before rounding normalize so bit #FLT_MANT_DIG is set (we will consider
2891 | the case of denormalized numbers in the rounding routine itself).
2892 | As in the addition (not in the subtraction!) we could have set 
2893 | one more bit we check this:
2894         btst    IMM (FLT_MANT_DIG+1),d0 
2895         beq     1f
2896 #ifndef __mcoldfire__
2897         lsrl    IMM (1),d0
2898         roxrl   IMM (1),d1
2899 #else
2900         lsrl    IMM (1),d1
2901         btst    IMM (0),d0
2902         beq     10f
2903         bset    IMM (31),d1
2904 10:     lsrl    IMM (1),d0
2905 #endif
2906         addl    IMM (1),d2
2907 1:
2908         lea     pc@(Laddsf$4),a0 | to return from rounding routine
2909         PICLEA  SYM (_fpCCR),a1 | check the rounding mode
2910 #ifdef __mcoldfire__
2911         clrl    d6
2912 #endif
2913         movew   a1@(6),d6       | rounding mode in d6
2914         beq     Lround$to$nearest
2915 #ifndef __mcoldfire__
2916         cmpw    IMM (ROUND_TO_PLUS),d6
2917 #else
2918         cmpl    IMM (ROUND_TO_PLUS),d6
2919 #endif
2920         bhi     Lround$to$minus
2921         blt     Lround$to$zero
2922         bra     Lround$to$plus
2923 Laddsf$4:
2924 | Put back the exponent, but check for overflow.
2925 #ifndef __mcoldfire__
2926         cmpw    IMM (0xff),d2
2927 #else
2928         cmpl    IMM (0xff),d2
2929 #endif
2930         bhi     1f
2931         bclr    IMM (FLT_MANT_DIG-1),d0
2932 #ifndef __mcoldfire__
2933         lslw    IMM (7),d2
2934 #else
2935         lsll    IMM (7),d2
2936 #endif
2937         swap    d2
2938         orl     d2,d0
2939         bra     Laddsf$ret
2940 1:
2941         moveq   IMM (ADD),d5
2942         bra     Lf$overflow
2943
2944 Lsubsf$0:
2945 | We are here if a > 0 and b < 0 (sign bits cleared).
2946 | Here we do the subtraction.
2947         movel   d6,d7           | put sign in d7
2948         andl    IMM (0x80000000),d7
2949
2950         subl    d3,d1           | result in d0-d1
2951         subxl   d2,d0           |
2952         beq     Laddsf$ret      | if zero just exit
2953         bpl     1f              | if positive skip the following
2954         bchg    IMM (31),d7     | change sign bit in d7
2955         negl    d1
2956         negxl   d0
2957 1:
2958 #ifndef __mcoldfire__
2959         exg     d2,a0           | now we have the exponent in d2
2960         lsrw    IMM (8),d2      | put it in the first byte
2961 #else
2962         movel   d2,d4
2963         movel   a0,d2
2964         movel   d4,a0
2965         lsrl    IMM (8),d2      | put it in the first byte
2966 #endif
2967
2968 | Now d0-d1 is positive and the sign bit is in d7.
2969
2970 | Note that we do not have to normalize, since in the subtraction bit
2971 | #FLT_MANT_DIG+1 is never set, and denormalized numbers are handled by
2972 | the rounding routines themselves.
2973         lea     pc@(Lsubsf$1),a0 | to return from rounding routine
2974         PICLEA  SYM (_fpCCR),a1 | check the rounding mode
2975 #ifdef __mcoldfire__
2976         clrl    d6
2977 #endif
2978         movew   a1@(6),d6       | rounding mode in d6
2979         beq     Lround$to$nearest
2980 #ifndef __mcoldfire__
2981         cmpw    IMM (ROUND_TO_PLUS),d6
2982 #else
2983         cmpl    IMM (ROUND_TO_PLUS),d6
2984 #endif
2985         bhi     Lround$to$minus
2986         blt     Lround$to$zero
2987         bra     Lround$to$plus
2988 Lsubsf$1:
2989 | Put back the exponent (we can't have overflow!). '
2990         bclr    IMM (FLT_MANT_DIG-1),d0
2991 #ifndef __mcoldfire__
2992         lslw    IMM (7),d2
2993 #else
2994         lsll    IMM (7),d2
2995 #endif
2996         swap    d2
2997         orl     d2,d0
2998         bra     Laddsf$ret
2999
3000 | If one of the numbers was too small (difference of exponents >= 
3001 | FLT_MANT_DIG+2) we return the other (and now we don't have to '
3002 | check for finiteness or zero).
3003 Laddsf$a$small:
3004         movel   a6@(12),d0
3005         PICLEA  SYM (_fpCCR),a0
3006         movew   IMM (0),a0@
3007 #ifndef __mcoldfire__
3008         moveml  sp@+,d2-d7      | restore data registers
3009 #else
3010         moveml  sp@,d2-d7
3011         | XXX if frame pointer is ever removed, stack pointer must
3012         | be adjusted here.
3013 #endif
3014         unlk    a6              | and return
3015         rts
3016
3017 Laddsf$b$small:
3018         movel   a6@(8),d0
3019         PICLEA  SYM (_fpCCR),a0
3020         movew   IMM (0),a0@
3021 #ifndef __mcoldfire__
3022         moveml  sp@+,d2-d7      | restore data registers
3023 #else
3024         moveml  sp@,d2-d7
3025         | XXX if frame pointer is ever removed, stack pointer must
3026         | be adjusted here.
3027 #endif
3028         unlk    a6              | and return
3029         rts
3030
3031 | If the numbers are denormalized remember to put exponent equal to 1.
3032
3033 Laddsf$a$den:
3034         movel   d5,d6           | d5 contains 0x01000000
3035         swap    d6
3036         bra     Laddsf$1
3037
3038 Laddsf$b$den:
3039         movel   d5,d7
3040         swap    d7
3041         notl    d4              | make d4 into a mask for the fraction
3042                                 | (this was not executed after the jump)
3043         bra     Laddsf$2
3044
3045 | The rest is mainly code for the different results which can be 
3046 | returned (checking always for +/-INFINITY and NaN).
3047
3048 Laddsf$b:
3049 | Return b (if a is zero).
3050         movel   a6@(12),d0
3051         cmpl    IMM (0x80000000),d0     | Check if b is -0
3052         bne     1f
3053         movel   a0,d7
3054         andl    IMM (0x80000000),d7     | Use the sign of a
3055         clrl    d0
3056         bra     Laddsf$ret
3057 Laddsf$a:
3058 | Return a (if b is zero).
3059         movel   a6@(8),d0
3060 1:
3061         moveq   IMM (ADD),d5
3062 | We have to check for NaN and +/-infty.
3063         movel   d0,d7
3064         andl    IMM (0x80000000),d7     | put sign in d7
3065         bclr    IMM (31),d0             | clear sign
3066         cmpl    IMM (INFINITY),d0       | check for infty or NaN
3067         bge     2f
3068         movel   d0,d0           | check for zero (we do this because we don't '
3069         bne     Laddsf$ret      | want to return -0 by mistake
3070         bclr    IMM (31),d7     | if zero be sure to clear sign
3071         bra     Laddsf$ret      | if everything OK just return
3072 2:
3073 | The value to be returned is either +/-infty or NaN
3074         andl    IMM (0x007fffff),d0     | check for NaN
3075         bne     Lf$inop                 | if mantissa not zero is NaN
3076         bra     Lf$infty
3077
3078 Laddsf$ret:
3079 | Normal exit (a and b nonzero, result is not NaN nor +/-infty).
3080 | We have to clear the exception flags (just the exception type).
3081         PICLEA  SYM (_fpCCR),a0
3082         movew   IMM (0),a0@
3083         orl     d7,d0           | put sign bit
3084 #ifndef __mcoldfire__
3085         moveml  sp@+,d2-d7      | restore data registers
3086 #else
3087         moveml  sp@,d2-d7
3088         | XXX if frame pointer is ever removed, stack pointer must
3089         | be adjusted here.
3090 #endif
3091         unlk    a6              | and return
3092         rts
3093
3094 Laddsf$ret$den:
3095 | Return a denormalized number (for addition we don't signal underflow) '
3096         lsrl    IMM (1),d0      | remember to shift right back once
3097         bra     Laddsf$ret      | and return
3098
3099 | Note: when adding two floats of the same sign if either one is 
3100 | NaN we return NaN without regard to whether the other is finite or 
3101 | not. When subtracting them (i.e., when adding two numbers of 
3102 | opposite signs) things are more complicated: if both are INFINITY 
3103 | we return NaN, if only one is INFINITY and the other is NaN we return
3104 | NaN, but if it is finite we return INFINITY with the corresponding sign.
3105
3106 Laddsf$nf:
3107         moveq   IMM (ADD),d5
3108 | This could be faster but it is not worth the effort, since it is not
3109 | executed very often. We sacrifice speed for clarity here.
3110         movel   a6@(8),d0       | get the numbers back (remember that we
3111         movel   a6@(12),d1      | did some processing already)
3112         movel   IMM (INFINITY),d4 | useful constant (INFINITY)
3113         movel   d0,d2           | save sign bits
3114         movel   d1,d3
3115         bclr    IMM (31),d0     | clear sign bits
3116         bclr    IMM (31),d1
3117 | We know that one of them is either NaN of +/-INFINITY
3118 | Check for NaN (if either one is NaN return NaN)
3119         cmpl    d4,d0           | check first a (d0)
3120         bhi     Lf$inop         
3121         cmpl    d4,d1           | check now b (d1)
3122         bhi     Lf$inop         
3123 | Now comes the check for +/-INFINITY. We know that both are (maybe not
3124 | finite) numbers, but we have to check if both are infinite whether we
3125 | are adding or subtracting them.
3126         eorl    d3,d2           | to check sign bits
3127         bmi     1f
3128         movel   d0,d7
3129         andl    IMM (0x80000000),d7     | get (common) sign bit
3130         bra     Lf$infty
3131 1:
3132 | We know one (or both) are infinite, so we test for equality between the
3133 | two numbers (if they are equal they have to be infinite both, so we
3134 | return NaN).
3135         cmpl    d1,d0           | are both infinite?
3136         beq     Lf$inop         | if so return NaN
3137
3138         movel   d0,d7
3139         andl    IMM (0x80000000),d7 | get a's sign bit '
3140         cmpl    d4,d0           | test now for infinity
3141         beq     Lf$infty        | if a is INFINITY return with this sign
3142         bchg    IMM (31),d7     | else we know b is INFINITY and has
3143         bra     Lf$infty        | the opposite sign
3144
3145 |=============================================================================
3146 |                             __mulsf3
3147 |=============================================================================
3148
3149 | float __mulsf3(float, float);
3150         FUNC(__mulsf3)
3151 SYM (__mulsf3):
3152 #ifndef __mcoldfire__
3153         link    a6,IMM (0)
3154         moveml  d2-d7,sp@-
3155 #else
3156         link    a6,IMM (-24)
3157         moveml  d2-d7,sp@
3158 #endif
3159         movel   a6@(8),d0       | get a into d0
3160         movel   a6@(12),d1      | and b into d1
3161         movel   d0,d7           | d7 will hold the sign of the product
3162         eorl    d1,d7           |
3163         andl    IMM (0x80000000),d7
3164         movel   IMM (INFINITY),d6       | useful constant (+INFINITY)
3165         movel   d6,d5                   | another (mask for fraction)
3166         notl    d5                      |
3167         movel   IMM (0x00800000),d4     | this is to put hidden bit back
3168         bclr    IMM (31),d0             | get rid of a's sign bit '
3169         movel   d0,d2                   |
3170         beq     Lmulsf$a$0              | branch if a is zero
3171         bclr    IMM (31),d1             | get rid of b's sign bit '
3172         movel   d1,d3           |
3173         beq     Lmulsf$b$0      | branch if b is zero
3174         cmpl    d6,d0           | is a big?
3175         bhi     Lmulsf$inop     | if a is NaN return NaN
3176         beq     Lmulsf$inf      | if a is INFINITY we have to check b
3177         cmpl    d6,d1           | now compare b with INFINITY
3178         bhi     Lmulsf$inop     | is b NaN?
3179         beq     Lmulsf$overflow | is b INFINITY?
3180 | Here we have both numbers finite and nonzero (and with no sign bit).
3181 | Now we get the exponents into d2 and d3.
3182         andl    d6,d2           | and isolate exponent in d2
3183         beq     Lmulsf$a$den    | if exponent is zero we have a denormalized
3184         andl    d5,d0           | and isolate fraction
3185         orl     d4,d0           | and put hidden bit back
3186         swap    d2              | I like exponents in the first byte
3187 #ifndef __mcoldfire__
3188         lsrw    IMM (7),d2      | 
3189 #else
3190         lsrl    IMM (7),d2      | 
3191 #endif
3192 Lmulsf$1:                       | number
3193         andl    d6,d3           |
3194         beq     Lmulsf$b$den    |
3195         andl    d5,d1           |
3196         orl     d4,d1           |
3197         swap    d3              |
3198 #ifndef __mcoldfire__
3199         lsrw    IMM (7),d3      |
3200 #else
3201         lsrl    IMM (7),d3      |
3202 #endif
3203 Lmulsf$2:                       |
3204 #ifndef __mcoldfire__
3205         addw    d3,d2           | add exponents
3206         subw    IMM (F_BIAS+1),d2 | and subtract bias (plus one)
3207 #else
3208         addl    d3,d2           | add exponents
3209         subl    IMM (F_BIAS+1),d2 | and subtract bias (plus one)
3210 #endif
3211
3212 | We are now ready to do the multiplication. The situation is as follows:
3213 | both a and b have bit FLT_MANT_DIG-1 set (even if they were 
3214 | denormalized to start with!), which means that in the product 
3215 | bit 2*(FLT_MANT_DIG-1) (that is, bit 2*FLT_MANT_DIG-2-32 of the 
3216 | high long) is set. 
3217
3218 | To do the multiplication let us move the number a little bit around ...
3219         movel   d1,d6           | second operand in d6
3220         movel   d0,d5           | first operand in d4-d5
3221         movel   IMM (0),d4
3222         movel   d4,d1           | the sums will go in d0-d1
3223         movel   d4,d0
3224
3225 | now bit FLT_MANT_DIG-1 becomes bit 31:
3226         lsll    IMM (31-FLT_MANT_DIG+1),d6              
3227
3228 | Start the loop (we loop #FLT_MANT_DIG times):
3229         moveq   IMM (FLT_MANT_DIG-1),d3 
3230 1:      addl    d1,d1           | shift sum 
3231         addxl   d0,d0
3232         lsll    IMM (1),d6      | get bit bn
3233         bcc     2f              | if not set skip sum
3234         addl    d5,d1           | add a
3235         addxl   d4,d0
3236 2:
3237 #ifndef __mcoldfire__
3238         dbf     d3,1b           | loop back
3239 #else
3240         subql   IMM (1),d3
3241         bpl     1b
3242 #endif
3243
3244 | Now we have the product in d0-d1, with bit (FLT_MANT_DIG - 1) + FLT_MANT_DIG
3245 | (mod 32) of d0 set. The first thing to do now is to normalize it so bit 
3246 | FLT_MANT_DIG is set (to do the rounding).
3247 #ifndef __mcoldfire__
3248         rorl    IMM (6),d1
3249         swap    d1
3250         movew   d1,d3
3251         andw    IMM (0x03ff),d3
3252         andw    IMM (0xfd00),d1
3253 #else
3254         movel   d1,d3
3255         lsll    IMM (8),d1
3256         addl    d1,d1
3257         addl    d1,d1
3258         moveq   IMM (22),d5
3259         lsrl    d5,d3
3260         orl     d3,d1
3261         andl    IMM (0xfffffd00),d1
3262 #endif
3263         lsll    IMM (8),d0
3264         addl    d0,d0
3265         addl    d0,d0
3266 #ifndef __mcoldfire__
3267         orw     d3,d0
3268 #else
3269         orl     d3,d0
3270 #endif
3271
3272         moveq   IMM (MULTIPLY),d5
3273         
3274         btst    IMM (FLT_MANT_DIG+1),d0
3275         beq     Lround$exit
3276 #ifndef __mcoldfire__
3277         lsrl    IMM (1),d0
3278         roxrl   IMM (1),d1
3279         addw    IMM (1),d2
3280 #else
3281         lsrl    IMM (1),d1
3282         btst    IMM (0),d0
3283         beq     10f
3284         bset    IMM (31),d1
3285 10:     lsrl    IMM (1),d0
3286         addql   IMM (1),d2
3287 #endif
3288         bra     Lround$exit
3289
3290 Lmulsf$inop:
3291         moveq   IMM (MULTIPLY),d5
3292         bra     Lf$inop
3293
3294 Lmulsf$overflow:
3295         moveq   IMM (MULTIPLY),d5
3296         bra     Lf$overflow
3297
3298 Lmulsf$inf:
3299         moveq   IMM (MULTIPLY),d5
3300 | If either is NaN return NaN; else both are (maybe infinite) numbers, so
3301 | return INFINITY with the correct sign (which is in d7).
3302         cmpl    d6,d1           | is b NaN?
3303         bhi     Lf$inop         | if so return NaN
3304         bra     Lf$overflow     | else return +/-INFINITY
3305
3306 | If either number is zero return zero, unless the other is +/-INFINITY, 
3307 | or NaN, in which case we return NaN.
3308 Lmulsf$b$0:
3309 | Here d1 (==b) is zero.
3310         movel   a6@(8),d1       | get a again to check for non-finiteness
3311         bra     1f
3312 Lmulsf$a$0:
3313         movel   a6@(12),d1      | get b again to check for non-finiteness
3314 1:      bclr    IMM (31),d1     | clear sign bit 
3315         cmpl    IMM (INFINITY),d1 | and check for a large exponent
3316         bge     Lf$inop         | if b is +/-INFINITY or NaN return NaN
3317         movel   d7,d0           | else return signed zero
3318         PICLEA  SYM (_fpCCR),a0 |
3319         movew   IMM (0),a0@     | 
3320 #ifndef __mcoldfire__
3321         moveml  sp@+,d2-d7      | 
3322 #else
3323         moveml  sp@,d2-d7
3324         | XXX if frame pointer is ever removed, stack pointer must
3325         | be adjusted here.
3326 #endif
3327         unlk    a6              | 
3328         rts                     | 
3329
3330 | If a number is denormalized we put an exponent of 1 but do not put the 
3331 | hidden bit back into the fraction; instead we shift left until bit 23
3332 | (the hidden bit) is set, adjusting the exponent accordingly. We do this
3333 | to ensure that the product of the fractions is close to 1.
3334 Lmulsf$a$den:
3335         movel   IMM (1),d2
3336         andl    d5,d0
3337 1:      addl    d0,d0           | shift a left (until bit 23 is set)
3338 #ifndef __mcoldfire__
3339         subw    IMM (1),d2      | and adjust exponent
3340 #else
3341         subql   IMM (1),d2      | and adjust exponent
3342 #endif
3343         btst    IMM (FLT_MANT_DIG-1),d0
3344         bne     Lmulsf$1        |
3345         bra     1b              | else loop back
3346
3347 Lmulsf$b$den:
3348         movel   IMM (1),d3
3349         andl    d5,d1
3350 1:      addl    d1,d1           | shift b left until bit 23 is set
3351 #ifndef __mcoldfire__
3352         subw    IMM (1),d3      | and adjust exponent
3353 #else
3354         subql   IMM (1),d3      | and adjust exponent
3355 #endif
3356         btst    IMM (FLT_MANT_DIG-1),d1
3357         bne     Lmulsf$2        |
3358         bra     1b              | else loop back
3359
3360 |=============================================================================
3361 |                             __divsf3
3362 |=============================================================================
3363
3364 | float __divsf3(float, float);
3365         FUNC(__divsf3)
3366 SYM (__divsf3):
3367 #ifndef __mcoldfire__
3368         link    a6,IMM (0)
3369         moveml  d2-d7,sp@-
3370 #else
3371         link    a6,IMM (-24)
3372         moveml  d2-d7,sp@
3373 #endif
3374         movel   a6@(8),d0               | get a into d0
3375         movel   a6@(12),d1              | and b into d1
3376         movel   d0,d7                   | d7 will hold the sign of the result
3377         eorl    d1,d7                   |
3378         andl    IMM (0x80000000),d7     | 
3379         movel   IMM (INFINITY),d6       | useful constant (+INFINITY)
3380         movel   d6,d5                   | another (mask for fraction)
3381         notl    d5                      |
3382         movel   IMM (0x00800000),d4     | this is to put hidden bit back
3383         bclr    IMM (31),d0             | get rid of a's sign bit '
3384         movel   d0,d2                   |
3385         beq     Ldivsf$a$0              | branch if a is zero
3386         bclr    IMM (31),d1             | get rid of b's sign bit '
3387         movel   d1,d3                   |
3388         beq     Ldivsf$b$0              | branch if b is zero
3389         cmpl    d6,d0                   | is a big?
3390         bhi     Ldivsf$inop             | if a is NaN return NaN
3391         beq     Ldivsf$inf              | if a is INFINITY we have to check b
3392         cmpl    d6,d1                   | now compare b with INFINITY 
3393         bhi     Ldivsf$inop             | if b is NaN return NaN
3394         beq     Ldivsf$underflow
3395 | Here we have both numbers finite and nonzero (and with no sign bit).
3396 | Now we get the exponents into d2 and d3 and normalize the numbers to
3397 | ensure that the ratio of the fractions is close to 1. We do this by
3398 | making sure that bit #FLT_MANT_DIG-1 (hidden bit) is set.
3399         andl    d6,d2           | and isolate exponent in d2
3400         beq     Ldivsf$a$den    | if exponent is zero we have a denormalized
3401         andl    d5,d0           | and isolate fraction
3402         orl     d4,d0           | and put hidden bit back
3403         swap    d2              | I like exponents in the first byte
3404 #ifndef __mcoldfire__
3405         lsrw    IMM (7),d2      | 
3406 #else
3407         lsrl    IMM (7),d2      | 
3408 #endif
3409 Ldivsf$1:                       | 
3410         andl    d6,d3           |
3411         beq     Ldivsf$b$den    |
3412         andl    d5,d1           |
3413         orl     d4,d1           |
3414         swap    d3              |
3415 #ifndef __mcoldfire__
3416         lsrw    IMM (7),d3      |
3417 #else
3418         lsrl    IMM (7),d3      |
3419 #endif
3420 Ldivsf$2:                       |
3421 #ifndef __mcoldfire__
3422         subw    d3,d2           | subtract exponents
3423         addw    IMM (F_BIAS),d2 | and add bias
3424 #else
3425         subl    d3,d2           | subtract exponents
3426         addl    IMM (F_BIAS),d2 | and add bias
3427 #endif
3428  
3429 | We are now ready to do the division. We have prepared things in such a way
3430 | that the ratio of the fractions will be less than 2 but greater than 1/2.
3431 | At this point the registers in use are:
3432 | d0    holds a (first operand, bit FLT_MANT_DIG=0, bit FLT_MANT_DIG-1=1)
3433 | d1    holds b (second operand, bit FLT_MANT_DIG=1)
3434 | d2    holds the difference of the exponents, corrected by the bias
3435 | d7    holds the sign of the ratio
3436 | d4, d5, d6 hold some constants
3437         movel   d7,a0           | d6-d7 will hold the ratio of the fractions
3438         movel   IMM (0),d6      | 
3439         movel   d6,d7
3440
3441         moveq   IMM (FLT_MANT_DIG+1),d3
3442 1:      cmpl    d0,d1           | is a < b?
3443         bhi     2f              |
3444         bset    d3,d6           | set a bit in d6
3445         subl    d1,d0           | if a >= b  a <-- a-b
3446         beq     3f              | if a is zero, exit
3447 2:      addl    d0,d0           | multiply a by 2
3448 #ifndef __mcoldfire__
3449         dbra    d3,1b
3450 #else
3451         subql   IMM (1),d3
3452         bpl     1b
3453 #endif
3454
3455 | Now we keep going to set the sticky bit ...
3456         moveq   IMM (FLT_MANT_DIG),d3
3457 1:      cmpl    d0,d1
3458         ble     2f
3459         addl    d0,d0
3460 #ifndef __mcoldfire__
3461         dbra    d3,1b
3462 #else
3463         subql   IMM(1),d3
3464         bpl     1b
3465 #endif
3466         movel   IMM (0),d1
3467         bra     3f
3468 2:      movel   IMM (0),d1
3469 #ifndef __mcoldfire__
3470         subw    IMM (FLT_MANT_DIG),d3
3471         addw    IMM (31),d3
3472 #else
3473         subl    IMM (FLT_MANT_DIG),d3
3474         addl    IMM (31),d3
3475 #endif
3476         bset    d3,d1
3477 3:
3478         movel   d6,d0           | put the ratio in d0-d1
3479         movel   a0,d7           | get sign back
3480
3481 | Because of the normalization we did before we are guaranteed that 
3482 | d0 is smaller than 2^26 but larger than 2^24. Thus bit 26 is not set,
3483 | bit 25 could be set, and if it is not set then bit 24 is necessarily set.
3484         btst    IMM (FLT_MANT_DIG+1),d0         
3485         beq     1f              | if it is not set, then bit 24 is set
3486         lsrl    IMM (1),d0      |
3487 #ifndef __mcoldfire__
3488         addw    IMM (1),d2      |
3489 #else
3490         addl    IMM (1),d2      |
3491 #endif
3492 1:
3493 | Now round, check for over- and underflow, and exit.
3494         moveq   IMM (DIVIDE),d5
3495         bra     Lround$exit
3496
3497 Ldivsf$inop:
3498         moveq   IMM (DIVIDE),d5
3499         bra     Lf$inop
3500
3501 Ldivsf$overflow:
3502         moveq   IMM (DIVIDE),d5
3503         bra     Lf$overflow
3504
3505 Ldivsf$underflow:
3506         moveq   IMM (DIVIDE),d5
3507         bra     Lf$underflow
3508
3509 Ldivsf$a$0:
3510         moveq   IMM (DIVIDE),d5
3511 | If a is zero check to see whether b is zero also. In that case return
3512 | NaN; then check if b is NaN, and return NaN also in that case. Else
3513 | return a properly signed zero.
3514         andl    IMM (0x7fffffff),d1     | clear sign bit and test b
3515         beq     Lf$inop                 | if b is also zero return NaN
3516         cmpl    IMM (INFINITY),d1       | check for NaN
3517         bhi     Lf$inop                 | 
3518         movel   d7,d0                   | else return signed zero
3519         PICLEA  SYM (_fpCCR),a0         |
3520         movew   IMM (0),a0@             |
3521 #ifndef __mcoldfire__
3522         moveml  sp@+,d2-d7              | 
3523 #else
3524         moveml  sp@,d2-d7               | 
3525         | XXX if frame pointer is ever removed, stack pointer must
3526         | be adjusted here.
3527 #endif
3528         unlk    a6                      | 
3529         rts                             | 
3530         
3531 Ldivsf$b$0:
3532         moveq   IMM (DIVIDE),d5
3533 | If we got here a is not zero. Check if a is NaN; in that case return NaN,
3534 | else return +/-INFINITY. Remember that a is in d0 with the sign bit 
3535 | cleared already.
3536         cmpl    IMM (INFINITY),d0       | compare d0 with INFINITY
3537         bhi     Lf$inop                 | if larger it is NaN
3538         bra     Lf$div$0                | else signal DIVIDE_BY_ZERO
3539
3540 Ldivsf$inf:
3541         moveq   IMM (DIVIDE),d5
3542 | If a is INFINITY we have to check b
3543         cmpl    IMM (INFINITY),d1       | compare b with INFINITY 
3544         bge     Lf$inop                 | if b is NaN or INFINITY return NaN
3545         bra     Lf$overflow             | else return overflow
3546
3547 | If a number is denormalized we put an exponent of 1 but do not put the 
3548 | bit back into the fraction.
3549 Ldivsf$a$den:
3550         movel   IMM (1),d2
3551         andl    d5,d0
3552 1:      addl    d0,d0           | shift a left until bit FLT_MANT_DIG-1 is set
3553 #ifndef __mcoldfire__
3554         subw    IMM (1),d2      | and adjust exponent
3555 #else
3556         subl    IMM (1),d2      | and adjust exponent
3557 #endif
3558         btst    IMM (FLT_MANT_DIG-1),d0
3559         bne     Ldivsf$1
3560         bra     1b
3561
3562 Ldivsf$b$den:
3563         movel   IMM (1),d3
3564         andl    d5,d1
3565 1:      addl    d1,d1           | shift b left until bit FLT_MANT_DIG is set
3566 #ifndef __mcoldfire__
3567         subw    IMM (1),d3      | and adjust exponent
3568 #else
3569         subl    IMM (1),d3      | and adjust exponent
3570 #endif
3571         btst    IMM (FLT_MANT_DIG-1),d1
3572         bne     Ldivsf$2
3573         bra     1b
3574
3575 Lround$exit:
3576 | This is a common exit point for __mulsf3 and __divsf3. 
3577
3578 | First check for underlow in the exponent:
3579 #ifndef __mcoldfire__
3580         cmpw    IMM (-FLT_MANT_DIG-1),d2                
3581 #else
3582         cmpl    IMM (-FLT_MANT_DIG-1),d2                
3583 #endif
3584         blt     Lf$underflow    
3585 | It could happen that the exponent is less than 1, in which case the 
3586 | number is denormalized. In this case we shift right and adjust the 
3587 | exponent until it becomes 1 or the fraction is zero (in the latter case 
3588 | we signal underflow and return zero).
3589         movel   IMM (0),d6      | d6 is used temporarily
3590 #ifndef __mcoldfire__
3591         cmpw    IMM (1),d2      | if the exponent is less than 1 we 
3592 #else
3593         cmpl    IMM (1),d2      | if the exponent is less than 1 we 
3594 #endif
3595         bge     2f              | have to shift right (denormalize)
3596 1:
3597 #ifndef __mcoldfire__
3598         addw    IMM (1),d2      | adjust the exponent
3599         lsrl    IMM (1),d0      | shift right once 
3600         roxrl   IMM (1),d1      |
3601         roxrl   IMM (1),d6      | d6 collect bits we would lose otherwise
3602         cmpw    IMM (1),d2      | is the exponent 1 already?
3603 #else
3604         addql   IMM (1),d2      | adjust the exponent
3605         lsrl    IMM (1),d6
3606         btst    IMM (0),d1
3607         beq     11f
3608         bset    IMM (31),d6
3609 11:     lsrl    IMM (1),d1
3610         btst    IMM (0),d0
3611         beq     10f
3612         bset    IMM (31),d1
3613 10:     lsrl    IMM (1),d0
3614         cmpl    IMM (1),d2      | is the exponent 1 already?
3615 #endif
3616         beq     2f              | if not loop back
3617         bra     1b              |
3618         bra     Lf$underflow    | safety check, shouldn't execute '
3619 2:      orl     d6,d1           | this is a trick so we don't lose  '
3620                                 | the extra bits which were flushed right
3621 | Now call the rounding routine (which takes care of denormalized numbers):
3622         lea     pc@(Lround$0),a0 | to return from rounding routine
3623         PICLEA  SYM (_fpCCR),a1 | check the rounding mode
3624 #ifdef __mcoldfire__
3625         clrl    d6
3626 #endif
3627         movew   a1@(6),d6       | rounding mode in d6
3628         beq     Lround$to$nearest
3629 #ifndef __mcoldfire__
3630         cmpw    IMM (ROUND_TO_PLUS),d6
3631 #else
3632         cmpl    IMM (ROUND_TO_PLUS),d6
3633 #endif
3634         bhi     Lround$to$minus
3635         blt     Lround$to$zero
3636         bra     Lround$to$plus
3637 Lround$0:
3638 | Here we have a correctly rounded result (either normalized or denormalized).
3639
3640 | Here we should have either a normalized number or a denormalized one, and
3641 | the exponent is necessarily larger or equal to 1 (so we don't have to  '
3642 | check again for underflow!). We have to check for overflow or for a 
3643 | denormalized number (which also signals underflow).
3644 | Check for overflow (i.e., exponent >= 255).
3645 #ifndef __mcoldfire__
3646         cmpw    IMM (0x00ff),d2
3647 #else
3648         cmpl    IMM (0x00ff),d2
3649 #endif
3650         bge     Lf$overflow
3651 | Now check for a denormalized number (exponent==0).
3652         movew   d2,d2
3653         beq     Lf$den
3654 1:
3655 | Put back the exponents and sign and return.
3656 #ifndef __mcoldfire__
3657         lslw    IMM (7),d2      | exponent back to fourth byte
3658 #else
3659         lsll    IMM (7),d2      | exponent back to fourth byte
3660 #endif
3661         bclr    IMM (FLT_MANT_DIG-1),d0
3662         swap    d0              | and put back exponent
3663 #ifndef __mcoldfire__
3664         orw     d2,d0           | 
3665 #else
3666         orl     d2,d0
3667 #endif
3668         swap    d0              |
3669         orl     d7,d0           | and sign also
3670
3671         PICLEA  SYM (_fpCCR),a0
3672         movew   IMM (0),a0@
3673 #ifndef __mcoldfire__
3674         moveml  sp@+,d2-d7
3675 #else
3676         moveml  sp@,d2-d7
3677         | XXX if frame pointer is ever removed, stack pointer must
3678         | be adjusted here.
3679 #endif
3680         unlk    a6
3681         rts
3682
3683 |=============================================================================
3684 |                             __negsf2
3685 |=============================================================================
3686
3687 | This is trivial and could be shorter if we didn't bother checking for NaN '
3688 | and +/-INFINITY.
3689
3690 | float __negsf2(float);
3691         FUNC(__negsf2)
3692 SYM (__negsf2):
3693 #ifndef __mcoldfire__
3694         link    a6,IMM (0)
3695         moveml  d2-d7,sp@-
3696 #else
3697         link    a6,IMM (-24)
3698         moveml  d2-d7,sp@
3699 #endif
3700         moveq   IMM (NEGATE),d5
3701         movel   a6@(8),d0       | get number to negate in d0
3702         bchg    IMM (31),d0     | negate
3703         movel   d0,d1           | make a positive copy
3704         bclr    IMM (31),d1     |
3705         tstl    d1              | check for zero
3706         beq     2f              | if zero (either sign) return +zero
3707         cmpl    IMM (INFINITY),d1 | compare to +INFINITY
3708         blt     1f              |
3709         bhi     Lf$inop         | if larger (fraction not zero) is NaN
3710         movel   d0,d7           | else get sign and return INFINITY
3711         andl    IMM (0x80000000),d7
3712         bra     Lf$infty                
3713 1:      PICLEA  SYM (_fpCCR),a0
3714         movew   IMM (0),a0@
3715 #ifndef __mcoldfire__
3716         moveml  sp@+,d2-d7
3717 #else
3718         moveml  sp@,d2-d7
3719         | XXX if frame pointer is ever removed, stack pointer must
3720         | be adjusted here.
3721 #endif
3722         unlk    a6
3723         rts
3724 2:      bclr    IMM (31),d0
3725         bra     1b
3726
3727 |=============================================================================
3728 |                             __cmpsf2
3729 |=============================================================================
3730
3731 GREATER =  1
3732 LESS    = -1
3733 EQUAL   =  0
3734
3735 | int __cmpsf2_internal(float, float, int);
3736 SYM (__cmpsf2_internal):
3737 #ifndef __mcoldfire__
3738         link    a6,IMM (0)
3739         moveml  d2-d7,sp@-      | save registers
3740 #else
3741         link    a6,IMM (-24)
3742         moveml  d2-d7,sp@
3743 #endif
3744         moveq   IMM (COMPARE),d5
3745         movel   a6@(8),d0       | get first operand
3746         movel   a6@(12),d1      | get second operand
3747 | Check if either is NaN, and in that case return garbage and signal
3748 | INVALID_OPERATION. Check also if either is zero, and clear the signs
3749 | if necessary.
3750         movel   d0,d6
3751         andl    IMM (0x7fffffff),d0
3752         beq     Lcmpsf$a$0
3753         cmpl    IMM (0x7f800000),d0
3754         bhi     Lcmpf$inop
3755 Lcmpsf$1:
3756         movel   d1,d7
3757         andl    IMM (0x7fffffff),d1
3758         beq     Lcmpsf$b$0
3759         cmpl    IMM (0x7f800000),d1
3760         bhi     Lcmpf$inop
3761 Lcmpsf$2:
3762 | Check the signs
3763         eorl    d6,d7
3764         bpl     1f
3765 | If the signs are not equal check if a >= 0
3766         tstl    d6
3767         bpl     Lcmpsf$a$gt$b   | if (a >= 0 && b < 0) => a > b
3768         bmi     Lcmpsf$b$gt$a   | if (a < 0 && b >= 0) => a < b
3769 1:
3770 | If the signs are equal check for < 0
3771         tstl    d6
3772         bpl     1f
3773 | If both are negative exchange them
3774 #ifndef __mcoldfire__
3775         exg     d0,d1
3776 #else
3777         movel   d0,d7
3778         movel   d1,d0
3779         movel   d7,d1
3780 #endif
3781 1:
3782 | Now that they are positive we just compare them as longs (does this also
3783 | work for denormalized numbers?).
3784         cmpl    d0,d1
3785         bhi     Lcmpsf$b$gt$a   | |b| > |a|
3786         bne     Lcmpsf$a$gt$b   | |b| < |a|
3787 | If we got here a == b.
3788         movel   IMM (EQUAL),d0
3789 #ifndef __mcoldfire__
3790         moveml  sp@+,d2-d7      | put back the registers
3791 #else
3792         moveml  sp@,d2-d7
3793 #endif
3794         unlk    a6
3795         rts
3796 Lcmpsf$a$gt$b:
3797         movel   IMM (GREATER),d0
3798 #ifndef __mcoldfire__
3799         moveml  sp@+,d2-d7      | put back the registers
3800 #else
3801         moveml  sp@,d2-d7
3802         | XXX if frame pointer is ever removed, stack pointer must
3803         | be adjusted here.
3804 #endif
3805         unlk    a6
3806         rts
3807 Lcmpsf$b$gt$a:
3808         movel   IMM (LESS),d0
3809 #ifndef __mcoldfire__
3810         moveml  sp@+,d2-d7      | put back the registers
3811 #else
3812         moveml  sp@,d2-d7
3813         | XXX if frame pointer is ever removed, stack pointer must
3814         | be adjusted here.
3815 #endif
3816         unlk    a6
3817         rts
3818
3819 Lcmpsf$a$0:     
3820         bclr    IMM (31),d6
3821         bra     Lcmpsf$1
3822 Lcmpsf$b$0:
3823         bclr    IMM (31),d7
3824         bra     Lcmpsf$2
3825
3826 Lcmpf$inop:
3827         movl    a6@(16),d0
3828         moveq   IMM (INEXACT_RESULT+INVALID_OPERATION),d7
3829         moveq   IMM (SINGLE_FLOAT),d6
3830         PICJUMP $_exception_handler
3831
3832 | int __cmpsf2(float, float);
3833         FUNC(__cmpsf2)
3834 SYM (__cmpsf2):
3835         link    a6,IMM (0)
3836         pea     1
3837         movl    a6@(12),sp@-
3838         movl    a6@(8),sp@-
3839         PICCALL SYM (__cmpsf2_internal)
3840         unlk    a6
3841         rts
3842
3843 |=============================================================================
3844 |                           rounding routines
3845 |=============================================================================
3846
3847 | The rounding routines expect the number to be normalized in registers
3848 | d0-d1, with the exponent in register d2. They assume that the 
3849 | exponent is larger or equal to 1. They return a properly normalized number
3850 | if possible, and a denormalized number otherwise. The exponent is returned
3851 | in d2.
3852
3853 Lround$to$nearest:
3854 | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
3855 | Here we assume that the exponent is not too small (this should be checked
3856 | before entering the rounding routine), but the number could be denormalized.
3857
3858 | Check for denormalized numbers:
3859 1:      btst    IMM (FLT_MANT_DIG),d0
3860         bne     2f              | if set the number is normalized
3861 | Normalize shifting left until bit #FLT_MANT_DIG is set or the exponent 
3862 | is one (remember that a denormalized number corresponds to an 
3863 | exponent of -F_BIAS+1).
3864 #ifndef __mcoldfire__
3865         cmpw    IMM (1),d2      | remember that the exponent is at least one
3866 #else
3867         cmpl    IMM (1),d2      | remember that the exponent is at least one
3868 #endif
3869         beq     2f              | an exponent of one means denormalized
3870         addl    d1,d1           | else shift and adjust the exponent
3871         addxl   d0,d0           |
3872 #ifndef __mcoldfire__
3873         dbra    d2,1b           |
3874 #else
3875         subql   IMM (1),d2
3876         bpl     1b
3877 #endif
3878 2:
3879 | Now round: we do it as follows: after the shifting we can write the
3880 | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
3881 | If delta < 1, do nothing. If delta > 1, add 1 to f. 
3882 | If delta == 1, we make sure the rounded number will be even (odd?) 
3883 | (after shifting).
3884         btst    IMM (0),d0      | is delta < 1?
3885         beq     2f              | if so, do not do anything
3886         tstl    d1              | is delta == 1?
3887         bne     1f              | if so round to even
3888         movel   d0,d1           | 
3889         andl    IMM (2),d1      | bit 1 is the last significant bit
3890         addl    d1,d0           | 
3891         bra     2f              | 
3892 1:      movel   IMM (1),d1      | else add 1 
3893         addl    d1,d0           |
3894 | Shift right once (because we used bit #FLT_MANT_DIG!).
3895 2:      lsrl    IMM (1),d0              
3896 | Now check again bit #FLT_MANT_DIG (rounding could have produced a
3897 | 'fraction overflow' ...).
3898         btst    IMM (FLT_MANT_DIG),d0   
3899         beq     1f
3900         lsrl    IMM (1),d0
3901 #ifndef __mcoldfire__
3902         addw    IMM (1),d2
3903 #else
3904         addql   IMM (1),d2
3905 #endif
3906 1:
3907 | If bit #FLT_MANT_DIG-1 is clear we have a denormalized number, so we 
3908 | have to put the exponent to zero and return a denormalized number.
3909         btst    IMM (FLT_MANT_DIG-1),d0
3910         beq     1f
3911         jmp     a0@
3912 1:      movel   IMM (0),d2
3913         jmp     a0@
3914
3915 Lround$to$zero:
3916 Lround$to$plus:
3917 Lround$to$minus:
3918         jmp     a0@
3919 #endif /* L_float */
3920
3921 | gcc expects the routines __eqdf2, __nedf2, __gtdf2, __gedf2,
3922 | __ledf2, __ltdf2 to all return the same value as a direct call to
3923 | __cmpdf2 would.  In this implementation, each of these routines
3924 | simply calls __cmpdf2.  It would be more efficient to give the
3925 | __cmpdf2 routine several names, but separating them out will make it
3926 | easier to write efficient versions of these routines someday.
3927 | If the operands recompare unordered unordered __gtdf2 and __gedf2 return -1.
3928 | The other routines return 1.
3929
3930 #ifdef  L_eqdf2
3931         .text
3932         FUNC(__eqdf2)
3933         .globl  SYM (__eqdf2)
3934 SYM (__eqdf2):
3935         link    a6,IMM (0)
3936         pea     1
3937         movl    a6@(20),sp@-
3938         movl    a6@(16),sp@-
3939         movl    a6@(12),sp@-
3940         movl    a6@(8),sp@-
3941         PICCALL SYM (__cmpdf2_internal)
3942         unlk    a6
3943         rts
3944 #endif /* L_eqdf2 */
3945
3946 #ifdef  L_nedf2
3947         .text
3948         FUNC(__nedf2)
3949         .globl  SYM (__nedf2)
3950 SYM (__nedf2):
3951         link    a6,IMM (0)
3952         pea     1
3953         movl    a6@(20),sp@-
3954         movl    a6@(16),sp@-
3955         movl    a6@(12),sp@-
3956         movl    a6@(8),sp@-
3957         PICCALL SYM (__cmpdf2_internal)
3958         unlk    a6
3959         rts
3960 #endif /* L_nedf2 */
3961
3962 #ifdef  L_gtdf2
3963         .text
3964         FUNC(__gtdf2)
3965         .globl  SYM (__gtdf2)
3966 SYM (__gtdf2):
3967         link    a6,IMM (0)
3968         pea     -1
3969         movl    a6@(20),sp@-
3970         movl    a6@(16),sp@-
3971         movl    a6@(12),sp@-
3972         movl    a6@(8),sp@-
3973         PICCALL SYM (__cmpdf2_internal)
3974         unlk    a6
3975         rts
3976 #endif /* L_gtdf2 */
3977
3978 #ifdef  L_gedf2
3979         .text
3980         FUNC(__gedf2)
3981         .globl  SYM (__gedf2)
3982 SYM (__gedf2):
3983         link    a6,IMM (0)
3984         pea     -1
3985         movl    a6@(20),sp@-
3986         movl    a6@(16),sp@-
3987         movl    a6@(12),sp@-
3988         movl    a6@(8),sp@-
3989         PICCALL SYM (__cmpdf2_internal)
3990         unlk    a6
3991         rts
3992 #endif /* L_gedf2 */
3993
3994 #ifdef  L_ltdf2
3995         .text
3996         FUNC(__ltdf2)
3997         .globl  SYM (__ltdf2)
3998 SYM (__ltdf2):
3999         link    a6,IMM (0)
4000         pea     1
4001         movl    a6@(20),sp@-
4002         movl    a6@(16),sp@-
4003         movl    a6@(12),sp@-
4004         movl    a6@(8),sp@-
4005         PICCALL SYM (__cmpdf2_internal)
4006         unlk    a6
4007         rts
4008 #endif /* L_ltdf2 */
4009
4010 #ifdef  L_ledf2
4011         .text
4012         FUNC(__ledf2)
4013         .globl  SYM (__ledf2)
4014 SYM (__ledf2):
4015         link    a6,IMM (0)
4016         pea     1
4017         movl    a6@(20),sp@-
4018         movl    a6@(16),sp@-
4019         movl    a6@(12),sp@-
4020         movl    a6@(8),sp@-
4021         PICCALL SYM (__cmpdf2_internal)
4022         unlk    a6
4023         rts
4024 #endif /* L_ledf2 */
4025
4026 | The comments above about __eqdf2, et. al., also apply to __eqsf2,
4027 | et. al., except that the latter call __cmpsf2 rather than __cmpdf2.
4028
4029 #ifdef  L_eqsf2
4030         .text
4031         FUNC(__eqsf2)
4032         .globl  SYM (__eqsf2)
4033 SYM (__eqsf2):
4034         link    a6,IMM (0)
4035         pea     1
4036         movl    a6@(12),sp@-
4037         movl    a6@(8),sp@-
4038         PICCALL SYM (__cmpsf2_internal)
4039         unlk    a6
4040         rts
4041 #endif /* L_eqsf2 */
4042
4043 #ifdef  L_nesf2
4044         .text
4045         FUNC(__nesf2)
4046         .globl  SYM (__nesf2)
4047 SYM (__nesf2):
4048         link    a6,IMM (0)
4049         pea     1
4050         movl    a6@(12),sp@-
4051         movl    a6@(8),sp@-
4052         PICCALL SYM (__cmpsf2_internal)
4053         unlk    a6
4054         rts
4055 #endif /* L_nesf2 */
4056
4057 #ifdef  L_gtsf2
4058         .text
4059         FUNC(__gtsf2)
4060         .globl  SYM (__gtsf2)
4061 SYM (__gtsf2):
4062         link    a6,IMM (0)
4063         pea     -1
4064         movl    a6@(12),sp@-
4065         movl    a6@(8),sp@-
4066         PICCALL SYM (__cmpsf2_internal)
4067         unlk    a6
4068         rts
4069 #endif /* L_gtsf2 */
4070
4071 #ifdef  L_gesf2
4072         .text
4073         FUNC(__gesf2)
4074         .globl  SYM (__gesf2)
4075 SYM (__gesf2):
4076         link    a6,IMM (0)
4077         pea     -1
4078         movl    a6@(12),sp@-
4079         movl    a6@(8),sp@-
4080         PICCALL SYM (__cmpsf2_internal)
4081         unlk    a6
4082         rts
4083 #endif /* L_gesf2 */
4084
4085 #ifdef  L_ltsf2
4086         .text
4087         FUNC(__ltsf2)
4088         .globl  SYM (__ltsf2)
4089 SYM (__ltsf2):
4090         link    a6,IMM (0)
4091         pea     1
4092         movl    a6@(12),sp@-
4093         movl    a6@(8),sp@-
4094         PICCALL SYM (__cmpsf2_internal)
4095         unlk    a6
4096         rts
4097 #endif /* L_ltsf2 */
4098
4099 #ifdef  L_lesf2
4100         .text
4101         FUNC(__lesf2)
4102         .globl  SYM (__lesf2)
4103 SYM (__lesf2):
4104         link    a6,IMM (0)
4105         pea     1
4106         movl    a6@(12),sp@-
4107         movl    a6@(8),sp@-
4108         PICCALL SYM (__cmpsf2_internal)
4109         unlk    a6
4110         rts
4111 #endif /* L_lesf2 */
4112
4113 #if defined (__ELF__) && defined (__linux__)
4114         /* Make stack non-executable for ELF linux targets.  */
4115         .section        .note.GNU-stack,"",@progbits
4116 #endif