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]