home *** CD-ROM | disk | FTP | other *** search
- |
- | single floating point add/subtract routine
- |
- #ifndef __M68881__
- .text
- .even
- .globl __subsf3, ___subsf3
- .globl __addsf3, ___addsf3
- # ifndef sfp004
- |
- | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
- | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
- |
- | Revision 1.3, kub 01-90 :
- | added support for denormalized numbers
- |
- | Revision 1.2, kub 01-90 :
- | replace far shifts by swaps to gain speed (more optimization is of course
- | possible by doing shifts all in one intruction, but what about the rounding
- | bits)
- |
- | Revision 1.1, kub 12-89 :
- | Created single float version for 68000
- |
- | Revision 1.0:
- | original 8088 code from P.S.Housel for double floats
-
- __subsf3:
- ___subsf3:
- eorb #0x80,sp@(8) | reverse sign of v
- __addsf3:
- ___addsf3:
- lea sp@(4),a0 | pointer to u and v parameter
- moveml d2-d5,sp@- | save registers
- moveml a0@,d4/d5 | d4 = v, d5 = u
-
- movel d5,d0 | d0 = u.exp
- swap d0
- movel d5,d2 | d2.h = u.sign
- movew d0,d2
- lsrw #7,d0
- andw #0xff,d0 | kill sign bit (exponent is 8 bits)
-
- movel d4,d1 | d1 = v.exp
- swap d1
- eorw d1,d2 | d2.l = u.sign ^ v.sign
- lsrw #7,d1
- andw #0xff,d1 | kill sign bit (exponent is 8 bits)
-
- andl #0x7fffff,d5 | remove exponent from mantissa
- tstw d0 | check for zero exponent - no leading "1"
- beq 0f
- orl #0x800000,d5 | restore implied leading "1"
- bra 1f
- 0: addw #1,d0 | "normalize" exponent
- 1:
- andl #0x7fffff,d4 | remove exponent from mantissa
- tstw d1 | check for zero exponent - no leading "1"
- beq 0f
- orl #0x800000,d4 | restore implied leading "1"
- bra 1f
- 0: addw #1,d1 | "normalize" exponent
- 1:
- clrw d3 | (put initial zero rounding bits in d3)
- negw d1 | d1 = u.exp - v.exp
- addw d0,d1
- beq 5f | exponents are equal - no shifting neccessary
- bgt 1f | not equal but no exchange neccessary
- exg d4,d5 | exchange u and v
- subw d1,d0 | d0 = u.exp - (u.exp - v.exp) = v.exp
- negw d1
- tstw d2 | d2.h = u.sign ^ (u.sign ^ v.sign) = v.sign
- bpl 1f
- bchg #31,d2
- 1:
- cmpw #24,d1 | is u so much bigger that v is not
- bge 7f | significant ?
-
- movew #7-1,d3 | shift u left up to 7 bits to minimize loss
- 2:
- addl d5,d5
- subw #1,d0 | decrement exponent
- subw #1,d1 | done shifting altogether ?
- dbeq d3,2b | loop if still can shift u.mant more
- clrw d3
-
- cmpw #16,d1 | see if fast rotate possible
- blt 4f
- orb d4,d3 | set rounding bits
- orb d2,d3
- sne d2 | "sticky byte"
- movew d4,d3
- lsrw #8,d3
- clrw d4 | rotate by swapping register halfs
- swap d4
- subw #16,d1
- 0:
- lsrl #1,d4 | shift v.mant right the rest of the way
- orb d3,d2 | set "sticky byte" if necessary
- roxrw #1,d3 | shift into rounding bits
- 4: dbra d1,0b | loop
- andb #1,d2 | see if "sticky bit" should be set
- orb d2,d3
- 5:
- tstw d2 | are the signs equal ?
- bpl 6f | yes, no negate necessary
-
- negb d3 | negate rounding bits and v.mant
- negl d4
- 6:
- addl d4,d5 | u.mant = u.mant + v.mant
- bcs 7f | needn not negate
- tstw d2 | opposite signs ?
- bpl 7f | do not need to negate result
-
- negb d3 | negate rounding bits and u.mant
- negl d5
- notl d2 | switch sign
- 7:
- movel d5,d4 | move result for normalization
- moveb d3,d1 | put rounding bits in d1 for norm_sf
- swap d2 | put sign into d2 (exponent is in d0)
- jmp norm_sf | leave registers on stack for norm_sf
-
- # else sfp004
-
- | single precision floating point stuff for Atari-gcc using the SFP004
- | developed with gas
- |
- | single floating point add/subtract routine
- |
- | M. Ritzert (mjr at dmzrzu71)
- |
- | 4.10.1990
- |
- | no NAN checking implemented since the 68881 treats this situation "correct",
- | i.e. according to IEEE
-
- | addresses of the 68881 data port. This choice is fastest when much data is
- | transferred between the two processors.
-
- comm = -6
- resp = -16
- zahl = 0
-
- | waiting loop ...
- |
- | wait:
- | ww: cmpiw #0x8900,a0@(resp)
- | beq ww
- | is coded directly by
- | .long 0x0c688900, 0xfff067f8
-
- __subsf3:
- ___subsf3:
- lea 0xfffffa50:w,a0
- movew #0x4400,a0@(comm) | load first argument to fp0
- cmpiw #0x8900,a0@(resp) | check
- movel a7@(4),a0@
- movew #0x4428,a0@(comm)
- .long 0x0c688900, 0xfff067f8
- movel a7@(8),a0@
- movew #0x6400,a0@(comm) | result to d0
- .long 0x0c688900, 0xfff067f8
- movel a0@,d0
- rts
-
- __addsf3:
- ___addsf3:
- lea 0xfffffa50:w,a0
- movew #0x4400,a0@(comm) | load fp0
- cmpiw #0x8900,a0@(resp) | got it?
- movel a7@(4),a0@ | take a from stack to FPU
- movew #0x4422,a0@(comm) | add second arg to fp0
- .long 0x0c688900, 0xfff067f8
- movel a7@(8),a0@ | move b from stack to FPU
- movew #0x6400,a0@(comm) | result to d0
- .long 0x0c688900, 0xfff067f8
- movel a0@,d0 | download result
- rts
-
- # endif sfp004
- #endif __M68881__
-