1/* Internal libc stuff for floating point environment routines. 2 Copyright (C) 1997 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, write to the Free 17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 02111-1307 USA. */ 19 20#ifndef _FENV_LIBC_H 21#define _FENV_LIBC_H 1 22 23#include <fenv.h> 24 25/* The sticky bits in the FPSCR indicating exceptions have occurred. */ 26#define FPSCR_STICKY_BITS ((FE_ALL_EXCEPT | FE_ALL_INVALID) & ~FE_INVALID) 27 28/* Equivalent to fegetenv, but returns a fenv_t instead of taking a 29 pointer. */ 30#define fegetenv_register() \ 31 ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; }) 32 33/* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */ 34#define fesetenv_register(env) \ 35 ({ double d = (env); asm volatile ("mtfsf 0xff,%0" : : "f" (d)); }) 36 37/* This very handy macro: 38 - Sets the rounding mode to 'round to nearest'; 39 - Sets the processor into IEEE mode; and 40 - Prevents exceptions from being raised for inexact results. 41 These things happen to be exactly what you need for typical elementary 42 functions. */ 43#define relax_fenv_state() asm ("mtfsfi 7,0") 44 45/* Set/clear a particular FPSCR bit (for instance, 46 reset_fpscr_bit(FPSCR_VE); 47 prevents INVALID exceptions from being raised). */ 48#define set_fpscr_bit(x) asm volatile ("mtfsb1 %0" : : "i"(x)) 49#define reset_fpscr_bit(x) asm volatile ("mtfsb0 %0" : : "i"(x)) 50 51typedef union 52{ 53 fenv_t fenv; 54 unsigned int l[2]; 55} fenv_union_t; 56 57/* Definitions of all the FPSCR bit numbers */ 58enum { 59 FPSCR_FX = 0, /* exception summary */ 60 FPSCR_FEX, /* enabled exception summary */ 61 FPSCR_VX, /* invalid operation summary */ 62 FPSCR_OX, /* overflow */ 63 FPSCR_UX, /* underflow */ 64 FPSCR_ZX, /* zero divide */ 65 FPSCR_XX, /* inexact */ 66 FPSCR_VXSNAN, /* invalid operation for SNaN */ 67 FPSCR_VXISI, /* invalid operation for Inf-Inf */ 68 FPSCR_VXIDI, /* invalid operation for Inf/Inf */ 69 FPSCR_VXZDZ, /* invalid operation for 0/0 */ 70 FPSCR_VXIMZ, /* invalid operation for Inf*0 */ 71 FPSCR_VXVC, /* invalid operation for invalid compare */ 72 FPSCR_FR, /* fraction rounded [fraction was incremented by round] */ 73 FPSCR_FI, /* fraction inexact */ 74 FPSCR_FPRF_C, /* result class descriptor */ 75 FPSCR_FPRF_FL, /* result less than (usually, less than 0) */ 76 FPSCR_FPRF_FG, /* result greater than */ 77 FPSCR_FPRF_FE, /* result equal to */ 78 FPSCR_FPRF_FU, /* result unordered */ 79 FPSCR_20, /* reserved */ 80 FPSCR_VXSOFT, /* invalid operation set by software */ 81 FPSCR_VXSQRT, /* invalid operation for square root */ 82 FPSCR_VXCVI, /* invalid operation for invalid integer convert */ 83 FPSCR_VE, /* invalid operation exception enable */ 84 FPSCR_OE, /* overflow exception enable */ 85 FPSCR_UE, /* underflow exception enable */ 86 FPSCR_ZE, /* zero divide exception enable */ 87 FPSCR_XE, /* inexact exception enable */ 88 FPSCR_NI /* non-IEEE mode (typically, no denormalised numbers) */ 89 /* the remaining two least-significant bits keep the rounding mode */ 90}; 91 92/* This operation (i) sets the appropriate FPSCR bits for its 93 parameter, (ii) converts SNaN to the corresponding NaN, and (iii) 94 otherwise passes its parameter through unchanged (in particular, -0 95 and +0 stay as they were). The `obvious' way to do this is optimised 96 out by gcc. */ 97#define f_wash(x) \ 98 ({ double d; asm volatile ("fmul %0,%1,%2" \ 99 : "=f"(d) \ 100 : "f" (x), "f"((float)1.0)); d; }) 101#define f_washf(x) \ 102 ({ float f; asm volatile ("fmuls %0,%1,%2" \ 103 : "=f"(f) \ 104 : "f" (x), "f"((float)1.0)); f; }) 105 106#endif /* fenv_libc.h */ 107