xref: /titanic_52/usr/src/lib/crt/i386/fsr.s (revision 3e0c804466b61d42dc6a3e1cb114c11681ef181a)
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, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#include <sys/asm_linkage.h>
28
29	.file	"fsr.s"
30
31	.section	.data
32	.align 4
33
34/*
35 * The following table maps trap enable bits in __fsr_init_value
36 * (after shifting right one bit):
37 *
38 * bit 0 - inexact trap
39 * bit 1 - division trap
40 * bit 2 - underflow trap
41 * bit 3 - overflow trap
42 * bit 4 - invalid trap
43 *
44 * to exception masks in the floating point control word
45 *
46 * bit 0 - invalid mask
47 * bit 2 - zero divide mask
48 * bit 3 - overflow mask
49 * bit 4 - underflow mask
50 * bit 5 - inexact mask
51 */
52	.local	trap_table
53	.type	trap_table,@object
54trap_table:
55	.byte	0b11111111
56	.byte	0b11011111
57	.byte	0b11111011
58	.byte	0b11011011
59	.byte	0b11101111
60	.byte	0b11001111
61	.byte	0b11101011
62	.byte	0b11001011
63	.byte	0b11110111
64	.byte	0b11010111
65	.byte	0b11110011
66	.byte	0b11010011
67	.byte	0b11100111
68	.byte	0b11000111
69	.byte	0b11100011
70	.byte	0b11000011
71	.byte	0b11111110
72	.byte	0b11011110
73	.byte	0b11111010
74	.byte	0b11011010
75	.byte	0b11101110
76	.byte	0b11001110
77	.byte	0b11101010
78	.byte	0b11001010
79	.byte	0b11110110
80	.byte	0b11010110
81	.byte	0b11110010
82	.byte	0b11010010
83	.byte	0b11100110
84	.byte	0b11000110
85	.byte	0b11100010
86	.byte	0b11000010
87
88	.size	trap_table,32
89
90ENTRY_NP(__fsr)
91	pushl	%ebp
92	movl	%esp,%ebp
93	pushl	%edx
94	pushl	%ecx
95	pushl	%ebx
96	subl	$4,%esp
97
98	/* Setup PIC */
99	call	9f
1009:	popl	%ebx
101	addl	$_GLOBAL_OFFSET_TABLE_ + [. - 9b], %ebx
102
103	movl	8(%ebp), %ecx		/* the value set by CG is passed in */
104	shrl	$1,%ecx			/* get rid of fns bit */
105	cmpl	$0,%ecx			/* if remaining bits are zero */
106	je	3f			/*   there's nothing to do */
107
108	fstcw	0(%esp)			/* store the control word */
109
110	movl	%ecx,%edx
111	andl	$0x1f,%edx		/* get the trap enable bits */
112	movl	trap_table@GOT(%ebx), %eax
113	addl	%eax,%edx
114	movb	(%edx),%al
115	andb	%al,0(%esp)	/* unmask the corresponding exceptions */
116
117	testl	$0x200,%ecx		/* test denormal trap enable */
118	jz	1f			/* skip if zero */
119
120	andb	$0xfd,0(%esp)	/* unmask denormal exception */
121
1221:
123	movl	%ecx,%edx
124	andl	$0x60,%edx		/* get the rounding direction */
125	jz	1f			/* skip if zero */
126
127	movl	%edx,%eax		/* exchange negative<->tozero */
128	andl	$0x20,%eax		/*   leaving nearest and positive */
129	shll	$1,%eax			/*   as is */
130	xorl	%eax,%edx
131	shll	$5,%edx
132	andw	$0xf3ff,0(%esp)		/* update rounding direction */
133	orw	%dx,0(%esp)
134
1351:
136	andl	$0x180,%ecx		/* get the rounding precision */
137	jz	1f			/* skip if zero */
138
139	xorl	$0x180,%ecx		/* reverse bits */
140	shll	$1,%ecx
141	andw	$0xfcff,0(%esp)		/* update rounding precision */
142	orw	%cx,0(%esp)
143
1441:
145	fldcw	0(%esp)			/* load the modified control word */
146
1473:
148	addl	$4,%esp
149	popl	%ebx
150	popl	%ecx
151	popl	%edx
152	popl	%ebp
153	ret
154SET_SIZE(__fsr)
155