xref: /original-bsd/lib/libc/tahoe/fpe/modf.s (revision b8338845)
1/*
2 * Copyright (c) 1986 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Computer Consoles Inc.
7 *
8 * Redistribution and use in source and binary forms are permitted
9 * provided that the above copyright notice and this paragraph are
10 * duplicated in all such forms and that any documentation,
11 * advertising materials, and other materials related to such
12 * distribution and use acknowledge that the software was developed
13 * by the University of California, Berkeley.  The name of the
14 * University may not be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 */
20
21#if defined(SYSLIBC_SCCS) && !defined(lint)
22	.asciz "@(#)modf.s	1.2 (Berkeley) 02/17/89"
23#endif /* SYSLIBC_SCCS and not lint */
24
25/*
26 *  double modf (value, iptr)
27 *  double value, *iptr;
28 *
29 *  Modf returns the fractional part of "value",
30 *  and stores the integer part indirectly through "iptr".
31 */
32#include <tahoemath/fp.h>
33#include "DEFS.h"
34
35ENTRY(modf, R2|R3|R4|R5)
36 /*
37 * Some initializations:
38 */
39	ldd	4(fp)		/* load accumulator, for converison	*/
40	cvdl	r2		/*  to an integer.			*/
41	bvs	gsb		/* iff too big grunt it out		*/
42	cvld	r2		/* float the integer part		*/
43	std	r2
44	ldd	4(fp)		/* isolate the fraction			*/
45	subd	r2
46	std	r0
47	movl	12(fp),r6	/* get int return address */
48	movl	r2,(r6)
49	movl	r3,4(r6)
50	ret
51gsb:	clrl	r3
52	movl	4(fp),r0	/* fetch operand to r0,r1. */
53	movl	8(fp),r1
54	movl	12(fp),r6	/* fetch addr of int to r6. */
55 /*
56 * get exponent
57 */
58	andl3	$EXPMASK,r0,r2	/* r2 will hold the exponent. */
59	jeql	is_reserved	/* check for reserved operand.  */
60	shrl	$EXPSHIFT,r2,r2
61	subl2	$BIAS,r2	/* unbias it.  */
62	jleq	allfrac		/* it's int part is  zero. */
63	cmpl	r2,$56
64	jgeq	allint		/* it's fraction part is zero. */
65 /*
66 * get fraction
67 */
68	movl	r0,r4		/* remember the original number. */
69	movl	r1,r5
70	bbc	$31,r0,positive	/* if negative remember it. */
71	incl	r3
72positive:
73				/* clear the non fraction parts. */
74	andl2	$(0!(EXPMASK | SIGNBIT)),r0
75				/* add the hidden bit. */
76	orl2	$(0!CLEARHID),r0
77
78	cmpl	r2,$HID_POS	/* see if there are bits to clear only in r0 */
79				/* or r1 has to be taken care of. */
80				/* ( for fraction calculation) */
81
82	jgtr	in_r1		/* some bytes in r1. */
83
84	jeql	onlyallr0	/* all r0 must be cleared,r1 unchanged. */
85
86				/* only r0 must be canged. */
87	mnegl	r2,r7		/* r7 - loop counter. */
88	movl	$CLEARHID,r8	/* first bit to clear. */
891:
90	andl2	r8,r0		/* clear int. bits from fraction part. */
91	shar	$1,r8,r8
92	aoblss	$0,r7,1b
931:
94	andl2	r8,r4		/* clear frac bits for int calculation: */
95	shar	$1,r8,r8
96	cmpl	$0xffffffff,r8
97	jneq	1b
98	clrl	r5
99	jmp	norm
100
101onlyallr0:
102	clrl	r0
103	clrl	r5
104	jmp 	norm
105
106in_r1:
107	clrl	r0		/* clear int part for frac. calculation. */
108	subl3	r2,$HID_POS,r7
109	movl	$0x7fffffff,r8
1101:
111	andl2	r8,r1
112	shar	$1,r8,r8
113	orl2	$0x80000000,r8		/* force the 'sign' bit to be on. */
114	aoblss	$0,r7,1b
1151:
116	andl2	r8,r5
117	shar	$1,r8,r8
118	cmpl	$0xffffffff,r8
119	jneq	1b
120
121norm:
122	addl2	$BIAS,r2	/* fnorm expects it biased. */
123	callf	$4,fnorm	/* normelize fraction part. */
124	cmpl	$0,r0
125	jeql	1f
126	bbc	$0,r3,1f
127	orl2	$0x80000000,r0
1281:
129	movl	r4,(r6)		/* put int part in place. */
130	movl	r5,4(r6)
131	ret
132
133allint:
134	movl	r0,(r6)		/* copy the argument to the int addr. */
135	movl	r1,4(r6)
136	clrl	r0		/* clear the fraction part. */
137	clrl	r1
138	ret
139
140allfrac:
141				/* the fraction is ready in r0,r1. */
142	clrl	(r6)		/* zero the int part. */
143	clrl	4(r6)
144	ret
145
146ret_zero:
147	clrl	(r6)
148	clrl	4(r6)
149	clrl	r0
150	clrl	r1
151	ret
152
153is_reserved:
154	bbc	$31,r0,ret_zero
155	callf 	$4,fpresop
156	ret
157