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