home *** CD-ROM | disk | FTP | other *** search
- |
- | single floating point divide routine
- |
- #ifndef __M68881__
- .text
- .even
- .globl __divsf3, ___divsf3
- #ifdef ERROR_CHECK
- #include "errbase.h"
- .globl __infinitysf
-
- LC0:
- .ascii "floating point division by 0\12\15\0"
- .even
- #endif ERROR_CHECK
-
- __divsf3:
- ___divsf3:
-
- #ifdef ERROR_CHECK
- tstl a7@(8) | check if divisor is 0
- bne no_exception
-
- pea pc@(LC0)
- pea Stderr
- jbsr _fprintf |
- addql #8,a7 |
- | set _errno to ERANGE
- moveq #ERANGE,d0
- Emove d0,Errno
- movel __infinitysf,d0 | return signed infinity
- btst #31,a7@(4) | transfer sign of dividend
- beq clear | (mjr++)
- bset #31,d0 |
- rts |
- clear: |
- rts
-
- no_exception:
- #endif ERROR_CHECK
-
- #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.2, kub 01-90 :
- | added support for denormalized numbers
- |
- | 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
-
- BIAS4 = 0x7F-1
-
- lea sp@(4),a0 | pointer to parameters u and v
- moveml d2-d5,sp@- | save registers
- moveml a0@,d4/d5 | d4 = u, d5 = v
-
- movel d4,d0 | d0 = u.exp
- swap d0
- movew d0,d2 | d2 = u.sign
- lsrw #7,d0
- andw #0xff,d0 | kill sign bit
-
- movel d5,d1 | d1 = v.exp
- swap d1
- eorw d1,d2 | d2 = u.sign ^ v.sign (in bit 31)
- lsrw #7,d1
- andw #0xff,d1 | kill sign bit
-
- andl #0x7fffff,d4 | remove exponent from u.mantissa
- tstw d0 | check for zero exponent - no leading "1"
- beq 0f
- orl #0x800000,d4 | restore implied leading "1"
- bra 1f
- 0: addw #1,d0 | "normalize" exponent
- 1:
- # ifndef ERROR_CHECK
- tstl d4
- beq retz | dividing zero
- # endif ERROR_CHECK
-
- andl #0x7fffff,d5 | remove exponent from v.mantissa
- tstw d1 | check for zero exponent - no leading "1"
- beq 0f
- orl #0x800000,d5 | restore implied leading "1"
- bra 1f
- 0: addw #1,d1 | "normalize" exponent
- 1: tstl d5
- beq divz | divide by zero
-
- subw d1,d0 | subtract exponents,
- addw #BIAS4-8+1,d0 | add bias back in, account for shift
- addw #34,d0 | add loop offset, +2 for extra rounding bits
- | for denormalized numbers (2 implied by dbra)
- movew #27,d1 | bit number for "implied" pos (+4 for rounding)
- movel #-1,d3 | zero quotient (for speed a one''s complement)
- subl d5,d4 | initial subtraction, u = u - v
- 2:
- btst d1,d3 | divide until 1 in implied position
- beq 5f
-
- addl d4,d4
- bcs 4f | if carry is set, add, else subtract
-
- addxl d3,d3 | shift quotient and set bit zero
- subl d5,d4 | subtract, u = u - v
- dbra d0,2b | give up if result is denormalized
- bra 5f
- 4:
- addxl d3,d3 | shift quotient and clear bit zero
- addl d5,d4 | add (restore), u = u + v
- dbra d0,2b | give up if result is denormalized
- 5: subw #2,d0 | remove rounding offset for denormalized nums
- notl d3 | invert quotient to get it right
-
- movel d3,d4 | save quotient mantissa
- clrw d1 | zero rounding bits
- jmp norm_sf | (registers on stack removed by norm_sf)
-
- # ifndef ERROR_CHECK
- retz: clrl d0 | zero destination
- moveml sp@+,d2-d5
- rts | no normalization needed
-
- divz: movel __infinitysf,d0 | return infinity value
- moveml sp@+,d2-d5 | should really cause trap ?!?
- btst #31,sp@(4) | transfer sign of dividend
- beq clear | (mjr++)
- bset #31,d0 |
- rts |
- clear: |
- bclr #31,d0 |
- rts
- # endif ERROR_CHECK
- #else
-
- | single precision floating point stuff for Atari-gcc using the SFP004
- | or compatible boards with a memory mapped 68881
- | developed with gas
- |
- | single floating point divide routine
- |
- | M. Ritzert (mjr at dmzrzu71)
- | (ritzert@dfg.dbp.de)
- | 4.10.1990
- |
- | +_infinitysf returned instead of a NAN
- | the DOMAIN exception is not supported yet. In case of an exception
- | _errno is always set to ERANGE
-
- | 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
-
- lea 0xfffffa50:w,a0
- movew #0x4400,a0@(comm) | load first argument to fp0
- cmpiw #0x8900,a0@(resp) | check
- movel a7@(4),a0@
- movew #0x4424,a0@(comm)
- .long 0x0c688900, 0xfff067f8
- movel a7@(8),a0@
- movew #0x6400,a0@(comm) | result to d0
- .long 0x0c688900, 0xfff067f8
- movel a0@,d0 | REMARK: 0/0 returns a NAN
- rts | if ERROR_CHECK is disabled
-
- #endif sfp004
- #endif /* !__M68881__ */
-