Hello! Similar to x86, this patch puts soft-FP exception handler out-of-line. The patch also cleans asm constraints a bit (introduces "+"), but has no other functional changes.
2012-06-12 Uros Bizjak <ubiz...@gmail.com> * config/ia64/sfp-machine.h (__sfp_handle_exceptions): New function declaration. (FP_EX_MASK): New. (FP_HANDLE_EXCEPTIONS): Use __sfp_handle_exceptions. * config/ia64/sfp-exceptions.c: New. * config/ia64/t-softfp (LIB2ADD): Add sfp-exceptions.c. The patch is only compile tested, needs someone to regression test it ... Uros.
Index: config/ia64/sfp-exceptions.c =================================================================== --- config/ia64/sfp-exceptions.c (revision 0) +++ config/ia64/sfp-exceptions.c (revision 0) @@ -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)); + } +} Index: config/ia64/t-softfp =================================================================== --- config/ia64/t-softfp (revision 188431) +++ config/ia64/t-softfp (working copy) @@ -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 Index: config/ia64/sfp-machine.h =================================================================== --- config/ia64/sfp-machine.h (revision 188431) +++ config/ia64/sfp-machine.h (working copy) @@ -55,40 +55,16 @@ #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) +#define FP_EX_MASK 0x3f +void __sfp_handle_exceptions (int); + +#define FP_HANDLE_EXCEPTIONS \ + do { \ + if (_fex & FP_EX_MASK) \ + __sfp_handle_exceptions (_fex); \ + } while (0); + #define FP_RND_NEAREST 0 #define FP_RND_ZERO 0xc00L #define FP_RND_PINF 0x800L