xref: /minix3/lib/libm/arch/i387/s_modf.S (revision 2fe8fb192fe7e8720e3e7a77f928da545e872a6a)
1/*	$NetBSD: s_modf.S,v 1.1 2006/03/22 20:45:58 drochner Exp $	*/
2
3/*-
4 * Copyright (c) 1990 The Regents of the University of California.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Sean Eric Fagan.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 *	from: @(#)modf.s	5.5 (Berkeley) 3/18/91
35 */
36
37#include <machine/asm.h>
38#if defined(LIBC_SCCS)
39	RCSID("$NetBSD: s_modf.S,v 1.1 2006/03/22 20:45:58 drochner Exp $")
40#endif
41
42/*
43 * modf(value, iptr): return fractional part of value, and stores the
44 * integral part into iptr (a pointer to double).
45 *
46 * Written by Sean Eric Fagan (sef@kithrup.COM)
47 * Sun Mar 11 20:27:30 PST 1990
48 */
49
50/* With CHOP mode on, frndint behaves as TRUNC does.  Useful. */
51ENTRY(modf)
52#ifdef __x86_64__
53	pushq	%rbp
54	movq	%rsp,%rbp
55	subq	$24,%rsp
56
57	/* Set chop mode. */
58	fnstcw	-12(%rbp)
59	movw	-12(%rbp),%dx
60	orw	$3072,%dx
61	movw	%dx,-16(%rbp)
62	fldcw	-16(%rbp)
63
64	/* Get integral part. */
65	movsd	%xmm0,-24(%rbp)
66	fldl	-24(%rbp)
67	frndint
68	fstpl	-8(%rbp)
69
70	/* Restore control word. */
71	fldcw	-12(%rbp)
72
73	/* Store integral part. */
74	movsd	-8(%rbp),%xmm0
75	movsd	%xmm0,(%rdi)
76
77	/* Get fractional part and return it. */
78	fldl	-24(%rbp)
79	fsubl	-8(%rbp)
80	fstpl	-24(%rbp)
81	movsd	-24(%rbp),%xmm0
82#else
83	pushl	%ebp
84	movl	%esp,%ebp
85	subl	$16,%esp
86	fnstcw	-12(%ebp)
87	movw	-12(%ebp),%dx
88	orw	$3072,%dx
89	movw	%dx,-16(%ebp)
90	fldcw	-16(%ebp)
91	fldl	8(%ebp)
92	frndint
93	fstpl	-8(%ebp)
94	fldcw	-12(%ebp)
95	movl	16(%ebp),%eax
96	movl	-8(%ebp),%edx
97	movl	-4(%ebp),%ecx
98	movl	%edx,(%eax)
99	movl	%ecx,4(%eax)
100	fldl	8(%ebp)
101	fsubl	-8(%ebp)
102	jmp	L1
103L1:
104#endif
105	leave
106	ret
107