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

  1.  ! C68 8 byte floating point divide routine
  2.  !-----------------------------------------------------------------------------
  3.  ! ported to 68000 by Kai-Uwe Bloem, 12/89
  4.  !  #1    original author: Peter S. Housel 4/8/89,6/2/89,6/13/89
  5.  !  #2    added support for denormalized numbers            -kub-, 01/90
  6.  !  #3    change loop criterion for division loop to have a 1 behind the implied
  7.  !    1 position of result. This gives greater accuracy, especially when
  8.  !    dealing with denormalized numbers (although there are now eventually
  9.  !    8 bits which are no longer calculated - .norm8 uses 4 of them for
  10.  !    rounding)                        -kub-, 01/90
  11.  !  bugs:
  12.  !    Division has only 4 rounding bits. There is no "sticky bit" information.
  13.  !    Due to speed improvements the code is rather cryptic.
  14.  !  #4  Redid register usage, and then added wrapper routine
  15.  !    to provide C68 IEEE compatibility    Dave & Keith Walker    02/92
  16.  !  #5  Changed exit code to put pointer to result in D0   Dave Walker  12/92
  17.  !  #6  Changed entry/exit points so that these are now C68 compatible,
  18.  !    Removed ACK entry points
  19.  !    Changed error handling code                 -djw-    09/93
  20.  !-----------------------------------------------------------------------------
  21.  
  22. SAVEREG    =    6*4        !  size of saved registers on stack
  23. BIAS8    =    0x3FF - 1
  24.  
  25.     .sect .text
  26.  
  27.     .define .Xdfdiv
  28.     .define .Xasdfdiv
  29.  
  30. !----------------------------------------
  31. !    sp    Return address
  32. !    sp+4    address of result
  33. !    sp+8    address of second operand
  34. !    sp+12    address of first operand
  35. !----------------------------------------
  36. .Xdfdiv:
  37.     movem.l    d2-d7,-(sp)        ! save registers
  38.     move.l    SAVEREG+12(sp),a1    ! address of v
  39.     movem.l    (a1),d4-d5        ! load v
  40.     move.l    SAVEREG+8(sp),a1    ! address of u
  41.     movem.l    (a1),d6-d7        ! load u
  42.     move.l    SAVEREG+4(sp),a1    ! result address
  43.     bsr    dfdivide
  44.     movem.l    (sp)+,d2-d7
  45.  
  46.     move.l    (sp)+,a1        ! get return address
  47.     lea    12(sp),sp        ! remove 3 parameters from stack
  48.     jmp    (a1)            ! ... and return
  49.  
  50. !----------------------------------------
  51. !    sp    Return address
  52. !    sp+4    address of result/first operand
  53. !    sp+8    address of second operand
  54. !----------------------------------------
  55. .Xasdfdiv:
  56.     movem.l    d2-d7,-(sp)        ! save registers
  57.     move.l    SAVEREG+8(sp),a1    ! address of v
  58.     movem.l    (a1),d4-d5        ! load v
  59.     move.l    SAVEREG+4(sp),a1    ! address of u / result address
  60.     movem.l    (a1),d6-d7        ! load u
  61.     bsr    dfdivide
  62.     movem.l    (sp)+,d2-d7
  63.  
  64.     move.l    (sp)+,a1        ! get return address
  65.     move.l    (sp),d0            ! address of v returned as result
  66.     addq.l    #8,sp            ! remove 2 parameters from stack
  67.     jmp    (a1)            ! ... and return
  68.  
  69.  !-------------------------------------------------------------------------
  70.  ! This is the routine that actually carries out the operation.
  71.  !
  72.  ! Register usage:
  73.  !
  74.  !        Entry                Exit
  75.  !
  76.  !    d0    ?                undefined
  77.  !    d1    ?                undefined
  78.  !    d2    ?                undefined
  79.  !    d3    ?                undefined
  80.  !    d4-d5    v                undefined
  81.  !    d6-d7    u                undefined
  82.  !
  83.  !    A1    Address for result        preserved
  84.  !
  85.  !-----------------------------------------------------------------------------
  86.  
  87. dfdivide:
  88.     move.l    d6,d0        ! d0 = u.exp
  89.     swap    d0
  90.     move.w    d0,d2        ! d2 = u.sign
  91.  
  92.     move.l    d4,d1        ! d1 = v.exp
  93.     swap    d1
  94.     eor.w    d1,d2        ! d2 = u.sign ^ v.sign (in bit 31)
  95.  
  96.     and.l    #0x0fffff,d6    ! remove exponent from u.mantissa
  97.     lsr.w    #4,d0
  98.     and.w    #0x07ff,d0    ! kill sign bit
  99.     beq    0f        ! check for zero exponent - no leading "1"
  100.     or.l    #0x100000,d6    ! restore implied leading "1"
  101.     bra    1f
  102. 0:    add.w    #1,d0        ! "normalize" exponent
  103. 1:    move.l    d6,d3
  104.     or.l    d7,d3
  105.     beq    retz        ! dividing zero
  106.  
  107.     and.l    #0x0fffff,d4    ! remove exponent from v.mantissa
  108.     lsr.w    #4,d1
  109.     and.w    #0x07ff,d1    ! kill sign bit
  110.     beq    0f        ! check for zero exponent - no leading "1"
  111.     or.l    #0x100000,d4    ! restore implied leading "1"
  112.     bra    1f
  113. 0:    add.w    #1,d1        ! "normalize" exponent
  114. 1:    move.l    d4,d3
  115.     or.l    d5,d3
  116.     beq    divz        ! divide by zero
  117.  
  118.     move.w    d2,a0        ! save sign
  119.  
  120.     sub.w    d1,d0        ! subtract exponents,
  121.     add.w    #BIAS8-11+1,d0    !  add bias back in, account for shift
  122.     add.w    #66,d0        !  add loop offset, +2 for extra rounding bits
  123.                 !   for denormalized numbers (2 implied by dbra)
  124.     move    #24,d1        ! bit number for "implied" pos (+4 for rounding)
  125.     move.l    #-1,d2        ! zero the quotient
  126.     move.l    #-1,d3        !  (for speed it is a one s complement)
  127.     sub.l    d5,d7        ! initial subtraction,
  128.     subx.l    d4,d6        ! u = u - v
  129. 2:
  130.     btst    d1,d2        ! divide until 1 in implied position
  131.     beq    5f
  132.  
  133.     add.l    d7,d7
  134.     addx.l    d6,d6
  135.     bcs    4f        ! if carry is set, add, else subtract
  136.  
  137.     addx.l    d3,d3        ! shift quotient and set bit zero
  138.     addx.l    d2,d2
  139.     sub.l    d5,d7        ! subtract
  140.     subx.l    d4,d6        ! u = u - v
  141.     dbra    d0,2b        ! give up if result is denormalized
  142.     bra    5f
  143. 4:
  144.     addx.l    d3,d3        ! shift quotient and clear bit zero
  145.     addx.l    d2,d2
  146.     add.l    d5,d7        ! add (restore)
  147.     addx.l    d4,d6        ! u = u + v
  148.     dbra    d0,2b        ! give up if result is denormalized
  149. 5:    sub.w    #2,d0        ! remove rounding offset for denormalized nums
  150.     not.l    d2        ! invert quotient to get it right
  151.     not.l    d3
  152.  
  153.     movem.l    d2-d3,(a1)    ! save quotient mantissa
  154.     move.w    a0,d2        ! get sign back
  155.     clr.w    d1        ! zero rounding bits
  156.     jmp    .Xnorm8        ! (a1 still points to result)
  157.  
  158.  
  159. retz:    clr.l    (a1)        ! zero destination
  160.     clr.l    4(a1)
  161.     rts            ! no normalization needed
  162.  
  163. divz:
  164.     jsr    .divzero    ! call exception routine
  165.     movem.l    d0-d1,(a1)    ! store result if control returned
  166.     rts            ! ... and exit
  167.