home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / gnu / libsrc87 / _addsubd.cpp next >
Encoding:
Text File  |  1993-07-30  |  6.7 KB  |  300 lines

  1. |
  2. | double floating point add/subtract routine
  3. |
  4. #ifndef __M68881__
  5.     .text
  6.     .even
  7.     .globl    __subdf3, ___subdf3
  8.     .globl    __adddf3, ___adddf3
  9. # ifndef    sfp004
  10. |
  11. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  12. | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
  13. | patched by Olaf Flebbe (flebbe@tat.physik.uni-tuebingen.de)
  14. |
  15. | Revision 1.3.4 olaf 11-92 :
  16. |  + added support for NaN and infinities
  17. |    > floating point is now excellent!
  18. |
  19. |  -- still lacks trap handling for exceptions
  20. |  -- dont know the external representation of quiet and signaling NaN
  21. |     I decided 0x7fffffff,ffffffff to be a quiet NaN
  22. |     the rest should be signaling (but isnt)
  23. |
  24. | Revision 1.3.3 olaf 11-92 :
  25. |  + changed to get rid of rounding bits. a sticky register (d3) is
  26. |    sufficient. 
  27. | Revision 1.3.2 olaf 10-92 :
  28. |  + increased comparson by one again. (Dont understand, but it works)
  29. |  + corrected negation of rounding bits and mantissa
  30. |     >enquire now detects correct IEEE precision
  31. |     >paranoia now qualifies add/sub as correctly rounded
  32. |
  33. | Revision 1.3.1 olaf 10-92 :
  34. |  + increased comparison of exponents by one.
  35. |  + initialized sticky byte
  36. |  + corrected handling of rounding bits
  37. |     >paranoia now detects no SERIOUS DEFECTS any more
  38. |     ** Patches need _normdf Rev 1.6.1 (or higher) **
  39. |
  40. | Revision 1.3, kub 01-90 :
  41. | added support for denormalized numbers
  42. |
  43. | Revision 1.2, kub 01-90 :
  44. | replace far shifts by swaps to gain speed
  45. |
  46. | Revision 1.1, kub 12-89 :
  47. | Ported over to 68k assembler
  48. |
  49. | Revision 1.0:
  50. | original 8088 code from P.S.Housel
  51.  
  52. __subdf3:
  53. ___subdf3:
  54.     eorb    #0x80,sp@(12)    | reverse sign of v
  55. __adddf3:
  56. ___adddf3:
  57.     lea    sp@(4),a0    | pointer to u and v parameter
  58.     moveml    d2-d7,sp@-    | save registers
  59.     moveml    a0@,d4-d5/d6-d7    | d4-d5 = v, d6-d7 = u
  60.  
  61.     movel    d6,d0        | d0 = u.exp
  62.     swap    d0
  63.     movel    d6,d2        | d2.h = u.sign
  64.     movew    d0,d2
  65.     lsrw    #4,d0
  66.     andw    #0x07ff,d0    | kill sign bit
  67.  
  68.     movel    d4,d1        | d1 = v.exp
  69.     swap    d1
  70.     eorw    d1,d2        | d2.l = u.sign ^ v.sign
  71.     lsrw    #4,d1
  72.     andw    #0x07ff,d1    | kill sign bit
  73.  
  74.     andl    #0x0fffff,d6    | remove exponent from u.mantissa
  75.     andl    #0x0fffff,d4    | remove exponent from v.mantissa
  76. |
  77. | Now perform testing of NaN And infinities
  78. |
  79.     cmpw    #0x07ff,d0
  80.     beq    0f
  81.     cmpw    #0x07ff,d1
  82.     bne    nospec
  83.     bra    1f
  84. |    first operand is special
  85. |
  86. 0:    cmpw    d0,d1
  87.     beq    bothspec
  88. |
  89. |    u is special
  90.     movel    d7,d0
  91.     orl    d6,d0
  92.     bne    retnan        | arith with Nan gives always Nan
  93.  
  94.     movel    a0@(8),d0        | copy infinity
  95.     clrl    d1
  96.     bra     return
  97. |
  98. |    v is special
  99. |
  100. 1:    movel    d5,d0
  101.     orl    d4,d0
  102.     bne    retnan
  103.     movel    a0@,d0
  104.     clrl    d1
  105.     bra    return
  106. |
  107. |    u and v are both special
  108. |
  109. bothspec:
  110.     movel    d7,d0
  111.     orl    d6,d0
  112.     orl    d5,d0
  113.     orl    d4,d0
  114.     beq    bothinf
  115.     bra    retnan    
  116. |
  117. | Both are infinities Test if cancellation
  118. bothinf:
  119.     tstw    d2
  120.     bpl    retinf    
  121. |
  122. | return a quiet NaN
  123. |
  124. retnan:    movel    #0x7fffffff,d0
  125.     moveql  #-1,d1
  126.     bra    return
  127.  
  128. retinf: movel   #0x7ff00000,d0
  129.     clrl    d1
  130.     tstl    d2
  131.     bpl    return
  132.     bchg    #31,d0
  133. return:    moveml    sp@+,d2-d7
  134.     rts
  135. |    
  136. | Ok, no inifinty or Nan involved..
  137. |
  138. nospec:    tstw    d0        | check for zero exponent - no leading "1"
  139.     beq    0f
  140.     orl    #0x100000,d6    | restore implied leading "1"
  141.     bra    1f
  142. 0:    addw    #1,d0        | "normalize" exponent
  143. 1:
  144.     tstw    d1        | check for zero exponent - no leading "1"
  145.     beq    0f
  146.     orl    #0x100000,d4    | restore implied leading "1"
  147.     bra    1f
  148. 0:    addw    #1,d1        | "normalize" exponent
  149. 1:
  150.     clrl    d3        | init sticky register
  151.     negw    d1        | d1 = u.exp - v.exp
  152.     addw    d0,d1
  153.     beq    5f        | exponents are equal - no shifting neccessary
  154.     bgt    1f        | not equal but no exchange neccessary
  155.     exg    d4,d6        | exchange u and v
  156.     exg    d5,d7
  157.     subw    d1,d0        | d0 = u.exp - (u.exp - v.exp) = v.exp
  158.     negw    d1
  159.     tstw    d2        | d2.h = u.sign ^ (u.sign ^ v.sign) = v.sign
  160.     bpl    1f
  161.     bchg    #31,d2
  162. 1:
  163.     cmpw    #55,d1        | is u so much bigger that v is not
  164.     bge    7f        | significant ?
  165. |
  166. | shift mantissa left two digits, to allow cancellation of
  167. | most significant digit, while gaining an additional digit for
  168. | rounding.
  169. |
  170.     moveql  #1,d3    
  171. 2:    addl    d7,d7
  172.     addxl    d6,d6
  173.     subw    #1,d0        | decrement exponent
  174.     subw    #1,d1        | decrement counter
  175.     dbeq    d3,2b
  176.     clrl    d3
  177. |
  178. | now shift other mantissa right as fast as possible (almost).
  179. |
  180. 3:    
  181.     cmpw    #16,d1        | see if fast rotate possible
  182.     blt    4f
  183.     orw    d5,d3        | set sticky word
  184.     movew    d4,d5        | rotate by swapping register halfs
  185.     swap    d5
  186.     clrw    d4
  187.     swap    d4
  188.     subw    #16,d1
  189.     bra    3b
  190.  
  191. 0:    moveb   d5,d2        | use d2.b as scratch
  192.     andb    #1,d2        | test if 1 is shifted out
  193.     orb    d2,d3        | and put it in sticky 
  194.     lsrl    #1,d4        | shift v.mant right the rest of the way
  195.     roxrl    #1,d5        | to line it up with u.mant
  196. 4:    dbra    d1,0b        | loop
  197.     
  198. 5:
  199.     tstw    d2        | are the signs equal ?
  200.     bpl    6f        | yes, no negate necessary
  201. |
  202. | negate secand mantissa. One has to check the sticky word in order
  203. | to correct the twos complement.
  204. |
  205.     tstw    d3        | 
  206.     beq     9f        | No cerrection necessary
  207.     clrl    d1
  208.     addql   #1,d5
  209.     addxl   d1,d4
  210. 9:    negl    d5
  211.     negxl    d4
  212.         
  213. 6:
  214.     addl    d5,d7        | u.mant = u.mant + v.mant
  215.     addxl    d4,d6
  216.     bcs    7f        | need not negate
  217.     tstw    d2        | opposite signs ?
  218.     bpl    7f        | do not need to negate result
  219.  
  220.     negl    d7
  221.     negxl    d6
  222.     notl    d2        |     switch sign
  223. 7:
  224.     movel    d6,d4        | move result for normalization
  225.     movel    d7,d5
  226.     clrl    d1
  227.     tstl    d3
  228.     beq     8f
  229.     moveql   #-1,d1
  230. 8:    swap    d2        | put sign into d2 (exponent is in d0)
  231.     jmp    norm_df        | leave registers on stack for norm_df
  232. #else    sfp004
  233. | double precision floating point stuff for Atari-gcc using the SFP004
  234. | developed with gas
  235. |
  236. | double floating point add/subtract routine
  237. |
  238. | M. Ritzert (mjr at dmzrzu71)
  239. |
  240. | 4.10.1990
  241. |
  242. | no NAN checking implemented since the 68881 treats this situation "correct",
  243. | i.e. according to IEEE
  244.  
  245. | addresses of the 68881 data port. This choice is fastest when much data is
  246. | transferred between the two processors.
  247.  
  248. comm =     -6
  249. resp =    -16
  250. zahl =      0
  251.  
  252. | waiting loop ...
  253. |
  254. | wait:
  255. | ww:    cmpiw    #0x8900,a0@(resp)
  256. |     beq    ww
  257. | is coded directly by
  258. |    .long    0x0c688900, 0xfff067f8
  259.  
  260. __subdf3:
  261. ___subdf3:
  262. | double precision subtraction
  263. | sub second arg from fp0
  264.     lea    0xfffffa50:w,a0
  265.     movew    #0x5400,a0@(comm)    | load first argument to fp0
  266.     cmpiw    #0x8900,a0@(resp)    | check
  267.     movel    a7@(4),a0@
  268.     movel    a7@(8),a0@
  269.     movew    #0x5428,a0@(comm)
  270.     .long    0x0c688900, 0xfff067f8
  271.     movel    a7@(12),a0@
  272.     movel    a7@(16),a0@
  273.     movew    #0x7400,a0@(comm)    | result to d0/d1
  274.     .long    0x0c688900, 0xfff067f8
  275.     movel    a0@,d0
  276.     movel    a0@,d1
  277.      rts
  278.  
  279. __adddf3:
  280. ___adddf3:
  281.     lea    0xfffffa50:w,a0
  282.     movew    #0x5400,a0@(comm)        | load fp0
  283.     cmpiw    #0x8900,a0@(resp)        | got it?
  284.     movel    a7@(4),a0@            | take a hi from stack to FPU
  285.     movel    a7@(8),a0@            | take a lo from stack to FPU
  286.     movew    #0x5422,a0@(comm)        | add second arg to fp0
  287.     .long    0x0c688900, 0xfff067f8
  288.     movel    a7@(12),a0@            | move b hi from stack to FPU
  289.     movel    a7@(16),a0@            | move b lo from stack to FPU
  290.     movew    #0x7400,a0@(comm)        | result to d0/d1
  291.     .long    0x0c688900, 0xfff067f8
  292.     movel    a0@,d0                | download result
  293.     movel    a0@,d1                | download result
  294.      rts
  295. #endif    sfp004
  296. #endif    __M68881__
  297.