Commit | Line | Data |
---|---|---|
6ed22137 | 1 | #ifdef LIBC_SCCS |
c338853c | 2 | .asciz "@(#)modf.s 1.2 (Berkeley) %G%" |
6ed22137 SL |
3 | #endif LIBC_SCCS |
4 | ||
5 | /* | |
6 | * double modf (value, iptr) | |
7 | * double value, *iptr; | |
8 | * | |
9 | * Modf returns the fractional part of "value", | |
10 | * and stores the integer part indirectly through "iptr". | |
11 | * | |
12 | * This version uses floating point (look in ../fpe for | |
13 | * a much slower integer version). | |
14 | */ | |
15 | ||
16 | #include "DEFS.h" | |
17 | ||
18 | ENTRY(modf, 0) | |
c338853c SL |
19 | ldd 4(fp) # value |
20 | cvdl r2 # integerize | |
21 | bvs 1f # did integer part overflow? | |
22 | cvld r2 # integer part | |
23 | std r0 | |
24 | std *12(fp) # *iptr = r2 | |
6ed22137 | 25 | ldd 4(fp) |
c338853c SL |
26 | subd r0 # value-(int)value |
27 | std r0 # return fraction | |
6ed22137 SL |
28 | ret |
29 | 1: | |
c338853c SL |
30 | /* |
31 | * If the integer portion overflowed, mask out the fractional | |
32 | * bits in the double word instead of cvdl-ing. | |
33 | */ | |
34 | ldd 4(fp) | |
35 | std r0 # (r0,r1) = value | |
36 | shrl $23,r0,r2 # extract sign,exponent of value | |
37 | andl2 $255,r2 # exponent | |
38 | subl2 $152,r2 # e-152 | |
39 | /* | |
40 | * If it overflowed then value>=2^31 and e>=160 | |
41 | * so we mask only r1 (low bits of fraction), not r0 | |
42 | */ | |
43 | mnegl $1,r3 | |
44 | shrl r2,r3,r3 # -1>>(e-152) is neg mask to clear fraction | |
45 | mcoml r3,r3 # complement mask | |
46 | andl2 r3,r1 # mask off truly fractional bits from fraction | |
47 | ldd r0 # now (r0,r1) = integerized value | |
48 | std *12(fp) # *iptr = integerized | |
6ed22137 SL |
49 | ldd 4(fp) |
50 | subd r0 | |
c338853c | 51 | std r0 # return fraction |
6ed22137 | 52 | ret |