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

  1. | double 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
  12. |
  13. | Revision 1.1, kub 12-89 :
  14. | Ported over to 68k assembler
  15. |
  16. | Revision 1.0:
  17. | original 8088 code from P.S.Housel
  18.  
  19.     .text
  20.     .even
  21.     .globl    __subdf3, ___subdf3
  22.     .globl    __adddf3, ___adddf3
  23.  
  24. __subdf3:
  25. ___subdf3:
  26.     eorb    #0x80,sp@(12)    | reverse sign of v
  27. __adddf3:
  28. ___adddf3:
  29.     lea    sp@(4),a0    | pointer to u and v parameter
  30.     moveml    d2-d7,sp@-    | save registers
  31.     moveml    a0@,d4-d5/d6-d7    | d4-d5 = v, d6-d7 = u
  32.  
  33.     movel    d6,d0        | d0 = u.exp
  34.     swap    d0
  35.     movel    d6,d2        | d2.h = u.sign
  36.     movew    d0,d2
  37.     lsrw    #4,d0
  38.     andw    #0x07ff,d0    | kill sign bit
  39.  
  40.     movel    d4,d1        | d1 = v.exp
  41.     swap    d1
  42.     eorw    d1,d2        | d2.l = u.sign ^ v.sign
  43.     lsrw    #4,d1
  44.     andw    #0x07ff,d1    | kill sign bit
  45.  
  46.     andl    #0x0fffff,d6    | remove exponent from u.mantissa
  47.     tstw    d0        | check for zero exponent - no leading "1"
  48.     beq    0f
  49.     orl    #0x100000,d6    | restore implied leading "1"
  50.     bra    1f
  51. 0:    addw    #1,d0        | "normalize" exponent
  52. 1:
  53.     andl    #0x0fffff,d4    | remove exponent from v.mantissa
  54.     tstw    d1        | check for zero exponent - no leading "1"
  55.     beq    0f
  56.     orl    #0x100000,d4    | restore implied leading "1"
  57.     bra    1f
  58. 0:    addw    #1,d1        | "normalize" exponent
  59. 1:
  60.     clrw    d3        | (put initial zero rounding bits in d3)
  61.     negw    d1        | d1 = u.exp - v.exp
  62.     addw    d0,d1
  63.     beq    5f        | exponents are equal - no shifting neccessary
  64.     bgt    1f        | not equal but no exchange neccessary
  65.     exg    d4,d6        | exchange u and v
  66.     exg    d5,d7
  67.     subw    d1,d0        | d0 = u.exp - (u.exp - v.exp) = v.exp
  68.     negw    d1
  69.     tstw    d2        | d2.h = u.sign ^ (u.sign ^ v.sign) = v.sign
  70.     bpl    1f
  71.     bchg    #31,d2
  72. 1:
  73.     cmpw    #53,d1        | is u so much bigger that v is not
  74.     bge    7f        | significant ?
  75.  
  76.     movew    #10-1,d3    | shift u left up to 10 bits to minimize loss
  77. 2:
  78.     addl    d7,d7
  79.     addxl    d6,d6
  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. 3:
  85.     cmpw    #16,d1        | see if fast rotate possible
  86.     blt    4f
  87.     orb    d5,d3        | set rounding bits
  88.     orb    d2,d3
  89.     sne    d2        | "sticky byte"
  90.     movew    d5,d3
  91.     lsrw    #8,d3
  92.     movew    d4,d5        | rotate by swapping register halfs
  93.     swap    d5
  94.     clrw    d4
  95.     swap    d4
  96.     subw    #16,d1
  97.     bra    3b
  98. 0:
  99.     lsrl    #1,d4        | shift v.mant right the rest of the way
  100.     roxrl    #1,d5        | to line it up with u.mant
  101.     orb    d3,d2        | set "sticky byte" if necessary
  102.     roxrw    #1,d3        | shift into rounding bits
  103. 4:    dbra    d1,0b        | loop
  104.     andb    #1,d2        | see if "sticky bit" should be set
  105.     orb    d2,d3
  106. 5:
  107.     tstw    d2        | are the signs equal ?
  108.     bpl    6f        | yes, no negate necessary
  109.  
  110.     negb    d3        | negate rounding bits and v.mant
  111.     negl    d5
  112.     negxl    d4
  113. 6:
  114.     addl    d5,d7        | u.mant = u.mant + v.mant
  115.     addxl    d4,d6
  116.     bcs    7f        | needn't negate
  117.     tstw    d2        | opposite signs ?
  118.     bpl    7f        | don't need to negate result
  119.  
  120.     negb    d3        | negate rounding bits and u.mant
  121.     negl    d7
  122.     negxl    d6
  123.     notl    d2        | switch sign
  124. 7:
  125.     movel    d6,d4        | move result for normalization
  126.     movel    d7,d5
  127.     moveb    d3,d1        | put rounding bits in d1 for norm_df
  128.     swap    d2        | put sign into d2 (exponent is in d0)
  129.     jmp    norm_df        | leave registers on stack for norm_df
  130.