Remove building with NOCRYPTO option
[minix3.git] / lib / libm / arch / riscv / fenv.c
blob6bc5fc425cdea0f7bb0f5bdb20b4f45ab5610447
1 /* $NetBSD: fenv.c,v 1.1 2014/09/19 17:36:25 matt Exp $ */
3 /*-
4 * Copyright (c) 2014 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas of 3am Software Foundry.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: fenv.c,v 1.1 2014/09/19 17:36:25 matt Exp $");
35 #include <sys/param.h>
36 #include <sys/sysctl.h>
37 #include <assert.h>
38 #include <fenv.h>
39 #include <stddef.h>
40 #include <string.h>
42 #include <riscv/sysreg.h>
45 * The following constant represents the default floating-point environment
46 * (that is, the one installed at program startup) and has type pointer to
47 * const-qualified fenv_t.
49 * It can be used as an argument to the functions within the <fenv.h> header
50 * that manage the floating-point environment, namely fesetenv() and
51 * feupdateenv().
53 fenv_t __fe_dfl_env = __SHIFTIN(FCSR_FRM_RNE, FCSR_FRM);
56 * The feclearexcept() function clears the supported floating-point exceptions
57 * represented by `excepts'.
59 int
60 feclearexcept(int excepts)
62 _DIAGASSERT((excepts & ~FE_ALL_EXCEPT) == 0);
64 int fflags = riscvreg_fcsr_read_fflags();
66 fflags &= ~(excepts & FE_ALL_EXCEPT);
68 riscvreg_fcsr_write_fflags(fflags);
70 /* Success */
71 return (0);
75 * The fegetexceptflag() function stores an implementation-defined
76 * representation of the states of the floating-point status flags indicated by
77 * the argument excepts in the object pointed to by the argument flagp.
79 int
80 fegetexceptflag(fexcept_t *flagp, int excepts)
82 _DIAGASSERT(flagp != NULL);
83 _DIAGASSERT((excepts & ~FE_ALL_EXCEPT) == 0);
85 *flagp = riscvreg_fcsr_read_fflags() & excepts;
87 /* Success */
88 return (0);
92 * The feraiseexcept() function raises the supported floating-point exceptions
93 * represented by the argument `excepts'.
95 * The standard explicitly allows us to execute an instruction that has the
96 * exception as a side effect, but we choose to manipulate the status register
97 * directly.
99 * The validation of input is being deferred to fesetexceptflag().
102 feraiseexcept(int excepts)
104 fexcept_t ex = 0;
106 _DIAGASSERT((excepts & ~FE_ALL_EXCEPT) == 0);
108 excepts &= FE_ALL_EXCEPT;
109 fesetexceptflag(&ex, excepts);
110 /* XXX exception magic XXX */
112 /* Success */
113 return (0);
117 * This function sets the floating-point status flags indicated by the argument
118 * `excepts' to the states stored in the object pointed to by `flagp'. It does
119 * NOT raise any floating-point exceptions, but only sets the state of the flags.
122 fesetexceptflag(const fexcept_t *flagp, int excepts)
124 _DIAGASSERT(flagp != NULL);
125 _DIAGASSERT((excepts & ~FE_ALL_EXCEPT) == 0);
127 excepts &= FE_ALL_EXCEPT;
129 int fflags = riscvreg_fcsr_read_fflags();
131 fflags = (fflags & ~excepts) | (*flagp & excepts);
133 riscvreg_fcsr_write_fflags(fflags);
135 /* Success */
136 return (0);
140 * The fetestexcept() function determines which of a specified subset of the
141 * floating-point exception flags are currently set. The `excepts' argument
142 * specifies the floating-point status flags to be queried.
145 fetestexcept(int excepts)
147 _DIAGASSERT((excepts & ~FE_ALL_EXCEPT) == 0);
149 return riscvreg_fcsr_read_fflags() & excepts & FE_ALL_EXCEPT;
153 fegetround(void)
155 return riscvreg_fcsr_read_frm();
159 * The fesetround() function shall establish the rounding direction represented
160 * by its argument round. If the argument is not equal to the value of a
161 * rounding direction macro, the rounding direction is not changed.
164 fesetround(int round)
166 if ((unsigned int)round > FCSR_FRM_RMM) {
167 /* Failure */
168 return (-1);
171 riscvreg_fcsr_write_frm(round);
173 /* Success */
174 return (0);
178 * The fegetenv() function attempts to store the current floating-point
179 * environment in the object pointed to by envp.
182 fegetenv(fenv_t *envp)
184 _DIAGASSERT(envp != NULL);
186 *envp = riscvreg_fcsr_read();
188 /* Success */
189 return (0);
193 * The feholdexcept() function saves the current floating-point environment in
194 * the object pointed to by envp, clears the floating-point status flags, and
195 * then installs a non-stop (continue on floating-point exceptions) mode, if
196 * available, for all floating-point exceptions.
199 feholdexcept(fenv_t *envp)
201 _DIAGASSERT(envp != NULL);
203 *envp = riscvreg_fcsr_read();
205 riscvreg_fcsr_write_fflags(0);
207 /* Success */
208 return (0);
212 * The fesetenv() function attempts to establish the floating-point environment
213 * represented by the object pointed to by envp. The argument `envp' points
214 * to an object set by a call to fegetenv() or feholdexcept(), or equal a
215 * floating-point environment macro. The fesetenv() function does not raise
216 * floating-point exceptions, but only installs the state of the floating-point
217 * status flags represented through its argument.
220 fesetenv(const fenv_t *envp)
223 _DIAGASSERT(envp != NULL);
225 fenv_t env = *envp;
227 if ((env & ~(FCSR_FRM|FCSR_FFLAGS)
228 || __SHIFTOUT(env, FCSR_FRM) > FCSR_FRM_RMM)) {
229 return -1;
232 riscvreg_fcsr_write(env);
234 /* Success */
235 return (0);
239 * The feupdateenv() function saves the currently raised floating-point
240 * exceptions in its automatic storage, installs the floating-point environment
241 * represented by the object pointed to by `envp', and then raises the saved
242 * floating-point exceptions. The argument `envp' shall point to an object set
243 * by a call to feholdexcept() or fegetenv(), or equal a floating-point
244 * environment macro.
247 feupdateenv(const fenv_t *envp)
249 _DIAGASSERT(envp != NULL);
251 int fflags = riscvreg_fcsr_read_fflags();
253 fesetenv(envp);
254 feraiseexcept(fflags);
256 /* Success */
257 return (0);
261 * The following functions are extentions to the standard
264 feenableexcept(int nmask)
266 return 0;
270 fedisableexcept(int nmask)
272 return 0;
276 fegetexcept(void)
278 return 0;