home *** CD-ROM | disk | FTP | other *** search
-
- #if !defined (__M68881__) && !defined (sfp004)
-
- | add exponent to floating point number
- | C Interface
- | double ldexp(double value, unsigned int exp);
- | returns value * 2**exp
- | (int is 16 bits if -mshort, 32 bits if !-mshort)
- |-----------------------------------------------------------------------------
- | ported to 68000 by Kai-Uwe Bloem, 12/89
- | #1 original author: Peter S. Housel 9/21/88,01/17/89,03/19/89,5/24/89
- | #2 added support for denormalized numbers -kub-, 01/90
- | #3 ported to gcc ++jrb 04/90
- | #4 handle exponent overflow when ints are 32 bits -kub-, 04/90
- |-----------------------------------------------------------------------------
-
- .text; .even
- .globl _ldexp
- .globl __infinitydf
-
- #ifdef ERROR_CHECK
- _Overflow:
- .ascii "ldexp: OVERFLOW\12\15\0"
- .even
- #endif ERROR_CHECK
-
- _ldexp:
- lea sp@(4),a1
- moveml d2-d7,sp@- | save d2-d7
-
- movew a1@,d0 | extract value.exp
- movew d0,d2 | extract value.sign
- lsrw #4,d0
- andw #0x7ff,d0 | kill sign bit
-
- andw #0x0f,a1@ | remove exponent from value.mantissa
- tstw d0 | check for zero exponent - no leading 1
- beq 0f
- orw #0x10,a1@ | restore implied leading 1
- bra 1f
- 0: addw #1,d0
- 1:
- #ifdef __MSHORT__
- addw a1@(8),d0 | add in exponent
- extl d0
- #else
- extl d0
- addl a1@(8),d0 | add in exponent
- #endif
- cmpl #-53,d0 | hmm. works only if 1 in implied position...
- ble retz | range error - underflow
- cmpl #2047,d0
- bge rangerr | range error - overflow
-
- clrw d1 | zero rounding bits
- moveml a1@,d4-d5 | value into d4,d5
- jmp norm_df | norm_df will pop d2-d7 and rts
-
-
- .globl _errno | from <errno.h>
- ERANGE = 63
-
- retz:
- moveq #0,d0 | zero return value
- moveq #0,d1
- jra L0
-
- rangerr:
-
- #ifdef ERROR_CHECK
- # ifdef __MSHORT__
- movew #ERANGE,_errno | set errno
- # else
- movel #ERANGE,_errno | set errno
- # endif
- moveml d0-d1,a7@-
- pea _Overflow | for printf
- pea __iob+52 |
- jbsr _fprintf |
- addql #8,a7 |
- moveml a7@+,d0-d1
- #endif ERROR_CHECK
-
- moveml __infinitydf,d0-d1 | return HUGE_VAL (same as in <math.h>)
- andw #0x8000,d2 | get sign bit of argument
- swap d2
- clrw d2
- orl d2,d0
- L0:
- moveml sp@+,d2-d7 | pop saved reggies
- rts
-
- #else __M68881__ || sfp004
- #ifdef __M68881__
- |#######################################################################
- |
- |# add exponent to floating point number
- |# C Interface
- |# double ldexp(double value, unsigned int exp);
- |# returns value * 2**exp
- |# (int is 16 bits if -mshort, 32 bits if !-mshort)
- |# performed entirely on the 68881 to avoid overfow as good as possible
- |##############################################################################
- |# hacked for the 68881 by Michael Ritzert, 5.10.90
- |##############################################################################
- |# ported fromt sfp004 to real coprocessor, mjr, August 1991
- |################################################################################
-
- .text; .even
- .globl _ldexp
-
- #ifdef ERROR_CHECK
- _Domain:
- .ascii "ldexp: NAN\12\15\0"
- _Overflow:
- .ascii "ldexp: OVERFLOW\12\15\0"
- .even
- double_max:
- .long 0x7fee42d1
- .long 0x30273b76
- double_min:
- .long 0xffee42d1
- .long 0x30273b76
- NaN:
- .long 0x7fffffff
- .long 0xffffffff
- p_Inf:
- .long 0x7ff00000
- .long 0x00000000
- m_Inf:
- .long 0xfff00000
- .long 0x00000000
- .even
- #endif ERROR_CHECK
-
- _ldexp:
-
- #ifdef __MSHORT__
- movew a7@(12),d0 | get exponent
- extl d0
- #else
- movel a7@(12),d0 | get exponent
- #endif
- fgetexpd a7@(4),fp1 | extract exponent of 1st arg
- fmovel fp1,d1 | d1 serves as accumulator
- addl d0,d1 | sum of exp_s of both args
-
- ftwotoxl d0,fp0 | ftwotox to fp0 (as long int!)
- fmuld a7@(4),fp0 | fmul value,fp0
- fmoved fp0,a7@- | get double from fp0
- moveml a7@+,d0-d1
-
- #endif __M68881__
- #ifdef sfp004
-
- | add exponent to floating point number
- | C Interface
- | double ldexp(double value, unsigned int exp);
- | returns value * 2**exp
- | (int is 16 bits if -mshort, 32 bits if !-mshort)
- | performed entirely on the 68881 to avoid overfow as good as possible
- |
- | hacked for the 68881 by Michael Ritzert, 5.10.90
- |
-
- | addresses of the 68881 data port. This choice is fastest when much data is
- | transferred between the two processors.
-
- comm = -6 | fpu command reg
- resp = -16 | fpu response reg
- zahl = 0 | fpu data reg
-
- | waiting loop ...
- |
- | wait:
- | ww: cmpiw #0x8900,a1@(resp)
- | beq ww
- | is coded directly by
- | .byte 0x0c,0x69,0x89,0x00,0xff,0xf0,0x67,0xf8 (a1)
- | or
- | .long 0x0c6889000, 0x000067f8 (a0)
-
- .text; .even
- .globl _ldexp
-
- #ifdef ERROR_CHECK
- _Domain:
- .ascii "ldexp: NAN\12\15\0"
- _Overflow:
- .ascii "ldexp: OVERFLOW\12\15\0"
- .even
- double_max:
- .long 0x7fee42d1
- .long 0x30273b76
- double_min:
- .long 0xffee42d1
- .long 0x30273b76
- NaN:
- .long 0x7fffffff
- .long 0xffffffff
- p_Inf:
- .long 0x7ff00000
- .long 0x00000000
- m_Inf:
- .long 0xfff00000
- .long 0x00000000
- .even
- #endif ERROR_CHECK
-
- _ldexp:
- lea 0xfffa50,a0 | fpu address
- movew #0x4011,a0@(comm) | ftwotox to fp0 (as long int!)
- #ifdef __MSHORT__
- movew a7@(12),d0 | get exponent
- extl d0
- #else
- movel a7@(12),d0 | get exponent
- #endif
- cmpiw #0x8900,a0@(resp) | check if fpu is ready
- movel d0,a0@ | push arg
- .long 0x0c6889000, 0xfff067f8 | wait
- movew #0x5423,a0@(comm) | fmul value,fp0
- .long 0x0c6889000, 0xfff067f8 | wait
- movel a7@(4),a0@ | load value
- movel a7@(8),a0@ |
- .long 0x0c6889000, 0xfff067f8 | wait
- movew #0x7400,a0@(comm) | get double from fp0
- .long 0x0c6889000, 0xfff067f8 | wait
- movel a0@,d0
- movel a0@,d1
- #endif sfp004
-
- #ifdef ERROR_CHECK
- lea double_max,a0 |
- swap d0 | exponent into lower word
- cmpw a0@(16),d0 | == NaN ?
- beq error_nan |
- cmpw a0@(24),d0 | == + Infinity ?
- beq error_plus |
- swap d0 | result ok,
- rts | restore d0
- # ifndef __MSHORT__
- error_plus:
- swap d0
- movel #63,_errno | Overflow: errno = ERANGE
- moveml d0-d1,a7@- | print error message
- pea _Domain | for printf
- bra error_exit |
- error_nan:
- moveml a0@(24),d0-d1 | result = +inf
- movel #62,_errno | NAN => errno = EDOM
- moveml d0-d1,a7@- | print error message
- pea _Overflow | for printf
- # else __MSHORT__
- error_plus:
- swap d0
- movew #63,_errno | Overflow: errno = ERANGE
- moveml d0-d1,a7@- | print error message
- pea _Domain | for printf
- bra error_exit |
- error_nan:
- moveml a0@(24),d0-d1 | result = +inf
- movew #62,_errno | NAN => errno = EDOM
- moveml d0-d1,a7@- | print error message
- pea _Overflow | for printf
- # endif __MSHORT__
- error_exit:
- pea __iob+52 |
- jbsr _fprintf |
- addql #8,a7 |
- moveml a7@+,d0-d1
- rts
- #else ERROR_CHECK
- rts
- #endif ERROR_CHECK
-
- #endif /* !__M68881__ && !sfp004 */
-