home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
zip
/
mint
/
mntlib16.lzh
/
MNTLIB16
/
MODF.S
< prev
next >
Wrap
Text File
|
1993-08-03
|
3KB
|
104 lines
#APP
| 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