from pixar!ph; handle overflow correctly (previous version just punted
[unix-history] / usr / src / lib / libc / tahoe / gen / modf.s
CommitLineData
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
18ENTRY(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
291:
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