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