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