home *** CD-ROM | disk | FTP | other *** search
- | 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
- _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 = 34
-
- retz:
- #ifdef __MSHORT__
- movew #ERANGE,_errno | set errno
- #else
- movel #ERANGE,_errno | set errno
- #endif
- moveq #0,d0 | zero return value
- moveq #0,d1
- jra L0
-
- rangerr:
- #ifdef __MSHORT__
- movew #ERANGE,_errno | set errno
- #else
- movel #ERANGE,_errno | set errno
- #endif
- 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
-