Annotation of gcc/config/m68k/lb1sf68.asm, revision 1.1

1.1     ! root        1: /* libgcc1 routines for 68000 w/o floating-point hardware. */
        !             2: /* Copyright (C) 1994 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is free software; you can redistribute it and/or modify it
        !             5: under the terms of the GNU General Public License as published by the
        !             6: Free Software Foundation; either version 2, or (at your option) any
        !             7: later version.
        !             8: 
        !             9: In addition to the permissions in the GNU General Public License, the
        !            10: Free Software Foundation gives you unlimited permission to link the
        !            11: compiled version of this file with other programs, and to distribute
        !            12: those programs without any restriction coming from the use of this
        !            13: file.  (The General Public License restrictions do apply in other
        !            14: respects; for example, they cover modification of the file, and
        !            15: distribution when not linked into another program.)
        !            16: 
        !            17: This file is distributed in the hope that it will be useful, but
        !            18: WITHOUT ANY WARRANTY; without even the implied warranty of
        !            19: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        !            20: General Public License for more details.
        !            21: 
        !            22: You should have received a copy of the GNU General Public License
        !            23: along with this program; see the file COPYING.  If not, write to
        !            24: the Free Software Foundation, 59 Temple Place - Suite 330,
        !            25: Boston, MA 02111-1307, USA.  */
        !            26: 
        !            27: /* As a special exception, if you link this library with files
        !            28:    compiled with GCC to produce an executable, this does not cause
        !            29:    the resulting executable to be covered by the GNU General Public License.
        !            30:    This exception does not however invalidate any other reasons why
        !            31:    the executable file might be covered by the GNU General Public License.  */
        !            32: 
        !            33: /* Use this one for any 680x0; assumes no floating point hardware.
        !            34:    The trailing " '" appearing on some lines is for ANSI preprocessors.  Yuk.
        !            35:    Some of this code comes from MINIX, via the folks at ericsson.
        !            36:    D. V. Henkel-Wallace ([email protected]) Fete Bastille, 1992
        !            37: */
        !            38: 
        !            39: /* These are predefined by new versions of GNU cpp.  */
        !            40: 
        !            41: #ifndef __USER_LABEL_PREFIX__
        !            42: #define __USER_LABEL_PREFIX__ _
        !            43: #endif
        !            44: 
        !            45: #ifndef __REGISTER_PREFIX__
        !            46: #define __REGISTER_PREFIX__
        !            47: #endif
        !            48: 
        !            49: #ifndef __IMMEDIATE_PREFIX__
        !            50: #define __IMMEDIATE_PREFIX__ #
        !            51: #endif
        !            52: 
        !            53: /* ANSI concatenation macros.  */
        !            54: 
        !            55: #define CONCAT1(a, b) CONCAT2(a, b)
        !            56: #define CONCAT2(a, b) a ## b
        !            57: 
        !            58: /* Use the right prefix for global labels.  */
        !            59: 
        !            60: #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
        !            61: 
        !            62: /* Use the right prefix for registers.  */
        !            63: 
        !            64: #define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
        !            65: 
        !            66: /* Use the right prefix for immediate values.  */
        !            67: 
        !            68: #define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
        !            69: 
        !            70: #define d0 REG (d0)
        !            71: #define d1 REG (d1)
        !            72: #define d2 REG (d2)
        !            73: #define d3 REG (d3)
        !            74: #define d4 REG (d4)
        !            75: #define d5 REG (d5)
        !            76: #define d6 REG (d6)
        !            77: #define d7 REG (d7)
        !            78: #define a0 REG (a0)
        !            79: #define a1 REG (a1)
        !            80: #define a2 REG (a2)
        !            81: #define a3 REG (a3)
        !            82: #define a4 REG (a4)
        !            83: #define a5 REG (a5)
        !            84: #define a6 REG (a6)
        !            85: #define fp REG (fp)
        !            86: #define sp REG (sp)
        !            87: 
        !            88: #ifdef L_floatex
        !            89: 
        !            90: | This is an attempt at a decent floating point (single, double and 
        !            91: | extended double) code for the GNU C compiler. It should be easy to
        !            92: | adapt to other compilers (but beware of the local labels!).
        !            93: 
        !            94: | Starting date: 21 October, 1990
        !            95: 
        !            96: | It is convenient to introduce the notation (s,e,f) for a floating point
        !            97: | number, where s=sign, e=exponent, f=fraction. We will call a floating
        !            98: | point number fpn to abbreviate, independently of the precision.
        !            99: | Let MAX_EXP be in each case the maximum exponent (255 for floats, 1023 
        !           100: | for doubles and 16383 for long doubles). We then have the following 
        !           101: | different cases:
        !           102: |  1. Normalized fpns have 0 < e < MAX_EXP. They correspond to 
        !           103: |     (-1)^s x 1.f x 2^(e-bias-1).
        !           104: |  2. Denormalized fpns have e=0. They correspond to numbers of the form
        !           105: |     (-1)^s x 0.f x 2^(-bias).
        !           106: |  3. +/-INFINITY have e=MAX_EXP, f=0.
        !           107: |  4. Quiet NaN (Not a Number) have all bits set.
        !           108: |  5. Signaling NaN (Not a Number) have s=0, e=MAX_EXP, f=1.
        !           109: 
        !           110: |=============================================================================
        !           111: |                                  exceptions
        !           112: |=============================================================================
        !           113: 
        !           114: | This is the floating point condition code register (_fpCCR):
        !           115: |
        !           116: | struct {
        !           117: |   short _exception_bits;     
        !           118: |   short _trap_enable_bits;   
        !           119: |   short _sticky_bits;
        !           120: |   short _rounding_mode;
        !           121: |   short _format;
        !           122: |   short _last_operation;
        !           123: |   union {
        !           124: |     float sf;
        !           125: |     double df;
        !           126: |   } _operand1;
        !           127: |   union {
        !           128: |     float sf;
        !           129: |     double df;
        !           130: |   } _operand2;
        !           131: | } _fpCCR;
        !           132: 
        !           133:        .data
        !           134:        .even
        !           135: 
        !           136:        .globl  SYM (_fpCCR)
        !           137:        
        !           138: SYM (_fpCCR):
        !           139: __exception_bits:
        !           140:        .word   0
        !           141: __trap_enable_bits:
        !           142:        .word   0
        !           143: __sticky_bits:
        !           144:        .word   0
        !           145: __rounding_mode:
        !           146:        .word   ROUND_TO_NEAREST
        !           147: __format:
        !           148:        .word   NIL
        !           149: __last_operation:
        !           150:        .word   NOOP
        !           151: __operand1:
        !           152:        .long   0
        !           153:        .long   0
        !           154: __operand2:
        !           155:        .long   0
        !           156:        .long   0
        !           157: 
        !           158: | Offsets:
        !           159: EBITS  = __exception_bits - SYM (_fpCCR)
        !           160: TRAPE  = __trap_enable_bits - SYM (_fpCCR)
        !           161: STICK  = __sticky_bits - SYM (_fpCCR)
        !           162: ROUND  = __rounding_mode - SYM (_fpCCR)
        !           163: FORMT  = __format - SYM (_fpCCR)
        !           164: LASTO  = __last_operation - SYM (_fpCCR)
        !           165: OPER1  = __operand1 - SYM (_fpCCR)
        !           166: OPER2  = __operand2 - SYM (_fpCCR)
        !           167: 
        !           168: | The following exception types are supported:
        !           169: INEXACT_RESULT                 = 0x0001
        !           170: UNDERFLOW              = 0x0002
        !           171: OVERFLOW               = 0x0004
        !           172: DIVIDE_BY_ZERO                 = 0x0008
        !           173: INVALID_OPERATION      = 0x0010
        !           174: 
        !           175: | The allowed rounding modes are:
        !           176: UNKNOWN           = -1
        !           177: ROUND_TO_NEAREST  = 0 | round result to nearest representable value
        !           178: ROUND_TO_ZERO     = 1 | round result towards zero
        !           179: ROUND_TO_PLUS     = 2 | round result towards plus infinity
        !           180: ROUND_TO_MINUS    = 3 | round result towards minus infinity
        !           181: 
        !           182: | The allowed values of format are:
        !           183: NIL          = 0
        !           184: SINGLE_FLOAT = 1
        !           185: DOUBLE_FLOAT = 2
        !           186: LONG_FLOAT   = 3
        !           187: 
        !           188: | The allowed values for the last operation are:
        !           189: NOOP         = 0
        !           190: ADD          = 1
        !           191: MULTIPLY     = 2
        !           192: DIVIDE       = 3
        !           193: NEGATE       = 4
        !           194: COMPARE      = 5
        !           195: EXTENDSFDF   = 6
        !           196: TRUNCDFSF    = 7
        !           197: 
        !           198: |=============================================================================
        !           199: |                           __clear_sticky_bits
        !           200: |=============================================================================
        !           201: 
        !           202: | The sticky bits are normally not cleared (thus the name), whereas the 
        !           203: | exception type and exception value reflect the last computation. 
        !           204: | This routine is provided to clear them (you can also write to _fpCCR,
        !           205: | since it is globally visible).
        !           206: 
        !           207:        .globl  SYM (__clear_sticky_bit)
        !           208: 
        !           209:        .text
        !           210:        .even
        !           211: 
        !           212: | void __clear_sticky_bits(void);
        !           213: SYM (__clear_sticky_bit):              
        !           214:        lea     SYM (_fpCCR),a0
        !           215:        movew   IMM (0),a0@(STICK)
        !           216:        rts
        !           217: 
        !           218: |=============================================================================
        !           219: |                           $_exception_handler
        !           220: |=============================================================================
        !           221: 
        !           222:        .globl  $_exception_handler
        !           223: 
        !           224:        .text
        !           225:        .even
        !           226: 
        !           227: | This is the common exit point if an exception occurs.
        !           228: | NOTE: it is NOT callable from C!
        !           229: | It expects the exception type in d7, the format (SINGLE_FLOAT,
        !           230: | DOUBLE_FLOAT or LONG_FLOAT) in d6, and the last operation code in d5.
        !           231: | It sets the corresponding exception and sticky bits, and the format. 
        !           232: | Depending on the format if fills the corresponding slots for the 
        !           233: | operands which produced the exception (all this information is provided
        !           234: | so if you write your own exception handlers you have enough information
        !           235: | to deal with the problem).
        !           236: | Then checks to see if the corresponding exception is trap-enabled, 
        !           237: | in which case it pushes the address of _fpCCR and traps through 
        !           238: | trap FPTRAP (15 for the moment).
        !           239: 
        !           240: FPTRAP = 15
        !           241: 
        !           242: $_exception_handler:
        !           243:        lea     SYM (_fpCCR),a0
        !           244:        movew   d7,a0@(EBITS)   | set __exception_bits
        !           245:        orw     d7,a0@(STICK)   | and __sticky_bits
        !           246:        movew   d6,a0@(FORMT)   | and __format
        !           247:        movew   d5,a0@(LASTO)   | and __last_operation
        !           248: 
        !           249: | Now put the operands in place:
        !           250:        cmpw    IMM (SINGLE_FLOAT),d6
        !           251:        beq     1f
        !           252:        movel   a6@(8),a0@(OPER1)
        !           253:        movel   a6@(12),a0@(OPER1+4)
        !           254:        movel   a6@(16),a0@(OPER2)
        !           255:        movel   a6@(20),a0@(OPER2+4)
        !           256:        bra     2f
        !           257: 1:     movel   a6@(8),a0@(OPER1)
        !           258:        movel   a6@(12),a0@(OPER2)
        !           259: 2:
        !           260: | And check whether the exception is trap-enabled:
        !           261:        andw    a0@(TRAPE),d7   | is exception trap-enabled?
        !           262:        beq     1f              | no, exit
        !           263:        pea     SYM (_fpCCR)    | yes, push address of _fpCCR
        !           264:        trap    IMM (FPTRAP)    | and trap
        !           265: 1:     moveml  sp@+,d2-d7      | restore data registers
        !           266:        unlk    a6              | and return
        !           267:        rts
        !           268: #endif /* L_floatex */
        !           269: 
        !           270: #ifdef  L_mulsi3
        !           271:        .text
        !           272:        .proc
        !           273:        .globl  SYM (__mulsi3)
        !           274: SYM (__mulsi3):
        !           275:        movew   sp@(4), d0      /* x0 -> d0 */
        !           276:        muluw   sp@(10), d0     /* x0*y1 */
        !           277:        movew   sp@(6), d1      /* x1 -> d1 */
        !           278:        muluw   sp@(8), d1      /* x1*y0 */
        !           279:        addw    d1, d0
        !           280:        swap    d0
        !           281:        clrw    d0
        !           282:        movew   sp@(6), d1      /* x1 -> d1 */
        !           283:        muluw   sp@(10), d1     /* x1*y1 */
        !           284:        addl    d1, d0
        !           285: 
        !           286:        rts
        !           287: #endif /* L_mulsi3 */
        !           288: 
        !           289: #ifdef  L_udivsi3
        !           290:        .text
        !           291:        .proc
        !           292:        .globl  SYM (__udivsi3)
        !           293: SYM (__udivsi3):
        !           294:        movel   d2, sp@-
        !           295:        movel   sp@(12), d1     /* d1 = divisor */
        !           296:        movel   sp@(8), d0      /* d0 = dividend */
        !           297: 
        !           298:        cmpl    IMM (0x10000), d1 /* divisor >= 2 ^ 16 ?   */
        !           299:        jcc     L3              /* then try next algorithm */
        !           300:        movel   d0, d2
        !           301:        clrw    d2
        !           302:        swap    d2
        !           303:        divu    d1, d2          /* high quotient in lower word */
        !           304:        movew   d2, d0          /* save high quotient */
        !           305:        swap    d0
        !           306:        movew   sp@(10), d2     /* get low dividend + high rest */
        !           307:        divu    d1, d2          /* low quotient */
        !           308:        movew   d2, d0
        !           309:        jra     L6
        !           310: 
        !           311: L3:    movel   d1, d2          /* use d2 as divisor backup */
        !           312: L4:    lsrl    IMM (1), d1     /* shift divisor */
        !           313:        lsrl    IMM (1), d0     /* shift dividend */
        !           314:        cmpl    IMM (0x10000), d1 /* still divisor >= 2 ^ 16 ?  */
        !           315:        jcc     L4
        !           316:        divu    d1, d0          /* now we have 16 bit divisor */
        !           317:        andl    IMM (0xffff), d0 /* mask out divisor, ignore remainder */
        !           318: 
        !           319: /* Multiply the 16 bit tentative quotient with the 32 bit divisor.  Because of
        !           320:    the operand ranges, this might give a 33 bit product.  If this product is
        !           321:    greater than the dividend, the tentative quotient was too large. */
        !           322:        movel   d2, d1
        !           323:        mulu    d0, d1          /* low part, 32 bits */
        !           324:        swap    d2
        !           325:        mulu    d0, d2          /* high part, at most 17 bits */
        !           326:        swap    d2              /* align high part with low part */
        !           327:        btst    IMM (0), d2     /* high part 17 bits? */
        !           328:        jne     L5              /* if 17 bits, quotient was too large */
        !           329:        addl    d2, d1          /* add parts */
        !           330:        jcs     L5              /* if sum is 33 bits, quotient was too large */
        !           331:        cmpl    sp@(8), d1      /* compare the sum with the dividend */
        !           332:        jls     L6              /* if sum > dividend, quotient was too large */
        !           333: L5:    subql   IMM (1), d0     /* adjust quotient */
        !           334: 
        !           335: L6:    movel   sp@+, d2
        !           336:        rts
        !           337: #endif /* L_udivsi3 */
        !           338: 
        !           339: #ifdef  L_divsi3
        !           340:        .text
        !           341:        .proc
        !           342:        .globl  SYM (__divsi3)
        !           343: SYM (__divsi3):
        !           344:        movel   d2, sp@-
        !           345: 
        !           346:        moveb   IMM (1), d2     /* sign of result stored in d2 (=1 or =-1) */
        !           347:        movel   sp@(12), d1     /* d1 = divisor */
        !           348:        jpl     L1
        !           349:        negl    d1
        !           350:        negb    d2              /* change sign because divisor <0  */
        !           351: L1:    movel   sp@(8), d0      /* d0 = dividend */
        !           352:        jpl     L2
        !           353:        negl    d0
        !           354:        negb    d2
        !           355: 
        !           356: L2:    movel   d1, sp@-
        !           357:        movel   d0, sp@-
        !           358:        jbsr    SYM (__udivsi3) /* divide abs(dividend) by abs(divisor) */
        !           359:        addql   IMM (8), sp
        !           360: 
        !           361:        tstb    d2
        !           362:        jpl     L3
        !           363:        negl    d0
        !           364: 
        !           365: L3:    movel   sp@+, d2
        !           366:        rts
        !           367: #endif /* L_divsi3 */
        !           368: 
        !           369: #ifdef  L_umodsi3
        !           370:        .text
        !           371:        .proc
        !           372:        .globl  SYM (__umodsi3)
        !           373: SYM (__umodsi3):
        !           374:        movel   sp@(8), d1      /* d1 = divisor */
        !           375:        movel   sp@(4), d0      /* d0 = dividend */
        !           376:        movel   d1, sp@-
        !           377:        movel   d0, sp@-
        !           378:        jbsr    SYM (__udivsi3)
        !           379:        addql   IMM (8), sp
        !           380:        movel   sp@(8), d1      /* d1 = divisor */
        !           381:        movel   d1, sp@-
        !           382:        movel   d0, sp@-
        !           383:        jbsr    SYM (__mulsi3)  /* d0 = (a/b)*b */
        !           384:        addql   IMM (8), sp
        !           385:        movel   sp@(4), d1      /* d1 = dividend */
        !           386:        subl    d0, d1          /* d1 = a - (a/b)*b */
        !           387:        movel   d1, d0
        !           388:        rts
        !           389: #endif /* L_umodsi3 */
        !           390: 
        !           391: #ifdef  L_modsi3
        !           392:        .text
        !           393:        .proc
        !           394:        .globl  SYM (__modsi3)
        !           395: SYM (__modsi3):
        !           396:        movel   sp@(8), d1      /* d1 = divisor */
        !           397:        movel   sp@(4), d0      /* d0 = dividend */
        !           398:        movel   d1, sp@-
        !           399:        movel   d0, sp@-
        !           400:        jbsr    SYM (__divsi3)
        !           401:        addql   IMM (8), sp
        !           402:        movel   sp@(8), d1      /* d1 = divisor */
        !           403:        movel   d1, sp@-
        !           404:        movel   d0, sp@-
        !           405:        jbsr    SYM (__mulsi3)  /* d0 = (a/b)*b */
        !           406:        addql   IMM (8), sp
        !           407:        movel   sp@(4), d1      /* d1 = dividend */
        !           408:        subl    d0, d1          /* d1 = a - (a/b)*b */
        !           409:        movel   d1, d0
        !           410:        rts
        !           411: #endif /* L_modsi3 */
        !           412: 
        !           413: 
        !           414: #ifdef  L_double
        !           415: 
        !           416:        .globl  SYM (_fpCCR)
        !           417:        .globl  $_exception_handler
        !           418: 
        !           419: QUIET_NaN      = 0xffffffff
        !           420: 
        !           421: D_MAX_EXP      = 0x07ff
        !           422: D_BIAS         = 1022
        !           423: DBL_MAX_EXP    = D_MAX_EXP - D_BIAS
        !           424: DBL_MIN_EXP    = 1 - D_BIAS
        !           425: DBL_MANT_DIG   = 53
        !           426: 
        !           427: INEXACT_RESULT                 = 0x0001
        !           428: UNDERFLOW              = 0x0002
        !           429: OVERFLOW               = 0x0004
        !           430: DIVIDE_BY_ZERO                 = 0x0008
        !           431: INVALID_OPERATION      = 0x0010
        !           432: 
        !           433: DOUBLE_FLOAT = 2
        !           434: 
        !           435: NOOP         = 0
        !           436: ADD          = 1
        !           437: MULTIPLY     = 2
        !           438: DIVIDE       = 3
        !           439: NEGATE       = 4
        !           440: COMPARE      = 5
        !           441: EXTENDSFDF   = 6
        !           442: TRUNCDFSF    = 7
        !           443: 
        !           444: UNKNOWN           = -1
        !           445: ROUND_TO_NEAREST  = 0 | round result to nearest representable value
        !           446: ROUND_TO_ZERO     = 1 | round result towards zero
        !           447: ROUND_TO_PLUS     = 2 | round result towards plus infinity
        !           448: ROUND_TO_MINUS    = 3 | round result towards minus infinity
        !           449: 
        !           450: | Entry points:
        !           451: 
        !           452:        .globl SYM (__adddf3)
        !           453:        .globl SYM (__subdf3)
        !           454:        .globl SYM (__muldf3)
        !           455:        .globl SYM (__divdf3)
        !           456:        .globl SYM (__negdf2)
        !           457:        .globl SYM (__cmpdf2)
        !           458: 
        !           459:        .text
        !           460:        .even
        !           461: 
        !           462: | These are common routines to return and signal exceptions.   
        !           463: 
        !           464: Ld$den:
        !           465: | Return and signal a denormalized number
        !           466:        orl     d7,d0
        !           467:        movew   IMM (UNDERFLOW),d7
        !           468:        orw     IMM (INEXACT_RESULT),d7
        !           469:        movew   IMM (DOUBLE_FLOAT),d6
        !           470:        jmp     $_exception_handler
        !           471: 
        !           472: Ld$infty:
        !           473: Ld$overflow:
        !           474: | Return a properly signed INFINITY and set the exception flags 
        !           475:        movel   IMM (0x7ff00000),d0
        !           476:        movel   IMM (0),d1
        !           477:        orl     d7,d0
        !           478:        movew   IMM (OVERFLOW),d7
        !           479:        orw     IMM (INEXACT_RESULT),d7
        !           480:        movew   IMM (DOUBLE_FLOAT),d6
        !           481:        jmp     $_exception_handler
        !           482: 
        !           483: Ld$underflow:
        !           484: | Return 0 and set the exception flags 
        !           485:        movel   IMM (0),d0
        !           486:        movel   d0,d1
        !           487:        movew   IMM (UNDERFLOW),d7
        !           488:        orw     IMM (INEXACT_RESULT),d7
        !           489:        movew   IMM (DOUBLE_FLOAT),d6
        !           490:        jmp     $_exception_handler
        !           491: 
        !           492: Ld$inop:
        !           493: | Return a quiet NaN and set the exception flags
        !           494:        movel   IMM (QUIET_NaN),d0
        !           495:        movel   d0,d1
        !           496:        movew   IMM (INVALID_OPERATION),d7
        !           497:        orw     IMM (INEXACT_RESULT),d7
        !           498:        movew   IMM (DOUBLE_FLOAT),d6
        !           499:        jmp     $_exception_handler
        !           500: 
        !           501: Ld$div$0:
        !           502: | Return a properly signed INFINITY and set the exception flags
        !           503:        movel   IMM (0x7ff00000),d0
        !           504:        movel   IMM (0),d1
        !           505:        orl     d7,d0
        !           506:        movew   IMM (DIVIDE_BY_ZERO),d7
        !           507:        orw     IMM (INEXACT_RESULT),d7
        !           508:        movew   IMM (DOUBLE_FLOAT),d6
        !           509:        jmp     $_exception_handler
        !           510: 
        !           511: |=============================================================================
        !           512: |=============================================================================
        !           513: |                         double precision routines
        !           514: |=============================================================================
        !           515: |=============================================================================
        !           516: 
        !           517: | A double precision floating point number (double) has the format:
        !           518: |
        !           519: | struct _double {
        !           520: |  unsigned int sign      : 1;  /* sign bit */ 
        !           521: |  unsigned int exponent  : 11; /* exponent, shifted by 126 */
        !           522: |  unsigned int fraction  : 52; /* fraction */
        !           523: | } double;
        !           524: | 
        !           525: | Thus sizeof(double) = 8 (64 bits). 
        !           526: |
        !           527: | All the routines are callable from C programs, and return the result 
        !           528: | in the register pair d0-d1. They also preserve all registers except 
        !           529: | d0-d1 and a0-a1.
        !           530: 
        !           531: |=============================================================================
        !           532: |                              __subdf3
        !           533: |=============================================================================
        !           534: 
        !           535: | double __subdf3(double, double);
        !           536: SYM (__subdf3):
        !           537:        bchg    IMM (31),sp@(12) | change sign of second operand
        !           538:                                | and fall through, so we always add
        !           539: |=============================================================================
        !           540: |                              __adddf3
        !           541: |=============================================================================
        !           542: 
        !           543: | double __adddf3(double, double);
        !           544: SYM (__adddf3):
        !           545:        link    a6,IMM (0)      | everything will be done in registers
        !           546:        moveml  d2-d7,sp@-      | save all data registers and a2 (but d0-d1)
        !           547:        movel   a6@(8),d0       | get first operand
        !           548:        movel   a6@(12),d1      | 
        !           549:        movel   a6@(16),d2      | get second operand
        !           550:        movel   a6@(20),d3      | 
        !           551: 
        !           552:        movel   d0,d7           | get d0's sign bit in d7 '
        !           553:        addl    d1,d1           | check and clear sign bit of a, and gain one
        !           554:        addxl   d0,d0           | bit of extra precision
        !           555:        beq     Ladddf$b        | if zero return second operand
        !           556: 
        !           557:        movel   d2,d6           | save sign in d6 
        !           558:        addl    d3,d3           | get rid of sign bit and gain one bit of
        !           559:        addxl   d2,d2           | extra precision
        !           560:        beq     Ladddf$a        | if zero return first operand
        !           561: 
        !           562:        andl    IMM (0x80000000),d7 | isolate a's sign bit '
        !           563:         swap   d6              | and also b's sign bit '
        !           564:        andw    IMM (0x8000),d6 |
        !           565:        orw     d6,d7           | and combine them into d7, so that a's sign '
        !           566:                                | bit is in the high word and b's is in the '
        !           567:                                | low word, so d6 is free to be used
        !           568:        movel   d7,a0           | now save d7 into a0, so d7 is free to
        !           569:                                | be used also
        !           570: 
        !           571: | Get the exponents and check for denormalized and/or infinity.
        !           572: 
        !           573:        movel   IMM (0x001fffff),d6 | mask for the fraction
        !           574:        movel   IMM (0x00200000),d7 | mask to put hidden bit back
        !           575: 
        !           576:        movel   d0,d4           | 
        !           577:        andl    d6,d0           | get fraction in d0
        !           578:        notl    d6              | make d6 into mask for the exponent
        !           579:        andl    d6,d4           | get exponent in d4
        !           580:        beq     Ladddf$a$den    | branch if a is denormalized
        !           581:        cmpl    d6,d4           | check for INFINITY or NaN
        !           582:        beq     Ladddf$nf       | 
        !           583:        orl     d7,d0           | and put hidden bit back
        !           584: Ladddf$1:
        !           585:        swap    d4              | shift right exponent so that it starts
        !           586:        lsrw    IMM (5),d4      | in bit 0 and not bit 20
        !           587: | Now we have a's exponent in d4 and fraction in d0-d1 '
        !           588:        movel   d2,d5           | save b to get exponent
        !           589:        andl    d6,d5           | get exponent in d5
        !           590:        beq     Ladddf$b$den    | branch if b is denormalized
        !           591:        cmpl    d6,d5           | check for INFINITY or NaN
        !           592:        beq     Ladddf$nf
        !           593:        notl    d6              | make d6 into mask for the fraction again
        !           594:        andl    d6,d2           | and get fraction in d2
        !           595:        orl     d7,d2           | and put hidden bit back
        !           596: Ladddf$2:
        !           597:        swap    d5              | shift right exponent so that it starts
        !           598:        lsrw    IMM (5),d5      | in bit 0 and not bit 20
        !           599: 
        !           600: | Now we have b's exponent in d5 and fraction in d2-d3. '
        !           601: 
        !           602: | The situation now is as follows: the signs are combined in a0, the 
        !           603: | numbers are in d0-d1 (a) and d2-d3 (b), and the exponents in d4 (a)
        !           604: | and d5 (b). To do the rounding correctly we need to keep all the
        !           605: | bits until the end, so we need to use d0-d1-d2-d3 for the first number
        !           606: | and d4-d5-d6-d7 for the second. To do this we store (temporarily) the
        !           607: | exponents in a2-a3.
        !           608: 
        !           609:        moveml  a2-a3,sp@-      | save the address registers
        !           610: 
        !           611:        movel   d4,a2           | save the exponents
        !           612:        movel   d5,a3           | 
        !           613: 
        !           614:        movel   IMM (0),d7      | and move the numbers around
        !           615:        movel   d7,d6           |
        !           616:        movel   d3,d5           |
        !           617:        movel   d2,d4           |
        !           618:        movel   d7,d3           |
        !           619:        movel   d7,d2           |
        !           620: 
        !           621: | Here we shift the numbers until the exponents are the same, and put 
        !           622: | the largest exponent in a2.
        !           623:        exg     d4,a2           | get exponents back
        !           624:        exg     d5,a3           |
        !           625:        cmpw    d4,d5           | compare the exponents
        !           626:        beq     Ladddf$3        | if equal don't shift '
        !           627:        bhi     9f              | branch if second exponent is higher
        !           628: 
        !           629: | Here we have a's exponent larger than b's, so we have to shift b. We do 
        !           630: | this by using as counter d2:
        !           631: 1:     movew   d4,d2           | move largest exponent to d2
        !           632:        subw    d5,d2           | and subtract second exponent
        !           633:        exg     d4,a2           | get back the longs we saved
        !           634:        exg     d5,a3           |
        !           635: | if difference is too large we don't shift (actually, we can just exit) '
        !           636:        cmpw    IMM (DBL_MANT_DIG+2),d2
        !           637:        bge     Ladddf$b$small
        !           638:        cmpw    IMM (32),d2     | if difference >= 32, shift by longs
        !           639:        bge     5f
        !           640: 2:     cmpw    IMM (16),d2     | if difference >= 16, shift by words   
        !           641:        bge     6f
        !           642:        bra     3f              | enter dbra loop
        !           643: 
        !           644: 4:     lsrl    IMM (1),d4
        !           645:        roxrl   IMM (1),d5
        !           646:        roxrl   IMM (1),d6
        !           647:        roxrl   IMM (1),d7
        !           648: 3:     dbra    d2,4b
        !           649:        movel   IMM (0),d2
        !           650:        movel   d2,d3   
        !           651:        bra     Ladddf$4
        !           652: 5:
        !           653:        movel   d6,d7
        !           654:        movel   d5,d6
        !           655:        movel   d4,d5
        !           656:        movel   IMM (0),d4
        !           657:        subw    IMM (32),d2
        !           658:        bra     2b
        !           659: 6:
        !           660:        movew   d6,d7
        !           661:        swap    d7
        !           662:        movew   d5,d6
        !           663:        swap    d6
        !           664:        movew   d4,d5
        !           665:        swap    d5
        !           666:        movew   IMM (0),d4
        !           667:        swap    d4
        !           668:        subw    IMM (16),d2
        !           669:        bra     3b
        !           670:        
        !           671: 9:     exg     d4,d5
        !           672:        movew   d4,d6
        !           673:        subw    d5,d6           | keep d5 (largest exponent) in d4
        !           674:        exg     d4,a2
        !           675:        exg     d5,a3
        !           676: | if difference is too large we don't shift (actually, we can just exit) '
        !           677:        cmpw    IMM (DBL_MANT_DIG+2),d6
        !           678:        bge     Ladddf$a$small
        !           679:        cmpw    IMM (32),d6     | if difference >= 32, shift by longs
        !           680:        bge     5f
        !           681: 2:     cmpw    IMM (16),d6     | if difference >= 16, shift by words   
        !           682:        bge     6f
        !           683:        bra     3f              | enter dbra loop
        !           684: 
        !           685: 4:     lsrl    IMM (1),d0
        !           686:        roxrl   IMM (1),d1
        !           687:        roxrl   IMM (1),d2
        !           688:        roxrl   IMM (1),d3
        !           689: 3:     dbra    d6,4b
        !           690:        movel   IMM (0),d7
        !           691:        movel   d7,d6
        !           692:        bra     Ladddf$4
        !           693: 5:
        !           694:        movel   d2,d3
        !           695:        movel   d1,d2
        !           696:        movel   d0,d1
        !           697:        movel   IMM (0),d0
        !           698:        subw    IMM (32),d6
        !           699:        bra     2b
        !           700: 6:
        !           701:        movew   d2,d3
        !           702:        swap    d3
        !           703:        movew   d1,d2
        !           704:        swap    d2
        !           705:        movew   d0,d1
        !           706:        swap    d1
        !           707:        movew   IMM (0),d0
        !           708:        swap    d0
        !           709:        subw    IMM (16),d6
        !           710:        bra     3b
        !           711: Ladddf$3:
        !           712:        exg     d4,a2   
        !           713:        exg     d5,a3
        !           714: Ladddf$4:      
        !           715: | Now we have the numbers in d0--d3 and d4--d7, the exponent in a2, and
        !           716: | the signs in a4.
        !           717: 
        !           718: | Here we have to decide whether to add or subtract the numbers:
        !           719:        exg     d7,a0           | get the signs 
        !           720:        exg     d6,a3           | a3 is free to be used
        !           721:        movel   d7,d6           |
        !           722:        movew   IMM (0),d7      | get a's sign in d7 '
        !           723:        swap    d6              |
        !           724:        movew   IMM (0),d6      | and b's sign in d6 '
        !           725:        eorl    d7,d6           | compare the signs
        !           726:        bmi     Lsubdf$0        | if the signs are different we have 
        !           727:                                | to subtract
        !           728:        exg     d7,a0           | else we add the numbers
        !           729:        exg     d6,a3           |
        !           730:        addl    d7,d3           |
        !           731:        addxl   d6,d2           |
        !           732:        addxl   d5,d1           | 
        !           733:        addxl   d4,d0           |
        !           734: 
        !           735:        movel   a2,d4           | return exponent to d4
        !           736:        movel   a0,d7           | 
        !           737:        andl    IMM (0x80000000),d7 | d7 now has the sign
        !           738: 
        !           739:        moveml  sp@+,a2-a3      
        !           740: 
        !           741: | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
        !           742: | the case of denormalized numbers in the rounding routine itself).
        !           743: | As in the addition (not in the subtraction!) we could have set 
        !           744: | one more bit we check this:
        !           745:        btst    IMM (DBL_MANT_DIG+1),d0 
        !           746:        beq     1f
        !           747:        lsrl    IMM (1),d0
        !           748:        roxrl   IMM (1),d1
        !           749:        roxrl   IMM (1),d2
        !           750:        roxrl   IMM (1),d3
        !           751:        addw    IMM (1),d4
        !           752: 1:
        !           753:        lea     Ladddf$5,a0     | to return from rounding routine
        !           754:        lea     SYM (_fpCCR),a1 | check the rounding mode
        !           755:        movew   a1@(6),d6       | rounding mode in d6
        !           756:        beq     Lround$to$nearest
        !           757:        cmpw    IMM (ROUND_TO_PLUS),d6
        !           758:        bhi     Lround$to$minus
        !           759:        blt     Lround$to$zero
        !           760:        bra     Lround$to$plus
        !           761: Ladddf$5:
        !           762: | Put back the exponent and check for overflow
        !           763:        cmpw    IMM (0x7ff),d4  | is the exponent big?
        !           764:        bge     1f
        !           765:        bclr    IMM (DBL_MANT_DIG-1),d0
        !           766:        lslw    IMM (4),d4      | put exponent back into position
        !           767:        swap    d0              | 
        !           768:        orw     d4,d0           |
        !           769:        swap    d0              |
        !           770:        bra     Ladddf$ret
        !           771: 1:
        !           772:        movew   IMM (ADD),d5
        !           773:        bra     Ld$overflow
        !           774: 
        !           775: Lsubdf$0:
        !           776: | Here we do the subtraction.
        !           777:        exg     d7,a0           | put sign back in a0
        !           778:        exg     d6,a3           |
        !           779:        subl    d7,d3           |
        !           780:        subxl   d6,d2           |
        !           781:        subxl   d5,d1           |
        !           782:        subxl   d4,d0           |
        !           783:        beq     Ladddf$ret$1    | if zero just exit
        !           784:        bpl     1f              | if positive skip the following
        !           785:        exg     d7,a0           |
        !           786:        bchg    IMM (31),d7     | change sign bit in d7
        !           787:        exg     d7,a0           |
        !           788:        negl    d3              |
        !           789:        negxl   d2              |
        !           790:        negxl   d1              | and negate result
        !           791:        negxl   d0              |
        !           792: 1:     
        !           793:        movel   a2,d4           | return exponent to d4
        !           794:        movel   a0,d7
        !           795:        andl    IMM (0x80000000),d7 | isolate sign bit
        !           796:        moveml  sp@+,a2-a3      |
        !           797: 
        !           798: | Before rounding normalize so bit #DBL_MANT_DIG is set (we will consider
        !           799: | the case of denormalized numbers in the rounding routine itself).
        !           800: | As in the addition (not in the subtraction!) we could have set 
        !           801: | one more bit we check this:
        !           802:        btst    IMM (DBL_MANT_DIG+1),d0 
        !           803:        beq     1f
        !           804:        lsrl    IMM (1),d0
        !           805:        roxrl   IMM (1),d1
        !           806:        roxrl   IMM (1),d2
        !           807:        roxrl   IMM (1),d3
        !           808:        addw    IMM (1),d4
        !           809: 1:
        !           810:        lea     Lsubdf$1,a0     | to return from rounding routine
        !           811:        lea     SYM (_fpCCR),a1 | check the rounding mode
        !           812:        movew   a1@(6),d6       | rounding mode in d6
        !           813:        beq     Lround$to$nearest
        !           814:        cmpw    IMM (ROUND_TO_PLUS),d6
        !           815:        bhi     Lround$to$minus
        !           816:        blt     Lround$to$zero
        !           817:        bra     Lround$to$plus
        !           818: Lsubdf$1:
        !           819: | Put back the exponent and sign (we don't have overflow). '
        !           820:        bclr    IMM (DBL_MANT_DIG-1),d0 
        !           821:        lslw    IMM (4),d4      | put exponent back into position
        !           822:        swap    d0              | 
        !           823:        orw     d4,d0           |
        !           824:        swap    d0              |
        !           825:        bra     Ladddf$ret
        !           826: 
        !           827: | If one of the numbers was too small (difference of exponents >= 
        !           828: | DBL_MANT_DIG+1) we return the other (and now we don't have to '
        !           829: | check for finiteness or zero).
        !           830: Ladddf$a$small:
        !           831:        moveml  sp@+,a2-a3      
        !           832:        movel   a6@(16),d0
        !           833:        movel   a6@(20),d1
        !           834:        lea     SYM (_fpCCR),a0
        !           835:        movew   IMM (0),a0@
        !           836:        moveml  sp@+,d2-d7      | restore data registers
        !           837:        unlk    a6              | and return
        !           838:        rts
        !           839: 
        !           840: Ladddf$b$small:
        !           841:        moveml  sp@+,a2-a3      
        !           842:        movel   a6@(8),d0
        !           843:        movel   a6@(12),d1
        !           844:        lea     SYM (_fpCCR),a0
        !           845:        movew   IMM (0),a0@
        !           846:        moveml  sp@+,d2-d7      | restore data registers
        !           847:        unlk    a6              | and return
        !           848:        rts
        !           849: 
        !           850: Ladddf$a$den:
        !           851:        movel   d7,d4           | d7 contains 0x00200000
        !           852:        bra     Ladddf$1
        !           853: 
        !           854: Ladddf$b$den:
        !           855:        movel   d7,d5           | d7 contains 0x00200000
        !           856:        notl    d6
        !           857:        bra     Ladddf$2
        !           858: 
        !           859: Ladddf$b:
        !           860: | Return b (if a is zero)
        !           861:        movel   d2,d0
        !           862:        movel   d3,d1
        !           863:        bra     1f
        !           864: Ladddf$a:
        !           865:        movel   a6@(8),d0
        !           866:        movel   a6@(12),d1
        !           867: 1:
        !           868:        movew   IMM (ADD),d5
        !           869: | Check for NaN and +/-INFINITY.
        !           870:        movel   d0,d7                   |
        !           871:        andl    IMM (0x80000000),d7     |
        !           872:        bclr    IMM (31),d0             |
        !           873:        cmpl    IMM (0x7ff00000),d0     |
        !           874:        bge     2f                      |
        !           875:        movel   d0,d0                   | check for zero, since we don't  '
        !           876:        bne     Ladddf$ret              | want to return -0 by mistake
        !           877:        bclr    IMM (31),d7             |
        !           878:        bra     Ladddf$ret              |
        !           879: 2:
        !           880:        andl    IMM (0x000fffff),d0     | check for NaN (nonzero fraction)
        !           881:        orl     d1,d0                   |
        !           882:        bne     Ld$inop                 |
        !           883:        bra     Ld$infty                |
        !           884:        
        !           885: Ladddf$ret$1:
        !           886:        moveml  sp@+,a2-a3      | restore regs and exit
        !           887: 
        !           888: Ladddf$ret:
        !           889: | Normal exit.
        !           890:        lea     SYM (_fpCCR),a0
        !           891:        movew   IMM (0),a0@
        !           892:        orl     d7,d0           | put sign bit back
        !           893:        moveml  sp@+,d2-d7
        !           894:        unlk    a6
        !           895:        rts
        !           896: 
        !           897: Ladddf$ret$den:
        !           898: | Return a denormalized number.
        !           899:        lsrl    IMM (1),d0      | shift right once more
        !           900:        roxrl   IMM (1),d1      |
        !           901:        bra     Ladddf$ret
        !           902: 
        !           903: Ladddf$nf:
        !           904:        movew   IMM (ADD),d5
        !           905: | This could be faster but it is not worth the effort, since it is not
        !           906: | executed very often. We sacrifice speed for clarity here.
        !           907:        movel   a6@(8),d0       | get the numbers back (remember that we
        !           908:        movel   a6@(12),d1      | did some processing already)
        !           909:        movel   a6@(16),d2      | 
        !           910:        movel   a6@(20),d3      | 
        !           911:        movel   IMM (0x7ff00000),d4 | useful constant (INFINITY)
        !           912:        movel   d0,d7           | save sign bits
        !           913:        movel   d2,d6           | 
        !           914:        bclr    IMM (31),d0     | clear sign bits
        !           915:        bclr    IMM (31),d2     | 
        !           916: | We know that one of them is either NaN of +/-INFINITY
        !           917: | Check for NaN (if either one is NaN return NaN)
        !           918:        cmpl    d4,d0           | check first a (d0)
        !           919:        bhi     Ld$inop         | if d0 > 0x7ff00000 or equal and
        !           920:        bne     2f
        !           921:        tstl    d1              | d1 > 0, a is NaN
        !           922:        bne     Ld$inop         | 
        !           923: 2:     cmpl    d4,d2           | check now b (d1)
        !           924:        bhi     Ld$inop         | 
        !           925:        bne     3f
        !           926:        tstl    d3              | 
        !           927:        bne     Ld$inop         | 
        !           928: 3:
        !           929: | Now comes the check for +/-INFINITY. We know that both are (maybe not
        !           930: | finite) numbers, but we have to check if both are infinite whether we
        !           931: | are adding or subtracting them.
        !           932:        eorl    d7,d6           | to check sign bits
        !           933:        bmi     1f
        !           934:        andl    IMM (0x80000000),d7 | get (common) sign bit
        !           935:        bra     Ld$infty
        !           936: 1:
        !           937: | We know one (or both) are infinite, so we test for equality between the
        !           938: | two numbers (if they are equal they have to be infinite both, so we
        !           939: | return NaN).
        !           940:        cmpl    d2,d0           | are both infinite?
        !           941:        bne     1f              | if d0 <> d2 they are not equal
        !           942:        cmpl    d3,d1           | if d0 == d2 test d3 and d1
        !           943:        beq     Ld$inop         | if equal return NaN
        !           944: 1:     
        !           945:        andl    IMM (0x80000000),d7 | get a's sign bit '
        !           946:        cmpl    d4,d0           | test now for infinity
        !           947:        beq     Ld$infty        | if a is INFINITY return with this sign
        !           948:        bchg    IMM (31),d7     | else we know b is INFINITY and has
        !           949:        bra     Ld$infty        | the opposite sign
        !           950: 
        !           951: |=============================================================================
        !           952: |                              __muldf3
        !           953: |=============================================================================
        !           954: 
        !           955: | double __muldf3(double, double);
        !           956: SYM (__muldf3):
        !           957:        link    a6,IMM (0)
        !           958:        moveml  d2-d7,sp@-
        !           959:        movel   a6@(8),d0               | get a into d0-d1
        !           960:        movel   a6@(12),d1              | 
        !           961:        movel   a6@(16),d2              | and b into d2-d3
        !           962:        movel   a6@(20),d3              |
        !           963:        movel   d0,d7                   | d7 will hold the sign of the product
        !           964:        eorl    d2,d7                   |
        !           965:        andl    IMM (0x80000000),d7     |
        !           966:        movel   d7,a0                   | save sign bit into a0 
        !           967:        movel   IMM (0x7ff00000),d7     | useful constant (+INFINITY)
        !           968:        movel   d7,d6                   | another (mask for fraction)
        !           969:        notl    d6                      |
        !           970:        bclr    IMM (31),d0             | get rid of a's sign bit '
        !           971:        movel   d0,d4                   | 
        !           972:        orl     d1,d4                   | 
        !           973:        beq     Lmuldf$a$0              | branch if a is zero
        !           974:        movel   d0,d4                   |
        !           975:        bclr    IMM (31),d2             | get rid of b's sign bit '
        !           976:        movel   d2,d5                   |
        !           977:        orl     d3,d5                   | 
        !           978:        beq     Lmuldf$b$0              | branch if b is zero
        !           979:        movel   d2,d5                   | 
        !           980:        cmpl    d7,d0                   | is a big?
        !           981:        bhi     Lmuldf$inop             | if a is NaN return NaN
        !           982:        beq     Lmuldf$a$nf             | we still have to check d1 and b ...
        !           983:        cmpl    d7,d2                   | now compare b with INFINITY
        !           984:        bhi     Lmuldf$inop             | is b NaN?
        !           985:        beq     Lmuldf$b$nf             | we still have to check d3 ...
        !           986: | Here we have both numbers finite and nonzero (and with no sign bit).
        !           987: | Now we get the exponents into d4 and d5.
        !           988:        andl    d7,d4                   | isolate exponent in d4
        !           989:        beq     Lmuldf$a$den            | if exponent zero, have denormalized
        !           990:        andl    d6,d0                   | isolate fraction
        !           991:        orl     IMM (0x00100000),d0     | and put hidden bit back
        !           992:        swap    d4                      | I like exponents in the first byte
        !           993:        lsrw    IMM (4),d4              | 
        !           994: Lmuldf$1:                      
        !           995:        andl    d7,d5                   |
        !           996:        beq     Lmuldf$b$den            |
        !           997:        andl    d6,d2                   |
        !           998:        orl     IMM (0x00100000),d2     | and put hidden bit back
        !           999:        swap    d5                      |
        !          1000:        lsrw    IMM (4),d5              |
        !          1001: Lmuldf$2:                              |
        !          1002:        addw    d5,d4                   | add exponents
        !          1003:        subw    IMM (D_BIAS+1),d4       | and subtract bias (plus one)
        !          1004: 
        !          1005: | We are now ready to do the multiplication. The situation is as follows:
        !          1006: | both a and b have bit 52 ( bit 20 of d0 and d2) set (even if they were 
        !          1007: | denormalized to start with!), which means that in the product bit 104 
        !          1008: | (which will correspond to bit 8 of the fourth long) is set.
        !          1009: 
        !          1010: | Here we have to do the product.
        !          1011: | To do it we have to juggle the registers back and forth, as there are not
        !          1012: | enough to keep everything in them. So we use the address registers to keep
        !          1013: | some intermediate data.
        !          1014: 
        !          1015:        moveml  a2-a3,sp@-      | save a2 and a3 for temporary use
        !          1016:        movel   IMM (0),a2      | a2 is a null register
        !          1017:        movel   d4,a3           | and a3 will preserve the exponent
        !          1018: 
        !          1019: | First, shift d2-d3 so bit 20 becomes bit 31:
        !          1020:        rorl    IMM (5),d2      | rotate d2 5 places right
        !          1021:        swap    d2              | and swap it
        !          1022:        rorl    IMM (5),d3      | do the same thing with d3
        !          1023:        swap    d3              |
        !          1024:        movew   d3,d6           | get the rightmost 11 bits of d3
        !          1025:        andw    IMM (0x07ff),d6 |
        !          1026:        orw     d6,d2           | and put them into d2
        !          1027:        andw    IMM (0xf800),d3 | clear those bits in d3
        !          1028: 
        !          1029:        movel   d2,d6           | move b into d6-d7
        !          1030:        movel   d3,d7           | move a into d4-d5
        !          1031:        movel   d0,d4           | and clear d0-d1-d2-d3 (to put result)
        !          1032:        movel   d1,d5           |
        !          1033:        movel   IMM (0),d3      |
        !          1034:        movel   d3,d2           |
        !          1035:        movel   d3,d1           |
        !          1036:        movel   d3,d0           |
        !          1037: 
        !          1038: | We use a1 as counter:        
        !          1039:        movel   IMM (DBL_MANT_DIG-1),a1         
        !          1040:        exg     d7,a1
        !          1041: 
        !          1042: 1:     exg     d7,a1           | put counter back in a1
        !          1043:        addl    d3,d3           | shift sum once left
        !          1044:        addxl   d2,d2           |
        !          1045:        addxl   d1,d1           |
        !          1046:        addxl   d0,d0           |
        !          1047:        addl    d7,d7           |
        !          1048:        addxl   d6,d6           |
        !          1049:        bcc     2f              | if bit clear skip the following
        !          1050:        exg     d7,a2           |
        !          1051:        addl    d5,d3           | else add a to the sum
        !          1052:        addxl   d4,d2           |
        !          1053:        addxl   d7,d1           |
        !          1054:        addxl   d7,d0           |
        !          1055:        exg     d7,a2           | 
        !          1056: 2:     exg     d7,a1           | put counter in d7
        !          1057:        dbf     d7,1b           | decrement and branch
        !          1058: 
        !          1059:        movel   a3,d4           | restore exponent
        !          1060:        moveml  sp@+,a2-a3
        !          1061: 
        !          1062: | Now we have the product in d0-d1-d2-d3, with bit 8 of d0 set. The 
        !          1063: | first thing to do now is to normalize it so bit 8 becomes bit 
        !          1064: | DBL_MANT_DIG-32 (to do the rounding); later we will shift right.
        !          1065:        swap    d0
        !          1066:        swap    d1
        !          1067:        movew   d1,d0
        !          1068:        swap    d2
        !          1069:        movew   d2,d1
        !          1070:        swap    d3
        !          1071:        movew   d3,d2
        !          1072:        movew   IMM (0),d3
        !          1073:        lsrl    IMM (1),d0
        !          1074:        roxrl   IMM (1),d1
        !          1075:        roxrl   IMM (1),d2
        !          1076:        roxrl   IMM (1),d3
        !          1077:        lsrl    IMM (1),d0
        !          1078:        roxrl   IMM (1),d1
        !          1079:        roxrl   IMM (1),d2
        !          1080:        roxrl   IMM (1),d3
        !          1081:        lsrl    IMM (1),d0
        !          1082:        roxrl   IMM (1),d1
        !          1083:        roxrl   IMM (1),d2
        !          1084:        roxrl   IMM (1),d3
        !          1085:        
        !          1086: | Now round, check for over- and underflow, and exit.
        !          1087:        movel   a0,d7           | get sign bit back into d7
        !          1088:        movew   IMM (MULTIPLY),d5
        !          1089: 
        !          1090:        btst    IMM (DBL_MANT_DIG+1-32),d0
        !          1091:        beq     Lround$exit
        !          1092:        lsrl    IMM (1),d0
        !          1093:        roxrl   IMM (1),d1
        !          1094:        addw    IMM (1),d4
        !          1095:        bra     Lround$exit
        !          1096: 
        !          1097: Lmuldf$inop:
        !          1098:        movew   IMM (MULTIPLY),d5
        !          1099:        bra     Ld$inop
        !          1100: 
        !          1101: Lmuldf$b$nf:
        !          1102:        movew   IMM (MULTIPLY),d5
        !          1103:        movel   a0,d7           | get sign bit back into d7
        !          1104:        tstl    d3              | we know d2 == 0x7ff00000, so check d3
        !          1105:        bne     Ld$inop         | if d3 <> 0 b is NaN
        !          1106:        bra     Ld$overflow     | else we have overflow (since a is finite)
        !          1107: 
        !          1108: Lmuldf$a$nf:
        !          1109:        movew   IMM (MULTIPLY),d5
        !          1110:        movel   a0,d7           | get sign bit back into d7
        !          1111:        tstl    d1              | we know d0 == 0x7ff00000, so check d1
        !          1112:        bne     Ld$inop         | if d1 <> 0 a is NaN
        !          1113:        bra     Ld$overflow     | else signal overflow
        !          1114: 
        !          1115: | If either number is zero return zero, unless the other is +/-INFINITY or
        !          1116: | NaN, in which case we return NaN.
        !          1117: Lmuldf$b$0:
        !          1118:        movew   IMM (MULTIPLY),d5
        !          1119:        exg     d2,d0           | put b (==0) into d0-d1
        !          1120:        exg     d3,d1           | and a (with sign bit cleared) into d2-d3
        !          1121:        bra     1f
        !          1122: Lmuldf$a$0:
        !          1123:        movel   a6@(16),d2      | put b into d2-d3 again
        !          1124:        movel   a6@(20),d3      |
        !          1125:        bclr    IMM (31),d2     | clear sign bit
        !          1126: 1:     cmpl    IMM (0x7ff00000),d2 | check for non-finiteness
        !          1127:        bge     Ld$inop         | in case NaN or +/-INFINITY return NaN
        !          1128:        lea     SYM (_fpCCR),a0
        !          1129:        movew   IMM (0),a0@
        !          1130:        moveml  sp@+,d2-d7
        !          1131:        unlk    a6
        !          1132:        rts
        !          1133: 
        !          1134: | If a number is denormalized we put an exponent of 1 but do not put the 
        !          1135: | hidden bit back into the fraction; instead we shift left until bit 21
        !          1136: | (the hidden bit) is set, adjusting the exponent accordingly. We do this
        !          1137: | to ensure that the product of the fractions is close to 1.
        !          1138: Lmuldf$a$den:
        !          1139:        movel   IMM (1),d4
        !          1140:        andl    d6,d0
        !          1141: 1:     addl    d1,d1           | shift a left until bit 20 is set
        !          1142:        addxl   d0,d0           |
        !          1143:        subw    IMM (1),d4      | and adjust exponent
        !          1144:        btst    IMM (20),d0     |
        !          1145:        bne     Lmuldf$1        |
        !          1146:        bra     1b
        !          1147: 
        !          1148: Lmuldf$b$den:
        !          1149:        movel   IMM (1),d5
        !          1150:        andl    d6,d2
        !          1151: 1:     addl    d3,d3           | shift b left until bit 20 is set
        !          1152:        addxl   d2,d2           |
        !          1153:        subw    IMM (1),d5      | and adjust exponent
        !          1154:        btst    IMM (20),d2     |
        !          1155:        bne     Lmuldf$2        |
        !          1156:        bra     1b
        !          1157: 
        !          1158: 
        !          1159: |=============================================================================
        !          1160: |                              __divdf3
        !          1161: |=============================================================================
        !          1162: 
        !          1163: | double __divdf3(double, double);
        !          1164: SYM (__divdf3):
        !          1165:        link    a6,IMM (0)
        !          1166:        moveml  d2-d7,sp@-
        !          1167:        movel   a6@(8),d0       | get a into d0-d1
        !          1168:        movel   a6@(12),d1      | 
        !          1169:        movel   a6@(16),d2      | and b into d2-d3
        !          1170:        movel   a6@(20),d3      |
        !          1171:        movel   d0,d7           | d7 will hold the sign of the result
        !          1172:        eorl    d2,d7           |
        !          1173:        andl    IMM (0x80000000),d7
        !          1174:        movel   d7,a0           | save sign into a0
        !          1175:        movel   IMM (0x7ff00000),d7 | useful constant (+INFINITY)
        !          1176:        movel   d7,d6           | another (mask for fraction)
        !          1177:        notl    d6              |
        !          1178:        bclr    IMM (31),d0     | get rid of a's sign bit '
        !          1179:        movel   d0,d4           |
        !          1180:        orl     d1,d4           |
        !          1181:        beq     Ldivdf$a$0      | branch if a is zero
        !          1182:        movel   d0,d4           |
        !          1183:        bclr    IMM (31),d2     | get rid of b's sign bit '
        !          1184:        movel   d2,d5           |
        !          1185:        orl     d3,d5           |
        !          1186:        beq     Ldivdf$b$0      | branch if b is zero
        !          1187:        movel   d2,d5
        !          1188:        cmpl    d7,d0           | is a big?
        !          1189:        bhi     Ldivdf$inop     | if a is NaN return NaN
        !          1190:        beq     Ldivdf$a$nf     | if d0 == 0x7ff00000 we check d1
        !          1191:        cmpl    d7,d2           | now compare b with INFINITY 
        !          1192:        bhi     Ldivdf$inop     | if b is NaN return NaN
        !          1193:        beq     Ldivdf$b$nf     | if d2 == 0x7ff00000 we check d3
        !          1194: | Here we have both numbers finite and nonzero (and with no sign bit).
        !          1195: | Now we get the exponents into d4 and d5 and normalize the numbers to
        !          1196: | ensure that the ratio of the fractions is around 1. We do this by
        !          1197: | making sure that both numbers have bit #DBL_MANT_DIG-32-1 (hidden bit)
        !          1198: | set, even if they were denormalized to start with.
        !          1199: | Thus, the result will satisfy: 2 > result > 1/2.
        !          1200:        andl    d7,d4           | and isolate exponent in d4
        !          1201:        beq     Ldivdf$a$den    | if exponent is zero we have a denormalized
        !          1202:        andl    d6,d0           | and isolate fraction
        !          1203:        orl     IMM (0x00100000),d0 | and put hidden bit back
        !          1204:        swap    d4              | I like exponents in the first byte
        !          1205:        lsrw    IMM (4),d4      | 
        !          1206: Ldivdf$1:                      | 
        !          1207:        andl    d7,d5           |
        !          1208:        beq     Ldivdf$b$den    |
        !          1209:        andl    d6,d2           |
        !          1210:        orl     IMM (0x00100000),d2
        !          1211:        swap    d5              |
        !          1212:        lsrw    IMM (4),d5      |
        !          1213: Ldivdf$2:                      |
        !          1214:        subw    d5,d4           | subtract exponents
        !          1215:        addw    IMM (D_BIAS),d4 | and add bias
        !          1216: 
        !          1217: | We are now ready to do the division. We have prepared things in such a way
        !          1218: | that the ratio of the fractions will be less than 2 but greater than 1/2.
        !          1219: | At this point the registers in use are:
        !          1220: | d0-d1        hold a (first operand, bit DBL_MANT_DIG-32=0, bit 
        !          1221: | DBL_MANT_DIG-1-32=1)
        !          1222: | d2-d3        hold b (second operand, bit DBL_MANT_DIG-32=1)
        !          1223: | d4   holds the difference of the exponents, corrected by the bias
        !          1224: | a0   holds the sign of the ratio
        !          1225: 
        !          1226: | To do the rounding correctly we need to keep information about the
        !          1227: | nonsignificant bits. One way to do this would be to do the division
        !          1228: | using four registers; another is to use two registers (as originally
        !          1229: | I did), but use a sticky bit to preserve information about the 
        !          1230: | fractional part. Note that we can keep that info in a1, which is not
        !          1231: | used.
        !          1232:        movel   IMM (0),d6      | d6-d7 will hold the result
        !          1233:        movel   d6,d7           | 
        !          1234:        movel   IMM (0),a1      | and a1 will hold the sticky bit
        !          1235: 
        !          1236:        movel   IMM (DBL_MANT_DIG-32+1),d5      
        !          1237:        
        !          1238: 1:     cmpl    d0,d2           | is a < b?
        !          1239:        bhi     3f              | if b > a skip the following
        !          1240:        beq     4f              | if d0==d2 check d1 and d3
        !          1241: 2:     subl    d3,d1           | 
        !          1242:        subxl   d2,d0           | a <-- a - b
        !          1243:        bset    d5,d6           | set the corresponding bit in d6
        !          1244: 3:     addl    d1,d1           | shift a by 1
        !          1245:        addxl   d0,d0           |
        !          1246:        dbra    d5,1b           | and branch back
        !          1247:        bra     5f                      
        !          1248: 4:     cmpl    d1,d3           | here d0==d2, so check d1 and d3
        !          1249:        bhi     3b              | if d1 > d2 skip the subtraction
        !          1250:        bra     2b              | else go do it
        !          1251: 5:
        !          1252: | Here we have to start setting the bits in the second long.
        !          1253:        movel   IMM (31),d5     | again d5 is counter
        !          1254: 
        !          1255: 1:     cmpl    d0,d2           | is a < b?
        !          1256:        bhi     3f              | if b > a skip the following
        !          1257:        beq     4f              | if d0==d2 check d1 and d3
        !          1258: 2:     subl    d3,d1           | 
        !          1259:        subxl   d2,d0           | a <-- a - b
        !          1260:        bset    d5,d7           | set the corresponding bit in d7
        !          1261: 3:     addl    d1,d1           | shift a by 1
        !          1262:        addxl   d0,d0           |
        !          1263:        dbra    d5,1b           | and branch back
        !          1264:        bra     5f                      
        !          1265: 4:     cmpl    d1,d3           | here d0==d2, so check d1 and d3
        !          1266:        bhi     3b              | if d1 > d2 skip the subtraction
        !          1267:        bra     2b              | else go do it
        !          1268: 5:
        !          1269: | Now go ahead checking until we hit a one, which we store in d2.
        !          1270:        movel   IMM (DBL_MANT_DIG),d5
        !          1271: 1:     cmpl    d2,d0           | is a < b?
        !          1272:        bhi     4f              | if b < a, exit
        !          1273:        beq     3f              | if d0==d2 check d1 and d3
        !          1274: 2:     addl    d1,d1           | shift a by 1
        !          1275:        addxl   d0,d0           |
        !          1276:        dbra    d5,1b           | and branch back
        !          1277:        movel   IMM (0),d2      | here no sticky bit was found
        !          1278:        movel   d2,d3
        !          1279:        bra     5f                      
        !          1280: 3:     cmpl    d1,d3           | here d0==d2, so check d1 and d3
        !          1281:        bhi     2b              | if d1 > d2 go back
        !          1282: 4:
        !          1283: | Here put the sticky bit in d2-d3 (in the position which actually corresponds
        !          1284: | to it; if you don't do this the algorithm loses in some cases). '
        !          1285:        movel   IMM (0),d2
        !          1286:        movel   d2,d3
        !          1287:        subw    IMM (DBL_MANT_DIG),d5
        !          1288:        addw    IMM (63),d5
        !          1289:        cmpw    IMM (31),d5
        !          1290:        bhi     2f
        !          1291: 1:     bset    d5,d3
        !          1292:        bra     5f
        !          1293:        subw    IMM (32),d5
        !          1294: 2:     bset    d5,d2
        !          1295: 5:
        !          1296: | Finally we are finished! Move the longs in the address registers to
        !          1297: | their final destination:
        !          1298:        movel   d6,d0
        !          1299:        movel   d7,d1
        !          1300:        movel   IMM (0),d3
        !          1301: 
        !          1302: | Here we have finished the division, with the result in d0-d1-d2-d3, with
        !          1303: | 2^21 <= d6 < 2^23. Thus bit 23 is not set, but bit 22 could be set.
        !          1304: | If it is not, then definitely bit 21 is set. Normalize so bit 22 is
        !          1305: | not set:
        !          1306:        btst    IMM (DBL_MANT_DIG-32+1),d0
        !          1307:        beq     1f
        !          1308:        lsrl    IMM (1),d0
        !          1309:        roxrl   IMM (1),d1
        !          1310:        roxrl   IMM (1),d2
        !          1311:        roxrl   IMM (1),d3
        !          1312:        addw    IMM (1),d4
        !          1313: 1:
        !          1314: | Now round, check for over- and underflow, and exit.
        !          1315:        movel   a0,d7           | restore sign bit to d7
        !          1316:        movew   IMM (DIVIDE),d5
        !          1317:        bra     Lround$exit
        !          1318: 
        !          1319: Ldivdf$inop:
        !          1320:        movew   IMM (DIVIDE),d5
        !          1321:        bra     Ld$inop
        !          1322: 
        !          1323: Ldivdf$a$0:
        !          1324: | If a is zero check to see whether b is zero also. In that case return
        !          1325: | NaN; then check if b is NaN, and return NaN also in that case. Else
        !          1326: | return zero.
        !          1327:        movew   IMM (DIVIDE),d5
        !          1328:        bclr    IMM (31),d2     |
        !          1329:        movel   d2,d4           | 
        !          1330:        orl     d3,d4           | 
        !          1331:        beq     Ld$inop         | if b is also zero return NaN
        !          1332:        cmpl    IMM (0x7ff00000),d2 | check for NaN
        !          1333:        bhi     Ld$inop         | 
        !          1334:        blt     1f              |
        !          1335:        tstl    d3              |
        !          1336:        bne     Ld$inop         |
        !          1337: 1:     movel   IMM (0),d0      | else return zero
        !          1338:        movel   d0,d1           | 
        !          1339:        lea     SYM (_fpCCR),a0 | clear exception flags
        !          1340:        movew   IMM (0),a0@     |
        !          1341:        moveml  sp@+,d2-d7      | 
        !          1342:        unlk    a6              | 
        !          1343:        rts                     |       
        !          1344: 
        !          1345: Ldivdf$b$0:
        !          1346:        movew   IMM (DIVIDE),d5
        !          1347: | If we got here a is not zero. Check if a is NaN; in that case return NaN,
        !          1348: | else return +/-INFINITY. Remember that a is in d0 with the sign bit 
        !          1349: | cleared already.
        !          1350:        movel   a0,d7           | put a's sign bit back in d7 '
        !          1351:        cmpl    IMM (0x7ff00000),d0 | compare d0 with INFINITY
        !          1352:        bhi     Ld$inop         | if larger it is NaN
        !          1353:        tstl    d1              | 
        !          1354:        bne     Ld$inop         | 
        !          1355:        bra     Ld$div$0        | else signal DIVIDE_BY_ZERO
        !          1356: 
        !          1357: Ldivdf$b$nf:
        !          1358:        movew   IMM (DIVIDE),d5
        !          1359: | If d2 == 0x7ff00000 we have to check d3.
        !          1360:        tstl    d3              |
        !          1361:        bne     Ld$inop         | if d3 <> 0, b is NaN
        !          1362:        bra     Ld$underflow    | else b is +/-INFINITY, so signal underflow
        !          1363: 
        !          1364: Ldivdf$a$nf:
        !          1365:        movew   IMM (DIVIDE),d5
        !          1366: | If d0 == 0x7ff00000 we have to check d1.
        !          1367:        tstl    d1              |
        !          1368:        bne     Ld$inop         | if d1 <> 0, a is NaN
        !          1369: | If a is INFINITY we have to check b
        !          1370:        cmpl    d7,d2           | compare b with INFINITY 
        !          1371:        bge     Ld$inop         | if b is NaN or INFINITY return NaN
        !          1372:        tstl    d3              |
        !          1373:        bne     Ld$inop         | 
        !          1374:        bra     Ld$overflow     | else return overflow
        !          1375: 
        !          1376: | If a number is denormalized we put an exponent of 1 but do not put the 
        !          1377: | bit back into the fraction.
        !          1378: Ldivdf$a$den:
        !          1379:        movel   IMM (1),d4
        !          1380:        andl    d6,d0
        !          1381: 1:     addl    d1,d1           | shift a left until bit 20 is set
        !          1382:        addxl   d0,d0
        !          1383:        subw    IMM (1),d4      | and adjust exponent
        !          1384:        btst    IMM (DBL_MANT_DIG-32-1),d0
        !          1385:        bne     Ldivdf$1
        !          1386:        bra     1b
        !          1387: 
        !          1388: Ldivdf$b$den:
        !          1389:        movel   IMM (1),d5
        !          1390:        andl    d6,d2
        !          1391: 1:     addl    d3,d3           | shift b left until bit 20 is set
        !          1392:        addxl   d2,d2
        !          1393:        subw    IMM (1),d5      | and adjust exponent
        !          1394:        btst    IMM (DBL_MANT_DIG-32-1),d2
        !          1395:        bne     Ldivdf$2
        !          1396:        bra     1b
        !          1397: 
        !          1398: Lround$exit:
        !          1399: | This is a common exit point for __muldf3 and __divdf3. When they enter
        !          1400: | this point the sign of the result is in d7, the result in d0-d1, normalized
        !          1401: | so that 2^21 <= d0 < 2^22, and the exponent is in the lower byte of d4.
        !          1402: 
        !          1403: | First check for underlow in the exponent:
        !          1404:        cmpw    IMM (-DBL_MANT_DIG-1),d4                
        !          1405:        blt     Ld$underflow    
        !          1406: | It could happen that the exponent is less than 1, in which case the 
        !          1407: | number is denormalized. In this case we shift right and adjust the 
        !          1408: | exponent until it becomes 1 or the fraction is zero (in the latter case 
        !          1409: | we signal underflow and return zero).
        !          1410:        movel   d7,a0           |
        !          1411:        movel   IMM (0),d6      | use d6-d7 to collect bits flushed right
        !          1412:        movel   d6,d7           | use d6-d7 to collect bits flushed right
        !          1413:        cmpw    IMM (1),d4      | if the exponent is less than 1 we 
        !          1414:        bge     2f              | have to shift right (denormalize)
        !          1415: 1:     addw    IMM (1),d4      | adjust the exponent
        !          1416:        lsrl    IMM (1),d0      | shift right once 
        !          1417:        roxrl   IMM (1),d1      |
        !          1418:        roxrl   IMM (1),d2      |
        !          1419:        roxrl   IMM (1),d3      |
        !          1420:        roxrl   IMM (1),d6      | 
        !          1421:        roxrl   IMM (1),d7      |
        !          1422:        cmpw    IMM (1),d4      | is the exponent 1 already?
        !          1423:        beq     2f              | if not loop back
        !          1424:        bra     1b              |
        !          1425:        bra     Ld$underflow    | safety check, shouldn't execute '
        !          1426: 2:     orl     d6,d2           | this is a trick so we don't lose  '
        !          1427:        orl     d7,d3           | the bits which were flushed right
        !          1428:        movel   a0,d7           | get back sign bit into d7
        !          1429: | Now call the rounding routine (which takes care of denormalized numbers):
        !          1430:        lea     Lround$0,a0     | to return from rounding routine
        !          1431:        lea     SYM (_fpCCR),a1 | check the rounding mode
        !          1432:        movew   a1@(6),d6       | rounding mode in d6
        !          1433:        beq     Lround$to$nearest
        !          1434:        cmpw    IMM (ROUND_TO_PLUS),d6
        !          1435:        bhi     Lround$to$minus
        !          1436:        blt     Lround$to$zero
        !          1437:        bra     Lround$to$plus
        !          1438: Lround$0:
        !          1439: | Here we have a correctly rounded result (either normalized or denormalized).
        !          1440: 
        !          1441: | Here we should have either a normalized number or a denormalized one, and
        !          1442: | the exponent is necessarily larger or equal to 1 (so we don't have to  '
        !          1443: | check again for underflow!). We have to check for overflow or for a 
        !          1444: | denormalized number (which also signals underflow).
        !          1445: | Check for overflow (i.e., exponent >= 0x7ff).
        !          1446:        cmpw    IMM (0x07ff),d4
        !          1447:        bge     Ld$overflow
        !          1448: | Now check for a denormalized number (exponent==0):
        !          1449:        movew   d4,d4
        !          1450:        beq     Ld$den
        !          1451: 1:
        !          1452: | Put back the exponents and sign and return.
        !          1453:        lslw    IMM (4),d4      | exponent back to fourth byte
        !          1454:        bclr    IMM (DBL_MANT_DIG-32-1),d0
        !          1455:        swap    d0              | and put back exponent
        !          1456:        orw     d4,d0           | 
        !          1457:        swap    d0              |
        !          1458:        orl     d7,d0           | and sign also
        !          1459: 
        !          1460:        lea     SYM (_fpCCR),a0
        !          1461:        movew   IMM (0),a0@
        !          1462:        moveml  sp@+,d2-d7
        !          1463:        unlk    a6
        !          1464:        rts
        !          1465: 
        !          1466: |=============================================================================
        !          1467: |                              __negdf2
        !          1468: |=============================================================================
        !          1469: 
        !          1470: | double __negdf2(double, double);
        !          1471: SYM (__negdf2):
        !          1472:        link    a6,IMM (0)
        !          1473:        moveml  d2-d7,sp@-
        !          1474:        movew   IMM (NEGATE),d5
        !          1475:        movel   a6@(8),d0       | get number to negate in d0-d1
        !          1476:        movel   a6@(12),d1      |
        !          1477:        bchg    IMM (31),d0     | negate
        !          1478:        movel   d0,d2           | make a positive copy (for the tests)
        !          1479:        bclr    IMM (31),d2     |
        !          1480:        movel   d2,d4           | check for zero
        !          1481:        orl     d1,d4           |
        !          1482:        beq     2f              | if zero (either sign) return +zero
        !          1483:        cmpl    IMM (0x7ff00000),d2 | compare to +INFINITY
        !          1484:        blt     1f              | if finite, return
        !          1485:        bhi     Ld$inop         | if larger (fraction not zero) is NaN
        !          1486:        tstl    d1              | if d2 == 0x7ff00000 check d1
        !          1487:        bne     Ld$inop         |
        !          1488:        movel   d0,d7           | else get sign and return INFINITY
        !          1489:        andl    IMM (0x80000000),d7
        !          1490:        bra     Ld$infty                
        !          1491: 1:     lea     SYM (_fpCCR),a0
        !          1492:        movew   IMM (0),a0@
        !          1493:        moveml  sp@+,d2-d7
        !          1494:        unlk    a6
        !          1495:        rts
        !          1496: 2:     bclr    IMM (31),d0
        !          1497:        bra     1b
        !          1498: 
        !          1499: |=============================================================================
        !          1500: |                              __cmpdf2
        !          1501: |=============================================================================
        !          1502: 
        !          1503: GREATER =  1
        !          1504: LESS    = -1
        !          1505: EQUAL   =  0
        !          1506: 
        !          1507: | int __cmpdf2(double, double);
        !          1508: SYM (__cmpdf2):
        !          1509:        link    a6,IMM (0)
        !          1510:        moveml  d2-d7,sp@-      | save registers
        !          1511:        movew   IMM (COMPARE),d5
        !          1512:        movel   a6@(8),d0       | get first operand
        !          1513:        movel   a6@(12),d1      |
        !          1514:        movel   a6@(16),d2      | get second operand
        !          1515:        movel   a6@(20),d3      |
        !          1516: | First check if a and/or b are (+/-) zero and in that case clear
        !          1517: | the sign bit.
        !          1518:        movel   d0,d6           | copy signs into d6 (a) and d7(b)
        !          1519:        bclr    IMM (31),d0     | and clear signs in d0 and d2
        !          1520:        movel   d2,d7           |
        !          1521:        bclr    IMM (31),d2     |
        !          1522:        cmpl    IMM (0x7fff0000),d0 | check for a == NaN
        !          1523:        bhi     Ld$inop         | if d0 > 0x7ff00000, a is NaN
        !          1524:        beq     Lcmpdf$a$nf     | if equal can be INFINITY, so check d1
        !          1525:        movel   d0,d4           | copy into d4 to test for zero
        !          1526:        orl     d1,d4           |
        !          1527:        beq     Lcmpdf$a$0      |
        !          1528: Lcmpdf$0:
        !          1529:        cmpl    IMM (0x7fff0000),d2 | check for b == NaN
        !          1530:        bhi     Ld$inop         | if d2 > 0x7ff00000, b is NaN
        !          1531:        beq     Lcmpdf$b$nf     | if equal can be INFINITY, so check d3
        !          1532:        movel   d2,d4           |
        !          1533:        orl     d3,d4           |
        !          1534:        beq     Lcmpdf$b$0      |
        !          1535: Lcmpdf$1:
        !          1536: | Check the signs
        !          1537:        eorl    d6,d7
        !          1538:        bpl     1f
        !          1539: | If the signs are not equal check if a >= 0
        !          1540:        tstl    d6
        !          1541:        bpl     Lcmpdf$a$gt$b   | if (a >= 0 && b < 0) => a > b
        !          1542:        bmi     Lcmpdf$b$gt$a   | if (a < 0 && b >= 0) => a < b
        !          1543: 1:
        !          1544: | If the signs are equal check for < 0
        !          1545:        tstl    d6
        !          1546:        bpl     1f
        !          1547: | If both are negative exchange them
        !          1548:        exg     d0,d2
        !          1549:        exg     d1,d3
        !          1550: 1:
        !          1551: | Now that they are positive we just compare them as longs (does this also
        !          1552: | work for denormalized numbers?).
        !          1553:        cmpl    d0,d2
        !          1554:        bhi     Lcmpdf$b$gt$a   | |b| > |a|
        !          1555:        bne     Lcmpdf$a$gt$b   | |b| < |a|
        !          1556: | If we got here d0 == d2, so we compare d1 and d3.
        !          1557:        cmpl    d1,d3
        !          1558:        bhi     Lcmpdf$b$gt$a   | |b| > |a|
        !          1559:        bne     Lcmpdf$a$gt$b   | |b| < |a|
        !          1560: | If we got here a == b.
        !          1561:        movel   IMM (EQUAL),d0
        !          1562:        moveml  sp@+,d2-d7      | put back the registers
        !          1563:        unlk    a6
        !          1564:        rts
        !          1565: Lcmpdf$a$gt$b:
        !          1566:        movel   IMM (GREATER),d0
        !          1567:        moveml  sp@+,d2-d7      | put back the registers
        !          1568:        unlk    a6
        !          1569:        rts
        !          1570: Lcmpdf$b$gt$a:
        !          1571:        movel   IMM (LESS),d0
        !          1572:        moveml  sp@+,d2-d7      | put back the registers
        !          1573:        unlk    a6
        !          1574:        rts
        !          1575: 
        !          1576: Lcmpdf$a$0:    
        !          1577:        bclr    IMM (31),d6
        !          1578:        bra     Lcmpdf$0
        !          1579: Lcmpdf$b$0:
        !          1580:        bclr    IMM (31),d7
        !          1581:        bra     Lcmpdf$1
        !          1582: 
        !          1583: Lcmpdf$a$nf:
        !          1584:        tstl    d1
        !          1585:        bne     Ld$inop
        !          1586:        bra     Lcmpdf$0
        !          1587: 
        !          1588: Lcmpdf$b$nf:
        !          1589:        tstl    d3
        !          1590:        bne     Ld$inop
        !          1591:        bra     Lcmpdf$1
        !          1592: 
        !          1593: |=============================================================================
        !          1594: |                           rounding routines
        !          1595: |=============================================================================
        !          1596: 
        !          1597: | The rounding routines expect the number to be normalized in registers
        !          1598: | d0-d1-d2-d3, with the exponent in register d4. They assume that the 
        !          1599: | exponent is larger or equal to 1. They return a properly normalized number
        !          1600: | if possible, and a denormalized number otherwise. The exponent is returned
        !          1601: | in d4.
        !          1602: 
        !          1603: Lround$to$nearest:
        !          1604: | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
        !          1605: | Here we assume that the exponent is not too small (this should be checked
        !          1606: | before entering the rounding routine), but the number could be denormalized.
        !          1607: 
        !          1608: | Check for denormalized numbers:
        !          1609: 1:     btst    IMM (DBL_MANT_DIG-32),d0
        !          1610:        bne     2f              | if set the number is normalized
        !          1611: | Normalize shifting left until bit #DBL_MANT_DIG-32 is set or the exponent 
        !          1612: | is one (remember that a denormalized number corresponds to an 
        !          1613: | exponent of -D_BIAS+1).
        !          1614:        cmpw    IMM (1),d4      | remember that the exponent is at least one
        !          1615:        beq     2f              | an exponent of one means denormalized
        !          1616:        addl    d3,d3           | else shift and adjust the exponent
        !          1617:        addxl   d2,d2           |
        !          1618:        addxl   d1,d1           |
        !          1619:        addxl   d0,d0           |
        !          1620:        dbra    d4,1b           |
        !          1621: 2:
        !          1622: | Now round: we do it as follows: after the shifting we can write the
        !          1623: | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
        !          1624: | If delta < 1, do nothing. If delta > 1, add 1 to f. 
        !          1625: | If delta == 1, we make sure the rounded number will be even (odd?) 
        !          1626: | (after shifting).
        !          1627:        btst    IMM (0),d1      | is delta < 1?
        !          1628:        beq     2f              | if so, do not do anything
        !          1629:        orl     d2,d3           | is delta == 1?
        !          1630:        bne     1f              | if so round to even
        !          1631:        movel   d1,d3           | 
        !          1632:        andl    IMM (2),d3      | bit 1 is the last significant bit
        !          1633:        movel   IMM (0),d2      |
        !          1634:        addl    d3,d1           |
        !          1635:        addxl   d2,d0           |
        !          1636:        bra     2f              | 
        !          1637: 1:     movel   IMM (1),d3      | else add 1 
        !          1638:        movel   IMM (0),d2      |
        !          1639:        addl    d3,d1           |
        !          1640:        addxl   d2,d0
        !          1641: | Shift right once (because we used bit #DBL_MANT_DIG-32!).
        !          1642: 2:     lsrl    IMM (1),d0
        !          1643:        roxrl   IMM (1),d1              
        !          1644: 
        !          1645: | Now check again bit #DBL_MANT_DIG-32 (rounding could have produced a
        !          1646: | 'fraction overflow' ...).
        !          1647:        btst    IMM (DBL_MANT_DIG-32),d0        
        !          1648:        beq     1f
        !          1649:        lsrl    IMM (1),d0
        !          1650:        roxrl   IMM (1),d1
        !          1651:        addw    IMM (1),d4
        !          1652: 1:
        !          1653: | If bit #DBL_MANT_DIG-32-1 is clear we have a denormalized number, so we 
        !          1654: | have to put the exponent to zero and return a denormalized number.
        !          1655:        btst    IMM (DBL_MANT_DIG-32-1),d0
        !          1656:        beq     1f
        !          1657:        jmp     a0@
        !          1658: 1:     movel   IMM (0),d4
        !          1659:        jmp     a0@
        !          1660: 
        !          1661: Lround$to$zero:
        !          1662: Lround$to$plus:
        !          1663: Lround$to$minus:
        !          1664:        jmp     a0@
        !          1665: #endif /* L_double */
        !          1666: 
        !          1667: #ifdef  L_float
        !          1668: 
        !          1669:        .globl  SYM (_fpCCR)
        !          1670:        .globl  $_exception_handler
        !          1671: 
        !          1672: QUIET_NaN    = 0xffffffff
        !          1673: SIGNL_NaN    = 0x7f800001
        !          1674: INFINITY     = 0x7f800000
        !          1675: 
        !          1676: F_MAX_EXP      = 0xff
        !          1677: F_BIAS         = 126
        !          1678: FLT_MAX_EXP    = F_MAX_EXP - F_BIAS
        !          1679: FLT_MIN_EXP    = 1 - F_BIAS
        !          1680: FLT_MANT_DIG   = 24
        !          1681: 
        !          1682: INEXACT_RESULT                 = 0x0001
        !          1683: UNDERFLOW              = 0x0002
        !          1684: OVERFLOW               = 0x0004
        !          1685: DIVIDE_BY_ZERO                 = 0x0008
        !          1686: INVALID_OPERATION      = 0x0010
        !          1687: 
        !          1688: SINGLE_FLOAT = 1
        !          1689: 
        !          1690: NOOP         = 0
        !          1691: ADD          = 1
        !          1692: MULTIPLY     = 2
        !          1693: DIVIDE       = 3
        !          1694: NEGATE       = 4
        !          1695: COMPARE      = 5
        !          1696: EXTENDSFDF   = 6
        !          1697: TRUNCDFSF    = 7
        !          1698: 
        !          1699: UNKNOWN           = -1
        !          1700: ROUND_TO_NEAREST  = 0 | round result to nearest representable value
        !          1701: ROUND_TO_ZERO     = 1 | round result towards zero
        !          1702: ROUND_TO_PLUS     = 2 | round result towards plus infinity
        !          1703: ROUND_TO_MINUS    = 3 | round result towards minus infinity
        !          1704: 
        !          1705: | Entry points:
        !          1706: 
        !          1707:        .globl SYM (__addsf3)
        !          1708:        .globl SYM (__subsf3)
        !          1709:        .globl SYM (__mulsf3)
        !          1710:        .globl SYM (__divsf3)
        !          1711:        .globl SYM (__negsf2)
        !          1712:        .globl SYM (__cmpsf2)
        !          1713: 
        !          1714: | These are common routines to return and signal exceptions.   
        !          1715: 
        !          1716:        .text
        !          1717:        .even
        !          1718: 
        !          1719: Lf$den:
        !          1720: | Return and signal a denormalized number
        !          1721:        orl     d7,d0
        !          1722:        movew   IMM (UNDERFLOW),d7
        !          1723:        orw     IMM (INEXACT_RESULT),d7
        !          1724:        movew   IMM (SINGLE_FLOAT),d6
        !          1725:        jmp     $_exception_handler
        !          1726: 
        !          1727: Lf$infty:
        !          1728: Lf$overflow:
        !          1729: | Return a properly signed INFINITY and set the exception flags 
        !          1730:        movel   IMM (INFINITY),d0
        !          1731:        orl     d7,d0
        !          1732:        movew   IMM (OVERFLOW),d7
        !          1733:        orw     IMM (INEXACT_RESULT),d7
        !          1734:        movew   IMM (SINGLE_FLOAT),d6
        !          1735:        jmp     $_exception_handler
        !          1736: 
        !          1737: Lf$underflow:
        !          1738: | Return 0 and set the exception flags 
        !          1739:        movel   IMM (0),d0
        !          1740:        movew   IMM (UNDERFLOW),d7
        !          1741:        orw     IMM (INEXACT_RESULT),d7
        !          1742:        movew   IMM (SINGLE_FLOAT),d6
        !          1743:        jmp     $_exception_handler
        !          1744: 
        !          1745: Lf$inop:
        !          1746: | Return a quiet NaN and set the exception flags
        !          1747:        movel   IMM (QUIET_NaN),d0
        !          1748:        movew   IMM (INVALID_OPERATION),d7
        !          1749:        orw     IMM (INEXACT_RESULT),d7
        !          1750:        movew   IMM (SINGLE_FLOAT),d6
        !          1751:        jmp     $_exception_handler
        !          1752: 
        !          1753: Lf$div$0:
        !          1754: | Return a properly signed INFINITY and set the exception flags
        !          1755:        movel   IMM (INFINITY),d0
        !          1756:        orl     d7,d0
        !          1757:        movew   IMM (DIVIDE_BY_ZERO),d7
        !          1758:        orw     IMM (INEXACT_RESULT),d7
        !          1759:        movew   IMM (SINGLE_FLOAT),d6
        !          1760:        jmp     $_exception_handler
        !          1761: 
        !          1762: |=============================================================================
        !          1763: |=============================================================================
        !          1764: |                         single precision routines
        !          1765: |=============================================================================
        !          1766: |=============================================================================
        !          1767: 
        !          1768: | A single precision floating point number (float) has the format:
        !          1769: |
        !          1770: | struct _float {
        !          1771: |  unsigned int sign      : 1;  /* sign bit */ 
        !          1772: |  unsigned int exponent  : 8;  /* exponent, shifted by 126 */
        !          1773: |  unsigned int fraction  : 23; /* fraction */
        !          1774: | } float;
        !          1775: | 
        !          1776: | Thus sizeof(float) = 4 (32 bits). 
        !          1777: |
        !          1778: | All the routines are callable from C programs, and return the result 
        !          1779: | in the single register d0. They also preserve all registers except 
        !          1780: | d0-d1 and a0-a1.
        !          1781: 
        !          1782: |=============================================================================
        !          1783: |                              __subsf3
        !          1784: |=============================================================================
        !          1785: 
        !          1786: | float __subsf3(float, float);
        !          1787: SYM (__subsf3):
        !          1788:        bchg    IMM (31),sp@(8) | change sign of second operand
        !          1789:                                | and fall through
        !          1790: |=============================================================================
        !          1791: |                              __addsf3
        !          1792: |=============================================================================
        !          1793: 
        !          1794: | float __addsf3(float, float);
        !          1795: SYM (__addsf3):
        !          1796:        link    a6,IMM (0)      | everything will be done in registers
        !          1797:        moveml  d2-d7,sp@-      | save all data registers but d0-d1
        !          1798:        movel   a6@(8),d0       | get first operand
        !          1799:        movel   a6@(12),d1      | get second operand
        !          1800:        movel   d0,d6           | get d0's sign bit '
        !          1801:        addl    d0,d0           | check and clear sign bit of a
        !          1802:        beq     Laddsf$b        | if zero return second operand
        !          1803:        movel   d1,d7           | save b's sign bit '
        !          1804:        addl    d1,d1           | get rid of sign bit
        !          1805:        beq     Laddsf$a        | if zero return first operand
        !          1806: 
        !          1807:        movel   d6,a0           | save signs in address registers
        !          1808:        movel   d7,a1           | so we can use d6 and d7
        !          1809: 
        !          1810: | Get the exponents and check for denormalized and/or infinity.
        !          1811: 
        !          1812:        movel   IMM (0x00ffffff),d4     | mask to get fraction
        !          1813:        movel   IMM (0x01000000),d5     | mask to put hidden bit back
        !          1814: 
        !          1815:        movel   d0,d6           | save a to get exponent
        !          1816:        andl    d4,d0           | get fraction in d0
        !          1817:        notl    d4              | make d4 into a mask for the exponent
        !          1818:        andl    d4,d6           | get exponent in d6
        !          1819:        beq     Laddsf$a$den    | branch if a is denormalized
        !          1820:        cmpl    d4,d6           | check for INFINITY or NaN
        !          1821:        beq     Laddsf$nf
        !          1822:        swap    d6              | put exponent into first word
        !          1823:        orl     d5,d0           | and put hidden bit back
        !          1824: Laddsf$1:
        !          1825: | Now we have a's exponent in d6 (second byte) and the mantissa in d0. '
        !          1826:        movel   d1,d7           | get exponent in d7
        !          1827:        andl    d4,d7           | 
        !          1828:        beq     Laddsf$b$den    | branch if b is denormalized
        !          1829:        cmpl    d4,d7           | check for INFINITY or NaN
        !          1830:        beq     Laddsf$nf
        !          1831:        swap    d7              | put exponent into first word
        !          1832:        notl    d4              | make d4 into a mask for the fraction
        !          1833:        andl    d4,d1           | get fraction in d1
        !          1834:        orl     d5,d1           | and put hidden bit back
        !          1835: Laddsf$2:
        !          1836: | Now we have b's exponent in d7 (second byte) and the mantissa in d1. '
        !          1837: 
        !          1838: | Note that the hidden bit corresponds to bit #FLT_MANT_DIG-1, and we 
        !          1839: | shifted right once, so bit #FLT_MANT_DIG is set (so we have one extra
        !          1840: | bit).
        !          1841: 
        !          1842:        movel   d1,d2           | move b to d2, since we want to use
        !          1843:                                | two registers to do the sum
        !          1844:        movel   IMM (0),d1      | and clear the new ones
        !          1845:        movel   d1,d3           |
        !          1846: 
        !          1847: | Here we shift the numbers in registers d0 and d1 so the exponents are the
        !          1848: | same, and put the largest exponent in d6. Note that we are using two
        !          1849: | registers for each number (see the discussion by D. Knuth in "Seminumerical 
        !          1850: | Algorithms").
        !          1851:        cmpw    d6,d7           | compare exponents
        !          1852:        beq     Laddsf$3        | if equal don't shift '
        !          1853:        bhi     5f              | branch if second exponent largest
        !          1854: 1:
        !          1855:        subl    d6,d7           | keep the largest exponent
        !          1856:        negl    d7
        !          1857:        lsrw    IMM (8),d7      | put difference in lower byte
        !          1858: | if difference is too large we don't shift (actually, we can just exit) '
        !          1859:        cmpw    IMM (FLT_MANT_DIG+2),d7         
        !          1860:        bge     Laddsf$b$small
        !          1861:        cmpw    IMM (16),d7     | if difference >= 16 swap
        !          1862:        bge     4f
        !          1863: 2:
        !          1864:        subw    IMM (1),d7
        !          1865: 3:     lsrl    IMM (1),d2      | shift right second operand
        !          1866:        roxrl   IMM (1),d3
        !          1867:        dbra    d7,3b
        !          1868:        bra     Laddsf$3
        !          1869: 4:
        !          1870:        movew   d2,d3
        !          1871:        swap    d3
        !          1872:        movew   d3,d2
        !          1873:        swap    d2
        !          1874:        subw    IMM (16),d7
        !          1875:        bne     2b              | if still more bits, go back to normal case
        !          1876:        bra     Laddsf$3
        !          1877: 5:
        !          1878:        exg     d6,d7           | exchange the exponents
        !          1879:        subl    d6,d7           | keep the largest exponent
        !          1880:        negl    d7              |
        !          1881:        lsrw    IMM (8),d7      | put difference in lower byte
        !          1882: | if difference is too large we don't shift (and exit!) '
        !          1883:        cmpw    IMM (FLT_MANT_DIG+2),d7         
        !          1884:        bge     Laddsf$a$small
        !          1885:        cmpw    IMM (16),d7     | if difference >= 16 swap
        !          1886:        bge     8f
        !          1887: 6:
        !          1888:        subw    IMM (1),d7
        !          1889: 7:     lsrl    IMM (1),d0      | shift right first operand
        !          1890:        roxrl   IMM (1),d1
        !          1891:        dbra    d7,7b
        !          1892:        bra     Laddsf$3
        !          1893: 8:
        !          1894:        movew   d0,d1
        !          1895:        swap    d1
        !          1896:        movew   d1,d0
        !          1897:        swap    d0
        !          1898:        subw    IMM (16),d7
        !          1899:        bne     6b              | if still more bits, go back to normal case
        !          1900:                                | otherwise we fall through
        !          1901: 
        !          1902: | Now we have a in d0-d1, b in d2-d3, and the largest exponent in d6 (the
        !          1903: | signs are stored in a0 and a1).
        !          1904: 
        !          1905: Laddsf$3:
        !          1906: | Here we have to decide whether to add or subtract the numbers
        !          1907:        exg     d6,a0           | get signs back
        !          1908:        exg     d7,a1           | and save the exponents
        !          1909:        eorl    d6,d7           | combine sign bits
        !          1910:        bmi     Lsubsf$0        | if negative a and b have opposite 
        !          1911:                                | sign so we actually subtract the
        !          1912:                                | numbers
        !          1913: 
        !          1914: | Here we have both positive or both negative
        !          1915:        exg     d6,a0           | now we have the exponent in d6
        !          1916:        movel   a0,d7           | and sign in d7
        !          1917:        andl    IMM (0x80000000),d7
        !          1918: | Here we do the addition.
        !          1919:        addl    d3,d1
        !          1920:        addxl   d2,d0
        !          1921: | Note: now we have d2, d3, d4 and d5 to play with! 
        !          1922: 
        !          1923: | Put the exponent, in the first byte, in d2, to use the "standard" rounding
        !          1924: | routines:
        !          1925:        movel   d6,d2
        !          1926:        lsrw    IMM (8),d2
        !          1927: 
        !          1928: | Before rounding normalize so bit #FLT_MANT_DIG is set (we will consider
        !          1929: | the case of denormalized numbers in the rounding routine itself).
        !          1930: | As in the addition (not in the subtraction!) we could have set 
        !          1931: | one more bit we check this:
        !          1932:        btst    IMM (FLT_MANT_DIG+1),d0 
        !          1933:        beq     1f
        !          1934:        lsrl    IMM (1),d0
        !          1935:        roxrl   IMM (1),d1
        !          1936:        addl    IMM (1),d2
        !          1937: 1:
        !          1938:        lea     Laddsf$4,a0     | to return from rounding routine
        !          1939:        lea     SYM (_fpCCR),a1 | check the rounding mode
        !          1940:        movew   a1@(6),d6       | rounding mode in d6
        !          1941:        beq     Lround$to$nearest
        !          1942:        cmpw    IMM (ROUND_TO_PLUS),d6
        !          1943:        bhi     Lround$to$minus
        !          1944:        blt     Lround$to$zero
        !          1945:        bra     Lround$to$plus
        !          1946: Laddsf$4:
        !          1947: | Put back the exponent, but check for overflow.
        !          1948:        cmpw    IMM (0xff),d2
        !          1949:        bhi     1f
        !          1950:        bclr    IMM (FLT_MANT_DIG-1),d0
        !          1951:        lslw    IMM (7),d2
        !          1952:        swap    d2
        !          1953:        orl     d2,d0
        !          1954:        bra     Laddsf$ret
        !          1955: 1:
        !          1956:        movew   IMM (ADD),d5
        !          1957:        bra     Lf$overflow
        !          1958: 
        !          1959: Lsubsf$0:
        !          1960: | We are here if a > 0 and b < 0 (sign bits cleared).
        !          1961: | Here we do the subtraction.
        !          1962:        movel   d6,d7           | put sign in d7
        !          1963:        andl    IMM (0x80000000),d7
        !          1964: 
        !          1965:        subl    d3,d1           | result in d0-d1
        !          1966:        subxl   d2,d0           |
        !          1967:        beq     Laddsf$ret      | if zero just exit
        !          1968:        bpl     1f              | if positive skip the following
        !          1969:        bchg    IMM (31),d7     | change sign bit in d7
        !          1970:        negl    d1
        !          1971:        negxl   d0
        !          1972: 1:
        !          1973:        exg     d2,a0           | now we have the exponent in d2
        !          1974:        lsrw    IMM (8),d2      | put it in the first byte
        !          1975: 
        !          1976: | Now d0-d1 is positive and the sign bit is in d7.
        !          1977: 
        !          1978: | Note that we do not have to normalize, since in the subtraction bit
        !          1979: | #FLT_MANT_DIG+1 is never set, and denormalized numbers are handled by
        !          1980: | the rounding routines themselves.
        !          1981:        lea     Lsubsf$1,a0     | to return from rounding routine
        !          1982:        lea     SYM (_fpCCR),a1 | check the rounding mode
        !          1983:        movew   a1@(6),d6       | rounding mode in d6
        !          1984:        beq     Lround$to$nearest
        !          1985:        cmpw    IMM (ROUND_TO_PLUS),d6
        !          1986:        bhi     Lround$to$minus
        !          1987:        blt     Lround$to$zero
        !          1988:        bra     Lround$to$plus
        !          1989: Lsubsf$1:
        !          1990: | Put back the exponent (we can't have overflow!). '
        !          1991:        bclr    IMM (FLT_MANT_DIG-1),d0
        !          1992:        lslw    IMM (7),d2
        !          1993:        swap    d2
        !          1994:        orl     d2,d0
        !          1995:        bra     Laddsf$ret
        !          1996: 
        !          1997: | If one of the numbers was too small (difference of exponents >= 
        !          1998: | FLT_MANT_DIG+2) we return the other (and now we don't have to '
        !          1999: | check for finiteness or zero).
        !          2000: Laddsf$a$small:
        !          2001:        movel   a6@(12),d0
        !          2002:        lea     SYM (_fpCCR),a0
        !          2003:        movew   IMM (0),a0@
        !          2004:        moveml  sp@+,d2-d7      | restore data registers
        !          2005:        unlk    a6              | and return
        !          2006:        rts
        !          2007: 
        !          2008: Laddsf$b$small:
        !          2009:        movel   a6@(8),d0
        !          2010:        lea     SYM (_fpCCR),a0
        !          2011:        movew   IMM (0),a0@
        !          2012:        moveml  sp@+,d2-d7      | restore data registers
        !          2013:        unlk    a6              | and return
        !          2014:        rts
        !          2015: 
        !          2016: | If the numbers are denormalized remember to put exponent equal to 1.
        !          2017: 
        !          2018: Laddsf$a$den:
        !          2019:        movel   d5,d6           | d5 contains 0x01000000
        !          2020:        swap    d6
        !          2021:        bra     Laddsf$1
        !          2022: 
        !          2023: Laddsf$b$den:
        !          2024:        movel   d5,d7
        !          2025:        swap    d7
        !          2026:        notl    d4              | make d4 into a mask for the fraction
        !          2027:                                | (this was not executed after the jump)
        !          2028:        bra     Laddsf$2
        !          2029: 
        !          2030: | The rest is mainly code for the different results which can be 
        !          2031: | returned (checking always for +/-INFINITY and NaN).
        !          2032: 
        !          2033: Laddsf$b:
        !          2034: | Return b (if a is zero).
        !          2035:        movel   a6@(12),d0
        !          2036:        bra     1f
        !          2037: Laddsf$a:
        !          2038: | Return a (if b is zero).
        !          2039:        movel   a6@(8),d0
        !          2040: 1:
        !          2041:        movew   IMM (ADD),d5
        !          2042: | We have to check for NaN and +/-infty.
        !          2043:        movel   d0,d7
        !          2044:        andl    IMM (0x80000000),d7     | put sign in d7
        !          2045:        bclr    IMM (31),d0             | clear sign
        !          2046:        cmpl    IMM (INFINITY),d0       | check for infty or NaN
        !          2047:        bge     2f
        !          2048:        movel   d0,d0           | check for zero (we do this because we don't '
        !          2049:        bne     Laddsf$ret      | want to return -0 by mistake
        !          2050:        bclr    IMM (31),d7     | if zero be sure to clear sign
        !          2051:        bra     Laddsf$ret      | if everything OK just return
        !          2052: 2:
        !          2053: | The value to be returned is either +/-infty or NaN
        !          2054:        andl    IMM (0x007fffff),d0     | check for NaN
        !          2055:        bne     Lf$inop                 | if mantissa not zero is NaN
        !          2056:        bra     Lf$infty
        !          2057: 
        !          2058: Laddsf$ret:
        !          2059: | Normal exit (a and b nonzero, result is not NaN nor +/-infty).
        !          2060: | We have to clear the exception flags (just the exception type).
        !          2061:        lea     SYM (_fpCCR),a0
        !          2062:        movew   IMM (0),a0@
        !          2063:        orl     d7,d0           | put sign bit
        !          2064:        moveml  sp@+,d2-d7      | restore data registers
        !          2065:        unlk    a6              | and return
        !          2066:        rts
        !          2067: 
        !          2068: Laddsf$ret$den:
        !          2069: | Return a denormalized number (for addition we don't signal underflow) '
        !          2070:        lsrl    IMM (1),d0      | remember to shift right back once
        !          2071:        bra     Laddsf$ret      | and return
        !          2072: 
        !          2073: | Note: when adding two floats of the same sign if either one is 
        !          2074: | NaN we return NaN without regard to whether the other is finite or 
        !          2075: | not. When subtracting them (i.e., when adding two numbers of 
        !          2076: | opposite signs) things are more complicated: if both are INFINITY 
        !          2077: | we return NaN, if only one is INFINITY and the other is NaN we return
        !          2078: | NaN, but if it is finite we return INFINITY with the corresponding sign.
        !          2079: 
        !          2080: Laddsf$nf:
        !          2081:        movew   IMM (ADD),d5
        !          2082: | This could be faster but it is not worth the effort, since it is not
        !          2083: | executed very often. We sacrifice speed for clarity here.
        !          2084:        movel   a6@(8),d0       | get the numbers back (remember that we
        !          2085:        movel   a6@(12),d1      | did some processing already)
        !          2086:        movel   IMM (INFINITY),d4 | useful constant (INFINITY)
        !          2087:        movel   d0,d2           | save sign bits
        !          2088:        movel   d1,d3
        !          2089:        bclr    IMM (31),d0     | clear sign bits
        !          2090:        bclr    IMM (31),d1
        !          2091: | We know that one of them is either NaN of +/-INFINITY
        !          2092: | Check for NaN (if either one is NaN return NaN)
        !          2093:        cmpl    d4,d0           | check first a (d0)
        !          2094:        bhi     Lf$inop         
        !          2095:        cmpl    d4,d1           | check now b (d1)
        !          2096:        bhi     Lf$inop         
        !          2097: | Now comes the check for +/-INFINITY. We know that both are (maybe not
        !          2098: | finite) numbers, but we have to check if both are infinite whether we
        !          2099: | are adding or subtracting them.
        !          2100:        eorl    d3,d2           | to check sign bits
        !          2101:        bmi     1f
        !          2102:        movel   d0,d7
        !          2103:        andl    IMM (0x80000000),d7     | get (common) sign bit
        !          2104:        bra     Lf$infty
        !          2105: 1:
        !          2106: | We know one (or both) are infinite, so we test for equality between the
        !          2107: | two numbers (if they are equal they have to be infinite both, so we
        !          2108: | return NaN).
        !          2109:        cmpl    d1,d0           | are both infinite?
        !          2110:        beq     Lf$inop         | if so return NaN
        !          2111: 
        !          2112:        movel   d0,d7
        !          2113:        andl    IMM (0x80000000),d7 | get a's sign bit '
        !          2114:        cmpl    d4,d0           | test now for infinity
        !          2115:        beq     Lf$infty        | if a is INFINITY return with this sign
        !          2116:        bchg    IMM (31),d7     | else we know b is INFINITY and has
        !          2117:        bra     Lf$infty        | the opposite sign
        !          2118: 
        !          2119: |=============================================================================
        !          2120: |                             __mulsf3
        !          2121: |=============================================================================
        !          2122: 
        !          2123: | float __mulsf3(float, float);
        !          2124: SYM (__mulsf3):
        !          2125:        link    a6,IMM (0)
        !          2126:        moveml  d2-d7,sp@-
        !          2127:        movel   a6@(8),d0       | get a into d0
        !          2128:        movel   a6@(12),d1      | and b into d1
        !          2129:        movel   d0,d7           | d7 will hold the sign of the product
        !          2130:        eorl    d1,d7           |
        !          2131:        andl    IMM (0x80000000),d7
        !          2132:        movel   IMM (INFINITY),d6       | useful constant (+INFINITY)
        !          2133:        movel   d6,d5                   | another (mask for fraction)
        !          2134:        notl    d5                      |
        !          2135:        movel   IMM (0x00800000),d4     | this is to put hidden bit back
        !          2136:        bclr    IMM (31),d0             | get rid of a's sign bit '
        !          2137:        movel   d0,d2                   |
        !          2138:        beq     Lmulsf$a$0              | branch if a is zero
        !          2139:        bclr    IMM (31),d1             | get rid of b's sign bit '
        !          2140:        movel   d1,d3           |
        !          2141:        beq     Lmulsf$b$0      | branch if b is zero
        !          2142:        cmpl    d6,d0           | is a big?
        !          2143:        bhi     Lmulsf$inop     | if a is NaN return NaN
        !          2144:        beq     Lmulsf$inf      | if a is INFINITY we have to check b
        !          2145:        cmpl    d6,d1           | now compare b with INFINITY
        !          2146:        bhi     Lmulsf$inop     | is b NaN?
        !          2147:        beq     Lmulsf$overflow | is b INFINITY?
        !          2148: | Here we have both numbers finite and nonzero (and with no sign bit).
        !          2149: | Now we get the exponents into d2 and d3.
        !          2150:        andl    d6,d2           | and isolate exponent in d2
        !          2151:        beq     Lmulsf$a$den    | if exponent is zero we have a denormalized
        !          2152:        andl    d5,d0           | and isolate fraction
        !          2153:        orl     d4,d0           | and put hidden bit back
        !          2154:        swap    d2              | I like exponents in the first byte
        !          2155:        lsrw    IMM (7),d2      | 
        !          2156: Lmulsf$1:                      | number
        !          2157:        andl    d6,d3           |
        !          2158:        beq     Lmulsf$b$den    |
        !          2159:        andl    d5,d1           |
        !          2160:        orl     d4,d1           |
        !          2161:        swap    d3              |
        !          2162:        lsrw    IMM (7),d3      |
        !          2163: Lmulsf$2:                      |
        !          2164:        addw    d3,d2           | add exponents
        !          2165:        subw    IMM (F_BIAS+1),d2 | and subtract bias (plus one)
        !          2166: 
        !          2167: | We are now ready to do the multiplication. The situation is as follows:
        !          2168: | both a and b have bit FLT_MANT_DIG-1 set (even if they were 
        !          2169: | denormalized to start with!), which means that in the product 
        !          2170: | bit 2*(FLT_MANT_DIG-1) (that is, bit 2*FLT_MANT_DIG-2-32 of the 
        !          2171: | high long) is set. 
        !          2172: 
        !          2173: | To do the multiplication let us move the number a little bit around ...
        !          2174:        movel   d1,d6           | second operand in d6
        !          2175:        movel   d0,d5           | first operand in d4-d5
        !          2176:        movel   IMM (0),d4
        !          2177:        movel   d4,d1           | the sums will go in d0-d1
        !          2178:        movel   d4,d0
        !          2179: 
        !          2180: | now bit FLT_MANT_DIG-1 becomes bit 31:
        !          2181:        lsll    IMM (31-FLT_MANT_DIG+1),d6              
        !          2182: 
        !          2183: | Start the loop (we loop #FLT_MANT_DIG times):
        !          2184:        movew   IMM (FLT_MANT_DIG-1),d3 
        !          2185: 1:     addl    d1,d1           | shift sum 
        !          2186:        addxl   d0,d0
        !          2187:        lsll    IMM (1),d6      | get bit bn
        !          2188:        bcc     2f              | if not set skip sum
        !          2189:        addl    d5,d1           | add a
        !          2190:        addxl   d4,d0
        !          2191: 2:     dbf     d3,1b           | loop back
        !          2192: 
        !          2193: | Now we have the product in d0-d1, with bit (FLT_MANT_DIG - 1) + FLT_MANT_DIG
        !          2194: | (mod 32) of d0 set. The first thing to do now is to normalize it so bit 
        !          2195: | FLT_MANT_DIG is set (to do the rounding).
        !          2196:        rorl    IMM (6),d1
        !          2197:        swap    d1
        !          2198:        movew   d1,d3
        !          2199:        andw    IMM (0x03ff),d3
        !          2200:        andw    IMM (0xfd00),d1
        !          2201:        lsll    IMM (8),d0
        !          2202:        addl    d0,d0
        !          2203:        addl    d0,d0
        !          2204:        orw     d3,d0
        !          2205: 
        !          2206:        movew   IMM (MULTIPLY),d5
        !          2207:        
        !          2208:        btst    IMM (FLT_MANT_DIG+1),d0
        !          2209:        beq     Lround$exit
        !          2210:        lsrl    IMM (1),d0
        !          2211:        roxrl   IMM (1),d1
        !          2212:        addw    IMM (1),d2
        !          2213:        bra     Lround$exit
        !          2214: 
        !          2215: Lmulsf$inop:
        !          2216:        movew   IMM (MULTIPLY),d5
        !          2217:        bra     Lf$inop
        !          2218: 
        !          2219: Lmulsf$overflow:
        !          2220:        movew   IMM (MULTIPLY),d5
        !          2221:        bra     Lf$overflow
        !          2222: 
        !          2223: Lmulsf$inf:
        !          2224:        movew   IMM (MULTIPLY),d5
        !          2225: | If either is NaN return NaN; else both are (maybe infinite) numbers, so
        !          2226: | return INFINITY with the correct sign (which is in d7).
        !          2227:        cmpl    d6,d1           | is b NaN?
        !          2228:        bhi     Lf$inop         | if so return NaN
        !          2229:        bra     Lf$overflow     | else return +/-INFINITY
        !          2230: 
        !          2231: | If either number is zero return zero, unless the other is +/-INFINITY, 
        !          2232: | or NaN, in which case we return NaN.
        !          2233: Lmulsf$b$0:
        !          2234: | Here d1 (==b) is zero.
        !          2235:        movel   d1,d0           | put b into d0 (just a zero)
        !          2236:        movel   a6@(8),d1       | get a again to check for non-finiteness
        !          2237:        bra     1f
        !          2238: Lmulsf$a$0:
        !          2239:        movel   a6@(12),d1      | get b again to check for non-finiteness
        !          2240: 1:     bclr    IMM (31),d1     | clear sign bit 
        !          2241:        cmpl    IMM (INFINITY),d1 | and check for a large exponent
        !          2242:        bge     Lf$inop         | if b is +/-INFINITY or NaN return NaN
        !          2243:        lea     SYM (_fpCCR),a0 | else return zero
        !          2244:        movew   IMM (0),a0@     | 
        !          2245:        moveml  sp@+,d2-d7      | 
        !          2246:        unlk    a6              | 
        !          2247:        rts                     | 
        !          2248: 
        !          2249: | If a number is denormalized we put an exponent of 1 but do not put the 
        !          2250: | hidden bit back into the fraction; instead we shift left until bit 23
        !          2251: | (the hidden bit) is set, adjusting the exponent accordingly. We do this
        !          2252: | to ensure that the product of the fractions is close to 1.
        !          2253: Lmulsf$a$den:
        !          2254:        movel   IMM (1),d2
        !          2255:        andl    d5,d0
        !          2256: 1:     addl    d0,d0           | shift a left (until bit 23 is set)
        !          2257:        subw    IMM (1),d2      | and adjust exponent
        !          2258:        btst    IMM (FLT_MANT_DIG-1),d0
        !          2259:        bne     Lmulsf$1        |
        !          2260:        bra     1b              | else loop back
        !          2261: 
        !          2262: Lmulsf$b$den:
        !          2263:        movel   IMM (1),d3
        !          2264:        andl    d5,d1
        !          2265: 1:     addl    d1,d1           | shift b left until bit 23 is set
        !          2266:        subw    IMM (1),d3      | and adjust exponent
        !          2267:        btst    IMM (FLT_MANT_DIG-1),d1
        !          2268:        bne     Lmulsf$2        |
        !          2269:        bra     1b              | else loop back
        !          2270: 
        !          2271: |=============================================================================
        !          2272: |                             __divsf3
        !          2273: |=============================================================================
        !          2274: 
        !          2275: | float __divsf3(float, float);
        !          2276: SYM (__divsf3):
        !          2277:        link    a6,IMM (0)
        !          2278:        moveml  d2-d7,sp@-
        !          2279:        movel   a6@(8),d0               | get a into d0
        !          2280:        movel   a6@(12),d1              | and b into d1
        !          2281:        movel   d0,d7                   | d7 will hold the sign of the result
        !          2282:        eorl    d1,d7                   |
        !          2283:        andl    IMM (0x80000000),d7     | 
        !          2284:        movel   IMM (INFINITY),d6       | useful constant (+INFINITY)
        !          2285:        movel   d6,d5                   | another (mask for fraction)
        !          2286:        notl    d5                      |
        !          2287:        movel   IMM (0x00800000),d4     | this is to put hidden bit back
        !          2288:        bclr    IMM (31),d0             | get rid of a's sign bit '
        !          2289:        movel   d0,d2                   |
        !          2290:        beq     Ldivsf$a$0              | branch if a is zero
        !          2291:        bclr    IMM (31),d1             | get rid of b's sign bit '
        !          2292:        movel   d1,d3                   |
        !          2293:        beq     Ldivsf$b$0              | branch if b is zero
        !          2294:        cmpl    d6,d0                   | is a big?
        !          2295:        bhi     Ldivsf$inop             | if a is NaN return NaN
        !          2296:        beq     Ldivsf$inf              | if a is INFINITY we have to check b
        !          2297:        cmpl    d6,d1                   | now compare b with INFINITY 
        !          2298:        bhi     Ldivsf$inop             | if b is NaN return NaN
        !          2299:        beq     Ldivsf$underflow
        !          2300: | Here we have both numbers finite and nonzero (and with no sign bit).
        !          2301: | Now we get the exponents into d2 and d3 and normalize the numbers to
        !          2302: | ensure that the ratio of the fractions is close to 1. We do this by
        !          2303: | making sure that bit #FLT_MANT_DIG-1 (hidden bit) is set.
        !          2304:        andl    d6,d2           | and isolate exponent in d2
        !          2305:        beq     Ldivsf$a$den    | if exponent is zero we have a denormalized
        !          2306:        andl    d5,d0           | and isolate fraction
        !          2307:        orl     d4,d0           | and put hidden bit back
        !          2308:        swap    d2              | I like exponents in the first byte
        !          2309:        lsrw    IMM (7),d2      | 
        !          2310: Ldivsf$1:                      | 
        !          2311:        andl    d6,d3           |
        !          2312:        beq     Ldivsf$b$den    |
        !          2313:        andl    d5,d1           |
        !          2314:        orl     d4,d1           |
        !          2315:        swap    d3              |
        !          2316:        lsrw    IMM (7),d3      |
        !          2317: Ldivsf$2:                      |
        !          2318:        subw    d3,d2           | subtract exponents
        !          2319:        addw    IMM (F_BIAS),d2 | and add bias
        !          2320:  
        !          2321: | We are now ready to do the division. We have prepared things in such a way
        !          2322: | that the ratio of the fractions will be less than 2 but greater than 1/2.
        !          2323: | At this point the registers in use are:
        !          2324: | d0   holds a (first operand, bit FLT_MANT_DIG=0, bit FLT_MANT_DIG-1=1)
        !          2325: | d1   holds b (second operand, bit FLT_MANT_DIG=1)
        !          2326: | d2   holds the difference of the exponents, corrected by the bias
        !          2327: | d7   holds the sign of the ratio
        !          2328: | d4, d5, d6 hold some constants
        !          2329:        movel   d7,a0           | d6-d7 will hold the ratio of the fractions
        !          2330:        movel   IMM (0),d6      | 
        !          2331:        movel   d6,d7
        !          2332: 
        !          2333:        movew   IMM (FLT_MANT_DIG+1),d3
        !          2334: 1:     cmpl    d0,d1           | is a < b?
        !          2335:        bhi     2f              |
        !          2336:        bset    d3,d6           | set a bit in d6
        !          2337:        subl    d1,d0           | if a >= b  a <-- a-b
        !          2338:        beq     3f              | if a is zero, exit
        !          2339: 2:     addl    d0,d0           | multiply a by 2
        !          2340:        dbra    d3,1b
        !          2341: 
        !          2342: | Now we keep going to set the sticky bit ...
        !          2343:        movew   IMM (FLT_MANT_DIG),d3
        !          2344: 1:     cmpl    d0,d1
        !          2345:        ble     2f
        !          2346:        addl    d0,d0
        !          2347:        dbra    d3,1b
        !          2348:        movel   IMM (0),d1
        !          2349:        bra     3f
        !          2350: 2:     movel   IMM (0),d1
        !          2351:        subw    IMM (FLT_MANT_DIG),d3
        !          2352:        addw    IMM (31),d3
        !          2353:        bset    d3,d1
        !          2354: 3:
        !          2355:        movel   d6,d0           | put the ratio in d0-d1
        !          2356:        movel   a0,d7           | get sign back
        !          2357: 
        !          2358: | Because of the normalization we did before we are guaranteed that 
        !          2359: | d0 is smaller than 2^26 but larger than 2^24. Thus bit 26 is not set,
        !          2360: | bit 25 could be set, and if it is not set then bit 24 is necessarily set.
        !          2361:        btst    IMM (FLT_MANT_DIG+1),d0         
        !          2362:        beq     1f              | if it is not set, then bit 24 is set
        !          2363:        lsrl    IMM (1),d0      |
        !          2364:        addw    IMM (1),d2      |
        !          2365: 1:
        !          2366: | Now round, check for over- and underflow, and exit.
        !          2367:        movew   IMM (DIVIDE),d5
        !          2368:        bra     Lround$exit
        !          2369: 
        !          2370: Ldivsf$inop:
        !          2371:        movew   IMM (DIVIDE),d5
        !          2372:        bra     Lf$inop
        !          2373: 
        !          2374: Ldivsf$overflow:
        !          2375:        movew   IMM (DIVIDE),d5
        !          2376:        bra     Lf$overflow
        !          2377: 
        !          2378: Ldivsf$underflow:
        !          2379:        movew   IMM (DIVIDE),d5
        !          2380:        bra     Lf$underflow
        !          2381: 
        !          2382: Ldivsf$a$0:
        !          2383:        movew   IMM (DIVIDE),d5
        !          2384: | If a is zero check to see whether b is zero also. In that case return
        !          2385: | NaN; then check if b is NaN, and return NaN also in that case. Else
        !          2386: | return zero.
        !          2387:        andl    IMM (0x7fffffff),d1     | clear sign bit and test b
        !          2388:        beq     Lf$inop                 | if b is also zero return NaN
        !          2389:        cmpl    IMM (INFINITY),d1       | check for NaN
        !          2390:        bhi     Lf$inop                 | 
        !          2391:        movel   IMM (0),d0              | else return zero
        !          2392:        lea     SYM (_fpCCR),a0         |
        !          2393:        movew   IMM (0),a0@             |
        !          2394:        moveml  sp@+,d2-d7              | 
        !          2395:        unlk    a6                      | 
        !          2396:        rts                             | 
        !          2397:        
        !          2398: Ldivsf$b$0:
        !          2399:        movew   IMM (DIVIDE),d5
        !          2400: | If we got here a is not zero. Check if a is NaN; in that case return NaN,
        !          2401: | else return +/-INFINITY. Remember that a is in d0 with the sign bit 
        !          2402: | cleared already.
        !          2403:        cmpl    IMM (INFINITY),d0       | compare d0 with INFINITY
        !          2404:        bhi     Lf$inop                 | if larger it is NaN
        !          2405:        bra     Lf$div$0                | else signal DIVIDE_BY_ZERO
        !          2406: 
        !          2407: Ldivsf$inf:
        !          2408:        movew   IMM (DIVIDE),d5
        !          2409: | If a is INFINITY we have to check b
        !          2410:        cmpl    IMM (INFINITY),d1       | compare b with INFINITY 
        !          2411:        bge     Lf$inop                 | if b is NaN or INFINITY return NaN
        !          2412:        bra     Lf$overflow             | else return overflow
        !          2413: 
        !          2414: | If a number is denormalized we put an exponent of 1 but do not put the 
        !          2415: | bit back into the fraction.
        !          2416: Ldivsf$a$den:
        !          2417:        movel   IMM (1),d2
        !          2418:        andl    d5,d0
        !          2419: 1:     addl    d0,d0           | shift a left until bit FLT_MANT_DIG-1 is set
        !          2420:        subw    IMM (1),d2      | and adjust exponent
        !          2421:        btst    IMM (FLT_MANT_DIG-1),d0
        !          2422:        bne     Ldivsf$1
        !          2423:        bra     1b
        !          2424: 
        !          2425: Ldivsf$b$den:
        !          2426:        movel   IMM (1),d3
        !          2427:        andl    d5,d1
        !          2428: 1:     addl    d1,d1           | shift b left until bit FLT_MANT_DIG is set
        !          2429:        subw    IMM (1),d3      | and adjust exponent
        !          2430:        btst    IMM (FLT_MANT_DIG-1),d1
        !          2431:        bne     Ldivsf$2
        !          2432:        bra     1b
        !          2433: 
        !          2434: Lround$exit:
        !          2435: | This is a common exit point for __mulsf3 and __divsf3. 
        !          2436: 
        !          2437: | First check for underlow in the exponent:
        !          2438:        cmpw    IMM (-FLT_MANT_DIG-1),d2                
        !          2439:        blt     Lf$underflow    
        !          2440: | It could happen that the exponent is less than 1, in which case the 
        !          2441: | number is denormalized. In this case we shift right and adjust the 
        !          2442: | exponent until it becomes 1 or the fraction is zero (in the latter case 
        !          2443: | we signal underflow and return zero).
        !          2444:        movel   IMM (0),d6      | d6 is used temporarily
        !          2445:        cmpw    IMM (1),d2      | if the exponent is less than 1 we 
        !          2446:        bge     2f              | have to shift right (denormalize)
        !          2447: 1:     addw    IMM (1),d2      | adjust the exponent
        !          2448:        lsrl    IMM (1),d0      | shift right once 
        !          2449:        roxrl   IMM (1),d1      |
        !          2450:        roxrl   IMM (1),d6      | d6 collect bits we would lose otherwise
        !          2451:        cmpw    IMM (1),d2      | is the exponent 1 already?
        !          2452:        beq     2f              | if not loop back
        !          2453:        bra     1b              |
        !          2454:        bra     Lf$underflow    | safety check, shouldn't execute '
        !          2455: 2:     orl     d6,d1           | this is a trick so we don't lose  '
        !          2456:                                | the extra bits which were flushed right
        !          2457: | Now call the rounding routine (which takes care of denormalized numbers):
        !          2458:        lea     Lround$0,a0     | to return from rounding routine
        !          2459:        lea     SYM (_fpCCR),a1 | check the rounding mode
        !          2460:        movew   a1@(6),d6       | rounding mode in d6
        !          2461:        beq     Lround$to$nearest
        !          2462:        cmpw    IMM (ROUND_TO_PLUS),d6
        !          2463:        bhi     Lround$to$minus
        !          2464:        blt     Lround$to$zero
        !          2465:        bra     Lround$to$plus
        !          2466: Lround$0:
        !          2467: | Here we have a correctly rounded result (either normalized or denormalized).
        !          2468: 
        !          2469: | Here we should have either a normalized number or a denormalized one, and
        !          2470: | the exponent is necessarily larger or equal to 1 (so we don't have to  '
        !          2471: | check again for underflow!). We have to check for overflow or for a 
        !          2472: | denormalized number (which also signals underflow).
        !          2473: | Check for overflow (i.e., exponent >= 255).
        !          2474:        cmpw    IMM (0x00ff),d2
        !          2475:        bge     Lf$overflow
        !          2476: | Now check for a denormalized number (exponent==0).
        !          2477:        movew   d2,d2
        !          2478:        beq     Lf$den
        !          2479: 1:
        !          2480: | Put back the exponents and sign and return.
        !          2481:        lslw    IMM (7),d2      | exponent back to fourth byte
        !          2482:        bclr    IMM (FLT_MANT_DIG-1),d0
        !          2483:        swap    d0              | and put back exponent
        !          2484:        orw     d2,d0           | 
        !          2485:        swap    d0              |
        !          2486:        orl     d7,d0           | and sign also
        !          2487: 
        !          2488:        lea     SYM (_fpCCR),a0
        !          2489:        movew   IMM (0),a0@
        !          2490:        moveml  sp@+,d2-d7
        !          2491:        unlk    a6
        !          2492:        rts
        !          2493: 
        !          2494: |=============================================================================
        !          2495: |                             __negsf2
        !          2496: |=============================================================================
        !          2497: 
        !          2498: | This is trivial and could be shorter if we didn't bother checking for NaN '
        !          2499: | and +/-INFINITY.
        !          2500: 
        !          2501: | float __negsf2(float);
        !          2502: SYM (__negsf2):
        !          2503:        link    a6,IMM (0)
        !          2504:        moveml  d2-d7,sp@-
        !          2505:        movew   IMM (NEGATE),d5
        !          2506:        movel   a6@(8),d0       | get number to negate in d0
        !          2507:        bchg    IMM (31),d0     | negate
        !          2508:        movel   d0,d1           | make a positive copy
        !          2509:        bclr    IMM (31),d1     |
        !          2510:        tstl    d1              | check for zero
        !          2511:        beq     2f              | if zero (either sign) return +zero
        !          2512:        cmpl    IMM (INFINITY),d1 | compare to +INFINITY
        !          2513:        blt     1f              |
        !          2514:        bhi     Lf$inop         | if larger (fraction not zero) is NaN
        !          2515:        movel   d0,d7           | else get sign and return INFINITY
        !          2516:        andl    IMM (0x80000000),d7
        !          2517:        bra     Lf$infty                
        !          2518: 1:     lea     SYM (_fpCCR),a0
        !          2519:        movew   IMM (0),a0@
        !          2520:        moveml  sp@+,d2-d7
        !          2521:        unlk    a6
        !          2522:        rts
        !          2523: 2:     bclr    IMM (31),d0
        !          2524:        bra     1b
        !          2525: 
        !          2526: |=============================================================================
        !          2527: |                             __cmpsf2
        !          2528: |=============================================================================
        !          2529: 
        !          2530: GREATER =  1
        !          2531: LESS    = -1
        !          2532: EQUAL   =  0
        !          2533: 
        !          2534: | int __cmpsf2(float, float);
        !          2535: SYM (__cmpsf2):
        !          2536:        link    a6,IMM (0)
        !          2537:        moveml  d2-d7,sp@-      | save registers
        !          2538:        movew   IMM (COMPARE),d5
        !          2539:        movel   a6@(8),d0       | get first operand
        !          2540:        movel   a6@(12),d1      | get second operand
        !          2541: | Check if either is NaN, and in that case return garbage and signal
        !          2542: | INVALID_OPERATION. Check also if either is zero, and clear the signs
        !          2543: | if necessary.
        !          2544:        movel   d0,d6
        !          2545:        andl    IMM (0x7fffffff),d0
        !          2546:        beq     Lcmpsf$a$0
        !          2547:        cmpl    IMM (0x7f800000),d0
        !          2548:        bhi     Lf$inop
        !          2549: Lcmpsf$1:
        !          2550:        movel   d1,d7
        !          2551:        andl    IMM (0x7fffffff),d1
        !          2552:        beq     Lcmpsf$b$0
        !          2553:        cmpl    IMM (0x7f800000),d1
        !          2554:        bhi     Lf$inop
        !          2555: Lcmpsf$2:
        !          2556: | Check the signs
        !          2557:        eorl    d6,d7
        !          2558:        bpl     1f
        !          2559: | If the signs are not equal check if a >= 0
        !          2560:        tstl    d6
        !          2561:        bpl     Lcmpsf$a$gt$b   | if (a >= 0 && b < 0) => a > b
        !          2562:        bmi     Lcmpsf$b$gt$a   | if (a < 0 && b >= 0) => a < b
        !          2563: 1:
        !          2564: | If the signs are equal check for < 0
        !          2565:        tstl    d6
        !          2566:        bpl     1f
        !          2567: | If both are negative exchange them
        !          2568:        exg     d0,d1
        !          2569: 1:
        !          2570: | Now that they are positive we just compare them as longs (does this also
        !          2571: | work for denormalized numbers?).
        !          2572:        cmpl    d0,d1
        !          2573:        bhi     Lcmpsf$b$gt$a   | |b| > |a|
        !          2574:        bne     Lcmpsf$a$gt$b   | |b| < |a|
        !          2575: | If we got here a == b.
        !          2576:        movel   IMM (EQUAL),d0
        !          2577:        moveml  sp@+,d2-d7      | put back the registers
        !          2578:        unlk    a6
        !          2579:        rts
        !          2580: Lcmpsf$a$gt$b:
        !          2581:        movel   IMM (GREATER),d0
        !          2582:        moveml  sp@+,d2-d7      | put back the registers
        !          2583:        unlk    a6
        !          2584:        rts
        !          2585: Lcmpsf$b$gt$a:
        !          2586:        movel   IMM (LESS),d0
        !          2587:        moveml  sp@+,d2-d7      | put back the registers
        !          2588:        unlk    a6
        !          2589:        rts
        !          2590: 
        !          2591: Lcmpsf$a$0:    
        !          2592:        bclr    IMM (31),d6
        !          2593:        bra     Lcmpsf$1
        !          2594: Lcmpsf$b$0:
        !          2595:        bclr    IMM (31),d7
        !          2596:        bra     Lcmpsf$2
        !          2597: 
        !          2598: |=============================================================================
        !          2599: |                           rounding routines
        !          2600: |=============================================================================
        !          2601: 
        !          2602: | The rounding routines expect the number to be normalized in registers
        !          2603: | d0-d1, with the exponent in register d2. They assume that the 
        !          2604: | exponent is larger or equal to 1. They return a properly normalized number
        !          2605: | if possible, and a denormalized number otherwise. The exponent is returned
        !          2606: | in d2.
        !          2607: 
        !          2608: Lround$to$nearest:
        !          2609: | We now normalize as suggested by D. Knuth ("Seminumerical Algorithms"):
        !          2610: | Here we assume that the exponent is not too small (this should be checked
        !          2611: | before entering the rounding routine), but the number could be denormalized.
        !          2612: 
        !          2613: | Check for denormalized numbers:
        !          2614: 1:     btst    IMM (FLT_MANT_DIG),d0
        !          2615:        bne     2f              | if set the number is normalized
        !          2616: | Normalize shifting left until bit #FLT_MANT_DIG is set or the exponent 
        !          2617: | is one (remember that a denormalized number corresponds to an 
        !          2618: | exponent of -F_BIAS+1).
        !          2619:        cmpw    IMM (1),d2      | remember that the exponent is at least one
        !          2620:        beq     2f              | an exponent of one means denormalized
        !          2621:        addl    d1,d1           | else shift and adjust the exponent
        !          2622:        addxl   d0,d0           |
        !          2623:        dbra    d2,1b           |
        !          2624: 2:
        !          2625: | Now round: we do it as follows: after the shifting we can write the
        !          2626: | fraction part as f + delta, where 1 < f < 2^25, and 0 <= delta <= 2.
        !          2627: | If delta < 1, do nothing. If delta > 1, add 1 to f. 
        !          2628: | If delta == 1, we make sure the rounded number will be even (odd?) 
        !          2629: | (after shifting).
        !          2630:        btst    IMM (0),d0      | is delta < 1?
        !          2631:        beq     2f              | if so, do not do anything
        !          2632:        tstl    d1              | is delta == 1?
        !          2633:        bne     1f              | if so round to even
        !          2634:        movel   d0,d1           | 
        !          2635:        andl    IMM (2),d1      | bit 1 is the last significant bit
        !          2636:        addl    d1,d0           | 
        !          2637:        bra     2f              | 
        !          2638: 1:     movel   IMM (1),d1      | else add 1 
        !          2639:        addl    d1,d0           |
        !          2640: | Shift right once (because we used bit #FLT_MANT_DIG!).
        !          2641: 2:     lsrl    IMM (1),d0              
        !          2642: | Now check again bit #FLT_MANT_DIG (rounding could have produced a
        !          2643: | 'fraction overflow' ...).
        !          2644:        btst    IMM (FLT_MANT_DIG),d0   
        !          2645:        beq     1f
        !          2646:        lsrl    IMM (1),d0
        !          2647:        addw    IMM (1),d2
        !          2648: 1:
        !          2649: | If bit #FLT_MANT_DIG-1 is clear we have a denormalized number, so we 
        !          2650: | have to put the exponent to zero and return a denormalized number.
        !          2651:        btst    IMM (FLT_MANT_DIG-1),d0
        !          2652:        beq     1f
        !          2653:        jmp     a0@
        !          2654: 1:     movel   IMM (0),d2
        !          2655:        jmp     a0@
        !          2656: 
        !          2657: Lround$to$zero:
        !          2658: Lround$to$plus:
        !          2659: Lround$to$minus:
        !          2660:        jmp     a0@
        !          2661: #endif /* L_float */
        !          2662: 
        !          2663: | gcc expects the routines __eqdf2, __nedf2, __gtdf2, __gedf2,
        !          2664: | __ledf2, __ltdf2 to all return the same value as a direct call to
        !          2665: | __cmpdf2 would.  In this implementation, each of these routines
        !          2666: | simply calls __cmpdf2.  It would be more efficient to give the
        !          2667: | __cmpdf2 routine several names, but separating them out will make it
        !          2668: | easier to write efficient versions of these routines someday.
        !          2669: 
        !          2670: #ifdef  L_eqdf2
        !          2671: LL0:
        !          2672:        .text
        !          2673:        .proc
        !          2674: |#PROC# 04
        !          2675:        LF18    =       4
        !          2676:        LS18    =       128
        !          2677:        LFF18   =       0
        !          2678:        LSS18   =       0
        !          2679:        LV18    =       0
        !          2680:        .text
        !          2681:        .globl  SYM (__eqdf2)
        !          2682: SYM (__eqdf2):
        !          2683: |#PROLOGUE# 0
        !          2684:        link    a6,IMM (0)
        !          2685: |#PROLOGUE# 1
        !          2686:        movl    a6@(20),sp@-
        !          2687:        movl    a6@(16),sp@-
        !          2688:        movl    a6@(12),sp@-
        !          2689:        movl    a6@(8),sp@-
        !          2690:        jbsr    SYM (__cmpdf2)
        !          2691: |#PROLOGUE# 2
        !          2692:        unlk    a6
        !          2693: |#PROLOGUE# 3
        !          2694:        rts
        !          2695: #endif /* L_eqdf2 */
        !          2696: 
        !          2697: #ifdef  L_nedf2
        !          2698: LL0:
        !          2699:        .text
        !          2700:        .proc
        !          2701: |#PROC# 04
        !          2702:        LF18    =       8
        !          2703:        LS18    =       132
        !          2704:        LFF18   =       0
        !          2705:        LSS18   =       0
        !          2706:        LV18    =       0
        !          2707:        .text
        !          2708:        .globl  SYM (__nedf2)
        !          2709: SYM (__nedf2):
        !          2710: |#PROLOGUE# 0
        !          2711:        link    a6,IMM (0)
        !          2712: |#PROLOGUE# 1
        !          2713:        movl    a6@(20),sp@-
        !          2714:        movl    a6@(16),sp@-
        !          2715:        movl    a6@(12),sp@-
        !          2716:        movl    a6@(8),sp@-
        !          2717:        jbsr    SYM (__cmpdf2)
        !          2718: |#PROLOGUE# 2
        !          2719:        unlk    a6
        !          2720: |#PROLOGUE# 3
        !          2721:        rts
        !          2722: #endif /* L_nedf2 */
        !          2723: 
        !          2724: #ifdef  L_gtdf2
        !          2725:        .text
        !          2726:        .proc
        !          2727: |#PROC# 04
        !          2728:        LF18    =       8
        !          2729:        LS18    =       132
        !          2730:        LFF18   =       0
        !          2731:        LSS18   =       0
        !          2732:        LV18    =       0
        !          2733:        .text
        !          2734:        .globl  SYM (__gtdf2)
        !          2735: SYM (__gtdf2):
        !          2736: |#PROLOGUE# 0
        !          2737:        link    a6,IMM (0)
        !          2738: |#PROLOGUE# 1
        !          2739:        movl    a6@(20),sp@-
        !          2740:        movl    a6@(16),sp@-
        !          2741:        movl    a6@(12),sp@-
        !          2742:        movl    a6@(8),sp@-
        !          2743:        jbsr    SYM (__cmpdf2)
        !          2744: |#PROLOGUE# 2
        !          2745:        unlk    a6
        !          2746: |#PROLOGUE# 3
        !          2747:        rts
        !          2748: #endif /* L_gtdf2 */
        !          2749: 
        !          2750: #ifdef  L_gedf2
        !          2751: LL0:
        !          2752:        .text
        !          2753:        .proc
        !          2754: |#PROC# 04
        !          2755:        LF18    =       8
        !          2756:        LS18    =       132
        !          2757:        LFF18   =       0
        !          2758:        LSS18   =       0
        !          2759:        LV18    =       0
        !          2760:        .text
        !          2761:        .globl  SYM (__gedf2)
        !          2762: SYM (__gedf2):
        !          2763: |#PROLOGUE# 0
        !          2764:        link    a6,IMM (0)
        !          2765: |#PROLOGUE# 1
        !          2766:        movl    a6@(20),sp@-
        !          2767:        movl    a6@(16),sp@-
        !          2768:        movl    a6@(12),sp@-
        !          2769:        movl    a6@(8),sp@-
        !          2770:        jbsr    SYM (__cmpdf2)
        !          2771: |#PROLOGUE# 2
        !          2772:        unlk    a6
        !          2773: |#PROLOGUE# 3
        !          2774:        rts
        !          2775: #endif /* L_gedf2 */
        !          2776: 
        !          2777: #ifdef  L_ltdf2
        !          2778: LL0:
        !          2779:        .text
        !          2780:        .proc
        !          2781: |#PROC# 04
        !          2782:        LF18    =       8
        !          2783:        LS18    =       132
        !          2784:        LFF18   =       0
        !          2785:        LSS18   =       0
        !          2786:        LV18    =       0
        !          2787:        .text
        !          2788:        .globl  SYM (__ltdf2)
        !          2789: SYM (__ltdf2):
        !          2790: |#PROLOGUE# 0
        !          2791:        link    a6,IMM (0)
        !          2792: |#PROLOGUE# 1
        !          2793:        movl    a6@(20),sp@-
        !          2794:        movl    a6@(16),sp@-
        !          2795:        movl    a6@(12),sp@-
        !          2796:        movl    a6@(8),sp@-
        !          2797:        jbsr    SYM (__cmpdf2)
        !          2798: |#PROLOGUE# 2
        !          2799:        unlk    a6
        !          2800: |#PROLOGUE# 3
        !          2801:        rts
        !          2802: #endif /* L_ltdf2 */
        !          2803: 
        !          2804: #ifdef  L_ledf2
        !          2805:        .text
        !          2806:        .proc
        !          2807: |#PROC# 04
        !          2808:        LF18    =       8
        !          2809:        LS18    =       132
        !          2810:        LFF18   =       0
        !          2811:        LSS18   =       0
        !          2812:        LV18    =       0
        !          2813:        .text
        !          2814:        .globl  SYM (__ledf2)
        !          2815: SYM (__ledf2):
        !          2816: |#PROLOGUE# 0
        !          2817:        link    a6,IMM (0)
        !          2818: |#PROLOGUE# 1
        !          2819:        movl    a6@(20),sp@-
        !          2820:        movl    a6@(16),sp@-
        !          2821:        movl    a6@(12),sp@-
        !          2822:        movl    a6@(8),sp@-
        !          2823:        jbsr    SYM (__cmpdf2)
        !          2824: |#PROLOGUE# 2
        !          2825:        unlk    a6
        !          2826: |#PROLOGUE# 3
        !          2827:        rts
        !          2828: #endif /* L_ledf2 */
        !          2829: 
        !          2830: | The comments above about __eqdf2, et. al., also apply to __eqsf2,
        !          2831: | et. al., except that the latter call __cmpsf2 rather than __cmpdf2.
        !          2832: 
        !          2833: #ifdef  L_eqsf2
        !          2834:        .text
        !          2835:        .proc
        !          2836: |#PROC# 04
        !          2837:        LF18    =       4
        !          2838:        LS18    =       128
        !          2839:        LFF18   =       0
        !          2840:        LSS18   =       0
        !          2841:        LV18    =       0
        !          2842:        .text
        !          2843:        .globl  SYM (__eqsf2)
        !          2844: SYM (__eqsf2):
        !          2845: |#PROLOGUE# 0
        !          2846:        link    a6,IMM (0)
        !          2847: |#PROLOGUE# 1
        !          2848:        movl    a6@(12),sp@-
        !          2849:        movl    a6@(8),sp@-
        !          2850:        jbsr    SYM (__cmpsf2)
        !          2851: |#PROLOGUE# 2
        !          2852:        unlk    a6
        !          2853: |#PROLOGUE# 3
        !          2854:        rts
        !          2855: #endif /* L_eqsf2 */
        !          2856: 
        !          2857: #ifdef  L_nesf2
        !          2858:        .text
        !          2859:        .proc
        !          2860: |#PROC# 04
        !          2861:        LF18    =       8
        !          2862:        LS18    =       132
        !          2863:        LFF18   =       0
        !          2864:        LSS18   =       0
        !          2865:        LV18    =       0
        !          2866:        .text
        !          2867:        .globl  SYM (__nesf2)
        !          2868: SYM (__nesf2):
        !          2869: |#PROLOGUE# 0
        !          2870:        link    a6,IMM (0)
        !          2871: |#PROLOGUE# 1
        !          2872:        movl    a6@(12),sp@-
        !          2873:        movl    a6@(8),sp@-
        !          2874:        jbsr    SYM (__cmpsf2)
        !          2875: |#PROLOGUE# 2
        !          2876:        unlk    a6
        !          2877: |#PROLOGUE# 3
        !          2878:        rts
        !          2879: #endif /* L_nesf2 */
        !          2880: 
        !          2881: #ifdef  L_gtsf2
        !          2882:        .text
        !          2883:        .proc
        !          2884: |#PROC# 04
        !          2885:        LF18    =       8
        !          2886:        LS18    =       132
        !          2887:        LFF18   =       0
        !          2888:        LSS18   =       0
        !          2889:        LV18    =       0
        !          2890:        .text
        !          2891:        .globl  SYM (__gtsf2)
        !          2892: SYM (__gtsf2):
        !          2893: |#PROLOGUE# 0
        !          2894:        link    a6,IMM (0)
        !          2895: |#PROLOGUE# 1
        !          2896:        movl    a6@(12),sp@-
        !          2897:        movl    a6@(8),sp@-
        !          2898:        jbsr    SYM (__cmpsf2)
        !          2899: |#PROLOGUE# 2
        !          2900:        unlk    a6
        !          2901: |#PROLOGUE# 3
        !          2902:        rts
        !          2903: #endif /* L_gtsf2 */
        !          2904: 
        !          2905: #ifdef  L_gesf2
        !          2906:        .text
        !          2907:        .proc
        !          2908: |#PROC# 04
        !          2909:        LF18    =       8
        !          2910:        LS18    =       132
        !          2911:        LFF18   =       0
        !          2912:        LSS18   =       0
        !          2913:        LV18    =       0
        !          2914:        .text
        !          2915:        .globl  SYM (__gesf2)
        !          2916: SYM (__gesf2):
        !          2917: |#PROLOGUE# 0
        !          2918:        link    a6,IMM (0)
        !          2919: |#PROLOGUE# 1
        !          2920:        movl    a6@(12),sp@-
        !          2921:        movl    a6@(8),sp@-
        !          2922:        jbsr    SYM (__cmpsf2)
        !          2923: |#PROLOGUE# 2
        !          2924:        unlk    a6
        !          2925: |#PROLOGUE# 3
        !          2926:        rts
        !          2927: #endif /* L_gesf2 */
        !          2928: 
        !          2929: #ifdef  L_ltsf2
        !          2930:        .text
        !          2931:        .proc
        !          2932: |#PROC# 04
        !          2933:        LF18    =       8
        !          2934:        LS18    =       132
        !          2935:        LFF18   =       0
        !          2936:        LSS18   =       0
        !          2937:        LV18    =       0
        !          2938:        .text
        !          2939:        .globl  SYM (__ltsf2)
        !          2940: SYM (__ltsf2):
        !          2941: |#PROLOGUE# 0
        !          2942:        link    a6,IMM (0)
        !          2943: |#PROLOGUE# 1
        !          2944:        movl    a6@(12),sp@-
        !          2945:        movl    a6@(8),sp@-
        !          2946:        jbsr    SYM (__cmpsf2)
        !          2947: |#PROLOGUE# 2
        !          2948:        unlk    a6
        !          2949: |#PROLOGUE# 3
        !          2950:        rts
        !          2951: #endif /* L_ltsf2 */
        !          2952: 
        !          2953: #ifdef  L_lesf2
        !          2954:        .text
        !          2955:        .proc
        !          2956: |#PROC# 04
        !          2957:        LF18    =       8
        !          2958:        LS18    =       132
        !          2959:        LFF18   =       0
        !          2960:        LSS18   =       0
        !          2961:        LV18    =       0
        !          2962:        .text
        !          2963:        .globl  SYM (__lesf2)
        !          2964: SYM (__lesf2):
        !          2965: |#PROLOGUE# 0
        !          2966:        link    a6,IMM (0)
        !          2967: |#PROLOGUE# 1
        !          2968:        movl    a6@(12),sp@-
        !          2969:        movl    a6@(8),sp@-
        !          2970:        jbsr    SYM (__cmpsf2)
        !          2971: |#PROLOGUE# 2
        !          2972:        unlk    a6
        !          2973: |#PROLOGUE# 3
        !          2974:        rts
        !          2975: #endif /* L_lesf2 */
        !          2976: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.