home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / mntlib16.lzh / MNTLIB16 / _ADDSUBS.S < prev    next >
Text File  |  1993-07-29  |  3KB  |  122 lines

  1. | single floating point add/subtract routine
  2. |
  3. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  4. | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
  5. |
  6. |
  7. | Revision 1.3, kub 01-90 :
  8. | added support for denormalized numbers
  9. |
  10. | Revision 1.2, kub 01-90 :
  11. | replace far shifts by swaps to gain speed (more optimization is of course
  12. | possible by doing shifts all in one intruction, but what about the rounding
  13. | bits)
  14. |
  15. | Revision 1.1, kub 12-89 :
  16. | Created single float version for 68000
  17. |
  18. | Revision 1.0:
  19. | original 8088 code from P.S.Housel for double floats
  20.  
  21.     .text
  22.     .even
  23.     .globl    __subsf3, ___subsf3
  24.     .globl    __addsf3, ___addsf3
  25.  
  26. __subsf3:
  27. ___subsf3:
  28.     eorb    #0x80,sp@(8)    | reverse sign of v
  29. __addsf3:
  30. ___addsf3:
  31.     lea    sp@(4),a0    | pointer to u and v parameter
  32.     moveml    d2-d5,sp@-    | save registers
  33.     moveml    a0@,d4/d5    | d4 = v, d5 = u
  34.  
  35.     movel    d5,d0        | d0 = u.exp
  36.     swap    d0
  37.     movel    d5,d2        | d2.h = u.sign
  38.     movew    d0,d2
  39.     lsrw    #7,d0
  40.     andw    #0xff,d0    | kill sign bit (exponent is 8 bits)
  41.  
  42.     movel    d4,d1        | d1 = v.exp
  43.     swap    d1
  44.     eorw    d1,d2        | d2.l = u.sign ^ v.sign
  45.     lsrw    #7,d1
  46.     andw    #0xff,d1    | kill sign bit (exponent is 8 bits)
  47.  
  48.     andl    #0x7fffff,d5    | remove exponent from mantissa
  49.     tstw    d0        | check for zero exponent - no leading "1"
  50.     beq    0f
  51.     orl    #0x800000,d5    | restore implied leading "1"
  52.     bra    1f
  53. 0:    addw    #1,d0        | "normalize" exponent
  54. 1:
  55.     andl    #0x7fffff,d4    | remove exponent from mantissa
  56.     tstw    d1        | check for zero exponent - no leading "1"
  57.     beq    0f
  58.     orl    #0x800000,d4    | restore implied leading "1"
  59.     bra    1f
  60. 0:    addw    #1,d1        | "normalize" exponent
  61. 1:
  62.     clrw    d3        | (put initial zero rounding bits in d3)
  63.     negw    d1        | d1 = u.exp - v.exp
  64.     addw    d0,d1
  65.     beq    5f        | exponents are equal - no shifting neccessary
  66.     bgt    1f        | not equal but no exchange neccessary
  67.     exg    d4,d5        | exchange u and v
  68.     subw    d1,d0        | d0 = u.exp - (u.exp - v.exp) = v.exp
  69.     negw    d1
  70.     tstw    d2        | d2.h = u.sign ^ (u.sign ^ v.sign) = v.sign
  71.     bpl    1f
  72.     bchg    #31,d2
  73. 1:
  74.     cmpw    #24,d1        | is u so much bigger that v is not
  75.     bge    7f        | significant ?
  76.  
  77.     movew    #7-1,d3        | shift u left up to 7 bits to minimize loss
  78. 2:
  79.     addl    d5,d5
  80.     subw    #1,d0        | decrement exponent
  81.     subw    #1,d1        | done shifting altogether ?
  82.     dbeq    d3,2b        | loop if still can shift u.mant more
  83.     clrw    d3
  84.  
  85.     cmpw    #16,d1        | see if fast rotate possible
  86.     blt    4f
  87.     orb    d4,d3        | set rounding bits
  88.     orb    d2,d3
  89.     sne    d2        | "sticky byte"
  90.     movew    d4,d3
  91.     lsrw    #8,d3
  92.     clrw    d4        | rotate by swapping register halfs
  93.     swap    d4
  94.     subw    #16,d1
  95. 0:
  96.     lsrl    #1,d4        | shift v.mant right the rest of the way
  97.     orb    d3,d2        | set "sticky byte" if necessary
  98.     roxrw    #1,d3        | shift into rounding bits
  99. 4:    dbra    d1,0b        | loop
  100.     andb    #1,d2        | see if "sticky bit" should be set
  101.     orb    d2,d3
  102. 5:
  103.     tstw    d2        | are the signs equal ?
  104.     bpl    6f        | yes, no negate necessary
  105.  
  106.     negb    d3        | negate rounding bits and v.mant
  107.     negl    d4
  108. 6:
  109.     addl    d4,d5        | u.mant = u.mant + v.mant
  110.     bcs    7f        | needn't negate
  111.     tstw    d2        | opposite signs ?
  112.     bpl    7f        | don't need to negate result
  113.  
  114.     negb    d3        | negate rounding bits and u.mant
  115.     negl    d5
  116.     notl    d2        | switch sign
  117. 7:
  118.     movel    d5,d4        | move result for normalization
  119.     moveb    d3,d1        | put rounding bits in d1 for norm_sf
  120.     swap    d2        | put sign into d2 (exponent is in d0)
  121.     jmp    norm_sf        | leave registers on stack for norm_sf
  122.