home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / lib / mntc6846.zoo / patch / dfadd.s next >
Encoding:
Text File  |  1994-11-26  |  5.2 KB  |  192 lines

  1.  ! C68 8 byte floating point add/subtract routines
  2.  !-----------------------------------------------------------------------------
  3.  ! ported to 68000 by Kai-Uwe Bloem, 12/89
  4.  !  #1  original author: Peter S. Housel 9/21/88,01/17/89,03/19/89,5/24/89
  5.  !  #2  replaced shifts by swap if possible for speed increase    -kub-, 01/90
  6.  !  #3  Redid register usage, and then added wrapper routine
  7.  !    to provide C68 IEEE compatibility    Dave & Keith Walker    02/92
  8.  !  #4  Changed exit code to put pointer to result in D0   Dave Walker  12/92
  9.  !  #5  Changed entry point names for use with C68 v4.3
  10.  !    Changed exit code to C68 v4.3 compatibility
  11.  !    Removed ACK entry points.                -djw-    09/93
  12.  !-----------------------------------------------------------------------------
  13.  
  14.     .define .Xdfadd
  15.     .define .Xdfsub
  16.     .define .Xasdfadd
  17.     .define .Xasdfsub
  18.  
  19. SAVEREG    = 6*4        ! Size of saved registers on stack
  20.  
  21.     .sect .text
  22. !----------------------------------------
  23. !    sp    Return address
  24. !    sp+4    address of result
  25. !    sp+8    address of v
  26. !    sp+12    address of u
  27. !----------------------------------------
  28.  
  29. .Xdfadd:
  30.     moveq.l    #0,d0            ! set for add 
  31.     bra    1f
  32. .Xdfsub:
  33.     move.l    #0x80000000,d0         ! set for subtract
  34.  
  35. 1:    movem.l    d2-d7,-(sp)        ! save registers
  36.     move.l    SAVEREG+12(sp),a1    ! address of v
  37.     movem.l    (a1),d4-d5        !  ... load v
  38.     move.l    SAVEREG+8(sp),a1    ! address of u
  39.     movem.l    (a1),d6-d7        !  ... load u
  40.     move.l    SAVEREG+4(sp),a1    ! result address
  41.     bsr    dfaddsub        ! go to do operation
  42.     movem.l    (sp)+,d2-d7        ! restore saved registers
  43.  
  44.     move.l    (sp)+,a1        ! get return address
  45.     lea    12(sp),sp        ! remove 3 parameters from stack
  46.     jmp    (a1)            ! ... and return
  47.  
  48.  
  49. !----------------------------------------
  50. !    sp    Return address
  51. !    sp+4    address of result/v
  52. !    sp+8    address of u
  53. !----------------------------------------
  54.  
  55. .Xasdfadd:
  56.     moveq.l    #0,d0            ! set for add
  57.     bra    1f
  58.  
  59. .Xasdfsub:
  60.     move.l    #0x80000000,d0        ! set for subtract
  61.  
  62. 1:    movem.l    d2-d7,-(sp)        ! save registers
  63.     move.l    SAVEREG+8(sp),a1    ! address of u
  64.     movem.l    (a1),d4-d5        !  ... load u
  65.     move.l    SAVEREG+4(sp),a1    ! address of v / result address
  66.     movem.l    (a1),d6-d7        ! ... load v
  67.     bsr    dfaddsub        ! go to do operation
  68.     movem.l    (sp)+,d2-d7        ! restore saved registers
  69.  
  70.     move.l    (sp)+,a1        ! get return address
  71.     move.l    (sp),d0            ! address of v returned as result
  72.     addq.l    #8,sp            ! remove 2 parameters from stack
  73.     jmp    (a1)            ! ... and return
  74.  
  75.  
  76.  !-------------------------------------------------------------------------
  77.  ! This is the routine that actually carries out the operation.
  78.  !
  79.  ! Register usage:
  80.  !
  81.  !        Entry                Exit
  82.  !
  83.  !    d0    add/subtract mask        undefined
  84.  !    d1    ?                undefined
  85.  !    d2    ?                undefined
  86.  !    d3    ?                undefined
  87.  !    d4-d5    v                undefined
  88.  !    d6-d7    u                undefined
  89.  !
  90.  !    A1    Address for result        preserved
  91.  !
  92.  !-----------------------------------------------------------------------------
  93.  
  94. dfaddsub:
  95.     eor.l    d0,d4        ! reverse sign of v if needed (frees d0 for use)
  96.     move.l    d6,d0        ! d0 = u.exp
  97.     swap    d0
  98.     move.l    d6,d2        ! d2.h = u.sign
  99.     move.w    d0,d2
  100.     lsr.w    #4,d0
  101.     and.w    #0x07ff,d0    ! kill sign bit
  102.  
  103.     move.l    d4,d1        ! d1 = v.exp
  104.     swap    d1
  105.     eor.w    d1,d2        ! d2.l = u.sign ^ v.sign
  106.     lsr.w    #4,d1
  107.     and.w    #0x07ff,d1    ! kill sign bit
  108.  
  109.     and.l    #0x0fffff,d6    ! remove exponent from u.mantissa
  110.     tst.w    d0        ! check for zero exponent - no leading "1"
  111.     beq    0f
  112.     or.l    #0x100000,d6    ! restore implied leading "1"
  113.     bra    1f
  114. 0:    add.w    #1,d0        ! "normalize" exponent
  115. 1:
  116.     and.l    #0x0fffff,d4    ! remove exponent from v.mantissa
  117.     tst.w    d1        ! check for zero exponent - no leading "1"
  118.     beq    0f
  119.     or.l    #0x100000,d4    ! restore implied leading "1"
  120.     bra    1f
  121. 0:    add.w    #1,d1        ! "normalize" exponent
  122. 1:
  123.     clr.w    d3        ! (put initial zero rounding bits in d3)
  124.     neg.w    d1        ! d1 = u.exp - v.exp
  125.     add.w    d0,d1
  126.     beq    5f        ! exponents are equal - no shifting neccessary
  127.     bgt    1f        ! not equal but no exchange neccessary
  128.     exg    d4,d6        ! exchange u and v
  129.     exg    d5,d7
  130.     sub.w    d1,d0        ! d0 = u.exp - (u.exp - v.exp) = v.exp
  131.     neg.w    d1
  132.     tst.w    d2        ! d2.h = u.sign ^ (u.sign ^ v.sign) = v.sign
  133.     bpl    1f
  134.     bchg    #31,d2
  135. 1:
  136.     cmp.w    #53,d1        ! is u so much bigger that v is not
  137.     bge    7f        ! significant ?
  138.  
  139.     move.w    #10-1,d3    ! shift u left up to 10 bits to minimize loss
  140. 2:
  141.     add.l    d7,d7
  142.     addx.l    d6,d6
  143.     sub.w    #1,d0        ! decrement exponent
  144.     sub.w    #1,d1        ! done shifting altogether ?
  145.     dbeq    d3,2b        ! loop if still can shift u.mant more
  146.     clr.w    d3
  147. 3:
  148.     cmp.w    #16,d1        ! see if fast rotate possible
  149.     blt    4f
  150.     or.b    d5,d3        ! set rounding bits
  151.     or.b    d2,d3
  152.     sne    d2        ! "sticky byte"
  153.     move.w    d5,d3
  154.     lsr.w    #8,d3
  155.     move.w    d4,d5        ! rotate by swapping register halfs
  156.     swap    d5
  157.     clr.w    d4
  158.     swap    d4
  159.     sub.w    #16,d1
  160.     bra    3b
  161. 0:
  162.     lsr.l    #1,d4        ! shift v.mant right the rest of the way
  163.     roxr.l    #1,d5        ! to line it up with u.mant
  164.     or.b    d3,d2        ! set "sticky byte" if necessary
  165.     roxr.w    #1,d3        ! shift into rounding bits
  166. 4:    dbra    d1,0b        ! loop
  167.     and.b    #1,d2        ! see if "sticky bit" should be set
  168.     or.b    d2,d3
  169. 5:
  170.     tst.w    d2        ! are the signs equal ?
  171.     bpl    6f        ! yes, no negate necessary
  172.  
  173.     neg.b    d3        ! negate rounding bits and v.mant
  174.     neg.l    d5
  175.     negx.l    d4
  176. 6:
  177.     add.l    d5,d7        ! u.mant = u.mant + v.mant
  178.     addx.l    d4,d6
  179.     bcs    7f        ! need not negate
  180.     tst.w    d2        ! opposite signs ?
  181.     bpl    7f        ! do not need to negate result
  182.  
  183.     neg.b    d3        ! negate rounding bits and u.mant
  184.     neg.l    d7
  185.     negx.l    d6
  186.     not.l    d2        ! switch sign
  187. 7:
  188.     movem.l    d6-d7,(a1)    ! move result on stack
  189.     move.b    d3,d1        ! put rounding bits in d1 for .norm8
  190.     swap    d2        ! put sign into d2
  191.     jmp    .Xnorm8        ! exit via normalising routine
  192.