xref: /aosp_15_r20/bionic/libm/fenv-arm.c (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
1*8d67ca89SAndroid Build Coastguard Worker /*-
2*8d67ca89SAndroid Build Coastguard Worker  * Copyright (c) 2004 David Schultz <[email protected]>
3*8d67ca89SAndroid Build Coastguard Worker  * All rights reserved.
4*8d67ca89SAndroid Build Coastguard Worker  *
5*8d67ca89SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
6*8d67ca89SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
7*8d67ca89SAndroid Build Coastguard Worker  * are met:
8*8d67ca89SAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
9*8d67ca89SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
10*8d67ca89SAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
11*8d67ca89SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
12*8d67ca89SAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
13*8d67ca89SAndroid Build Coastguard Worker  *
14*8d67ca89SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*8d67ca89SAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*8d67ca89SAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*8d67ca89SAndroid Build Coastguard Worker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*8d67ca89SAndroid Build Coastguard Worker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*8d67ca89SAndroid Build Coastguard Worker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*8d67ca89SAndroid Build Coastguard Worker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*8d67ca89SAndroid Build Coastguard Worker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*8d67ca89SAndroid Build Coastguard Worker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*8d67ca89SAndroid Build Coastguard Worker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*8d67ca89SAndroid Build Coastguard Worker  * SUCH DAMAGE.
25*8d67ca89SAndroid Build Coastguard Worker  *
26*8d67ca89SAndroid Build Coastguard Worker  * $FreeBSD: src/lib/msun/arm/fenv.c,v 1.1 2004/06/06 10:03:59 das Exp $
27*8d67ca89SAndroid Build Coastguard Worker  */
28*8d67ca89SAndroid Build Coastguard Worker 
29*8d67ca89SAndroid Build Coastguard Worker #include <fenv.h>
30*8d67ca89SAndroid Build Coastguard Worker 
31*8d67ca89SAndroid Build Coastguard Worker #define FPSCR_RMODE_SHIFT 22
32*8d67ca89SAndroid Build Coastguard Worker 
33*8d67ca89SAndroid Build Coastguard Worker const fenv_t __fe_dfl_env = 0;
34*8d67ca89SAndroid Build Coastguard Worker 
fegetenv(fenv_t * __envp)35*8d67ca89SAndroid Build Coastguard Worker int fegetenv(fenv_t* __envp) {
36*8d67ca89SAndroid Build Coastguard Worker   fenv_t _fpscr;
37*8d67ca89SAndroid Build Coastguard Worker   __asm__ __volatile__("vmrs %0,fpscr" : "=r"(_fpscr));
38*8d67ca89SAndroid Build Coastguard Worker   *__envp = _fpscr;
39*8d67ca89SAndroid Build Coastguard Worker   return 0;
40*8d67ca89SAndroid Build Coastguard Worker }
41*8d67ca89SAndroid Build Coastguard Worker 
fesetenv(const fenv_t * __envp)42*8d67ca89SAndroid Build Coastguard Worker int fesetenv(const fenv_t* __envp) {
43*8d67ca89SAndroid Build Coastguard Worker   fenv_t _fpscr = *__envp;
44*8d67ca89SAndroid Build Coastguard Worker   __asm__ __volatile__("vmsr fpscr,%0" : : "ri"(_fpscr));
45*8d67ca89SAndroid Build Coastguard Worker   return 0;
46*8d67ca89SAndroid Build Coastguard Worker }
47*8d67ca89SAndroid Build Coastguard Worker 
feclearexcept(int __excepts)48*8d67ca89SAndroid Build Coastguard Worker int feclearexcept(int __excepts) {
49*8d67ca89SAndroid Build Coastguard Worker   fexcept_t __fpscr;
50*8d67ca89SAndroid Build Coastguard Worker   fegetenv(&__fpscr);
51*8d67ca89SAndroid Build Coastguard Worker   __fpscr &= ~__excepts;
52*8d67ca89SAndroid Build Coastguard Worker   fesetenv(&__fpscr);
53*8d67ca89SAndroid Build Coastguard Worker   return 0;
54*8d67ca89SAndroid Build Coastguard Worker }
55*8d67ca89SAndroid Build Coastguard Worker 
fegetexceptflag(fexcept_t * __flagp,int __excepts)56*8d67ca89SAndroid Build Coastguard Worker int fegetexceptflag(fexcept_t* __flagp, int __excepts) {
57*8d67ca89SAndroid Build Coastguard Worker   fexcept_t __fpscr;
58*8d67ca89SAndroid Build Coastguard Worker   fegetenv(&__fpscr);
59*8d67ca89SAndroid Build Coastguard Worker   *__flagp = __fpscr & __excepts;
60*8d67ca89SAndroid Build Coastguard Worker   return 0;
61*8d67ca89SAndroid Build Coastguard Worker }
62*8d67ca89SAndroid Build Coastguard Worker 
fesetexceptflag(const fexcept_t * __flagp,int __excepts)63*8d67ca89SAndroid Build Coastguard Worker int fesetexceptflag(const fexcept_t* __flagp, int __excepts) {
64*8d67ca89SAndroid Build Coastguard Worker   fexcept_t __fpscr;
65*8d67ca89SAndroid Build Coastguard Worker   fegetenv(&__fpscr);
66*8d67ca89SAndroid Build Coastguard Worker   __fpscr &= ~__excepts;
67*8d67ca89SAndroid Build Coastguard Worker   __fpscr |= *__flagp & __excepts;
68*8d67ca89SAndroid Build Coastguard Worker   fesetenv(&__fpscr);
69*8d67ca89SAndroid Build Coastguard Worker   return 0;
70*8d67ca89SAndroid Build Coastguard Worker }
71*8d67ca89SAndroid Build Coastguard Worker 
feraiseexcept(int __excepts)72*8d67ca89SAndroid Build Coastguard Worker int feraiseexcept(int __excepts) {
73*8d67ca89SAndroid Build Coastguard Worker   fexcept_t __ex = __excepts;
74*8d67ca89SAndroid Build Coastguard Worker   fesetexceptflag(&__ex, __excepts);
75*8d67ca89SAndroid Build Coastguard Worker   return 0;
76*8d67ca89SAndroid Build Coastguard Worker }
77*8d67ca89SAndroid Build Coastguard Worker 
fetestexcept(int __excepts)78*8d67ca89SAndroid Build Coastguard Worker int fetestexcept(int __excepts) {
79*8d67ca89SAndroid Build Coastguard Worker   fexcept_t __fpscr;
80*8d67ca89SAndroid Build Coastguard Worker   fegetenv(&__fpscr);
81*8d67ca89SAndroid Build Coastguard Worker   return (__fpscr & __excepts);
82*8d67ca89SAndroid Build Coastguard Worker }
83*8d67ca89SAndroid Build Coastguard Worker 
fegetround(void)84*8d67ca89SAndroid Build Coastguard Worker int fegetround(void) {
85*8d67ca89SAndroid Build Coastguard Worker   fenv_t _fpscr;
86*8d67ca89SAndroid Build Coastguard Worker   fegetenv(&_fpscr);
87*8d67ca89SAndroid Build Coastguard Worker   return ((_fpscr >> FPSCR_RMODE_SHIFT) & 0x3);
88*8d67ca89SAndroid Build Coastguard Worker }
89*8d67ca89SAndroid Build Coastguard Worker 
fesetround(int __round)90*8d67ca89SAndroid Build Coastguard Worker int fesetround(int __round) {
91*8d67ca89SAndroid Build Coastguard Worker   fenv_t _fpscr;
92*8d67ca89SAndroid Build Coastguard Worker   fegetenv(&_fpscr);
93*8d67ca89SAndroid Build Coastguard Worker   _fpscr &= ~(0x3 << FPSCR_RMODE_SHIFT);
94*8d67ca89SAndroid Build Coastguard Worker   _fpscr |= (__round << FPSCR_RMODE_SHIFT);
95*8d67ca89SAndroid Build Coastguard Worker   fesetenv(&_fpscr);
96*8d67ca89SAndroid Build Coastguard Worker   return 0;
97*8d67ca89SAndroid Build Coastguard Worker }
98*8d67ca89SAndroid Build Coastguard Worker 
feholdexcept(fenv_t * __envp)99*8d67ca89SAndroid Build Coastguard Worker int feholdexcept(fenv_t* __envp) {
100*8d67ca89SAndroid Build Coastguard Worker   fenv_t __env;
101*8d67ca89SAndroid Build Coastguard Worker   fegetenv(&__env);
102*8d67ca89SAndroid Build Coastguard Worker   *__envp = __env;
103*8d67ca89SAndroid Build Coastguard Worker   __env &= ~FE_ALL_EXCEPT;
104*8d67ca89SAndroid Build Coastguard Worker   fesetenv(&__env);
105*8d67ca89SAndroid Build Coastguard Worker   return 0;
106*8d67ca89SAndroid Build Coastguard Worker }
107*8d67ca89SAndroid Build Coastguard Worker 
feupdateenv(const fenv_t * __envp)108*8d67ca89SAndroid Build Coastguard Worker int feupdateenv(const fenv_t* __envp) {
109*8d67ca89SAndroid Build Coastguard Worker   fexcept_t __fpscr;
110*8d67ca89SAndroid Build Coastguard Worker   fegetenv(&__fpscr);
111*8d67ca89SAndroid Build Coastguard Worker   fesetenv(__envp);
112*8d67ca89SAndroid Build Coastguard Worker   feraiseexcept(__fpscr & FE_ALL_EXCEPT);
113*8d67ca89SAndroid Build Coastguard Worker   return 0;
114*8d67ca89SAndroid Build Coastguard Worker }
115*8d67ca89SAndroid Build Coastguard Worker 
feenableexcept(int __mask __unused)116*8d67ca89SAndroid Build Coastguard Worker int feenableexcept(int __mask __unused) {
117*8d67ca89SAndroid Build Coastguard Worker   return -1;
118*8d67ca89SAndroid Build Coastguard Worker }
119*8d67ca89SAndroid Build Coastguard Worker 
fedisableexcept(int __mask __unused)120*8d67ca89SAndroid Build Coastguard Worker int fedisableexcept(int __mask __unused) {
121*8d67ca89SAndroid Build Coastguard Worker   return 0;
122*8d67ca89SAndroid Build Coastguard Worker }
123*8d67ca89SAndroid Build Coastguard Worker 
fegetexcept(void)124*8d67ca89SAndroid Build Coastguard Worker int fegetexcept(void) {
125*8d67ca89SAndroid Build Coastguard Worker   return 0;
126*8d67ca89SAndroid Build Coastguard Worker }
127