xref: /illumos-gate/usr/src/lib/crt/i386/fsr.S (revision 5d9d9091)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate/*
238238724eSmike_s * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
273e76f9d6SRichard Lowe#include <sys/asm_linkage.h>
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate	.file	"fsr.s"
305e0a5eb7SRichard Lowe	.ident	""
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate	.section	.data
338238724eSmike_s	.align 4
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate/*
367c478bd9Sstevel@tonic-gate * The following table maps trap enable bits in __fsr_init_value
377c478bd9Sstevel@tonic-gate * (after shifting right one bit):
387c478bd9Sstevel@tonic-gate *
397c478bd9Sstevel@tonic-gate * bit 0 - inexact trap
407c478bd9Sstevel@tonic-gate * bit 1 - division trap
417c478bd9Sstevel@tonic-gate * bit 2 - underflow trap
427c478bd9Sstevel@tonic-gate * bit 3 - overflow trap
437c478bd9Sstevel@tonic-gate * bit 4 - invalid trap
447c478bd9Sstevel@tonic-gate *
457c478bd9Sstevel@tonic-gate * to exception masks in the floating point control word
467c478bd9Sstevel@tonic-gate *
477c478bd9Sstevel@tonic-gate * bit 0 - invalid mask
487c478bd9Sstevel@tonic-gate * bit 2 - zero divide mask
497c478bd9Sstevel@tonic-gate * bit 3 - overflow mask
507c478bd9Sstevel@tonic-gate * bit 4 - underflow mask
517c478bd9Sstevel@tonic-gate * bit 5 - inexact mask
527c478bd9Sstevel@tonic-gate */
537c478bd9Sstevel@tonic-gate	.local	trap_table
547c478bd9Sstevel@tonic-gate	.type	trap_table,@object
557c478bd9Sstevel@tonic-gatetrap_table:
567c478bd9Sstevel@tonic-gate	.byte	0b11111111
577c478bd9Sstevel@tonic-gate	.byte	0b11011111
587c478bd9Sstevel@tonic-gate	.byte	0b11111011
597c478bd9Sstevel@tonic-gate	.byte	0b11011011
607c478bd9Sstevel@tonic-gate	.byte	0b11101111
617c478bd9Sstevel@tonic-gate	.byte	0b11001111
627c478bd9Sstevel@tonic-gate	.byte	0b11101011
637c478bd9Sstevel@tonic-gate	.byte	0b11001011
647c478bd9Sstevel@tonic-gate	.byte	0b11110111
657c478bd9Sstevel@tonic-gate	.byte	0b11010111
667c478bd9Sstevel@tonic-gate	.byte	0b11110011
677c478bd9Sstevel@tonic-gate	.byte	0b11010011
687c478bd9Sstevel@tonic-gate	.byte	0b11100111
697c478bd9Sstevel@tonic-gate	.byte	0b11000111
707c478bd9Sstevel@tonic-gate	.byte	0b11100011
717c478bd9Sstevel@tonic-gate	.byte	0b11000011
727c478bd9Sstevel@tonic-gate	.byte	0b11111110
737c478bd9Sstevel@tonic-gate	.byte	0b11011110
747c478bd9Sstevel@tonic-gate	.byte	0b11111010
757c478bd9Sstevel@tonic-gate	.byte	0b11011010
767c478bd9Sstevel@tonic-gate	.byte	0b11101110
777c478bd9Sstevel@tonic-gate	.byte	0b11001110
787c478bd9Sstevel@tonic-gate	.byte	0b11101010
797c478bd9Sstevel@tonic-gate	.byte	0b11001010
807c478bd9Sstevel@tonic-gate	.byte	0b11110110
817c478bd9Sstevel@tonic-gate	.byte	0b11010110
827c478bd9Sstevel@tonic-gate	.byte	0b11110010
837c478bd9Sstevel@tonic-gate	.byte	0b11010010
847c478bd9Sstevel@tonic-gate	.byte	0b11100110
857c478bd9Sstevel@tonic-gate	.byte	0b11000110
867c478bd9Sstevel@tonic-gate	.byte	0b11100010
877c478bd9Sstevel@tonic-gate	.byte	0b11000010
887c478bd9Sstevel@tonic-gate
897c478bd9Sstevel@tonic-gate	.size	trap_table,32
907c478bd9Sstevel@tonic-gate
913e76f9d6SRichard LoweENTRY_NP(__fsr)
927c478bd9Sstevel@tonic-gate	pushl	%ebp
937c478bd9Sstevel@tonic-gate	movl	%esp,%ebp
947c478bd9Sstevel@tonic-gate	pushl	%edx
957c478bd9Sstevel@tonic-gate	pushl	%ecx
963e76f9d6SRichard Lowe	pushl	%ebx
977c478bd9Sstevel@tonic-gate	subl	$4,%esp
987c478bd9Sstevel@tonic-gate
993e76f9d6SRichard Lowe	/* Setup PIC */
1003e76f9d6SRichard Lowe	call	9f
1013e76f9d6SRichard Lowe9:	popl	%ebx
1023e76f9d6SRichard Lowe	addl	$_GLOBAL_OFFSET_TABLE_ + [. - 9b], %ebx
1033e76f9d6SRichard Lowe
1043e76f9d6SRichard Lowe	movl	8(%ebp), %ecx		/* the value set by CG is passed in */
1057c478bd9Sstevel@tonic-gate	shrl	$1,%ecx			/* get rid of fns bit */
1067c478bd9Sstevel@tonic-gate	cmpl	$0,%ecx			/* if remaining bits are zero */
1077c478bd9Sstevel@tonic-gate	je	3f			/*   there's nothing to do */
1087c478bd9Sstevel@tonic-gate
1097c478bd9Sstevel@tonic-gate	fstcw	0(%esp)			/* store the control word */
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate	movl	%ecx,%edx
1127c478bd9Sstevel@tonic-gate	andl	$0x1f,%edx		/* get the trap enable bits */
1133e76f9d6SRichard Lowe	movl	trap_table@GOT(%ebx), %eax
1143e76f9d6SRichard Lowe	addl	%eax,%edx
1153e76f9d6SRichard Lowe	movb	(%edx),%al
1167c478bd9Sstevel@tonic-gate	andb	%al,0(%esp)	/* unmask the corresponding exceptions */
1177c478bd9Sstevel@tonic-gate
1187c478bd9Sstevel@tonic-gate	testl	$0x200,%ecx		/* test denormal trap enable */
1197c478bd9Sstevel@tonic-gate	jz	1f			/* skip if zero */
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate	andb	$0xfd,0(%esp)	/* unmask denormal exception */
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate1:
1247c478bd9Sstevel@tonic-gate	movl	%ecx,%edx
1257c478bd9Sstevel@tonic-gate	andl	$0x60,%edx		/* get the rounding direction */
1267c478bd9Sstevel@tonic-gate	jz	1f			/* skip if zero */
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate	movl	%edx,%eax		/* exchange negative<->tozero */
1297c478bd9Sstevel@tonic-gate	andl	$0x20,%eax		/*   leaving nearest and positive */
1307c478bd9Sstevel@tonic-gate	shll	$1,%eax			/*   as is */
1317c478bd9Sstevel@tonic-gate	xorl	%eax,%edx
1327c478bd9Sstevel@tonic-gate	shll	$5,%edx
1337c478bd9Sstevel@tonic-gate	andw	$0xf3ff,0(%esp)		/* update rounding direction */
1347c478bd9Sstevel@tonic-gate	orw	%dx,0(%esp)
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate1:
1377c478bd9Sstevel@tonic-gate	andl	$0x180,%ecx		/* get the rounding precision */
1387c478bd9Sstevel@tonic-gate	jz	1f			/* skip if zero */
1397c478bd9Sstevel@tonic-gate
1407c478bd9Sstevel@tonic-gate	xorl	$0x180,%ecx		/* reverse bits */
1417c478bd9Sstevel@tonic-gate	shll	$1,%ecx
1427c478bd9Sstevel@tonic-gate	andw	$0xfcff,0(%esp)		/* update rounding precision */
1437c478bd9Sstevel@tonic-gate	orw	%cx,0(%esp)
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate1:
1467c478bd9Sstevel@tonic-gate	fldcw	0(%esp)			/* load the modified control word */
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate3:
1497c478bd9Sstevel@tonic-gate	addl	$4,%esp
1503e76f9d6SRichard Lowe	popl	%ebx
1517c478bd9Sstevel@tonic-gate	popl	%ecx
1527c478bd9Sstevel@tonic-gate	popl	%edx
1537c478bd9Sstevel@tonic-gate	popl	%ebp
1547c478bd9Sstevel@tonic-gate	ret
1553e76f9d6SRichard LoweSET_SIZE(__fsr)
156