Home | History | Annotate | Line # | Download | only in pa
      1      1.1  mrg /*
      2  1.1.1.2  mrg  * Copyright (C) 1997-2024 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 
     25      1.1  mrg #include "sfp-machine.h"
     26      1.1  mrg 
     27      1.1  mrg #define HUGE_VAL (__builtin_huge_val ())
     28      1.1  mrg 
     29      1.1  mrg /* Please see section 10,
     30      1.1  mrg    page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */
     31      1.1  mrg 
     32      1.1  mrg void
     33      1.1  mrg __sfp_handle_exceptions (int _fex)
     34      1.1  mrg {
     35      1.1  mrg   /* Raise exceptions represented by _FEX.  But we must raise only one
     36      1.1  mrg      signal at a time.  It is important that if the overflow/underflow
     37      1.1  mrg      exception and the divide by zero exception are given at the same
     38      1.1  mrg      time, the overflow/underflow exception follows the divide by zero
     39      1.1  mrg      exception.  */
     40      1.1  mrg 
     41      1.1  mrg   /* We do these bits in assembly to be certain GCC doesn't optimize
     42      1.1  mrg      away something important, and so we can force delayed traps to
     43      1.1  mrg      occur. */
     44      1.1  mrg 
     45      1.1  mrg   /* We use "fldd 0(%%sr0,%%sp),%0" to flush the delayed exception */
     46      1.1  mrg 
     47      1.1  mrg   /* First: Invalid exception.  */
     48      1.1  mrg   if (_fex & FP_EX_INVALID)
     49      1.1  mrg     {
     50      1.1  mrg       /* One example of an invalid operation is 0 * Infinity.  */
     51      1.1  mrg       double d = HUGE_VAL;
     52      1.1  mrg       __asm__ __volatile__ (
     53      1.1  mrg 		"	fcpy,dbl %%fr0,%%fr22\n"
     54      1.1  mrg 		"	fmpy,dbl %0,%%fr22,%0\n"
     55      1.1  mrg 		"	fldd 0(%%sr0,%%sp),%0"
     56      1.1  mrg 		: "+f" (d) : : "%fr22" );
     57      1.1  mrg     }
     58      1.1  mrg 
     59      1.1  mrg   /* Second: Division by zero.  */
     60      1.1  mrg   if (_fex & FP_EX_DIVZERO)
     61      1.1  mrg     {
     62      1.1  mrg       double d = 1.0;
     63      1.1  mrg       __asm__ __volatile__ (
     64      1.1  mrg 		"	fcpy,dbl %%fr0,%%fr22\n"
     65      1.1  mrg 		"	fdiv,dbl %0,%%fr22,%0\n"
     66      1.1  mrg 		"	fldd 0(%%sr0,%%sp),%0"
     67      1.1  mrg 		: "+f" (d) : : "%fr22" );
     68      1.1  mrg     }
     69      1.1  mrg 
     70      1.1  mrg   /* Third: Overflow.  */
     71      1.1  mrg   if (_fex & FP_EX_OVERFLOW)
     72      1.1  mrg     {
     73      1.1  mrg       double d = __DBL_MAX__;
     74      1.1  mrg       __asm__ __volatile__ (
     75      1.1  mrg 		"	fadd,dbl %0,%0,%0\n"
     76      1.1  mrg 		"	fldd 0(%%sr0,%%sp),%0"
     77      1.1  mrg 		: "+f" (d) );
     78      1.1  mrg     }
     79      1.1  mrg 
     80      1.1  mrg   /* Fourth: Underflow.  */
     81      1.1  mrg   if (_fex & FP_EX_UNDERFLOW)
     82      1.1  mrg     {
     83      1.1  mrg       double d = __DBL_MIN__;
     84      1.1  mrg       double e = 3.0;
     85      1.1  mrg       __asm__ __volatile__ (
     86      1.1  mrg 		"	fdiv,dbl %0,%1,%0\n"
     87      1.1  mrg 		"	fldd 0(%%sr0,%%sp),%0"
     88      1.1  mrg 		: "+f" (d) : "f" (e) );
     89      1.1  mrg     }
     90      1.1  mrg 
     91      1.1  mrg   /* Fifth: Inexact */
     92      1.1  mrg   if (_fex & FP_EX_INEXACT)
     93      1.1  mrg     {
     94      1.1  mrg       double d = 3.14159265358979323846;
     95      1.1  mrg       double e = 69.69;
     96      1.1  mrg       __asm__ __volatile__ (
     97      1.1  mrg 		"	fdiv,dbl %0,%1,%%fr22\n"
     98      1.1  mrg 		"	fcnvfxt,dbl,sgl %%fr22,%%fr22L\n"
     99      1.1  mrg 		"	fldd 0(%%sr0,%%sp),%%fr22"
    100      1.1  mrg 		: : "f" (d), "f" (e) : "%fr22" );
    101      1.1  mrg     }
    102      1.1  mrg }
    103