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 .ident "%Z%%M% %I% %E% SMI" 28 29 .file "fsr.s" 30 31 .section .data 32 .align 4 33 34 .weak __fsr_init_value 35 36 __fsr_init_value_ptr: 37 .4byte __fsr_init_value 38 .type __fsr_init_value_ptr,@object 39 .size __fsr_init_value_ptr,4 40 41 /* 42 * The following table maps trap enable bits in __fsr_init_value 43 * (after shifting right one bit): 44 * 45 * bit 0 - inexact trap 46 * bit 1 - division trap 47 * bit 2 - underflow trap 48 * bit 3 - overflow trap 49 * bit 4 - invalid trap 50 * 51 * to exception masks in the floating point control word 52 * 53 * bit 0 - invalid mask 54 * bit 2 - zero divide mask 55 * bit 3 - overflow mask 56 * bit 4 - underflow mask 57 * bit 5 - inexact mask 58 */ 59 .local trap_table 60 .type trap_table,@object 61 trap_table: 62 .byte 0b11111111 63 .byte 0b11011111 64 .byte 0b11111011 65 .byte 0b11011011 66 .byte 0b11101111 67 .byte 0b11001111 68 .byte 0b11101011 69 .byte 0b11001011 70 .byte 0b11110111 71 .byte 0b11010111 72 .byte 0b11110011 73 .byte 0b11010011 74 .byte 0b11100111 75 .byte 0b11000111 76 .byte 0b11100011 77 .byte 0b11000011 78 .byte 0b11111110 79 .byte 0b11011110 80 .byte 0b11111010 81 .byte 0b11011010 82 .byte 0b11101110 83 .byte 0b11001110 84 .byte 0b11101010 85 .byte 0b11001010 86 .byte 0b11110110 87 .byte 0b11010110 88 .byte 0b11110010 89 .byte 0b11010010 90 .byte 0b11100110 91 .byte 0b11000110 92 .byte 0b11100010 93 .byte 0b11000010 94 95 .size trap_table,32 96 97 .section .text 98 .align 4 99 100 .globl __fsr 101 .type __fsr,@function 102 __fsr: 103 pushl %ebp 104 movl %esp,%ebp 105 pushl %edx 106 pushl %ecx 107 subl $4,%esp 108 109 lea __fsr_init_value_ptr, %ecx 110 movl (%ecx),%ecx /* get the value set by CG */ 111 shrl $1,%ecx /* get rid of fns bit */ 112 cmpl $0,%ecx /* if remaining bits are zero */ 113 je 3f /* there's nothing to do */ 114 115 fstcw 0(%esp) /* store the control word */ 116 117 movl %ecx,%edx 118 andl $0x1f,%edx /* get the trap enable bits */ 119 movb trap_table(%edx),%al 120 andb %al,0(%esp) /* unmask the corresponding exceptions */ 121 122 testl $0x200,%ecx /* test denormal trap enable */ 123 jz 1f /* skip if zero */ 124 125 andb $0xfd,0(%esp) /* unmask denormal exception */ 126 127 1: 128 movl %ecx,%edx 129 andl $0x60,%edx /* get the rounding direction */ 130 jz 1f /* skip if zero */ 131 132 movl %edx,%eax /* exchange negative<->tozero */ 133 andl $0x20,%eax /* leaving nearest and positive */ 134 shll $1,%eax /* as is */ 135 xorl %eax,%edx 136 shll $5,%edx 137 andw $0xf3ff,0(%esp) /* update rounding direction */ 138 orw %dx,0(%esp) 139 140 1: 141 andl $0x180,%ecx /* get the rounding precision */ 142 jz 1f /* skip if zero */ 143 144 xorl $0x180,%ecx /* reverse bits */ 145 shll $1,%ecx 146 andw $0xfcff,0(%esp) /* update rounding precision */ 147 orw %cx,0(%esp) 148 149 1: 150 fldcw 0(%esp) /* load the modified control word */ 151 152 3: 153 addl $4,%esp 154 popl %ecx 155 popl %edx 156 popl %ebp 157 ret 158 159 .size __fsr,[.-__fsr]