xref: /illumos-gate/usr/src/lib/libc/amd64/fp/_xtoll.S (revision 5d9d9091f564c198a760790b0bfa72c44e17912b)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26	.file	"_xtoll.s"
27
28#include <SYS.h>
29
30	.set	cw,0
31	.set	cw_old,2
32	.set	two_words,4
33
34/* This function truncates the top of the 387 stack into a signed long. */
35
36	ENTRY(__xtol)	/* 387-stack to signed long */
37	subq	$8,%rsp
38	fstcw	cw_old(%rsp)
39	movw	cw_old(%rsp),%ax
40	movw	%ax,%cx
41	andw	$0x0c00,%cx		/* save RC */
42	orw	$0x0c00,%ax
43	movw	%ax,cw(%rsp)
44	fldcw	cw(%rsp)
45	fistpl	two_words(%rsp)
46					/* fwait implied here */
47	fstcw	cw(%rsp)		/* fetch CW in case masks changed */
48	movw	cw(%rsp),%ax
49	andw	$0xf3ff,%ax
50	orw	%cx,%ax			/* restore RC */
51	movw	%ax,cw(%rsp)
52	fldcw	cw(%rsp)
53	movl	two_words(%rsp),%eax
54	addq	$8,%rsp
55	ret
56	SET_SIZE(__xtol)
57
58/* This function truncates the top of the 387 stack into a signed long long. */
59
60	ENTRY(__xtoll)	/* 387-stack to signed long long */
61	subq	$16,%rsp
62	fstcw	cw_old(%rsp)
63	movw	cw_old(%rsp),%ax
64	movw	%ax,%cx
65	andw	$0x0c00,%cx		/* save RC */
66	orw	$0x0c00,%ax
67	movw	%ax,cw(%rsp)
68	fldcw	cw(%rsp)
69	fistpll	8(%rsp)
70					/* fwait implied here */
71	fstcw	cw(%rsp)		/* fetch CW in case masks changed */
72	movw	cw(%rsp),%ax
73	andw	$0xf3ff,%ax
74	orw	%cx,%ax			/* restore RC */
75	movw	%ax,cw(%rsp)
76	fldcw	cw(%rsp)
77	movq	8(%rsp),%rax
78	addq	$16,%rsp
79	ret
80	SET_SIZE(__xtoll)
81
82/* This function truncates the top of the 387 stack into a unsigned long. */
83
84	.align	16
85two_to_31: .4byte	0x4f000000
86
87	ENTRY(__xtoul)	/* 387-stack to unsigned */
88	subq	$8,%rsp
89	fstcw	cw_old(%rsp)
90	movw	cw_old(%rsp),%ax
91	movw	%ax,%cx
92	andw	$0x0c00,%cx		/* save RC */
93	orw	$0x0c00,%ax
94	movw	%ax,cw(%rsp)
95	fldcw	cw(%rsp)
96	flds	two_to_31(%rip)
97	fcomip	%st(1),%st		/* compare 2**31 to x */
98	jp	.donotsub		/* jump if x is NaN */
99	ja	.donotsub		/* jump if 2**31 > x */
100	fsubs	two_to_31(%rip)	/* subtract 2**31 */
101.donotsub:
102	fistpl	two_words(%rsp)
103	fwait				/* in case fistpl causes exception */
104	movl	two_words(%rsp),%eax
105	jp	.donotadd		/* flags did not change */
106	ja	.donotadd		/* flags did not change */
107	addl	$-2147483648,%eax	/* add back 2**31 */
108.donotadd:
109	fstcw	cw(%rsp)		/* fetch CW in case masks changed */
110	movw	cw(%rsp),%dx
111	andw	$0xf3ff,%dx
112	orw	%cx,%dx			/* restore RC */
113	movw	%dx,cw(%rsp)
114	fldcw	cw(%rsp)
115	addq	$8,%rsp
116	ret
117	SET_SIZE(__xtoul)
118