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