xref: /csrg-svn/lib/libc/tahoe/gen/modf.s (revision 61183)
134438Sbostic/*
2*61183Sbostic * Copyright (c) 1988, 1993
3*61183Sbostic *	The Regents of the University of California.  All rights reserved.
434438Sbostic *
534438Sbostic * This code is derived from software contributed to Berkeley by
634438Sbostic * Computer Consoles Inc.
746166Sbostic *
846166Sbostic * %sccs.include.redist.c%
934438Sbostic */
1029696Ssam
1134438Sbostic#if defined(LIBC_SCCS) && !defined(lint)
12*61183Sbostic	.asciz "@(#)modf.s	8.1 (Berkeley) 06/04/93"
1334438Sbostic#endif /* LIBC_SCCS and not lint */
1434438Sbostic
1529696Ssam/*
1629696Ssam * double modf (value, iptr)
1729696Ssam * double value, *iptr;
1829696Ssam *
1929696Ssam * Modf returns the fractional part of "value",
2029696Ssam * and stores the integer part indirectly through "iptr".
2129696Ssam *
2229696Ssam * This version uses floating point (look in ../fpe for
2329696Ssam * a much slower integer version).
2429696Ssam */
2529696Ssam
2629696Ssam#include "DEFS.h"
2729696Ssam
2829696SsamENTRY(modf, 0)
2930512Ssam	ldd	4(fp)		# value
3030512Ssam	cvdl	r2		# integerize
3130512Ssam	bvs	1f		# did integer part overflow?
3230512Ssam	cvld	r2		# integer part
3330512Ssam	std	r0
3430512Ssam	std	*12(fp)		# *iptr = r2
3529696Ssam	ldd	4(fp)
3630512Ssam	subd	r0		# value-(int)value
3730512Ssam	std	r0		# return fraction
3829696Ssam	ret
3929696Ssam1:
4030512Ssam	/*
4130512Ssam	 * If the integer portion overflowed, mask out the fractional
4230512Ssam	 * bits in the double word instead of cvdl-ing.
4330512Ssam	 */
4429696Ssam	ldd	4(fp)
4530512Ssam	std	r0		# (r0,r1) = value
4630512Ssam	shrl	$23,r0,r2	# extract sign,exponent of value
4730512Ssam	andl2	$255,r2		# exponent
4830512Ssam	subl2	$152,r2		# e-152
4930512Ssam	/*
5030512Ssam	 * If it overflowed then value>=2^31 and e>=160
5130512Ssam	 * so we mask only r1 (low bits of fraction), not r0
5230512Ssam	 */
5330512Ssam	mnegl	$1,r3
5430512Ssam	shrl	r2,r3,r3	# -1>>(e-152) is neg mask to clear fraction
5530512Ssam	mcoml	r3,r3		# complement mask
5630512Ssam	andl2	r3,r1		# mask off truly fractional bits from fraction
5730512Ssam	ldd	r0		# now (r0,r1) = integerized value
5830512Ssam	std	*12(fp)		# *iptr = integerized
5930512Ssam	ldd	4(fp)
6029696Ssam	subd	r0
6130512Ssam	std	r0		# return fraction
6229696Ssam	ret
63