Home | History | Annotate | Line # | Download | only in m68k
lb1sf68.S revision 1.1.1.6
      1 /* libgcc routines for 68000 w/o floating-point hardware.
      2    Copyright (C) 1994-2017 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 (at) 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
   4117