[BACK]Return to bindec.sa CVS log [TXT][DIR] Up to [local] / sys / arch / m68k / fpsp

Annotation of sys/arch/m68k/fpsp/bindec.sa, Revision 1.1.1.1

1.1       nbrk        1: *      $OpenBSD: bindec.sa,v 1.3 2001/09/20 17:02:30 mpech Exp $
                      2: *      $NetBSD: bindec.sa,v 1.3 1994/10/26 07:48:51 cgd Exp $
                      3:
                      4: *      MOTOROLA MICROPROCESSOR & MEMORY TECHNOLOGY GROUP
                      5: *      M68000 Hi-Performance Microprocessor Division
                      6: *      M68040 Software Package
                      7: *
                      8: *      M68040 Software Package Copyright (c) 1993, 1994 Motorola Inc.
                      9: *      All rights reserved.
                     10: *
                     11: *      THE SOFTWARE is provided on an "AS IS" basis and without warranty.
                     12: *      To the maximum extent permitted by applicable law,
                     13: *      MOTOROLA DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
                     14: *      INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
                     15: *      PARTICULAR PURPOSE and any warranty against infringement with
                     16: *      regard to the SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
                     17: *      and any accompanying written materials.
                     18: *
                     19: *      To the maximum extent permitted by applicable law,
                     20: *      IN NO EVENT SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER
                     21: *      (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS
                     22: *      PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR
                     23: *      OTHER PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE
                     24: *      SOFTWARE.  Motorola assumes no responsibility for the maintenance
                     25: *      and support of the SOFTWARE.
                     26: *
                     27: *      You are hereby granted a copyright license to use, modify, and
                     28: *      distribute the SOFTWARE so long as this entire notice is retained
                     29: *      without alteration in any modified and/or redistributed versions,
                     30: *      and that such modified versions are clearly identified as such.
                     31: *      No licenses are granted by implication, estoppel or otherwise
                     32: *      under any patents or trademarks of Motorola, Inc.
                     33:
                     34: *
                     35: *      bindec.sa 3.4 1/3/91
                     36: *
                     37: *      bindec
                     38: *
                     39: *      Description:
                     40: *              Converts an input in extended precision format
                     41: *              to bcd format.
                     42: *
                     43: *      Input:
                     44: *              a0 points to the input extended precision value
                     45: *              value in memory; d0 contains the k-factor sign-extended
                     46: *              to 32-bits.  The input may be either normalized,
                     47: *              unnormalized, or denormalized.
                     48: *
                     49: *      Output: result in the FP_SCR1 space on the stack.
                     50: *
                     51: *      Saves and Modifies: D2-D7,A2,FP2
                     52: *
                     53: *      Algorithm:
                     54: *
                     55: *      A1.     Set RM and size ext;  Set SIGMA = sign of input.
                     56: *              The k-factor is saved for use in d7. Clear the
                     57: *              BINDEC_FLG for separating normalized/denormalized
                     58: *              input.  If input is unnormalized or denormalized,
                     59: *              normalize it.
                     60: *
                     61: *      A2.     Set X = abs(input).
                     62: *
                     63: *      A3.     Compute ILOG.
                     64: *              ILOG is the log base 10 of the input value.  It is
                     65: *              approximated by adding e + 0.f when the original
                     66: *              value is viewed as 2^^e * 1.f in extended precision.
                     67: *              This value is stored in d6.
                     68: *
                     69: *      A4.     Clr INEX bit.
                     70: *              The operation in A3 above may have set INEX2.
                     71: *
                     72: *      A5.     Set ICTR = 0;
                     73: *              ICTR is a flag used in A13.  It must be set before the
                     74: *              loop entry A6.
                     75: *
                     76: *      A6.     Calculate LEN.
                     77: *              LEN is the number of digits to be displayed.  The
                     78: *              k-factor can dictate either the total number of digits,
                     79: *              if it is a positive number, or the number of digits
                     80: *              after the decimal point which are to be included as
                     81: *              significant.  See the 68882 manual for examples.
                     82: *              If LEN is computed to be greater than 17, set OPERR in
                     83: *              USER_FPSR.  LEN is stored in d4.
                     84: *
                     85: *      A7.     Calculate SCALE.
                     86: *              SCALE is equal to 10^ISCALE, where ISCALE is the number
                     87: *              of decimal places needed to insure LEN integer digits
                     88: *              in the output before conversion to bcd. LAMBDA is the
                     89: *              sign of ISCALE, used in A9. Fp1 contains
                     90: *              10^^(abs(ISCALE)) using a rounding mode which is a
                     91: *              function of the original rounding mode and the signs
                     92: *              of ISCALE and X.  A table is given in the code.
                     93: *
                     94: *      A8.     Clr INEX; Force RZ.
                     95: *              The operation in A3 above may have set INEX2.
                     96: *              RZ mode is forced for the scaling operation to insure
                     97: *              only one rounding error.  The grs bits are collected in
                     98: *              the INEX flag for use in A10.
                     99: *
                    100: *      A9.     Scale X -> Y.
                    101: *              The mantissa is scaled to the desired number of
                    102: *              significant digits.  The excess digits are collected
                    103: *              in INEX2.
                    104: *
                    105: *      A10.    Or in INEX.
                    106: *              If INEX is set, round error occurred.  This is
                    107: *              compensated for by 'or-ing' in the INEX2 flag to
                    108: *              the lsb of Y.
                    109: *
                    110: *      A11.    Restore original FPCR; set size ext.
                    111: *              Perform FINT operation in the user's rounding mode.
                    112: *              Keep the size to extended.
                    113: *
                    114: *      A12.    Calculate YINT = FINT(Y) according to user's rounding
                    115: *              mode.  The FPSP routine sintd0 is used.  The output
                    116: *              is in fp0.
                    117: *
                    118: *      A13.    Check for LEN digits.
                    119: *              If the int operation results in more than LEN digits,
                    120: *              or less than LEN -1 digits, adjust ILOG and repeat from
                    121: *              A6.  This test occurs only on the first pass.  If the
                    122: *              result is exactly 10^LEN, decrement ILOG and divide
                    123: *              the mantissa by 10.
                    124: *
                    125: *      A14.    Convert the mantissa to bcd.
                    126: *              The binstr routine is used to convert the LEN digit
                    127: *              mantissa to bcd in memory.  The input to binstr is
                    128: *              to be a fraction; i.e. (mantissa)/10^LEN and adjusted
                    129: *              such that the decimal point is to the left of bit 63.
                    130: *              The bcd digits are stored in the correct position in
                    131: *              the final string area in memory.
                    132: *
                    133: *      A15.    Convert the exponent to bcd.
                    134: *              As in A14 above, the exp is converted to bcd and the
                    135: *              digits are stored in the final string.
                    136: *              Test the length of the final exponent string.  If the
                    137: *              length is 4, set operr.
                    138: *
                    139: *      A16.    Write sign bits to final string.
                    140: *
                    141: *      Implementation Notes:
                    142: *
                    143: *      The registers are used as follows:
                    144: *
                    145: *              d0: scratch; LEN input to binstr
                    146: *              d1: scratch
                    147: *              d2: upper 32-bits of mantissa for binstr
                    148: *              d3: scratch;lower 32-bits of mantissa for binstr
                    149: *              d4: LEN
                    150: *                      d5: LAMBDA/ICTR
                    151: *              d6: ILOG
                    152: *              d7: k-factor
                    153: *              a0: ptr for original operand/final result
                    154: *              a1: scratch pointer
                    155: *              a2: pointer to FP_X; abs(original value) in ext
                    156: *              fp0: scratch
                    157: *              fp1: scratch
                    158: *              fp2: scratch
                    159: *              F_SCR1:
                    160: *              F_SCR2:
                    161: *              L_SCR1:
                    162: *              L_SCR2:
                    163: *
                    164:
                    165: BINDEC    IDNT    2,1 Motorola 040 Floating Point Software Package
                    166:
                    167:        include fpsp.h
                    168:
                    169:        section 8
                    170:
                    171: * Constants in extended precision
                    172: LOG2   dc.l    $3FFD0000,$9A209A84,$FBCFF798,$00000000
                    173: LOG2UP1        dc.l    $3FFD0000,$9A209A84,$FBCFF799,$00000000
                    174:
                    175: * Constants in single precision
                    176: FONE   dc.l    $3F800000,$00000000,$00000000,$00000000
                    177: FTWO   dc.l    $40000000,$00000000,$00000000,$00000000
                    178: FTEN   dc.l    $41200000,$00000000,$00000000,$00000000
                    179: F4933  dc.l    $459A2800,$00000000,$00000000,$00000000
                    180:
                    181: RBDTBL         dc.b    0,0,0,0
                    182:        dc.b    3,3,2,2
                    183:        dc.b    3,2,2,3
                    184:        dc.b    2,3,3,2
                    185:
                    186:        xref    binstr
                    187:        xref    sintdo
                    188:        xref    ptenrn,ptenrm,ptenrp
                    189:
                    190:        xdef    bindec
                    191:        xdef    sc_mul
                    192: bindec:
                    193:        movem.l d2-d7/a2,-(a7)
                    194:        fmovem.x fp0-fp2,-(a7)
                    195:
                    196: * A1. Set RM and size ext. Set SIGMA = sign input;
                    197: *     The k-factor is saved for use in d7.  Clear BINDEC_FLG for
                    198: *     separating  normalized/denormalized input.  If the input
                    199: *     is a denormalized number, set the BINDEC_FLG memory word
                    200: *     to signal denorm.  If the input is unnormalized, normalize
                    201: *     the input and test for denormalized result.
                    202: *
                    203:        fmove.l #rm_mode,FPCR   ;set RM and ext
                    204:        move.l  (a0),L_SCR2(a6) ;save exponent for sign check
                    205:        move.l  d0,d7           ;move k-factor to d7
                    206:        clr.b   BINDEC_FLG(a6)  ;clr norm/denorm flag
                    207:        move.w  STAG(a6),d0     ;get stag
                    208:        andi.w  #$e000,d0       ;isolate stag bits
                    209:        beq     A2_str          ;if zero, input is norm
                    210: *
                    211: * Normalize the denorm
                    212: *
                    213: un_de_norm:
                    214:        move.w  (a0),d0
                    215:        andi.w  #$7fff,d0       ;strip sign of normalized exp
                    216:        move.l  4(a0),d1
                    217:        move.l  8(a0),d2
                    218: norm_loop:
                    219:        sub.w   #1,d0
                    220:        add.l   d2,d2
                    221:        addx.l  d1,d1
                    222:        tst.l   d1
                    223:        bge.b   norm_loop
                    224: *
                    225: * Test if the normalized input is denormalized
                    226: *
                    227:        tst.w   d0
                    228:        bgt.b   pos_exp         ;if greater than zero, it is a norm
                    229:        st      BINDEC_FLG(a6)  ;set flag for denorm
                    230: pos_exp:
                    231:        andi.w  #$7fff,d0       ;strip sign of normalized exp
                    232:        move.w  d0,(a0)
                    233:        move.l  d1,4(a0)
                    234:        move.l  d2,8(a0)
                    235:
                    236: * A2. Set X = abs(input).
                    237: *
                    238: A2_str:
                    239:        move.l  (a0),FP_SCR2(a6) ; move input to work space
                    240:        move.l  4(a0),FP_SCR2+4(a6) ; move input to work space
                    241:        move.l  8(a0),FP_SCR2+8(a6) ; move input to work space
                    242:        andi.l  #$7fffffff,FP_SCR2(a6) ;create abs(X)
                    243:
                    244: * A3. Compute ILOG.
                    245: *     ILOG is the log base 10 of the input value.  It is approx-
                    246: *     imated by adding e + 0.f when the original value is viewed
                    247: *     as 2^^e * 1.f in extended precision.  This value is stored
                    248: *     in d6.
                    249: *
                    250: * Register usage:
                    251: *      Input/Output
                    252: *      d0: k-factor/exponent
                    253: *      d2: x/x
                    254: *      d3: x/x
                    255: *      d4: x/x
                    256: *      d5: x/x
                    257: *      d6: x/ILOG
                    258: *      d7: k-factor/Unchanged
                    259: *      a0: ptr for original operand/final result
                    260: *      a1: x/x
                    261: *      a2: x/x
                    262: *      fp0: x/float(ILOG)
                    263: *      fp1: x/x
                    264: *      fp2: x/x
                    265: *      F_SCR1:x/x
                    266: *      F_SCR2:Abs(X)/Abs(X) with $3fff exponent
                    267: *      L_SCR1:x/x
                    268: *      L_SCR2:first word of X packed/Unchanged
                    269:
                    270:        tst.b   BINDEC_FLG(a6)  ;check for denorm
                    271:        beq.b   A3_cont         ;if clr, continue with norm
                    272:        move.l  #-4933,d6       ;force ILOG = -4933
                    273:        bra.b   A4_str
                    274: A3_cont:
                    275:        move.w  FP_SCR2(a6),d0  ;move exp to d0
                    276:        move.w  #$3fff,FP_SCR2(a6) ;replace exponent with 0x3fff
                    277:        fmove.x FP_SCR2(a6),fp0 ;now fp0 has 1.f
                    278:        sub.w   #$3fff,d0       ;strip off bias
                    279:        fadd.w  d0,fp0          ;add in exp
                    280:        fsub.s  FONE,fp0        ;subtract off 1.0
                    281:        fbge.w  pos_res         ;if pos, branch
                    282:        fmul.x  LOG2UP1,fp0     ;if neg, mul by LOG2UP1
                    283:        fmove.l fp0,d6          ;put ILOG in d6 as a lword
                    284:        bra.b   A4_str          ;go move out ILOG
                    285: pos_res:
                    286:        fmul.x  LOG2,fp0        ;if pos, mul by LOG2
                    287:        fmove.l fp0,d6          ;put ILOG in d6 as a lword
                    288:
                    289:
                    290: * A4. Clr INEX bit.
                    291: *     The operation in A3 above may have set INEX2.
                    292:
                    293: A4_str:
                    294:        fmove.l #0,FPSR         ;zero all of fpsr - nothing needed
                    295:
                    296:
                    297: * A5. Set ICTR = 0;
                    298: *     ICTR is a flag used in A13.  It must be set before the
                    299: *     loop entry A6. The lower word of d5 is used for ICTR.
                    300:
                    301:        clr.w   d5              ;clear ICTR
                    302:
                    303:
                    304: * A6. Calculate LEN.
                    305: *     LEN is the number of digits to be displayed.  The k-factor
                    306: *     can dictate either the total number of digits, if it is
                    307: *     a positive number, or the number of digits after the
                    308: *     original decimal point which are to be included as
                    309: *     significant.  See the 68882 manual for examples.
                    310: *     If LEN is computed to be greater than 17, set OPERR in
                    311: *     USER_FPSR.  LEN is stored in d4.
                    312: *
                    313: * Register usage:
                    314: *      Input/Output
                    315: *      d0: exponent/Unchanged
                    316: *      d2: x/x/scratch
                    317: *      d3: x/x
                    318: *      d4: exc picture/LEN
                    319: *      d5: ICTR/Unchanged
                    320: *      d6: ILOG/Unchanged
                    321: *      d7: k-factor/Unchanged
                    322: *      a0: ptr for original operand/final result
                    323: *      a1: x/x
                    324: *      a2: x/x
                    325: *      fp0: float(ILOG)/Unchanged
                    326: *      fp1: x/x
                    327: *      fp2: x/x
                    328: *      F_SCR1:x/x
                    329: *      F_SCR2:Abs(X) with $3fff exponent/Unchanged
                    330: *      L_SCR1:x/x
                    331: *      L_SCR2:first word of X packed/Unchanged
                    332:
                    333: A6_str:
                    334:        tst.l   d7              ;branch on sign of k
                    335:        ble.b   k_neg           ;if k <= 0, LEN = ILOG + 1 - k
                    336:        move.l  d7,d4           ;if k > 0, LEN = k
                    337:        bra.b   len_ck          ;skip to LEN check
                    338: k_neg:
                    339:        move.l  d6,d4           ;first load ILOG to d4
                    340:        sub.l   d7,d4           ;subtract off k
                    341:        addq.l  #1,d4           ;add in the 1
                    342: len_ck:
                    343:        tst.l   d4              ;LEN check: branch on sign of LEN
                    344:        ble.b   LEN_ng          ;if neg, set LEN = 1
                    345:        cmp.l   #17,d4          ;test if LEN > 17
                    346:        ble.b   A7_str          ;if not, forget it
                    347:        move.l  #17,d4          ;set max LEN = 17
                    348:        tst.l   d7              ;if negative, never set OPERR
                    349:        ble.b   A7_str          ;if positive, continue
                    350:        or.l    #opaop_mask,USER_FPSR(a6) ;set OPERR & AIOP in USER_FPSR
                    351:        bra.b   A7_str          ;finished here
                    352: LEN_ng:
                    353:        moveq.l #1,d4           ;min LEN is 1
                    354:
                    355:
                    356: * A7. Calculate SCALE.
                    357: *     SCALE is equal to 10^ISCALE, where ISCALE is the number
                    358: *     of decimal places needed to insure LEN integer digits
                    359: *     in the output before conversion to bcd. LAMBDA is the sign
                    360: *     of ISCALE, used in A9.  Fp1 contains 10^^(abs(ISCALE)) using
                    361: *     the rounding mode as given in the following table (see
                    362: *     Coonen, p. 7.23 as ref.; however, the SCALE variable is
                    363: *     of opposite sign in bindec.sa from Coonen).
                    364: *
                    365: *      Initial                                 USE
                    366: *      FPCR[6:5]       LAMBDA  SIGN(X)         FPCR[6:5]
                    367: *      ----------------------------------------------
                    368: *       RN     00         0       0            00/0    RN
                    369: *       RN     00         0       1            00/0    RN
                    370: *       RN     00         1       0            00/0    RN
                    371: *       RN     00         1       1            00/0    RN
                    372: *       RZ     01         0       0            11/3    RP
                    373: *       RZ     01         0       1            11/3    RP
                    374: *       RZ     01         1       0            10/2    RM
                    375: *       RZ     01         1       1            10/2    RM
                    376: *       RM     10         0       0            11/3    RP
                    377: *       RM     10         0       1            10/2    RM
                    378: *       RM     10         1       0            10/2    RM
                    379: *       RM     10         1       1            11/3    RP
                    380: *       RP     11         0       0            10/2    RM
                    381: *       RP     11         0       1            11/3    RP
                    382: *       RP     11         1       0            11/3    RP
                    383: *       RP     11         1       1            10/2    RM
                    384: *
                    385: * Register usage:
                    386: *      Input/Output
                    387: *      d0: exponent/scratch - final is 0
                    388: *      d2: x/0 or 24 for A9
                    389: *      d3: x/scratch - offset ptr into PTENRM array
                    390: *      d4: LEN/Unchanged
                    391: *      d5: 0/ICTR:LAMBDA
                    392: *      d6: ILOG/ILOG or k if ((k<=0)&(ILOG<k))
                    393: *      d7: k-factor/Unchanged
                    394: *      a0: ptr for original operand/final result
                    395: *      a1: x/ptr to PTENRM array
                    396: *      a2: x/x
                    397: *      fp0: float(ILOG)/Unchanged
                    398: *      fp1: x/10^ISCALE
                    399: *      fp2: x/x
                    400: *      F_SCR1:x/x
                    401: *      F_SCR2:Abs(X) with $3fff exponent/Unchanged
                    402: *      L_SCR1:x/x
                    403: *      L_SCR2:first word of X packed/Unchanged
                    404:
                    405: A7_str:
                    406:        tst.l   d7              ;test sign of k
                    407:        bgt.b   k_pos           ;if pos and > 0, skip this
                    408:        cmp.l   d6,d7           ;test k - ILOG
                    409:        blt.b   k_pos           ;if ILOG >= k, skip this
                    410:        move.l  d7,d6           ;if ((k<0) & (ILOG < k)) ILOG = k
                    411: k_pos:
                    412:        move.l  d6,d0           ;calc ILOG + 1 - LEN in d0
                    413:        addq.l  #1,d0           ;add the 1
                    414:        sub.l   d4,d0           ;sub off LEN
                    415:        swap    d5              ;use upper word of d5 for LAMBDA
                    416:        clr.w   d5              ;set it zero initially
                    417:        clr.w   d2              ;set up d2 for very small case
                    418:        tst.l   d0              ;test sign of ISCALE
                    419:        bge.b   iscale          ;if pos, skip next inst
                    420:        addq.w  #1,d5           ;if neg, set LAMBDA true
                    421:        cmp.l   #$ffffecd4,d0   ;test iscale <= -4908
                    422:        bgt.b   no_inf          ;if false, skip rest
                    423:        addi.l  #24,d0          ;add in 24 to iscale
                    424:        move.l  #24,d2          ;put 24 in d2 for A9
                    425: no_inf:
                    426:        neg.l   d0              ;and take abs of ISCALE
                    427: iscale:
                    428:        fmove.s FONE,fp1        ;init fp1 to 1
                    429:        bfextu  USER_FPCR(a6){26:2},d1 ;get initial rmode bits
                    430:        add.w   d1,d1           ;put them in bits 2:1
                    431:        add.w   d5,d1           ;add in LAMBDA
                    432:        add.w   d1,d1           ;put them in bits 3:1
                    433:        tst.l   L_SCR2(a6)      ;test sign of original x
                    434:        bge.b   x_pos           ;if pos, don't set bit 0
                    435:        addq.l  #1,d1           ;if neg, set bit 0
                    436: x_pos:
                    437:        lea.l   RBDTBL,a2       ;load rbdtbl base
                    438:        move.b  (a2,d1),d3      ;load d3 with new rmode
                    439:        lsl.l   #4,d3           ;put bits in proper position
                    440:        fmove.l d3,fpcr         ;load bits into fpu
                    441:        lsr.l   #4,d3           ;put bits in proper position
                    442:        tst.b   d3              ;decode new rmode for pten table
                    443:        bne.b   not_rn          ;if zero, it is RN
                    444:        lea.l   PTENRN,a1       ;load a1 with RN table base
                    445:        bra.b   rmode           ;exit decode
                    446: not_rn:
                    447:        lsr.b   #1,d3           ;get lsb in carry
                    448:        bcc.b   not_rp          ;if carry clear, it is RM
                    449:        lea.l   PTENRP,a1       ;load a1 with RP table base
                    450:        bra.b   rmode           ;exit decode
                    451: not_rp:
                    452:        lea.l   PTENRM,a1       ;load a1 with RM table base
                    453: rmode:
                    454:        clr.l   d3              ;clr table index
                    455: e_loop:
                    456:        lsr.l   #1,d0           ;shift next bit into carry
                    457:        bcc.b   e_next          ;if zero, skip the mul
                    458:        fmul.x  (a1,d3),fp1     ;mul by 10**(d3_bit_no)
                    459: e_next:
                    460:        add.l   #12,d3          ;inc d3 to next pwrten table entry
                    461:        tst.l   d0              ;test if ISCALE is zero
                    462:        bne.b   e_loop          ;if not, loop
                    463:
                    464:
                    465: * A8. Clr INEX; Force RZ.
                    466: *     The operation in A3 above may have set INEX2.
                    467: *     RZ mode is forced for the scaling operation to insure
                    468: *     only one rounding error.  The grs bits are collected in
                    469: *     the INEX flag for use in A10.
                    470: *
                    471: * Register usage:
                    472: *      Input/Output
                    473:
                    474:        fmove.l #0,FPSR         ;clr INEX
                    475:        fmove.l #rz_mode,FPCR   ;set RZ rounding mode
                    476:
                    477:
                    478: * A9. Scale X -> Y.
                    479: *     The mantissa is scaled to the desired number of significant
                    480: *     digits.  The excess digits are collected in INEX2. If mul,
                    481: *     Check d2 for excess 10 exponential value.  If not zero,
                    482: *     the iscale value would have caused the pwrten calculation
                    483: *     to overflow.  Only a negative iscale can cause this, so
                    484: *     multiply by 10^(d2), which is now only allowed to be 24,
                    485: *     with a multiply by 10^8 and 10^16, which is exact since
                    486: *     10^24 is exact.  If the input was denormalized, we must
                    487: *     create a busy stack frame with the mul command and the
                    488: *     two operands, and allow the fpu to complete the multiply.
                    489: *
                    490: * Register usage:
                    491: *      Input/Output
                    492: *      d0: FPCR with RZ mode/Unchanged
                    493: *      d2: 0 or 24/unchanged
                    494: *      d3: x/x
                    495: *      d4: LEN/Unchanged
                    496: *      d5: ICTR:LAMBDA
                    497: *      d6: ILOG/Unchanged
                    498: *      d7: k-factor/Unchanged
                    499: *      a0: ptr for original operand/final result
                    500: *      a1: ptr to PTENRM array/Unchanged
                    501: *      a2: x/x
                    502: *      fp0: float(ILOG)/X adjusted for SCALE (Y)
                    503: *      fp1: 10^ISCALE/Unchanged
                    504: *      fp2: x/x
                    505: *      F_SCR1:x/x
                    506: *      F_SCR2:Abs(X) with $3fff exponent/Unchanged
                    507: *      L_SCR1:x/x
                    508: *      L_SCR2:first word of X packed/Unchanged
                    509:
                    510: A9_str:
                    511:        fmove.x (a0),fp0        ;load X from memory
                    512:        fabs.x  fp0             ;use abs(X)
                    513:        tst.w   d5              ;LAMBDA is in lower word of d5
                    514:        bne.b   sc_mul          ;if neg (LAMBDA = 1), scale by mul
                    515:        fdiv.x  fp1,fp0         ;calculate X / SCALE -> Y to fp0
                    516:        bra.b   A10_st          ;branch to A10
                    517:
                    518: sc_mul:
                    519:        tst.b   BINDEC_FLG(a6)  ;check for denorm
                    520:        beq.b   A9_norm         ;if norm, continue with mul
                    521:        fmovem.x fp1,-(a7)      ;load ETEMP with 10^ISCALE
                    522:        move.l  8(a0),-(a7)     ;load FPTEMP with input arg
                    523:        move.l  4(a0),-(a7)
                    524:        move.l  (a0),-(a7)
                    525:        move.l  #18,d3          ;load count for busy stack
                    526: A9_loop:
                    527:        clr.l   -(a7)           ;clear lword on stack
                    528:        dbf.w   d3,A9_loop
                    529:        move.b  VER_TMP(a6),(a7) ;write current version number
                    530:        move.b  #BUSY_SIZE-4,1(a7) ;write current busy size
                    531:        move.b  #$10,$44(a7)    ;set fcefpte[15] bit
                    532:        move.w  #$0023,$40(a7)  ;load cmdreg1b with mul command
                    533:        move.b  #$fe,$8(a7)     ;load all 1s to cu savepc
                    534:        frestore (a7)+          ;restore frame to fpu for completion
                    535:        fmul.x  36(a1),fp0      ;multiply fp0 by 10^8
                    536:        fmul.x  48(a1),fp0      ;multiply fp0 by 10^16
                    537:        bra.b   A10_st
                    538: A9_norm:
                    539:        tst.w   d2              ;test for small exp case
                    540:        beq.b   A9_con          ;if zero, continue as normal
                    541:        fmul.x  36(a1),fp0      ;multiply fp0 by 10^8
                    542:        fmul.x  48(a1),fp0      ;multiply fp0 by 10^16
                    543: A9_con:
                    544:        fmul.x  fp1,fp0         ;calculate X * SCALE -> Y to fp0
                    545:
                    546:
                    547: * A10. Or in INEX.
                    548: *      If INEX is set, round error occurred.  This is compensated
                    549: *      for by 'or-ing' in the INEX2 flag to the lsb of Y.
                    550: *
                    551: * Register usage:
                    552: *      Input/Output
                    553: *      d0: FPCR with RZ mode/FPSR with INEX2 isolated
                    554: *      d2: x/x
                    555: *      d3: x/x
                    556: *      d4: LEN/Unchanged
                    557: *      d5: ICTR:LAMBDA
                    558: *      d6: ILOG/Unchanged
                    559: *      d7: k-factor/Unchanged
                    560: *      a0: ptr for original operand/final result
                    561: *      a1: ptr to PTENxx array/Unchanged
                    562: *      a2: x/ptr to FP_SCR2(a6)
                    563: *      fp0: Y/Y with lsb adjusted
                    564: *      fp1: 10^ISCALE/Unchanged
                    565: *      fp2: x/x
                    566:
                    567: A10_st:
                    568:        fmove.l FPSR,d0         ;get FPSR
                    569:        fmove.x fp0,FP_SCR2(a6) ;move Y to memory
                    570:        lea.l   FP_SCR2(a6),a2  ;load a2 with ptr to FP_SCR2
                    571:        btst.l  #9,d0           ;check if INEX2 set
                    572:        beq.b   A11_st          ;if clear, skip rest
                    573:        ori.l   #1,8(a2)        ;or in 1 to lsb of mantissa
                    574:        fmove.x FP_SCR2(a6),fp0 ;write adjusted Y back to fpu
                    575:
                    576:
                    577: * A11. Restore original FPCR; set size ext.
                    578: *      Perform FINT operation in the user's rounding mode.  Keep
                    579: *      the size to extended.  The sintdo entry point in the sint
                    580: *      routine expects the FPCR value to be in USER_FPCR for
                    581: *      mode and precision.  The original FPCR is saved in L_SCR1.
                    582:
                    583: A11_st:
                    584:        move.l  USER_FPCR(a6),L_SCR1(a6) ;save it for later
                    585:        andi.l  #$00000030,USER_FPCR(a6) ;set size to ext,
                    586: *                                      ;block exceptions
                    587:
                    588:
                    589: * A12. Calculate YINT = FINT(Y) according to user's rounding mode.
                    590: *      The FPSP routine sintd0 is used.  The output is in fp0.
                    591: *
                    592: * Register usage:
                    593: *      Input/Output
                    594: *      d0: FPSR with AINEX cleared/FPCR with size set to ext
                    595: *      d2: x/x/scratch
                    596: *      d3: x/x
                    597: *      d4: LEN/Unchanged
                    598: *      d5: ICTR:LAMBDA/Unchanged
                    599: *      d6: ILOG/Unchanged
                    600: *      d7: k-factor/Unchanged
                    601: *      a0: ptr for original operand/src ptr for sintdo
                    602: *      a1: ptr to PTENxx array/Unchanged
                    603: *      a2: ptr to FP_SCR2(a6)/Unchanged
                    604: *      a6: temp pointer to FP_SCR2(a6) - orig value saved and restored
                    605: *      fp0: Y/YINT
                    606: *      fp1: 10^ISCALE/Unchanged
                    607: *      fp2: x/x
                    608: *      F_SCR1:x/x
                    609: *      F_SCR2:Y adjusted for inex/Y with original exponent
                    610: *      L_SCR1:x/original USER_FPCR
                    611: *      L_SCR2:first word of X packed/Unchanged
                    612:
                    613: A12_st:
                    614:        movem.l d0-d1/a0-a1,-(a7)       ;save regs used by sintd0
                    615:        move.l  L_SCR1(a6),-(a7)
                    616:        move.l  L_SCR2(a6),-(a7)
                    617:        lea.l   FP_SCR2(a6),a0          ;a0 is ptr to F_SCR2(a6)
                    618:        fmove.x fp0,(a0)                ;move Y to memory at FP_SCR2(a6)
                    619:        tst.l   L_SCR2(a6)              ;test sign of original operand
                    620:        bge.b   do_fint                 ;if pos, use Y
                    621:        or.l    #$80000000,(a0)         ;if neg, use -Y
                    622: do_fint:
                    623:        move.l  USER_FPSR(a6),-(a7)
                    624:        bsr     sintdo                  ;sint routine returns int in fp0
                    625:        move.b  (a7),USER_FPSR(a6)
                    626:        add.l   #4,a7
                    627:        move.l  (a7)+,L_SCR2(a6)
                    628:        move.l  (a7)+,L_SCR1(a6)
                    629:        movem.l (a7)+,d0-d1/a0-a1       ;restore regs used by sint
                    630:        move.l  L_SCR2(a6),FP_SCR2(a6)  ;restore original exponent
                    631:        move.l  L_SCR1(a6),USER_FPCR(a6) ;restore user's FPCR
                    632:
                    633:
                    634: * A13. Check for LEN digits.
                    635: *      If the int operation results in more than LEN digits,
                    636: *      or less than LEN -1 digits, adjust ILOG and repeat from
                    637: *      A6.  This test occurs only on the first pass.  If the
                    638: *      result is exactly 10^LEN, decrement ILOG and divide
                    639: *      the mantissa by 10.  The calculation of 10^LEN cannot
                    640: *      be inexact, since all powers of ten upto 10^27 are exact
                    641: *      in extended precision, so the use of a previous power-of-ten
                    642: *      table will introduce no error.
                    643: *
                    644: *
                    645: * Register usage:
                    646: *      Input/Output
                    647: *      d0: FPCR with size set to ext/scratch final = 0
                    648: *      d2: x/x
                    649: *      d3: x/scratch final = x
                    650: *      d4: LEN/LEN adjusted
                    651: *      d5: ICTR:LAMBDA/LAMBDA:ICTR
                    652: *      d6: ILOG/ILOG adjusted
                    653: *      d7: k-factor/Unchanged
                    654: *      a0: pointer into memory for packed bcd string formation
                    655: *      a1: ptr to PTENxx array/Unchanged
                    656: *      a2: ptr to FP_SCR2(a6)/Unchanged
                    657: *      fp0: int portion of Y/abs(YINT) adjusted
                    658: *      fp1: 10^ISCALE/Unchanged
                    659: *      fp2: x/10^LEN
                    660: *      F_SCR1:x/x
                    661: *      F_SCR2:Y with original exponent/Unchanged
                    662: *      L_SCR1:original USER_FPCR/Unchanged
                    663: *      L_SCR2:first word of X packed/Unchanged
                    664:
                    665: A13_st:
                    666:        swap    d5              ;put ICTR in lower word of d5
                    667:        tst.w   d5              ;check if ICTR = 0
                    668:        bne     not_zr          ;if non-zero, go to second test
                    669: *
                    670: * Compute 10^(LEN-1)
                    671: *
                    672:        fmove.s FONE,fp2        ;init fp2 to 1.0
                    673:        move.l  d4,d0           ;put LEN in d0
                    674:        subq.l  #1,d0           ;d0 = LEN -1
                    675:        clr.l   d3              ;clr table index
                    676: l_loop:
                    677:        lsr.l   #1,d0           ;shift next bit into carry
                    678:        bcc.b   l_next          ;if zero, skip the mul
                    679:        fmul.x  (a1,d3),fp2     ;mul by 10**(d3_bit_no)
                    680: l_next:
                    681:        add.l   #12,d3          ;inc d3 to next pwrten table entry
                    682:        tst.l   d0              ;test if LEN is zero
                    683:        bne.b   l_loop          ;if not, loop
                    684: *
                    685: * 10^LEN-1 is computed for this test and A14.  If the input was
                    686: * denormalized, check only the case in which YINT > 10^LEN.
                    687: *
                    688:        tst.b   BINDEC_FLG(a6)  ;check if input was norm
                    689:        beq.b   A13_con         ;if norm, continue with checking
                    690:        fabs.x  fp0             ;take abs of YINT
                    691:        bra     test_2
                    692: *
                    693: * Compare abs(YINT) to 10^(LEN-1) and 10^LEN
                    694: *
                    695: A13_con:
                    696:        fabs.x  fp0             ;take abs of YINT
                    697:        fcmp.x  fp2,fp0         ;compare abs(YINT) with 10^(LEN-1)
                    698:        fbge.w  test_2          ;if greater, do next test
                    699:        subq.l  #1,d6           ;subtract 1 from ILOG
                    700:        move.w  #1,d5           ;set ICTR
                    701:        fmove.l #rm_mode,FPCR   ;set rmode to RM
                    702:        fmul.s  FTEN,fp2        ;compute 10^LEN
                    703:        bra.w   A6_str          ;return to A6 and recompute YINT
                    704: test_2:
                    705:        fmul.s  FTEN,fp2        ;compute 10^LEN
                    706:        fcmp.x  fp2,fp0         ;compare abs(YINT) with 10^LEN
                    707:        fblt.w  A14_st          ;if less, all is ok, go to A14
                    708:        fbgt.w  fix_ex          ;if greater, fix and redo
                    709:        fdiv.s  FTEN,fp0        ;if equal, divide by 10
                    710:        addq.l  #1,d6           ; and inc ILOG
                    711:        bra.b   A14_st          ; and continue elsewhere
                    712: fix_ex:
                    713:        addq.l  #1,d6           ;increment ILOG by 1
                    714:        move.w  #1,d5           ;set ICTR
                    715:        fmove.l #rm_mode,FPCR   ;set rmode to RM
                    716:        bra.w   A6_str          ;return to A6 and recompute YINT
                    717: *
                    718: * Since ICTR <> 0, we have already been through one adjustment,
                    719: * and shouldn't have another; this is to check if abs(YINT) = 10^LEN
                    720: * 10^LEN is again computed using whatever table is in a1 since the
                    721: * value calculated cannot be inexact.
                    722: *
                    723: not_zr:
                    724:        fmove.s FONE,fp2        ;init fp2 to 1.0
                    725:        move.l  d4,d0           ;put LEN in d0
                    726:        clr.l   d3              ;clr table index
                    727: z_loop:
                    728:        lsr.l   #1,d0           ;shift next bit into carry
                    729:        bcc.b   z_next          ;if zero, skip the mul
                    730:        fmul.x  (a1,d3),fp2     ;mul by 10**(d3_bit_no)
                    731: z_next:
                    732:        add.l   #12,d3          ;inc d3 to next pwrten table entry
                    733:        tst.l   d0              ;test if LEN is zero
                    734:        bne.b   z_loop          ;if not, loop
                    735:        fabs.x  fp0             ;get abs(YINT)
                    736:        fcmp.x  fp2,fp0         ;check if abs(YINT) = 10^LEN
                    737:        fbne.w  A14_st          ;if not, skip this
                    738:        fdiv.s  FTEN,fp0        ;divide abs(YINT) by 10
                    739:        addq.l  #1,d6           ;and inc ILOG by 1
                    740:        addq.l  #1,d4           ; and inc LEN
                    741:        fmul.s  FTEN,fp2        ; if LEN++, the get 10^^LEN
                    742:
                    743:
                    744: * A14. Convert the mantissa to bcd.
                    745: *      The binstr routine is used to convert the LEN digit
                    746: *      mantissa to bcd in memory.  The input to binstr is
                    747: *      to be a fraction; i.e. (mantissa)/10^LEN and adjusted
                    748: *      such that the decimal point is to the left of bit 63.
                    749: *      The bcd digits are stored in the correct position in
                    750: *      the final string area in memory.
                    751: *
                    752: *
                    753: * Register usage:
                    754: *      Input/Output
                    755: *      d0: x/LEN call to binstr - final is 0
                    756: *      d1: x/0
                    757: *      d2: x/ms 32-bits of mant of abs(YINT)
                    758: *      d3: x/ls 32-bits of mant of abs(YINT)
                    759: *      d4: LEN/Unchanged
                    760: *      d5: ICTR:LAMBDA/LAMBDA:ICTR
                    761: *      d6: ILOG
                    762: *      d7: k-factor/Unchanged
                    763: *      a0: pointer into memory for packed bcd string formation
                    764: *          /ptr to first mantissa byte in result string
                    765: *      a1: ptr to PTENxx array/Unchanged
                    766: *      a2: ptr to FP_SCR2(a6)/Unchanged
                    767: *      fp0: int portion of Y/abs(YINT) adjusted
                    768: *      fp1: 10^ISCALE/Unchanged
                    769: *      fp2: 10^LEN/Unchanged
                    770: *      F_SCR1:x/Work area for final result
                    771: *      F_SCR2:Y with original exponent/Unchanged
                    772: *      L_SCR1:original USER_FPCR/Unchanged
                    773: *      L_SCR2:first word of X packed/Unchanged
                    774:
                    775: A14_st:
                    776:        fmove.l #rz_mode,FPCR   ;force rz for conversion
                    777:        fdiv.x  fp2,fp0         ;divide abs(YINT) by 10^LEN
                    778:        lea.l   FP_SCR1(a6),a0
                    779:        fmove.x fp0,(a0)        ;move abs(YINT)/10^LEN to memory
                    780:        move.l  4(a0),d2        ;move 2nd word of FP_RES to d2
                    781:        move.l  8(a0),d3        ;move 3rd word of FP_RES to d3
                    782:        clr.l   4(a0)           ;zero word 2 of FP_RES
                    783:        clr.l   8(a0)           ;zero word 3 of FP_RES
                    784:        move.l  (a0),d0         ;move exponent to d0
                    785:        swap    d0              ;put exponent in lower word
                    786:        beq.b   no_sft          ;if zero, don't shift
                    787:        subi.l  #$3ffd,d0       ;sub bias less 2 to make fract
                    788:        tst.l   d0              ;check if > 1
                    789:        bgt.b   no_sft          ;if so, don't shift
                    790:        neg.l   d0              ;make exp positive
                    791: m_loop:
                    792:        lsr.l   #1,d2           ;shift d2:d3 right, add 0s
                    793:        roxr.l  #1,d3           ;the number of places
                    794:        dbf.w   d0,m_loop       ;given in d0
                    795: no_sft:
                    796:        tst.l   d2              ;check for mantissa of zero
                    797:        bne.b   no_zr           ;if not, go on
                    798:        tst.l   d3              ;continue zero check
                    799:        beq.b   zer_m           ;if zero, go directly to binstr
                    800: no_zr:
                    801:        clr.l   d1              ;put zero in d1 for addx
                    802:        addi.l  #$00000080,d3   ;inc at bit 7
                    803:        addx.l  d1,d2           ;continue inc
                    804:        andi.l  #$ffffff80,d3   ;strip off lsb not used by 882
                    805: zer_m:
                    806:        move.l  d4,d0           ;put LEN in d0 for binstr call
                    807:        addq.l  #3,a0           ;a0 points to M16 byte in result
                    808:        bsr     binstr          ;call binstr to convert mant
                    809:
                    810:
                    811: * A15. Convert the exponent to bcd.
                    812: *      As in A14 above, the exp is converted to bcd and the
                    813: *      digits are stored in the final string.
                    814: *
                    815: *      Digits are stored in L_SCR1(a6) on return from BINDEC as:
                    816: *
                    817: *       32               16 15                0
                    818: *      -----------------------------------------
                    819: *      |  0 | e3 | e2 | e1 | e4 |  X |  X |  X |
                    820: *      -----------------------------------------
                    821: *
                    822: * And are moved into their proper places in FP_SCR1.  If digit e4
                    823: * is non-zero, OPERR is signaled.  In all cases, all 4 digits are
                    824: * written as specified in the 881/882 manual for packed decimal.
                    825: *
                    826: * Register usage:
                    827: *      Input/Output
                    828: *      d0: x/LEN call to binstr - final is 0
                    829: *      d1: x/scratch (0);shift count for final exponent packing
                    830: *      d2: x/ms 32-bits of exp fraction/scratch
                    831: *      d3: x/ls 32-bits of exp fraction
                    832: *      d4: LEN/Unchanged
                    833: *      d5: ICTR:LAMBDA/LAMBDA:ICTR
                    834: *      d6: ILOG
                    835: *      d7: k-factor/Unchanged
                    836: *      a0: ptr to result string/ptr to L_SCR1(a6)
                    837: *      a1: ptr to PTENxx array/Unchanged
                    838: *      a2: ptr to FP_SCR2(a6)/Unchanged
                    839: *      fp0: abs(YINT) adjusted/float(ILOG)
                    840: *      fp1: 10^ISCALE/Unchanged
                    841: *      fp2: 10^LEN/Unchanged
                    842: *      F_SCR1:Work area for final result/BCD result
                    843: *      F_SCR2:Y with original exponent/ILOG/10^4
                    844: *      L_SCR1:original USER_FPCR/Exponent digits on return from binstr
                    845: *      L_SCR2:first word of X packed/Unchanged
                    846:
                    847: A15_st:
                    848:        tst.b   BINDEC_FLG(a6)  ;check for denorm
                    849:        beq.b   not_denorm
                    850:        ftst.x  fp0             ;test for zero
                    851:        fbeq.w  den_zero        ;if zero, use k-factor or 4933
                    852:        fmove.l d6,fp0          ;float ILOG
                    853:        fabs.x  fp0             ;get abs of ILOG
                    854:        bra.b   convrt
                    855: den_zero:
                    856:        tst.l   d7              ;check sign of the k-factor
                    857:        blt.b   use_ilog        ;if negative, use ILOG
                    858:        fmove.s F4933,fp0       ;force exponent to 4933
                    859:        bra.b   convrt          ;do it
                    860: use_ilog:
                    861:        fmove.l d6,fp0          ;float ILOG
                    862:        fabs.x  fp0             ;get abs of ILOG
                    863:        bra.b   convrt
                    864: not_denorm:
                    865:        ftst.x  fp0             ;test for zero
                    866:        fbne.w  not_zero        ;if zero, force exponent
                    867:        fmove.s FONE,fp0        ;force exponent to 1
                    868:        bra.b   convrt          ;do it
                    869: not_zero:
                    870:        fmove.l d6,fp0          ;float ILOG
                    871:        fabs.x  fp0             ;get abs of ILOG
                    872: convrt:
                    873:        fdiv.x  24(a1),fp0      ;compute ILOG/10^4
                    874:        fmove.x fp0,FP_SCR2(a6) ;store fp0 in memory
                    875:        move.l  4(a2),d2        ;move word 2 to d2
                    876:        move.l  8(a2),d3        ;move word 3 to d3
                    877:        move.w  (a2),d0         ;move exp to d0
                    878:        beq.b   x_loop_fin      ;if zero, skip the shift
                    879:        subi.w  #$3ffd,d0       ;subtract off bias
                    880:        neg.w   d0              ;make exp positive
                    881: x_loop:
                    882:        lsr.l   #1,d2           ;shift d2:d3 right
                    883:        roxr.l  #1,d3           ;the number of places
                    884:        dbf.w   d0,x_loop       ;given in d0
                    885: x_loop_fin:
                    886:        clr.l   d1              ;put zero in d1 for addx
                    887:        addi.l  #$00000080,d3   ;inc at bit 6
                    888:        addx.l  d1,d2           ;continue inc
                    889:        andi.l  #$ffffff80,d3   ;strip off lsb not used by 882
                    890:        move.l  #4,d0           ;put 4 in d0 for binstr call
                    891:        lea.l   L_SCR1(a6),a0   ;a0 is ptr to L_SCR1 for exp digits
                    892:        bsr     binstr          ;call binstr to convert exp
                    893:        move.l  L_SCR1(a6),d0   ;load L_SCR1 lword to d0
                    894:        move.l  #12,d1          ;use d1 for shift count
                    895:        lsr.l   d1,d0           ;shift d0 right by 12
                    896:        bfins   d0,FP_SCR1(a6){4:12} ;put e3:e2:e1 in FP_SCR1
                    897:        lsr.l   d1,d0           ;shift d0 right by 12
                    898:        bfins   d0,FP_SCR1(a6){16:4} ;put e4 in FP_SCR1
                    899:        tst.b   d0              ;check if e4 is zero
                    900:        beq.b   A16_st          ;if zero, skip rest
                    901:        or.l    #opaop_mask,USER_FPSR(a6) ;set OPERR & AIOP in USER_FPSR
                    902:
                    903:
                    904: * A16. Write sign bits to final string.
                    905: *         Sigma is bit 31 of initial value; RHO is bit 31 of d6 (ILOG).
                    906: *
                    907: * Register usage:
                    908: *      Input/Output
                    909: *      d0: x/scratch - final is x
                    910: *      d2: x/x
                    911: *      d3: x/x
                    912: *      d4: LEN/Unchanged
                    913: *      d5: ICTR:LAMBDA/LAMBDA:ICTR
                    914: *      d6: ILOG/ILOG adjusted
                    915: *      d7: k-factor/Unchanged
                    916: *      a0: ptr to L_SCR1(a6)/Unchanged
                    917: *      a1: ptr to PTENxx array/Unchanged
                    918: *      a2: ptr to FP_SCR2(a6)/Unchanged
                    919: *      fp0: float(ILOG)/Unchanged
                    920: *      fp1: 10^ISCALE/Unchanged
                    921: *      fp2: 10^LEN/Unchanged
                    922: *      F_SCR1:BCD result with correct signs
                    923: *      F_SCR2:ILOG/10^4
                    924: *      L_SCR1:Exponent digits on return from binstr
                    925: *      L_SCR2:first word of X packed/Unchanged
                    926:
                    927: A16_st:
                    928:        clr.l   d0              ;clr d0 for collection of signs
                    929:        andi.b  #$0f,FP_SCR1(a6) ;clear first nibble of FP_SCR1
                    930:        tst.l   L_SCR2(a6)      ;check sign of original mantissa
                    931:        bge.b   mant_p          ;if pos, don't set SM
                    932:        moveq.l #2,d0           ;move 2 in to d0 for SM
                    933: mant_p:
                    934:        tst.l   d6              ;check sign of ILOG
                    935:        bge.b   wr_sgn          ;if pos, don't set SE
                    936:        addq.l  #1,d0           ;set bit 0 in d0 for SE
                    937: wr_sgn:
                    938:        bfins   d0,FP_SCR1(a6){0:2} ;insert SM and SE into FP_SCR1
                    939:
                    940: * Clean up and restore all registers used.
                    941:
                    942:        fmove.l #0,FPSR         ;clear possible inex2/ainex bits
                    943:        fmovem.x (a7)+,fp0-fp2
                    944:        movem.l (a7)+,d2-d7/a2
                    945:        rts
                    946:
                    947:        end

CVSweb