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