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 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/asm_linkage.h> 28 29 .file "fsr.s" 30 31 .section .data 32 .align 4 33 34 /* 35 * The following table maps trap enable bits in __fsr_init_value 36 * (after shifting right one bit): 37 * 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 43 * 44 * to exception masks in the floating point control word 45 * 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 51 */ 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 87 88 .size trap_table,32 89 90 ENTRY_NP(__fsr) 91 pushl %ebp 92 movl %esp,%ebp 93 pushl %edx 94 pushl %ecx 95 pushl %ebx 96 subl $4,%esp 97 98 /* Setup PIC */ 99 call 9f 100 9: popl %ebx 101 addl $_GLOBAL_OFFSET_TABLE_ + [. - 9b], %ebx 102 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 */ 107 108 fstcw 0(%esp) /* store the control word */ 109 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 */ 116 117 testl $0x200,%ecx /* test denormal trap enable */ 118 jz 1f /* skip if zero */ 119 120 andb $0xfd,0(%esp) /* unmask denormal exception */ 121 122 1: 123 movl %ecx,%edx 124 andl $0x60,%edx /* get the rounding direction */ 125 jz 1f /* skip if zero */ 126 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) 134 135 1: 136 andl $0x180,%ecx /* get the rounding precision */ 137 jz 1f /* skip if zero */ 138 139 xorl $0x180,%ecx /* reverse bits */ 140 shll $1,%ecx 141 andw $0xfcff,0(%esp) /* update rounding precision */ 142 orw %cx,0(%esp) 143 144 1: 145 fldcw 0(%esp) /* load the modified control word */ 146 147 3: 148 addl $4,%esp 149 popl %ebx 150 popl %ecx 151 popl %edx 152 popl %ebp 153 ret 154 SET_SIZE(__fsr)