Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / lib / crt / i386 / fsr.s
blobbafc28042faeab462cc0a7ec47293f40d56d2643
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <sys/asm_linkage.h>
29 .file "fsr.s"
31 .section .data
32 .align 4
35 * The following table maps trap enable bits in __fsr_init_value
36 * (after shifting right one bit):
38 * bit 0 - inexact trap
39 * bit 1 - division trap
40 * bit 2 - underflow trap
41 * bit 3 - overflow trap
42 * bit 4 - invalid trap
44 * to exception masks in the floating point control word
46 * bit 0 - invalid mask
47 * bit 2 - zero divide mask
48 * bit 3 - overflow mask
49 * bit 4 - underflow mask
50 * bit 5 - inexact mask
52 .local trap_table
53 .type trap_table,@object
54 trap_table:
55 .byte 0b11111111
56 .byte 0b11011111
57 .byte 0b11111011
58 .byte 0b11011011
59 .byte 0b11101111
60 .byte 0b11001111
61 .byte 0b11101011
62 .byte 0b11001011
63 .byte 0b11110111
64 .byte 0b11010111
65 .byte 0b11110011
66 .byte 0b11010011
67 .byte 0b11100111
68 .byte 0b11000111
69 .byte 0b11100011
70 .byte 0b11000011
71 .byte 0b11111110
72 .byte 0b11011110
73 .byte 0b11111010
74 .byte 0b11011010
75 .byte 0b11101110
76 .byte 0b11001110
77 .byte 0b11101010
78 .byte 0b11001010
79 .byte 0b11110110
80 .byte 0b11010110
81 .byte 0b11110010
82 .byte 0b11010010
83 .byte 0b11100110
84 .byte 0b11000110
85 .byte 0b11100010
86 .byte 0b11000010
88 .size trap_table,32
90 ENTRY_NP(__fsr)
91 pushl %ebp
92 movl %esp,%ebp
93 pushl %edx
94 pushl %ecx
95 pushl %ebx
96 subl $4,%esp
98 /* Setup PIC */
99 call 9f
100 9: popl %ebx
101 addl $_GLOBAL_OFFSET_TABLE_ + [. - 9b], %ebx
103 movl 8(%ebp), %ecx /* the value set by CG is passed in */
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 */
108 fstcw 0(%esp) /* store the control word */
110 movl %ecx,%edx
111 andl $0x1f,%edx /* get the trap enable bits */
112 movl trap_table@GOT(%ebx), %eax
113 addl %eax,%edx
114 movb (%edx),%al
115 andb %al,0(%esp) /* unmask the corresponding exceptions */
117 testl $0x200,%ecx /* test denormal trap enable */
118 jz 1f /* skip if zero */
120 andb $0xfd,0(%esp) /* unmask denormal exception */
123 movl %ecx,%edx
124 andl $0x60,%edx /* get the rounding direction */
125 jz 1f /* skip if zero */
127 movl %edx,%eax /* exchange negative<->tozero */
128 andl $0x20,%eax /* leaving nearest and positive */
129 shll $1,%eax /* as is */
130 xorl %eax,%edx
131 shll $5,%edx
132 andw $0xf3ff,0(%esp) /* update rounding direction */
133 orw %dx,0(%esp)
136 andl $0x180,%ecx /* get the rounding precision */
137 jz 1f /* skip if zero */
139 xorl $0x180,%ecx /* reverse bits */
140 shll $1,%ecx
141 andw $0xfcff,0(%esp) /* update rounding precision */
142 orw %cx,0(%esp)
145 fldcw 0(%esp) /* load the modified control word */
148 addl $4,%esp
149 popl %ebx
150 popl %ecx
151 popl %edx
152 popl %ebp
154 SET_SIZE(__fsr)