]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/powerpc/fpu/fenv_libc.h
Avoid passing NULL to DSO_FILENAME.
[thirdparty/glibc.git] / sysdeps / powerpc / fpu / fenv_libc.h
CommitLineData
1f205a47 1/* Internal libc stuff for floating point environment routines.
568035b7 2 Copyright (C) 1997-2013 Free Software Foundation, Inc.
1f205a47
UD
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
41bdb6e2
AJ
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.
1f205a47
UD
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
41bdb6e2 13 Lesser General Public License for more details.
1f205a47 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
1f205a47
UD
18
19#ifndef _FENV_LIBC_H
20#define _FENV_LIBC_H 1
21
22#include <fenv.h>
edba7a54
UD
23#include <ldsodefs.h>
24#include <sysdep.h>
1f205a47 25
246ec411
UD
26libm_hidden_proto (__fe_nomask_env)
27
1f205a47
UD
28/* The sticky bits in the FPSCR indicating exceptions have occurred. */
29#define FPSCR_STICKY_BITS ((FE_ALL_EXCEPT | FE_ALL_INVALID) & ~FE_INVALID)
30
31/* Equivalent to fegetenv, but returns a fenv_t instead of taking a
32 pointer. */
33#define fegetenv_register() \
0413b54c 34 ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; })
1f205a47
UD
35
36/* Equivalent to fesetenv, but takes a fenv_t instead of a pointer. */
37#define fesetenv_register(env) \
edba7a54
UD
38 do { \
39 double d = (env); \
40 if(GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \
1454da21
UD
41 asm volatile (".machine push; " \
42 ".machine \"power6\"; " \
43 "mtfsf 0xff,%0,1,0; " \
44 ".machine pop" : : "f" (d)); \
edba7a54
UD
45 else \
46 asm volatile ("mtfsf 0xff,%0" : : "f" (d)); \
47 } while(0)
1f205a47
UD
48
49/* This very handy macro:
50 - Sets the rounding mode to 'round to nearest';
51 - Sets the processor into IEEE mode; and
52 - Prevents exceptions from being raised for inexact results.
53 These things happen to be exactly what you need for typical elementary
54 functions. */
edba7a54
UD
55#define relax_fenv_state() \
56 do { \
1454da21
UD
57 if (GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \
58 asm (".machine push; .machine \"power6\"; " \
59 "mtfsfi 7,0,1; .machine pop"); \
edba7a54
UD
60 asm ("mtfsfi 7,0"); \
61 } while(0)
1f205a47 62
0413b54c
UD
63/* Set/clear a particular FPSCR bit (for instance,
64 reset_fpscr_bit(FPSCR_VE);
65 prevents INVALID exceptions from being raised). */
66#define set_fpscr_bit(x) asm volatile ("mtfsb1 %0" : : "i"(x))
67#define reset_fpscr_bit(x) asm volatile ("mtfsb0 %0" : : "i"(x))
68
1f205a47
UD
69typedef union
70{
71 fenv_t fenv;
4a28b3ca 72 unsigned long long l;
1f205a47
UD
73} fenv_union_t;
74
5c68d401
RM
75
76static inline int
77__fegetround (void)
78{
79 int result;
80 asm volatile ("mcrfs 7,7\n\t"
81 "mfcr %0" : "=r"(result) : : "cr7");
82 return result & 3;
83}
84#define fegetround() __fegetround()
85
86static inline int
87__fesetround (int round)
88{
89 if ((unsigned int) round < 2)
90 {
91 asm volatile ("mtfsb0 30");
92 if ((unsigned int) round == 0)
93 asm volatile ("mtfsb0 31");
94 else
95 asm volatile ("mtfsb1 31");
96 }
97 else
98 {
99 asm volatile ("mtfsb1 30");
100 if ((unsigned int) round == 2)
101 asm volatile ("mtfsb0 31");
102 else
103 asm volatile ("mtfsb1 31");
104 }
105
106 return 0;
107}
108#define fesetround(mode) __fesetround(mode)
109
0413b54c
UD
110/* Definitions of all the FPSCR bit numbers */
111enum {
112 FPSCR_FX = 0, /* exception summary */
113 FPSCR_FEX, /* enabled exception summary */
114 FPSCR_VX, /* invalid operation summary */
115 FPSCR_OX, /* overflow */
116 FPSCR_UX, /* underflow */
117 FPSCR_ZX, /* zero divide */
118 FPSCR_XX, /* inexact */
67e971f1 119 FPSCR_VXSNAN, /* invalid operation for sNaN */
0413b54c
UD
120 FPSCR_VXISI, /* invalid operation for Inf-Inf */
121 FPSCR_VXIDI, /* invalid operation for Inf/Inf */
122 FPSCR_VXZDZ, /* invalid operation for 0/0 */
123 FPSCR_VXIMZ, /* invalid operation for Inf*0 */
124 FPSCR_VXVC, /* invalid operation for invalid compare */
125 FPSCR_FR, /* fraction rounded [fraction was incremented by round] */
126 FPSCR_FI, /* fraction inexact */
127 FPSCR_FPRF_C, /* result class descriptor */
128 FPSCR_FPRF_FL, /* result less than (usually, less than 0) */
129 FPSCR_FPRF_FG, /* result greater than */
130 FPSCR_FPRF_FE, /* result equal to */
131 FPSCR_FPRF_FU, /* result unordered */
132 FPSCR_20, /* reserved */
133 FPSCR_VXSOFT, /* invalid operation set by software */
134 FPSCR_VXSQRT, /* invalid operation for square root */
135 FPSCR_VXCVI, /* invalid operation for invalid integer convert */
136 FPSCR_VE, /* invalid operation exception enable */
137 FPSCR_OE, /* overflow exception enable */
138 FPSCR_UE, /* underflow exception enable */
139 FPSCR_ZE, /* zero divide exception enable */
140 FPSCR_XE, /* inexact exception enable */
edba7a54
UD
141#ifdef _ARCH_PWR6
142 FPSCR_29, /* Reserved in ISA 2.05 */
143#else
0413b54c 144 FPSCR_NI /* non-IEEE mode (typically, no denormalised numbers) */
edba7a54 145#endif /* _ARCH_PWR6 */
0413b54c
UD
146 /* the remaining two least-significant bits keep the rounding mode */
147};
148
edba7a54
UD
149#ifdef _ARCH_PWR6
150 /* Not supported in ISA 2.05. Provided for source compat only. */
151# define FPSCR_NI 29
152#endif /* _ARCH_PWR6 */
153
0413b54c 154/* This operation (i) sets the appropriate FPSCR bits for its
67e971f1 155 parameter, (ii) converts sNaN to the corresponding qNaN, and (iii)
0413b54c
UD
156 otherwise passes its parameter through unchanged (in particular, -0
157 and +0 stay as they were). The `obvious' way to do this is optimised
158 out by gcc. */
159#define f_wash(x) \
160 ({ double d; asm volatile ("fmul %0,%1,%2" \
161 : "=f"(d) \
162 : "f" (x), "f"((float)1.0)); d; })
163#define f_washf(x) \
164 ({ float f; asm volatile ("fmuls %0,%1,%2" \
165 : "=f"(f) \
166 : "f" (x), "f"((float)1.0)); f; })
246ec411 167
1f205a47 168#endif /* fenv_libc.h */