diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-05 15:16:34 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-05 15:16:34 +0000 |
commit | 637f388d4b5f26804e4687ba130d83a853b9259e (patch) | |
tree | 96f0dba342fa3f8241e3f3155795e2e0dd60785e /libgcc/config/aarch64 | |
parent | 0f32be614d97e72c5e7e80b5ed0283f3b4645219 (diff) | |
download | gcc-637f388d4b5f26804e4687ba130d83a853b9259e.tar.gz |
2012-12-05 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 194222 using svnmerge.py
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@194223 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc/config/aarch64')
-rw-r--r-- | libgcc/config/aarch64/sfp-exceptions.c | 76 | ||||
-rw-r--r-- | libgcc/config/aarch64/sfp-machine.h | 68 | ||||
-rw-r--r-- | libgcc/config/aarch64/t-softfp | 2 |
3 files changed, 94 insertions, 52 deletions
diff --git a/libgcc/config/aarch64/sfp-exceptions.c b/libgcc/config/aarch64/sfp-exceptions.c new file mode 100644 index 00000000000..878cf8f95cd --- /dev/null +++ b/libgcc/config/aarch64/sfp-exceptions.c @@ -0,0 +1,76 @@ +/* + * 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) +{ + const float fp_max = __FLT_MAX__; + const float fp_min = __FLT_MIN__; + const float fp_1e32 = 1.0e32f; + const float fp_zero = 0.0; + const float fp_one = 1.0; + unsigned fpsr; + + if (_fex & FP_EX_INVALID) + { + __asm__ __volatile__ ("fdiv\ts0, %s0, %s0" + : + : "w" (fp_zero) + : "s0"); + __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); + } + if (_fex & FP_EX_DIVZERO) + { + __asm__ __volatile__ ("fdiv\ts0, %s0, %s1" + : + : "w" (fp_one), "w" (fp_zero) + : "s0"); + __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); + } + if (_fex & FP_EX_OVERFLOW) + { + __asm__ __volatile__ ("fadd\ts0, %s0, %s1" + : + : "w" (fp_max), "w" (fp_1e32) + : "s0"); + __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); + } + if (_fex & FP_EX_UNDERFLOW) + { + __asm__ __volatile__ ("fmul\ts0, %s0, %s0" + : + : "w" (fp_min) + : "s0"); + __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); + } + if (_fex & FP_EX_INEXACT) + { + __asm__ __volatile__ ("fsub\ts0, %s0, %s1" + : + : "w" (fp_max), "w" (fp_one) + : "s0"); + __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); + } +} diff --git a/libgcc/config/aarch64/sfp-machine.h b/libgcc/config/aarch64/sfp-machine.h index 3a09ae7605f..52b6fb2c446 100644 --- a/libgcc/config/aarch64/sfp-machine.h +++ b/libgcc/config/aarch64/sfp-machine.h @@ -69,62 +69,26 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); #define FP_EX_OVERFLOW 0x04 #define FP_EX_UNDERFLOW 0x08 #define FP_EX_INEXACT 0x10 +#define FP_EX_SHIFT 8 +#define FP_EX_ALL \ + (FP_EX_INVALID | FP_EX_DIVZERO | FP_EX_OVERFLOW | FP_EX_UNDERFLOW \ + | FP_EX_INEXACT) -#define FP_HANDLE_EXCEPTIONS \ - do { \ - const float fp_max = __FLT_MAX__; \ - const float fp_min = __FLT_MIN__; \ - const float fp_1e32 = 1.0e32f; \ - const float fp_zero = 0.0; \ - const float fp_one = 1.0; \ - unsigned fpsr; \ - if (_fex & FP_EX_INVALID) \ - { \ - __asm__ __volatile__ ("fdiv\ts0, %s0, %s0" \ - : \ - : "w" (fp_zero) \ - : "s0"); \ - __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); \ - } \ - if (_fex & FP_EX_DIVZERO) \ - { \ - __asm__ __volatile__ ("fdiv\ts0, %s0, %s1" \ - : \ - : "w" (fp_one), "w" (fp_zero) \ - : "s0"); \ - __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); \ - } \ - if (_fex & FP_EX_OVERFLOW) \ - { \ - __asm__ __volatile__ ("fadd\ts0, %s0, %s1" \ - : \ - : "w" (fp_max), "w" (fp_1e32) \ - : "s0"); \ - __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); \ - } \ - if (_fex & FP_EX_UNDERFLOW) \ - { \ - __asm__ __volatile__ ("fmul\ts0, %s0, %s0" \ - : \ - : "w" (fp_min) \ - : "s0"); \ - __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); \ - } \ - if (_fex & FP_EX_INEXACT) \ - { \ - __asm__ __volatile__ ("fsub\ts0, %s0, %s1" \ - : \ - : "w" (fp_max), "w" (fp_one) \ - : "s0"); \ - __asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr)); \ - } \ - } while (0) +void __sfp_handle_exceptions (int); +#define FP_HANDLE_EXCEPTIONS \ + do { \ + if (__builtin_expect (_fex, 0)) \ + __sfp_handle_exceptions (_fex); \ + } while (0); -#define FP_RND_NEAREST 0 -#define FP_RND_ZERO 0xc00000 +#define FP_TRAPPING_EXCEPTIONS ((_fpcr >> FP_EX_SHIFT) & FP_EX_ALL) + +#define FP_RND_NEAREST 0x000000 #define FP_RND_PINF 0x400000 #define FP_RND_MINF 0x800000 +#define FP_RND_ZERO 0xc00000 +#define FP_RND_MASK 0xc00000 #define _FP_DECL_EX \ unsigned long int _fpcr __attribute__ ((unused)) = FP_RND_NEAREST @@ -135,7 +99,7 @@ typedef int __gcc_CMPtype __attribute__ ((mode (__libgcc_cmp_return__))); : "=r" (_fpcr)); \ } while (0) -#define FP_ROUNDMODE (_fpcr & 0xc00000) +#define FP_ROUNDMODE (_fpcr & FP_RND_MASK) #define __LITTLE_ENDIAN 1234 #define __BIG_ENDIAN 4321 diff --git a/libgcc/config/aarch64/t-softfp b/libgcc/config/aarch64/t-softfp index 6500b5243e4..586dca22469 100644 --- a/libgcc/config/aarch64/t-softfp +++ b/libgcc/config/aarch64/t-softfp @@ -5,3 +5,5 @@ softfp_truncations := tfsf tfdf softfp_exclude_libgcc2 := n TARGET_LIBGCC2_CFLAGS += -Wno-missing-prototypes + +LIB2ADD += $(srcdir)/config/aarch64/sfp-exceptions.c |