xref: /illumos-gate/usr/src/lib/libc/i386/fp/_xtoll.S (revision da7fc762b82ced1a0ec19a51e04cdf823187ec77)
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	.set	four_words,8
34
35/ This function truncates the top of the 387 stack into a signed long.
36
37	ENTRY(__xtol)	// 387-stack to signed long
38	subl	$8,%esp
39	fstcw	cw_old(%esp)
40	movw	cw_old(%esp),%ax
41	movw	%ax,%cx
42	andw	$0x0c00,%cx		// save RC
43	orw	$0x0c00,%ax
44	movw	%ax,cw(%esp)
45	fldcw	cw(%esp)
46	fistpl	two_words(%esp)
47					// fwait implied here
48	fstcw	cw(%esp)		// fetch CW in case masks changed value
49	movw	cw(%esp),%ax
50	andw	$0xf3ff,%ax
51	orw	%cx,%ax			// restore RC
52	movw	%ax,cw(%esp)
53	fldcw	cw(%esp)
54	movl	two_words(%esp),%eax
55	addl	$8,%esp
56	ret
57	SET_SIZE(__xtol)
58
59/ This function truncates the top of the 387 stack into a signed long long.
60
61	ENTRY(__xtoll)	// 387-stack to signed long long
62	subl	$12,%esp
63	fstcw	cw_old(%esp)
64	movw	cw_old(%esp),%ax
65	movw	%ax,%cx
66	andw	$0x0c00,%cx		// save RC
67	orw	$0x0c00,%ax
68	movw	%ax,cw(%esp)
69	fldcw	cw(%esp)
70	fistpll	two_words(%esp)
71					// fwait implied here
72	fstcw	cw(%esp)		// fetch CW in case masks changed value
73	movw	cw(%esp),%ax
74	andw	$0xf3ff,%ax
75	orw	%cx,%ax			// restore RC
76	movw	%ax,cw(%esp)
77	fldcw	cw(%esp)
78	movl	two_words(%esp),%eax
79	movl	four_words(%esp),%edx
80	addl	$12,%esp
81	ret
82	SET_SIZE(__xtoll)
83
84/ This function truncates the top of the 387 stack into a unsigned long.
85
86	.align	4
87two_to_31: .long	0x4f000000
88
89	ENTRY(__xtoul)	// 387-stack to unsigned long
90	subl	$8,%esp
91	fstcw	cw_old(%esp)
92	movw	cw_old(%esp),%ax
93	movw	%ax,%cx
94	andw	$0x0c00,%cx		// save RC
95	orw	$0x0c00,%ax
96	movw	%ax,cw(%esp)
97	fldcw	cw(%esp)
98	_prologue_
99	fcoms	_sref_(two_to_31)	// compare st to 2**31
100	_epilogue_
101	fstsw	%ax			// store status in %ax
102					// use fstsw for correct trap handling
103	sahf				// load AH into flags
104	jb	.donotsub		// jump if st < 2**31 or is NaN
105	_prologue_
106	fsubs	_sref_(two_to_31)	// subtract 2**31
107	_epilogue_
108.donotsub:
109	fistpl	two_words(%esp)
110	fwait				// in case fistpl causes exception
111	movl	two_words(%esp),%eax
112	jb	.donotadd		// flags did not change
113	add	$0x80000000,%eax	// add back 2**31
114.donotadd:
115	fstcw	cw(%esp)		// fetch CW in case masks changed value
116	movw	cw(%esp),%dx
117	andw	$0xf3ff,%dx
118	orw	%cx,%dx			// restore RC
119	movw	%dx,cw(%esp)
120	fldcw	cw(%esp)
121	addl	$8,%esp
122	ret
123	SET_SIZE(__xtoul)
124