xref: /original-bsd/lib/libc/tahoe/gen/modf.s (revision fb9118b1)
1#ifdef LIBC_SCCS
2	.asciz	"@(#)modf.s	1.2 (Berkeley) 02/16/87"
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)
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
25	ldd	4(fp)
26	subd	r0		# value-(int)value
27	std	r0		# return fraction
28	ret
291:
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
49	ldd	4(fp)
50	subd	r0
51	std	r0		# return fraction
52	ret
53