xref: /original-bsd/lib/libc/tahoe/fpe/modf.s (revision 2301fdfb)
1#ifdef LIBC_SCCS
2	.asciz	"@(#)modf.s	1.1 (Berkeley/CCI) 07/02/86"
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#include <tahoemath/fp.h>
13#include "DEFS.h"
14
15ENTRY(modf, R2|R3|R4|R5)
16 /*
17 * Some initializations:
18 */
19	ldd	4(fp)		/* load accumulator, for converison	*/
20	cvdl	r2		/*  to an integer.			*/
21	bvs	gsb		/* iff too big grunt it out		*/
22	cvld	r2		/* float the integer part		*/
23	std	r2
24	ldd	4(fp)		/* isolate the fraction			*/
25	subd	r2
26	std	r0
27	movl	12(fp),r6	/* get int return address */
28	movl	r2,(r6)
29	movl	r3,4(r6)
30	ret
31gsb:	clrl	r3
32	movl	4(fp),r0	/* fetch operand to r0,r1. */
33	movl	8(fp),r1
34	movl	12(fp),r6	/* fetch addr of int to r6. */
35 /*
36 * get exponent
37 */
38	andl3	$EXPMASK,r0,r2	/* r2 will hold the exponent. */
39	jeql	is_reserved	/* check for reserved operand.  */
40	shrl	$EXPSHIFT,r2,r2
41	subl2	$BIAS,r2	/* unbias it.  */
42	jleq	allfrac		/* it's int part is  zero. */
43	cmpl	r2,$56
44	jgeq	allint		/* it's fraction part is zero. */
45 /*
46 * get fraction
47 */
48	movl	r0,r4		/* remember the original number. */
49	movl	r1,r5
50	bbc	$31,r0,positive	/* if negative remember it. */
51	incl	r3
52positive:
53				/* clear the non fraction parts. */
54	andl2	$(0!(EXPMASK | SIGNBIT)),r0
55				/* add the hidden bit. */
56	orl2	$(0!CLEARHID),r0
57
58	cmpl	r2,$HID_POS	/* see if there are bits to clear only in r0 */
59				/* or r1 has to be taken care of. */
60				/* ( for fraction calculation) */
61
62	jgtr	in_r1		/* some bytes in r1. */
63
64	jeql	onlyallr0	/* all r0 must be cleared,r1 unchanged. */
65
66				/* only r0 must be canged. */
67	mnegl	r2,r7		/* r7 - loop counter. */
68	movl	$CLEARHID,r8	/* first bit to clear. */
691:
70	andl2	r8,r0		/* clear int. bits from fraction part. */
71	shar	$1,r8,r8
72	aoblss	$0,r7,1b
731:
74	andl2	r8,r4		/* clear frac bits for int calculation: */
75	shar	$1,r8,r8
76	cmpl	$0xffffffff,r8
77	jneq	1b
78	clrl	r5
79	jmp	norm
80
81onlyallr0:
82	clrl	r0
83	clrl	r5
84	jmp 	norm
85
86in_r1:
87	clrl	r0		/* clear int part for frac. calculation. */
88	subl3	r2,$HID_POS,r7
89	movl	$0x7fffffff,r8
901:
91	andl2	r8,r1
92	shar	$1,r8,r8
93	orl2	$0x80000000,r8		/* force the 'sign' bit to be on. */
94	aoblss	$0,r7,1b
951:
96	andl2	r8,r5
97	shar	$1,r8,r8
98	cmpl	$0xffffffff,r8
99	jneq	1b
100
101norm:
102	addl2	$BIAS,r2	/* fnorm expects it biased. */
103	callf	$4,fnorm	/* normelize fraction part. */
104	cmpl	$0,r0
105	jeql	1f
106	bbc	$0,r3,1f
107	orl2	$0x80000000,r0
1081:
109	movl	r4,(r6)		/* put int part in place. */
110	movl	r5,4(r6)
111	ret
112
113allint:
114	movl	r0,(r6)		/* copy the argument to the int addr. */
115	movl	r1,4(r6)
116	clrl	r0		/* clear the fraction part. */
117	clrl	r1
118	ret
119
120allfrac:
121				/* the fraction is ready in r0,r1. */
122	clrl	(r6)		/* zero the int part. */
123	clrl	4(r6)
124	ret
125
126ret_zero:
127	clrl	(r6)
128	clrl	4(r6)
129	clrl	r0
130	clrl	r1
131	ret
132
133is_reserved:
134	bbc	$31,r0,ret_zero
135	callf 	$4,fpresop
136	ret
137