xref: /original-bsd/lib/libc/tahoe/fpe/modf.s (revision c3e32dec)
1/*
2 * Copyright (c) 1986, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Computer Consoles Inc.
7 *
8 * %sccs.include.redist.c%
9 */
10
11#if defined(SYSLIBC_SCCS) && !defined(lint)
12	.asciz "@(#)modf.s	8.1 (Berkeley) 06/04/93"
13#endif /* SYSLIBC_SCCS and not lint */
14
15/*
16 *  double modf (value, iptr)
17 *  double value, *iptr;
18 *
19 *  Modf returns the fractional part of "value",
20 *  and stores the integer part indirectly through "iptr".
21 */
22#include <tahoemath/fp.h>
23#include "DEFS.h"
24
25ENTRY(modf, R2|R3|R4|R5)
26 /*
27 * Some initializations:
28 */
29	ldd	4(fp)		/* load accumulator, for converison	*/
30	cvdl	r2		/*  to an integer.			*/
31	bvs	gsb		/* iff too big grunt it out		*/
32	cvld	r2		/* float the integer part		*/
33	std	r2
34	ldd	4(fp)		/* isolate the fraction			*/
35	subd	r2
36	std	r0
37	movl	12(fp),r6	/* get int return address */
38	movl	r2,(r6)
39	movl	r3,4(r6)
40	ret
41gsb:	clrl	r3
42	movl	4(fp),r0	/* fetch operand to r0,r1. */
43	movl	8(fp),r1
44	movl	12(fp),r6	/* fetch addr of int to r6. */
45 /*
46 * get exponent
47 */
48	andl3	$EXPMASK,r0,r2	/* r2 will hold the exponent. */
49	jeql	is_reserved	/* check for reserved operand.  */
50	shrl	$EXPSHIFT,r2,r2
51	subl2	$BIAS,r2	/* unbias it.  */
52	jleq	allfrac		/* it's int part is  zero. */
53	cmpl	r2,$56
54	jgeq	allint		/* it's fraction part is zero. */
55 /*
56 * get fraction
57 */
58	movl	r0,r4		/* remember the original number. */
59	movl	r1,r5
60	bbc	$31,r0,positive	/* if negative remember it. */
61	incl	r3
62positive:
63				/* clear the non fraction parts. */
64	andl2	$(0!(EXPMASK | SIGNBIT)),r0
65				/* add the hidden bit. */
66	orl2	$(0!CLEARHID),r0
67
68	cmpl	r2,$HID_POS	/* see if there are bits to clear only in r0 */
69				/* or r1 has to be taken care of. */
70				/* ( for fraction calculation) */
71
72	jgtr	in_r1		/* some bytes in r1. */
73
74	jeql	onlyallr0	/* all r0 must be cleared,r1 unchanged. */
75
76				/* only r0 must be canged. */
77	mnegl	r2,r7		/* r7 - loop counter. */
78	movl	$CLEARHID,r8	/* first bit to clear. */
791:
80	andl2	r8,r0		/* clear int. bits from fraction part. */
81	shar	$1,r8,r8
82	aoblss	$0,r7,1b
831:
84	andl2	r8,r4		/* clear frac bits for int calculation: */
85	shar	$1,r8,r8
86	cmpl	$0xffffffff,r8
87	jneq	1b
88	clrl	r5
89	jmp	norm
90
91onlyallr0:
92	clrl	r0
93	clrl	r5
94	jmp 	norm
95
96in_r1:
97	clrl	r0		/* clear int part for frac. calculation. */
98	subl3	r2,$HID_POS,r7
99	movl	$0x7fffffff,r8
1001:
101	andl2	r8,r1
102	shar	$1,r8,r8
103	orl2	$0x80000000,r8		/* force the 'sign' bit to be on. */
104	aoblss	$0,r7,1b
1051:
106	andl2	r8,r5
107	shar	$1,r8,r8
108	cmpl	$0xffffffff,r8
109	jneq	1b
110
111norm:
112	addl2	$BIAS,r2	/* fnorm expects it biased. */
113	callf	$4,fnorm	/* normelize fraction part. */
114	cmpl	$0,r0
115	jeql	1f
116	bbc	$0,r3,1f
117	orl2	$0x80000000,r0
1181:
119	movl	r4,(r6)		/* put int part in place. */
120	movl	r5,4(r6)
121	ret
122
123allint:
124	movl	r0,(r6)		/* copy the argument to the int addr. */
125	movl	r1,4(r6)
126	clrl	r0		/* clear the fraction part. */
127	clrl	r1
128	ret
129
130allfrac:
131				/* the fraction is ready in r0,r1. */
132	clrl	(r6)		/* zero the int part. */
133	clrl	4(r6)
134	ret
135
136ret_zero:
137	clrl	(r6)
138	clrl	4(r6)
139	clrl	r0
140	clrl	r1
141	ret
142
143is_reserved:
144	bbc	$31,r0,ret_zero
145	callf 	$4,fpresop
146	ret
147