home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / mint / mntlib24 / _addsubs.cpp < prev    next >
Encoding:
Text File  |  1993-08-03  |  4.6 KB  |  184 lines

  1. |
  2. | single floating point add/subtract routine
  3. |
  4. #ifndef    __M68881__
  5.     .text
  6.     .even
  7.     .globl    __subsf3, ___subsf3
  8.     .globl    __addsf3, ___addsf3
  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. |
  14. | Revision 1.3, kub 01-90 :
  15. | added support for denormalized numbers
  16. |
  17. | Revision 1.2, kub 01-90 :
  18. | replace far shifts by swaps to gain speed (more optimization is of course
  19. | possible by doing shifts all in one intruction, but what about the rounding
  20. | bits)
  21. |
  22. | Revision 1.1, kub 12-89 :
  23. | Created single float version for 68000
  24. |
  25. | Revision 1.0:
  26. | original 8088 code from P.S.Housel for double floats
  27.  
  28. __subsf3:
  29. ___subsf3:
  30.     eorb    #0x80,sp@(8)    | reverse sign of v
  31. __addsf3:
  32. ___addsf3:
  33.     lea    sp@(4),a0    | pointer to u and v parameter
  34.     moveml    d2-d5,sp@-    | save registers
  35.     moveml    a0@,d4/d5    | d4 = v, d5 = u
  36.  
  37.     movel    d5,d0        | d0 = u.exp
  38.     swap    d0
  39.     movel    d5,d2        | d2.h = u.sign
  40.     movew    d0,d2
  41.     lsrw    #7,d0
  42.     andw    #0xff,d0    | kill sign bit (exponent is 8 bits)
  43.  
  44.     movel    d4,d1        | d1 = v.exp
  45.     swap    d1
  46.     eorw    d1,d2        | d2.l = u.sign ^ v.sign
  47.     lsrw    #7,d1
  48.     andw    #0xff,d1    | kill sign bit (exponent is 8 bits)
  49.  
  50.     andl    #0x7fffff,d5    | remove exponent from mantissa
  51.     tstw    d0        | check for zero exponent - no leading "1"
  52.     beq    0f
  53.     orl    #0x800000,d5    | restore implied leading "1"
  54.     bra    1f
  55. 0:    addw    #1,d0        | "normalize" exponent
  56. 1:
  57.     andl    #0x7fffff,d4    | remove exponent from mantissa
  58.     tstw    d1        | check for zero exponent - no leading "1"
  59.     beq    0f
  60.     orl    #0x800000,d4    | restore implied leading "1"
  61.     bra    1f
  62. 0:    addw    #1,d1        | "normalize" exponent
  63. 1:
  64.     clrw    d3        | (put initial zero rounding bits in d3)
  65.     negw    d1        | d1 = u.exp - v.exp
  66.     addw    d0,d1
  67.     beq    5f        | exponents are equal - no shifting neccessary
  68.     bgt    1f        | not equal but no exchange neccessary
  69.     exg    d4,d5        | exchange u and v
  70.     subw    d1,d0        | d0 = u.exp - (u.exp - v.exp) = v.exp
  71.     negw    d1
  72.     tstw    d2        | d2.h = u.sign ^ (u.sign ^ v.sign) = v.sign
  73.     bpl    1f
  74.     bchg    #31,d2
  75. 1:
  76.     cmpw    #24,d1        | is u so much bigger that v is not
  77.     bge    7f        | significant ?
  78.  
  79.     movew    #7-1,d3        | shift u left up to 7 bits to minimize loss
  80. 2:
  81.     addl    d5,d5
  82.     subw    #1,d0        | decrement exponent
  83.     subw    #1,d1        | done shifting altogether ?
  84.     dbeq    d3,2b        | loop if still can shift u.mant more
  85.     clrw    d3
  86.  
  87.     cmpw    #16,d1        | see if fast rotate possible
  88.     blt    4f
  89.     orb    d4,d3        | set rounding bits
  90.     orb    d2,d3
  91.     sne    d2        | "sticky byte"
  92.     movew    d4,d3
  93.     lsrw    #8,d3
  94.     clrw    d4        | rotate by swapping register halfs
  95.     swap    d4
  96.     subw    #16,d1
  97. 0:
  98.     lsrl    #1,d4        | shift v.mant right the rest of the way
  99.     orb    d3,d2        | set "sticky byte" if necessary
  100.     roxrw    #1,d3        | shift into rounding bits
  101. 4:    dbra    d1,0b        | loop
  102.     andb    #1,d2        | see if "sticky bit" should be set
  103.     orb    d2,d3
  104. 5:
  105.     tstw    d2        | are the signs equal ?
  106.     bpl    6f        | yes, no negate necessary
  107.  
  108.     negb    d3        | negate rounding bits and v.mant
  109.     negl    d4
  110. 6:
  111.     addl    d4,d5        | u.mant = u.mant + v.mant
  112.     bcs    7f        | needn not negate
  113.     tstw    d2        | opposite signs ?
  114.     bpl    7f        | do not need to negate result
  115.  
  116.     negb    d3        | negate rounding bits and u.mant
  117.     negl    d5
  118.     notl    d2        | switch sign
  119. 7:
  120.     movel    d5,d4        | move result for normalization
  121.     moveb    d3,d1        | put rounding bits in d1 for norm_sf
  122.     swap    d2        | put sign into d2 (exponent is in d0)
  123.     jmp    norm_sf        | leave registers on stack for norm_sf
  124.  
  125. # else    sfp004
  126.  
  127. | single precision floating point stuff for Atari-gcc using the SFP004
  128. | developed with gas
  129. |
  130. |  single floating point add/subtract routine
  131. |
  132. | M. Ritzert (mjr at dmzrzu71)
  133. |
  134. | 4.10.1990
  135. |
  136. | no NAN checking implemented since the 68881 treats this situation "correct",
  137. | i.e. according to IEEE
  138.  
  139. | addresses of the 68881 data port. This choice is fastest when much data is
  140. | transferred between the two processors.
  141.  
  142. comm =     -6
  143. resp =    -16
  144. zahl =      0
  145.  
  146. | waiting loop ...
  147. |
  148. | wait:
  149. | ww:    cmpiw    #0x8900,a0@(resp)
  150. |     beq    ww
  151. | is coded directly by
  152. |    .long    0x0c688900, 0xfff067f8
  153.  
  154. __subsf3:
  155. ___subsf3:
  156.     lea    0xfffffa50:w,a0
  157.     movew    #0x4400,a0@(comm)    | load first argument to fp0
  158.     cmpiw    #0x8900,a0@(resp)    | check
  159.     movel    a7@(4),a0@
  160.     movew    #0x4428,a0@(comm)
  161.     .long    0x0c688900, 0xfff067f8
  162.     movel    a7@(8),a0@
  163.     movew    #0x6400,a0@(comm)    | result to d0
  164.     .long    0x0c688900, 0xfff067f8
  165.     movel    a0@,d0
  166.      rts
  167.  
  168. __addsf3:
  169. ___addsf3:
  170.     lea    0xfffffa50:w,a0
  171.     movew    #0x4400,a0@(comm)        | load fp0
  172.     cmpiw    #0x8900,a0@(resp)        | got it?
  173.     movel    a7@(4),a0@            | take a from stack to FPU
  174.     movew    #0x4422,a0@(comm)        | add second arg to fp0
  175.     .long    0x0c688900, 0xfff067f8
  176.     movel    a7@(8),a0@            | move b from stack to FPU
  177.     movew    #0x6400,a0@(comm)        | result to d0
  178.     .long    0x0c688900, 0xfff067f8
  179.     movel    a0@,d0                | download result
  180.      rts
  181.  
  182. # endif    sfp004
  183. #endif    __M68881__
  184.