fix regression from a745c4bfc8a9b5db4e48387170da0dc1d39e3abe
[uclibc-ng.git] / libm / metag / fraiseexcpt.c
blob5884ca23c03c185629854ac555b3d556e34d608e
1 /* Raise given exceptions.
2 Copyright (C) 2013 Imagination Technologies Ltd.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, see <http://www.gnu.org/licenses/>.  */
19 #include <fenv.h>
20 #include <math.h>
22 libm_hidden_proto(feraiseexcept)
24 int
25 feraiseexcept (int excepts)
27 /* Raise exceptions represented by EXPECTS. But we must raise only
28 one signal at a time. It is important that if the overflow/underflow
29 exception and the inexact exception are given at the same time,
30 the overflow/underflow exception follows the inexact exception. */
32 /* First: invalid exception. */
33 if ((FE_INVALID & excepts) != 0)
35 /* Reciprocal square root of a negative number is invalid. */
36 __asm__ volatile(
37 "F MOV FX.0,#0xc000 ! -2\n"
38 "F RSQ FX.1,FX.0\n"
42 /* Next: division by zero. */
43 if ((FE_DIVBYZERO & excepts) != 0)
45 __asm__ volatile(
46 "F MOV FX.0,#0\n"
47 "F RCP FX.1,FX.0\n"
51 /* Next: overflow. */
52 if ((FE_OVERFLOW & excepts) != 0)
54 /* Adding a large number in single precision can cause overflow. */
55 __asm__ volatile(
56 " MOVT D0.0,#0x7f7f\n"
57 " ADD D0.0,D0.0,#0xffff\n"
58 "F MOV FX.0,D0.0\n"
59 "F ADD FX.1,FX.0,FX.0\n"
63 /* Next: underflow. */
64 if ((FE_UNDERFLOW & excepts) != 0)
66 /* Multiplying a small value by 0.5 will cause an underflow. */
67 __asm__ volatile(
68 " MOV D0.0,#1\n"
69 "F MOV FX.0,D0.0\n"
70 " MOVT D0.0,#0x3f00\n"
71 "F MOV FX.1,D0.0\n"
72 "F MUL FX.2,FX.1,FX.0\n"
76 /* Last: inexact. */
77 if ((FE_INEXACT & excepts) != 0)
79 /* Converting a small single precision value to half precision
80 can cause an inexact exception. */
81 __asm__ volatile(
82 " MOV D0.0,#0x0001\n"
83 "F MOV FX.0,D0.0\n"
84 "F FTOH FX.1,FX.0\n"
88 /* Success. */
89 return 0;
91 libm_hidden_def(feraiseexcept)