home *** CD-ROM | disk | FTP | other *** search
- #if !defined (__M68881__) && !defined (sfp004)
-
- | take floating point to integer and fractional pieces
- |
- | C interface
- | double modf( double value, double *iptr)
- | returns fractional part of value
- | in *iptr returns the integral part
- | such that (*iptr + fractional) == value
- |
- |-----------------------------------------------------------------------------
- | 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 replaced shifts by swap if possible for speed increase -kub-, 01/90
- | #3 ported to gcc ++jrb 03/90
- |-----------------------------------------------------------------------------
-
- BIAS8 = 0x3ff - 1
-
- .text; .even
- .globl _modf
- _modf:
- lea sp@(4),a0 | a0 -> float argument
- movel sp@(12),a1 | a1 -> ipart result
- moveml d2-d7,sp@- | save d2-d7
-
- movew a0@,d0 | extract value.exp
- movew d0,d2 | extract value.sign
- lsrw #4,d0
- andw #0x7ff,d0 | kill sign bit
-
- cmpw #BIAS8,d0
- bge 1f | fabs(value) >= 1.0
-
- clrl a1@ | store zero as the integer part
- clrl a1@(4)
- moveml a0@,d0-d1 | return entire value as fractional part
- jra L0
-
- 1:
- cmpw #BIAS8+53,d0 | all integer, with no fractional part ?
- blt 2f | no, mixed
-
- movel a0@,a1@ | store entire value as the integer part
- movel a0@(4),a1@(4)
- moveq #0,d0 | return zero as fractional part
- moveq #0,d1
- L0:
- moveml sp@+,d2-d7 | restore saved d2-d7
- rts
- 2:
- | moveml d3-d7,sp@- | save some registers (d2 is pushed already)
- moveml a0@,d4-d5 | get value
-
- andl #0x0fffff,d4 | remove exponent from value.mantissa
- orl #0x100000,d4 | restore implied leading "1"
-
- moveq #0,d6 | zero fractional part
- moveq #0,d7
- 3:
- cmpw #BIAS8+37,d0 | fast shift, 16 bits ?
- bgt 4f
- movew d6,d7 | shift down 16 bits
- movew d5,d6
- movew d4,d5
- clrw d4
- swap d7
- swap d6
- swap d5
- swap d4
- addw #16,d0
- bra 3b
- 4:
- cmpw #BIAS8+53,d0 | done ?
- bge 5f
- lsrl #1,d4 | shift integer part
- roxrl #1,d5
-
- roxrl #1,d6 | shift high bit into fractional part
- roxrl #1,d7
-
- addw #1,d0 | increment ipart exponent
- bra 4b | keep shifting
- 5:
- | normalize ipart (all values are in correct reggies)
- | save a1, save d2-d7 that norm_df will pop
- movel a1,sp@-
- pea L1 | set up return address
- moveml d2-d7,sp@- | norm_df will pop this
- clrw d1
- jmp norm_df | go do it
- L1: | norm_df will rts to here
- movel sp@+,a1 | pop saved a1
- moveml d0-d1,a1@ | store result into ipart
-
- | norm fractional part
- movel d6,d4 | get frac into d4/d5
- movel d7,d5
- clrw d1 | rounding = 0
- movew #BIAS8-11,d0 | set frac part exponent, sign already in d2
- jmp norm_df | norm_df will pop d2/d7 we save before
- | it will return to our caller via rts
- | with result in d0-d1
-
- #endif /* __M68881__, sfp004 */
- #ifdef __M68881__
- |
- | modf: compiled by gcc from math-68881.h
- | manually optimized by Michael Ritzert
- |
- | double modf( double X, double * IP )
- |
- | 30.11.92
- | ritzert@dfg.dbp.de
- |
-
- .text; .even
-
- .globl _modf
-
- _modf:
- fmoved sp@(4),fp0 | load arg
- movel sp@(12),a0 | get pointer to IP
- fintrzx fp0,fp1 | get int part
- fmoved fp1,a0@ | return it to IP
- fsubx fp1,fp0 | get remainder
- fmoved fp0,sp@- | return it
- moveml sp@+,d0-d1 |
- rts
-
- #endif __M68881__
- #ifdef sfp004
-
- comm = -6
- resp = -16
- zahl = 0
-
- .even
- .text
- .globl _modf
- .even
- _modf:
- movel a1,a7@- | save a1 (necessary?)
- lea 0xfffa50,a0
- movew #0x5403,a0@(comm) | fintrz X -> fp0
- cmpiw #0x8900,a0@(resp) | check
- movel a7@(8),a0@ | load X_hi
- movel a7@(12),a0@ | load X_low
-
- movew #0x5480,a0@(comm) | X -> fp1
- .long 0x0c688900, 0xfff067f8
- movel a7@(8),a0@ | load X_hi
- movel a7@(12),a0@ | load X_low
-
- | 000 000 001 0101000 | sub fp0 -> fp1
- movew #0x00a8,a0@(comm) | sub fp0 -> fp1
- .word 0x4a68,0xfff0,0x6bfa | test
-
- movew #0x7400,a0@(comm) | fp0 to IntPart
- moveal a7@(16),a1 | address of IntPart while the fpu is active
- | wait
- .long 0x0c688900, 0xfff067f8
- movel a0@,a1@+
- movel a0@,a1@+
- movew #0x7480,a0@(comm) | Rest to d0/d1
- | wait
- .long 0x0c688900, 0xfff067f8
- movel a0@,d0
- movel a0@,d1
- movel a7@+,a1 | restore a1
- rts
-
- #endif sfp004
-