From cf349fcbb555b77f22d96fe3a7b25579337ab989 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Thu, 26 Nov 2009 10:20:01 +0000 Subject: libm: Add support for the Meta architecture Signed-off-by: Markos Chandras Signed-off-by: Bernhard Reutner-Fischer --- libm/metag/fraiseexcpt.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 libm/metag/fraiseexcpt.c (limited to 'libm/metag/fraiseexcpt.c') diff --git a/libm/metag/fraiseexcpt.c b/libm/metag/fraiseexcpt.c new file mode 100644 index 000000000..9ab39bbf6 --- /dev/null +++ b/libm/metag/fraiseexcpt.c @@ -0,0 +1,92 @@ +/* Raise given exceptions. + Copyright (C) 2013 Imagination Technologies Ltd. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +libm_hidden_proto(feraiseexcept) + +int +feraiseexcept (int excepts) +{ + /* Raise exceptions represented by EXPECTS. But we must raise only + one signal at a time. It is important that if the overflow/underflow + exception and the inexact exception are given at the same time, + the overflow/underflow exception follows the inexact exception. */ + + /* First: invalid exception. */ + if ((FE_INVALID & excepts) != 0) + { + /* Reciprocal square root of a negative number is invalid. */ + __asm__ volatile( + "F MOV FX.0,#0xc000 ! -2\n" + "F RSQ FX.1,FX.0\n" + ); + } + + /* Next: division by zero. */ + if ((FE_DIVBYZERO & excepts) != 0) + { + __asm__ volatile( + "F MOV FX.0,#0\n" + "F RCP FX.1,FX.0\n" + ); + } + + /* Next: overflow. */ + if ((FE_OVERFLOW & excepts) != 0) + { + /* Adding a large number in single precision can cause overflow. */ + __asm__ volatile( + " MOVT D0.0,#0x7f7f\n" + " ADD D0.0,D0.0,#0xffff\n" + "F MOV FX.0,D0.0\n" + "F ADD FX.1,FX.0,FX.0\n" + ); + } + + /* Next: underflow. */ + if ((FE_UNDERFLOW & excepts) != 0) + { + /* Multiplying a small value by 0.5 will cause an underflow. */ + __asm__ volatile( + " MOV D0.0,#1\n" + "F MOV FX.0,D0.0\n" + " MOVT D0.0,#0x3f00\n" + "F MOV FX.1,D0.0\n" + "F MUL FX.2,FX.1,FX.0\n" + ); + } + + /* Last: inexact. */ + if ((FE_INEXACT & excepts) != 0) + { + /* Converting a small single precision value to half precision + can cause an inexact exception. */ + __asm__ volatile( + " MOV D0.0,#0x0001\n" + "F MOV FX.0,D0.0\n" + "F FTOH FX.1,FX.0\n" + ); + } + + /* Success. */ + return 0; +} +libm_hidden_def(feraiseexcept) -- cgit v1.2.3