home *** CD-ROM | disk | FTP | other *** search
- #if !defined (__M68881__) && !defined (sfp004)
-
- | double floating point divide routine
- |
- | 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 :
- | Ported over to 68k assembler
- |
- | Revision 1.0:
- | original 8088 code from P.S.Housel
-
- BIAS8 = 0x3FF-1
-
- .text
- .even
- .globl __divdf3, ___divdf3
- .globl __infinitydf
-
- # ifdef ERROR_CHECK
- LC0:
- .ascii "floating point division by 0\12\15\0"
- .even
- # endif ERROR_CHECK
-
- __divdf3:
- ___divdf3:
-
- # ifdef ERROR_CHECK
- tstl a7@(12) | check if divisor is 0
- bne continue
- tstl a7@(16)
- bne continue
-
- moveml d0-d1,a7@-
- pea LC0
- pea __iob+52 |
- jbsr _fprintf |
- addql #8,a7 |
- moveml a7@+,d0-d1
- | set _errno to ERANGE
- # ifdef __MSHORT__
- movew #63,_errno
- # else
- movel #63,_errno
- # endif
- movel #0x7ff00000,d0 | return signed infinity
- clrl d1 |
- btst #31,a7@(4) | transfer sign of dividend
- beq clear | (mjr++)
- bset #31,d0 |
- rts |
- clear: |
- bclr #31,d0 |
- rts
- continue:
-
- # endif ERROR_CHECK
-
- lea sp@(4),a0 | pointer to parameters u and v
- moveml d2-d7,sp@- | save registers
- moveml a0@,d4-d5/d6-d7 | d4-d5 = u, d6-d7 = v
-
- movel d4,d0 | d0 = u.exp
- swap d0
- movew d0,d2 | d2 = u.sign
- lsrw #4,d0
- andw #0x07ff,d0 | kill sign bit
-
- movel d6,d1 | d1 = v.exp
- swap d1
- eorw d1,d2 | d2 = u.sign ^ v.sign (in bit 31)
- lsrw #4,d1
- andw #0x07ff,d1 | kill sign bit
-
- andl #0x0fffff,d4 | remove exponent from u.mantissa
- tstw d0 | check for zero exponent - no leading "1"
- beq 0f
- orl #0x100000,d4 | restore implied leading "1"
- bra 1f
- 0: addw #1,d0 | "normalize" exponent
- 1: movel d4,d3
- orl d5,d3
- beq retz | dividing zero
-
- andl #0x0fffff,d6 | remove exponent from v.mantissa
- tstw d1 | check for zero exponent - no leading "1"
- beq 0f
- orl #0x100000,d6 | restore implied leading "1"
- bra 1f
- 0: addw #1,d1 | "normalize" exponent
- 1: movel d6,d3
- orl d7,d3
-
- #ifndef ERROR_CHECK
- beq divz | divide by zero
- #endif ERROR_CHECK
-
- movew d2,a0 | save sign
-
- subw d1,d0 | subtract exponents,
- addw #BIAS8-11+1,d0 | add bias back in, account for shift
- addw #66,d0 | add loop offset, +2 for extra rounding bits
- | for denormalized numbers (2 implied by dbra)
- movew #24,d1 | bit number for "implied" pos (+4 for rounding)
- movel #-1,d2 | zero the quotient
- movel #-1,d3 | (for speed it is a one''s complement)
- subl d7,d5 | initial subtraction,
- subxl d6,d4 | u = u - v
- 2:
- btst d1,d2 | divide until 1 in implied position
- beq 5f
-
- addl d5,d5
- addxl d4,d4
- bcs 4f | if carry is set, add, else subtract
-
- addxl d3,d3 | shift quotient and set bit zero
- addxl d2,d2
- subl d7,d5 | subtract
- subxl d6,d4 | u = u - v
- dbra d0,2b | give up if result is denormalized
- bra 5f
- 4:
- addxl d3,d3 | shift quotient and clear bit zero
- addxl d2,d2
- addl d7,d5 | add (restore)
- addxl d6,d4 | u = u + v
- dbra d0,2b | give up if result is denormalized
- 5: subw #2,d0 | remove rounding offset for denormalized nums
- notl d2 | invert quotient to get it right
- notl d3
-
- movel d2,d4 | save quotient mantissa
- movel d3,d5
- movew a0,d2 | get sign back
- clrw d1 | zero rounding bits
- jmp norm_df | (registers on stack removed by norm_df)
-
- retz: clrl d0 | zero destination
- clrl d1
- moveml sp@+,d2-d7
- rts | no normalization needed
-
- #ifndef ERROR_CHECK
- divz: moveml __infinitydf,d0-d1 | return infinty value
- moveml sp@+,d2-d7 | should really cause trap ?!?
-
- btst #31,a7@(4) | transfer sign of dividend
- beq clear | (mjr++)
- bset #31,d0 |
- rts |
- clear: |
- bclr #31,d0 |
- rts
-
- #endif ERROR_CHECK
-
- #endif
- #ifdef sfp004
-
- | double precision floating point stuff for Atari-gcc using the SFP004
- | developed with gas
- |
- | double precision division
- |
- | M. Ritzert (mjr at dmzrzu71)
- |
- | 4.10.1990
- |
- | no NAN checking implemented to gain compatibility with the TT-lib
- |
- | 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
-
- # ifdef ERROR_CHECK
- LC0:
- .ascii "floating point division by 0\12\15\0"
- .even
- # endif ERROR_CHECK
-
- .text
- .even
- .globl __divdf3, ___divdf3
-
- __divdf3:
- ___divdf3:
-
- # ifdef ERROR_CHECK
- tstl a7@(12) | check if divisor is 0
- bne continue
- tstl a7@(16)
- bne continue
-
- moveml d0-d7/a0-a6,a7@- | print error message
- pea LC0
- movew #9,a7@-
- trap #1
- addql #6,a7
- moveml a7@+,d0-d7/a0-a6
- | set _errno to ERANGE
- # ifdef __MSHORT__
- movew #63,_errno
- # else
- movel #63,_errno
- # endif
- movel #0x7ff00000,d0 | return signed infinity
- clrl d1 |
- btst #31,a7@(4) | transfer sign of dividend
- beq clear | (mjr++)
- bset #31,d0 |
- rts |
- clear: |
- bclr #31,d0 |
- rts
- continue:
-
- # endif ERROR_CHECK
-
- lea 0xfffa50,a0
- movew #0x5400,a0@(comm) | load first argument to fp0
- cmpiw #0x8900,a0@(resp) | check
- movel a7@(4),a0@
- movel a7@(8),a0@
- movew #0x5420,a0@(comm)
- .long 0x0c688900, 0xfff067f8
- movel a7@(12),a0@
- movel a7@(16),a0@
- movew #0x7400,a0@(comm) | result to d0
- .long 0x0c688900, 0xfff067f8
- movel a0@,d0
- movel a0@,d1
- rts
- #endif sfp004
-