diff options
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 9 | ||||
-rw-r--r-- | libgcc/config/ia64/sfp-exceptions.c | 54 | ||||
-rw-r--r-- | libgcc/config/ia64/sfp-machine.h | 64 | ||||
-rw-r--r-- | libgcc/config/ia64/t-softfp | 2 |
4 files changed, 85 insertions, 44 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 17a2122..7f89da3 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,5 +1,14 @@ 2012-06-13 Uros Bizjak <ubizjak@gmail.com> + * config/ia64/sfp-machine.h (__sfp_handle_exceptions): New + function declaration. + (FP_HANDLE_EXCEPTIONS): Use __sfp_handle_exceptions. + (FP_RND_MASK): New. + * config/ia64/sfp-exceptions.c: New. + * config/ia64/t-softfp (LIB2ADD): Add sfp-exceptions.c. + +2012-06-13 Uros Bizjak <ubizjak@gmail.com> + * config/i386/32/sfp-machine.h (_FP_NANSIGN_S, _FP_NANSIGN_D, _FP_NANSIGN_E, _FP_NANSIGN_Q): Move ... * config/i386/64/sfp-machine: ... (delete here) ... diff --git a/libgcc/config/ia64/sfp-exceptions.c b/libgcc/config/ia64/sfp-exceptions.c new file mode 100644 index 0000000..58113c7 --- /dev/null +++ b/libgcc/config/ia64/sfp-exceptions.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2012 Free Software Foundation, Inc. + * + * This file is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 3, or (at your option) any + * later version. + * + * This file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * Under Section 7 of GPL version 3, you are granted additional + * permissions described in the GCC Runtime Library Exception, version + * 3.1, as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License and + * a copy of the GCC Runtime Library Exception along with this program; + * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include "sfp-machine.h" + +void +__sfp_handle_exceptions (int _fex) +{ + double d; + + if (_fex & FP_EX_INVALID) + { + asm volatile ("frcpa.s0 %0, p1 = f0, f0" : "=f" (d) : : "p1"); + } + if (_fex & FP_EX_DIVZERO) + { + asm volatile ("frcpa.s0 %0, p1 = f1, f0" : "=f" (d) : : "p1"); + } + if (_fex & FP_EX_OVERFLOW) + { + d = __DBL_MAX__; + asm volatile ("fadd.d.s0 %0 = %0, %0" : "+f" (d)); + } + if (_fex & FP_EX_UNDERFLOW) + { + d = __DBL_MIN__; + asm volatile ("fnma.d.s0 %0 = %0, %0, f0" : "+f" (d)); + } + if (_fex & FP_EX_INEXACT) + { + d = __DBL_MAX__; + asm volatile ("fsub.d.s0 %0 = %0, f1" : "+f" (d)); + } +} diff --git a/libgcc/config/ia64/sfp-machine.h b/libgcc/config/ia64/sfp-machine.h index bdcce77..e86b7e3 100644 --- a/libgcc/config/ia64/sfp-machine.h +++ b/libgcc/config/ia64/sfp-machine.h @@ -13,7 +13,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); #define CMPtype __gcc_CMPtype -#define _FP_MUL_MEAT_Q(R,X,Y) \ +#define _FP_MUL_MEAT_Q(R,X,Y) \ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y) @@ -22,13 +22,14 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); #define _FP_NANFRAC_D _FP_QNANBIT_D #define _FP_NANFRAC_E _FP_QNANBIT_E, 0 #define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0 + +#define _FP_KEEPNANFRACP 1 + #define _FP_NANSIGN_S 1 #define _FP_NANSIGN_D 1 #define _FP_NANSIGN_E 1 #define _FP_NANSIGN_Q 1 -#define _FP_KEEPNANFRACP 1 - /* Here is something Intel misdesigned: the specs don't define the case where we have two NaNs with same mantissas, but different sign. Different operations pick up different NaNs. */ @@ -38,12 +39,12 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); || (_FP_FRAC_EQ_##wc(X,Y) && (OP == '+' || OP == '*'))) \ { \ R##_s = X##_s; \ - _FP_FRAC_COPY_##wc(R,X); \ + _FP_FRAC_COPY_##wc(R,X); \ } \ else \ { \ R##_s = Y##_s; \ - _FP_FRAC_COPY_##wc(R,Y); \ + _FP_FRAC_COPY_##wc(R,Y); \ } \ R##_c = FP_CLS_NAN; \ } while (0) @@ -55,55 +56,30 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); #define FP_EX_UNDERFLOW 0x10 #define FP_EX_INEXACT 0x20 -#define FP_HANDLE_EXCEPTIONS \ - do { \ - double tmp, dummy; \ - if (_fex & FP_EX_INVALID) \ - { \ - tmp = 0.0; \ - __asm__ __volatile__ ("frcpa.s0 %0,p1=f0,f0" \ - : "=f" (tmp) : : "p1" ); \ - } \ - if (_fex & FP_EX_DIVZERO) \ - { \ - __asm__ __volatile__ ("frcpa.s0 %0,p1=f1,f0" \ - : "=f" (tmp) : : "p1" ); \ - } \ - if (_fex & FP_EX_OVERFLOW) \ - { \ - dummy = __DBL_MAX__; \ - __asm__ __volatile__ ("fadd.d.s0 %0=%1,%1" \ - : "=f" (dummy) : "0" (dummy)); \ - } \ - if (_fex & FP_EX_UNDERFLOW) \ - { \ - dummy = __DBL_MIN__; \ - __asm__ __volatile__ ("fnma.d.s0 %0=%1,%1,f0" \ - : "=f" (tmp) : "f" (dummy)); \ - } \ - if (_fex & FP_EX_INEXACT) \ - { \ - dummy = __DBL_MAX__; \ - __asm__ __volatile__ ("fsub.d.s0 %0=%1,f1" \ - : "=f" (dummy) : "0" (dummy)); \ - } \ - } while (0) +void __sfp_handle_exceptions (int); + +#define FP_HANDLE_EXCEPTIONS \ + do { \ + if (_fex) \ + __sfp_handle_exceptions (_fex); \ + } while (0); #define FP_RND_NEAREST 0 #define FP_RND_ZERO 0xc00L #define FP_RND_PINF 0x800L #define FP_RND_MINF 0x400L +#define FP_RND_MASK 0xc00L + #define _FP_DECL_EX \ - unsigned long int _fpsr __attribute__ ((unused)) = FP_RND_NEAREST + unsigned long int _fcw __attribute__ ((unused)) = FP_RND_NEAREST -#define FP_INIT_ROUNDMODE \ - do { \ - __asm__ __volatile__ ("mov.m %0=ar.fpsr" \ - : "=r" (_fpsr)); \ +#define FP_INIT_ROUNDMODE \ + do { \ + __asm__ __volatile__ ("mov.m %0 = ar.fpsr" : "=r" (_fcw)); \ } while (0) -#define FP_ROUNDMODE (_fpsr & 0xc00L) +#define FP_ROUNDMODE (_fcw & FP_RND_MASK) #define __LITTLE_ENDIAN 1234 #define __BIG_ENDIAN 4321 diff --git a/libgcc/config/ia64/t-softfp b/libgcc/config/ia64/t-softfp index 90acc37..0ac35e7 100644 --- a/libgcc/config/ia64/t-softfp +++ b/libgcc/config/ia64/t-softfp @@ -1,2 +1,4 @@ # Provide fallbacks for __builtin_copysignq and __builtin_fabsq. LIB2ADD += $(srcdir)/config/ia64/tf-signs.c + +LIB2ADD += $(srcdir)/config/ia64/sfp-exceptions.c |