Home | History | Annotate | Download | only in arm
      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 #include <fenv.h>
     30 
     31 #define FPSCR_ENABLE_SHIFT 8
     32 #define FPSCR_ENABLE_MASK  (FE_ALL_EXCEPT << FPSCR_ENABLE_SHIFT)
     33 
     34 #define FPSCR_RMODE_SHIFT 22
     35 
     36 const fenv_t __fe_dfl_env = 0;
     37 
     38 int fegetenv(fenv_t* __envp) {
     39   fenv_t _fpscr;
     40   __asm__ __volatile__("vmrs %0,fpscr" : "=r" (_fpscr));
     41   *__envp = _fpscr;
     42   return 0;
     43 }
     44 
     45 int fesetenv(const fenv_t* __envp) {
     46   fenv_t _fpscr = *__envp;
     47   __asm__ __volatile__("vmsr fpscr,%0" : :"ri" (_fpscr));
     48   return 0;
     49 }
     50 
     51 int feclearexcept(int __excepts) {
     52   fexcept_t __fpscr;
     53   fegetenv(&__fpscr);
     54   __fpscr &= ~__excepts;
     55   fesetenv(&__fpscr);
     56   return 0;
     57 }
     58 
     59 int fegetexceptflag(fexcept_t* __flagp, int __excepts) {
     60   fexcept_t __fpscr;
     61   fegetenv(&__fpscr);
     62   *__flagp = __fpscr & __excepts;
     63   return 0;
     64 }
     65 
     66 int fesetexceptflag(const fexcept_t* __flagp, int __excepts) {
     67   fexcept_t __fpscr;
     68   fegetenv(&__fpscr);
     69   __fpscr &= ~__excepts;
     70   __fpscr |= *__flagp & __excepts;
     71   fesetenv(&__fpscr);
     72   return 0;
     73 }
     74 
     75 int feraiseexcept(int __excepts) {
     76   fexcept_t __ex = __excepts;
     77   fesetexceptflag(&__ex, __excepts);
     78   return 0;
     79 }
     80 
     81 int fetestexcept(int __excepts) {
     82   fexcept_t __fpscr;
     83   fegetenv(&__fpscr);
     84   return (__fpscr & __excepts);
     85 }
     86 
     87 int fegetround(void) {
     88   fenv_t _fpscr;
     89   fegetenv(&_fpscr);
     90   return ((_fpscr >> FPSCR_RMODE_SHIFT) & 0x3);
     91 }
     92 
     93 int fesetround(int __round) {
     94   fenv_t _fpscr;
     95   fegetenv(&_fpscr);
     96   _fpscr &= ~(0x3 << FPSCR_RMODE_SHIFT);
     97   _fpscr |= (__round << FPSCR_RMODE_SHIFT);
     98   fesetenv(&_fpscr);
     99   return 0;
    100 }
    101 
    102 int feholdexcept(fenv_t* __envp) {
    103   fenv_t __env;
    104   fegetenv(&__env);
    105   *__envp = __env;
    106   __env &= ~(FE_ALL_EXCEPT | FPSCR_ENABLE_MASK);
    107   fesetenv(&__env);
    108   return 0;
    109 }
    110 
    111 int feupdateenv(const fenv_t* __envp) {
    112   fexcept_t __fpscr;
    113   fegetenv(&__fpscr);
    114   fesetenv(__envp);
    115   feraiseexcept(__fpscr & FE_ALL_EXCEPT);
    116   return 0;
    117 }
    118 
    119 int feenableexcept(int __mask) {
    120   fenv_t __old_fpscr, __new_fpscr;
    121   fegetenv(&__old_fpscr);
    122   __new_fpscr = __old_fpscr | (__mask & FE_ALL_EXCEPT) << FPSCR_ENABLE_SHIFT;
    123   fesetenv(&__new_fpscr);
    124   return ((__old_fpscr >> FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT);
    125 }
    126 
    127 int fedisableexcept(int __mask) {
    128   fenv_t __old_fpscr, __new_fpscr;
    129   fegetenv(&__old_fpscr);
    130   __new_fpscr = __old_fpscr & ~((__mask & FE_ALL_EXCEPT) << FPSCR_ENABLE_SHIFT);
    131   fesetenv(&__new_fpscr);
    132   return ((__old_fpscr >> FPSCR_ENABLE_SHIFT) & FE_ALL_EXCEPT);
    133 }
    134 
    135 int fegetexcept(void) {
    136   fenv_t __fpscr;
    137   fegetenv(&__fpscr);
    138   return ((__fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT);
    139 }
    140