1 /*
2 * Copyright (C) 2016-2017 Andes Technology, Inc.
3 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
4 */
5
6 /* Raise given exceptions.
7 Copyright (C) 2004-2013 Free Software Foundation, Inc.
8
9 The GNU C Library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 The GNU C Library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with the GNU C Library. If not, see
21 <http://www.gnu.org/licenses/>. */
22
23 #include <fpu_control.h>
24 #include <fenv.h>
25 #include <float.h>
26 #include "fenv_libc.h"
27
28 int
feraiseexcept(int excepts)29 feraiseexcept (int excepts)
30 {
31 #ifdef __NDS32_ABI_2FP_PLUS__
32 float temp1 = 0.0, temp2 = 1.0;
33 if (FE_INVALID & excepts)
34 {
35 __asm__ volatile(
36 "fmtsr\t %0, $fs0\n\t"
37 "fdivs\t $fs0, $fs0, $fs0\n\t"
38 :
39 :"r"(temp1)
40 :"$fs0"
41 );
42 }
43 if (FE_DIVBYZERO & excepts)
44 {
45 __asm__ volatile(
46 "fmtsr\t %0, $fs0\n\t"
47 "fmtsr\t %1, $fs1\n\t"
48 "fdivs\t $fs0, $fs1, $fs0\n\t"
49 :
50 :"r"(temp1),"r"(temp2)
51 :"$fs0"
52 );
53 }
54 if (FE_OVERFLOW & excepts)
55 {
56 /* There's no way to raise overflow without also raising inexact.
57 */
58 unsigned int fpcsr;
59 temp1 = FLT_MAX;
60 __asm__ volatile(
61 "fmfcsr\t %0\n\t"
62 "fmtsr\t %1, $fs0\n\t"
63 "fadds\t $fs0, $fs0, $fs0\n\t"
64 "ori\t %0,%0,0x10\n\t"
65 "fmtcsr\t %0\n\t"
66 :"=&r"(fpcsr)
67 :"r"(temp1)
68 :"$fs0"
69 );
70 }
71 if (FE_UNDERFLOW & excepts)
72 {
73 /* There's no way to raise overflow without also raising inexact.
74 */
75 temp1 = FLT_MIN;
76 temp2 = 2.0;
77 __asm__ volatile(
78 "fmtsr\t %0, $fs0\n\t"
79 "fmtsr\t %1, $fs1\n\t"
80 "fdivs\t $fs1, $fs0, $fs1\n\t"
81 :
82 :"r"(temp1),"r"(temp2)
83 :"$fs0","$fs1"
84 );
85 }
86 if (FE_INEXACT & excepts)
87 {
88 temp1 = 3.0;
89 __asm__ volatile(
90 "fmtsr\t %0, $fs1\n\t"
91 "fmtsr\t %1, $fs0\n\t"
92 "fdivs\t $fs1, $fs0, $fs1\n\t"
93 :
94 :"r"(temp1),"r"(temp2)
95 :"$fs0","$fs1"
96 );
97 }
98
99 return 0;
100
101 #endif
102 /* Unsupported, so fail unless nothing needs to be done. */
103 return (excepts != 0);
104 }
105