xref: /titanic_41/usr/src/lib/common/i386/fsr.s (revision ea394cb00fd96864e34d2841b4a22357b621c78f)
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	.ident	"%Z%%M%	%I%	%E% SMI"
28
29	.file	"fsr.s"
30
31	.section	.data
32	.align 4
33
34	.weak	__fsr_init_value
35
36__fsr_init_value_ptr:
37	.4byte	__fsr_init_value
38	.type   __fsr_init_value_ptr,@object
39	.size   __fsr_init_value_ptr,4
40
41/*
42 * The following table maps trap enable bits in __fsr_init_value
43 * (after shifting right one bit):
44 *
45 * bit 0 - inexact trap
46 * bit 1 - division trap
47 * bit 2 - underflow trap
48 * bit 3 - overflow trap
49 * bit 4 - invalid trap
50 *
51 * to exception masks in the floating point control word
52 *
53 * bit 0 - invalid mask
54 * bit 2 - zero divide mask
55 * bit 3 - overflow mask
56 * bit 4 - underflow mask
57 * bit 5 - inexact mask
58 */
59	.local	trap_table
60	.type	trap_table,@object
61trap_table:
62	.byte	0b11111111
63	.byte	0b11011111
64	.byte	0b11111011
65	.byte	0b11011011
66	.byte	0b11101111
67	.byte	0b11001111
68	.byte	0b11101011
69	.byte	0b11001011
70	.byte	0b11110111
71	.byte	0b11010111
72	.byte	0b11110011
73	.byte	0b11010011
74	.byte	0b11100111
75	.byte	0b11000111
76	.byte	0b11100011
77	.byte	0b11000011
78	.byte	0b11111110
79	.byte	0b11011110
80	.byte	0b11111010
81	.byte	0b11011010
82	.byte	0b11101110
83	.byte	0b11001110
84	.byte	0b11101010
85	.byte	0b11001010
86	.byte	0b11110110
87	.byte	0b11010110
88	.byte	0b11110010
89	.byte	0b11010010
90	.byte	0b11100110
91	.byte	0b11000110
92	.byte	0b11100010
93	.byte	0b11000010
94
95	.size	trap_table,32
96
97	.section	.text
98	.align	4
99
100	.globl	__fsr
101	.type	__fsr,@function
102__fsr:
103	pushl	%ebp
104	movl	%esp,%ebp
105	pushl	%edx
106	pushl	%ecx
107	subl	$4,%esp
108
109	lea	__fsr_init_value_ptr, %ecx
110	movl	(%ecx),%ecx		/* get the value set by CG */
111	shrl	$1,%ecx			/* get rid of fns bit */
112	cmpl	$0,%ecx			/* if remaining bits are zero */
113	je	3f			/*   there's nothing to do */
114
115	fstcw	0(%esp)			/* store the control word */
116
117	movl	%ecx,%edx
118	andl	$0x1f,%edx		/* get the trap enable bits */
119	movb	trap_table(%edx),%al
120	andb	%al,0(%esp)	/* unmask the corresponding exceptions */
121
122	testl	$0x200,%ecx		/* test denormal trap enable */
123	jz	1f			/* skip if zero */
124
125	andb	$0xfd,0(%esp)	/* unmask denormal exception */
126
1271:
128	movl	%ecx,%edx
129	andl	$0x60,%edx		/* get the rounding direction */
130	jz	1f			/* skip if zero */
131
132	movl	%edx,%eax		/* exchange negative<->tozero */
133	andl	$0x20,%eax		/*   leaving nearest and positive */
134	shll	$1,%eax			/*   as is */
135	xorl	%eax,%edx
136	shll	$5,%edx
137	andw	$0xf3ff,0(%esp)		/* update rounding direction */
138	orw	%dx,0(%esp)
139
1401:
141	andl	$0x180,%ecx		/* get the rounding precision */
142	jz	1f			/* skip if zero */
143
144	xorl	$0x180,%ecx		/* reverse bits */
145	shll	$1,%ecx
146	andw	$0xfcff,0(%esp)		/* update rounding precision */
147	orw	%cx,0(%esp)
148
1491:
150	fldcw	0(%esp)			/* load the modified control word */
151
1523:
153	addl	$4,%esp
154	popl	%ecx
155	popl	%edx
156	popl	%ebp
157	ret
158
159	.size	__fsr,[.-__fsr]
160