Home | History | Annotate | Line # | Download | only in i386
sfp-exceptions.c revision 1.1.1.3.4.2
      1          1.1     mrg /*
      2  1.1.1.3.4.2  martin  * Copyright (C) 2012-2018 Free Software Foundation, Inc.
      3          1.1     mrg  *
      4          1.1     mrg  * This file is free software; you can redistribute it and/or modify it
      5          1.1     mrg  * under the terms of the GNU General Public License as published by the
      6          1.1     mrg  * Free Software Foundation; either version 3, or (at your option) any
      7          1.1     mrg  * later version.
      8          1.1     mrg  *
      9          1.1     mrg  * This file is distributed in the hope that it will be useful, but
     10          1.1     mrg  * WITHOUT ANY WARRANTY; without even the implied warranty of
     11          1.1     mrg  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12          1.1     mrg  * General Public License for more details.
     13          1.1     mrg  *
     14          1.1     mrg  * Under Section 7 of GPL version 3, you are granted additional
     15          1.1     mrg  * permissions described in the GCC Runtime Library Exception, version
     16          1.1     mrg  * 3.1, as published by the Free Software Foundation.
     17          1.1     mrg  *
     18          1.1     mrg  * You should have received a copy of the GNU General Public License and
     19          1.1     mrg  * a copy of the GCC Runtime Library Exception along with this program;
     20          1.1     mrg  * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     21          1.1     mrg  * <http://www.gnu.org/licenses/>.
     22          1.1     mrg  */
     23          1.1     mrg 
     24          1.1     mrg #ifndef _SOFT_FLOAT
     25          1.1     mrg #include "sfp-machine.h"
     26          1.1     mrg 
     27          1.1     mrg struct fenv
     28          1.1     mrg {
     29          1.1     mrg   unsigned short int __control_word;
     30          1.1     mrg   unsigned short int __unused1;
     31          1.1     mrg   unsigned short int __status_word;
     32          1.1     mrg   unsigned short int __unused2;
     33          1.1     mrg   unsigned short int __tags;
     34          1.1     mrg   unsigned short int __unused3;
     35          1.1     mrg   unsigned int __eip;
     36          1.1     mrg   unsigned short int __cs_selector;
     37          1.1     mrg   unsigned int __opcode:11;
     38          1.1     mrg   unsigned int __unused4:5;
     39          1.1     mrg   unsigned int __data_offset;
     40          1.1     mrg   unsigned short int __data_selector;
     41          1.1     mrg   unsigned short int __unused5;
     42          1.1     mrg };
     43          1.1     mrg 
     44          1.1     mrg void
     45          1.1     mrg __sfp_handle_exceptions (int _fex)
     46          1.1     mrg {
     47          1.1     mrg   if (_fex & FP_EX_INVALID)
     48          1.1     mrg     {
     49          1.1     mrg       float f = 0.0f;
     50          1.1     mrg #ifdef __SSE_MATH__
     51          1.1     mrg       volatile float r __attribute__ ((unused));
     52          1.1     mrg       asm volatile ("%vdivss\t{%0, %d0|%d0, %0}" : "+x" (f));
     53          1.1     mrg       r = f; /* Needed to trigger exception.   */
     54          1.1     mrg #else
     55          1.1     mrg       asm volatile ("fdiv\t{%y0, %0|%0, %y0}" : "+t" (f));
     56          1.1     mrg       /* No need for fwait, exception is triggered by emitted fstp.  */
     57          1.1     mrg #endif
     58          1.1     mrg     }
     59          1.1     mrg   if (_fex & FP_EX_DENORM)
     60          1.1     mrg     {
     61          1.1     mrg       struct fenv temp;
     62          1.1     mrg       asm volatile ("fnstenv\t%0" : "=m" (temp));
     63          1.1     mrg       temp.__status_word |= FP_EX_DENORM;
     64          1.1     mrg       asm volatile ("fldenv\t%0" : : "m" (temp));
     65          1.1     mrg       asm volatile ("fwait");
     66          1.1     mrg     }
     67          1.1     mrg   if (_fex & FP_EX_DIVZERO)
     68          1.1     mrg     {
     69          1.1     mrg       float f = 1.0f, g = 0.0f;
     70          1.1     mrg #ifdef __SSE_MATH__
     71          1.1     mrg       volatile float r __attribute__ ((unused));
     72          1.1     mrg       asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
     73          1.1     mrg       r = f; /* Needed to trigger exception.   */
     74          1.1     mrg #else
     75          1.1     mrg       asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
     76          1.1     mrg       /* No need for fwait, exception is triggered by emitted fstp.  */
     77          1.1     mrg #endif
     78          1.1     mrg     }
     79          1.1     mrg   if (_fex & FP_EX_OVERFLOW)
     80          1.1     mrg     {
     81          1.1     mrg       struct fenv temp;
     82          1.1     mrg       asm volatile ("fnstenv\t%0" : "=m" (temp));
     83          1.1     mrg       temp.__status_word |= FP_EX_OVERFLOW;
     84          1.1     mrg       asm volatile ("fldenv\t%0" : : "m" (temp));
     85          1.1     mrg       asm volatile ("fwait");
     86          1.1     mrg     }
     87          1.1     mrg   if (_fex & FP_EX_UNDERFLOW)
     88          1.1     mrg     {
     89          1.1     mrg       struct fenv temp;
     90          1.1     mrg       asm volatile ("fnstenv\t%0" : "=m" (temp));
     91          1.1     mrg       temp.__status_word |= FP_EX_UNDERFLOW;
     92          1.1     mrg       asm volatile ("fldenv\t%0" : : "m" (temp));
     93          1.1     mrg       asm volatile ("fwait");
     94          1.1     mrg     }
     95          1.1     mrg   if (_fex & FP_EX_INEXACT)
     96          1.1     mrg     {
     97          1.1     mrg       float f = 1.0f, g = 3.0f;
     98          1.1     mrg #ifdef __SSE_MATH__
     99          1.1     mrg       volatile float r __attribute__ ((unused));
    100          1.1     mrg       asm volatile ("%vdivss\t{%1, %d0|%d0, %1}" : "+x" (f) : "xm" (g));
    101          1.1     mrg       r = f; /* Needed to trigger exception.   */
    102          1.1     mrg #else
    103          1.1     mrg       asm volatile ("fdivs\t%1" : "+t" (f) : "m" (g));
    104          1.1     mrg       /* No need for fwait, exception is triggered by emitted fstp.  */
    105          1.1     mrg #endif
    106          1.1     mrg     }
    107          1.1     mrg };
    108          1.1     mrg #endif
    109