]> git.ipfire.org Git - thirdparty/glibc.git/blame - soft-fp/soft-fp.h
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / soft-fp / soft-fp.h
CommitLineData
d876f532 1/* Software floating-point emulation.
04277e02 2 Copyright (C) 1997-2019 Free Software Foundation, Inc.
d876f532
UD
3 This file is part of the GNU C Library.
4 Contributed by Richard Henderson (rth@cygnus.com),
5 Jakub Jelinek (jj@ultra.linux.cz),
6 David S. Miller (davem@redhat.com) and
7 Peter Maydell (pmaydell@chiark.greenend.org.uk).
8
9 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
d876f532 13
638a783c
RM
14 In addition to the permissions in the GNU Lesser General Public
15 License, the Free Software Foundation gives you unlimited
16 permission to link the compiled version of this file into
17 combinations with other programs, and to distribute those
18 combinations without any restriction coming from the use of this
19 file. (The Lesser General Public License restrictions do apply in
20 other respects; for example, they cover modification of the file,
21 and distribution when not linked into a combine executable.)
22
d876f532
UD
23 The GNU C Library is distributed in the hope that it will be useful,
24 but WITHOUT ANY WARRANTY; without even the implied warranty of
25 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 26 Lesser General Public License for more details.
d876f532 27
41bdb6e2 28 You should have received a copy of the GNU Lesser General Public
59ba27a6 29 License along with the GNU C Library; if not, see
5a82c748 30 <https://www.gnu.org/licenses/>. */
d876f532
UD
31
32#ifndef SOFT_FP_H
a2f8be9c 33#define SOFT_FP_H 1
d876f532 34
fe0b1e85 35#ifdef _LIBC
71b4dea7 36# include <sfp-machine.h>
fa9dda64 37#elif defined __KERNEL__
0b3467b3 38/* The Linux kernel uses asm/ names for architecture-specific
fa9dda64
JM
39 files. */
40# include <asm/sfp-machine.h>
fe0b1e85 41#else
71b4dea7 42# include "sfp-machine.h"
fe0b1e85 43#endif
d876f532 44
c4fe3ea7 45/* Allow sfp-machine to have its own byte order definitions. */
d876f532 46#ifndef __BYTE_ORDER
71b4dea7
JM
47# ifdef _LIBC
48# include <endian.h>
49# else
50# error "endianness not defined by sfp-machine.h"
51# endif
d876f532
UD
52#endif
53
068a6274
JM
54/* For unreachable default cases in switch statements over bitwise OR
55 of FP_CLS_* values. */
56#if (defined __GNUC__ \
57 && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
58# define _FP_UNREACHABLE __builtin_unreachable ()
59#else
60# define _FP_UNREACHABLE abort ()
61#endif
62
7d67a196
JM
63#if ((defined __GNUC__ \
64 && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) \
65 || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L))
66# define _FP_STATIC_ASSERT(expr, msg) \
67 _Static_assert ((expr), msg)
68#else
69# define _FP_STATIC_ASSERT(expr, msg) \
70 extern int (*__Static_assert_function (void)) \
71 [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
72#endif
73
b838844b
JM
74/* In the Linux kernel, some architectures have a single function that
75 uses different kinds of unpacking and packing depending on the
76 instruction being emulated, meaning it is not readily visible to
77 the compiler that variables from _FP_DECL and _FP_FRAC_DECL_*
78 macros are only used in cases where they were initialized. */
79#ifdef __KERNEL__
80# define _FP_ZERO_INIT = 0
81#else
82# define _FP_ZERO_INIT
83#endif
84
d876f532 85#define _FP_WORKBITS 3
51ca9e29
JM
86#define _FP_WORK_LSB ((_FP_W_TYPE) 1 << 3)
87#define _FP_WORK_ROUND ((_FP_W_TYPE) 1 << 2)
88#define _FP_WORK_GUARD ((_FP_W_TYPE) 1 << 1)
89#define _FP_WORK_STICKY ((_FP_W_TYPE) 1 << 0)
d876f532
UD
90
91#ifndef FP_RND_NEAREST
92# define FP_RND_NEAREST 0
93# define FP_RND_ZERO 1
94# define FP_RND_PINF 2
95# define FP_RND_MINF 3
bde40c2f 96#endif
d876f532
UD
97#ifndef FP_ROUNDMODE
98# define FP_ROUNDMODE FP_RND_NEAREST
99#endif
d876f532 100
c4fe3ea7 101/* By default don't care about exceptions. */
d876f532 102#ifndef FP_EX_INVALID
71b4dea7 103# define FP_EX_INVALID 0
d876f532
UD
104#endif
105#ifndef FP_EX_OVERFLOW
71b4dea7 106# define FP_EX_OVERFLOW 0
d876f532
UD
107#endif
108#ifndef FP_EX_UNDERFLOW
71b4dea7 109# define FP_EX_UNDERFLOW 0
d876f532
UD
110#endif
111#ifndef FP_EX_DIVZERO
71b4dea7 112# define FP_EX_DIVZERO 0
d876f532
UD
113#endif
114#ifndef FP_EX_INEXACT
71b4dea7 115# define FP_EX_INEXACT 0
d876f532
UD
116#endif
117#ifndef FP_EX_DENORM
71b4dea7 118# define FP_EX_DENORM 0
d876f532
UD
119#endif
120
ff12c11f
JM
121/* Sub-exceptions of "invalid". */
122/* Signaling NaN operand. */
123#ifndef FP_EX_INVALID_SNAN
124# define FP_EX_INVALID_SNAN 0
125#endif
126/* Inf * 0. */
127#ifndef FP_EX_INVALID_IMZ
128# define FP_EX_INVALID_IMZ 0
129#endif
130/* fma (Inf, 0, c). */
131#ifndef FP_EX_INVALID_IMZ_FMA
132# define FP_EX_INVALID_IMZ_FMA 0
133#endif
134/* Inf - Inf. */
135#ifndef FP_EX_INVALID_ISI
136# define FP_EX_INVALID_ISI 0
137#endif
138/* 0 / 0. */
139#ifndef FP_EX_INVALID_ZDZ
140# define FP_EX_INVALID_ZDZ 0
141#endif
142/* Inf / Inf. */
143#ifndef FP_EX_INVALID_IDI
144# define FP_EX_INVALID_IDI 0
145#endif
146/* sqrt (negative). */
147#ifndef FP_EX_INVALID_SQRT
148# define FP_EX_INVALID_SQRT 0
149#endif
150/* Invalid conversion to integer. */
151#ifndef FP_EX_INVALID_CVI
152# define FP_EX_INVALID_CVI 0
153#endif
154/* Invalid comparison. */
155#ifndef FP_EX_INVALID_VC
156# define FP_EX_INVALID_VC 0
157#endif
158
f775c276
KT
159/* _FP_STRUCT_LAYOUT may be defined as an attribute to determine the
160 struct layout variant used for structures where bit-fields are used
161 to access specific parts of binary floating-point numbers. This is
162 required for systems where the default ABI uses struct layout with
163 differences in how consecutive bit-fields are laid out from the
164 default expected by soft-fp. */
165#ifndef _FP_STRUCT_LAYOUT
71b4dea7 166# define _FP_STRUCT_LAYOUT
f775c276
KT
167#endif
168
d876f532 169#ifdef _FP_DECL_EX
71b4dea7 170# define FP_DECL_EX \
d876f532
UD
171 int _fex = 0; \
172 _FP_DECL_EX
173#else
71b4dea7 174# define FP_DECL_EX int _fex = 0
d876f532 175#endif
fe2dcbcc 176
dcc2dd3f
JM
177/* Initialize any machine-specific state used in FP_ROUNDMODE,
178 FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS. */
d876f532 179#ifndef FP_INIT_ROUNDMODE
71b4dea7 180# define FP_INIT_ROUNDMODE do {} while (0)
d876f532
UD
181#endif
182
43059f42
JM
183/* Initialize any machine-specific state used in
184 FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS. */
185#ifndef FP_INIT_TRAPPING_EXCEPTIONS
186# define FP_INIT_TRAPPING_EXCEPTIONS FP_INIT_ROUNDMODE
187#endif
188
dcc2dd3f
JM
189/* Initialize any machine-specific state used in
190 FP_HANDLE_EXCEPTIONS. */
191#ifndef FP_INIT_EXCEPTIONS
43059f42 192# define FP_INIT_EXCEPTIONS FP_INIT_TRAPPING_EXCEPTIONS
dcc2dd3f
JM
193#endif
194
d876f532 195#ifndef FP_HANDLE_EXCEPTIONS
71b4dea7 196# define FP_HANDLE_EXCEPTIONS do {} while (0)
d876f532
UD
197#endif
198
454ac701
JM
199/* Whether to flush subnormal inputs to zero with the same sign. */
200#ifndef FP_DENORM_ZERO
201# define FP_DENORM_ZERO 0
202#endif
203
d876f532
UD
204#ifndef FP_INHIBIT_RESULTS
205/* By default we write the results always.
c4fe3ea7
JM
206 sfp-machine may override this and e.g.
207 check if some exceptions are unmasked
208 and inhibit it in such a case. */
71b4dea7 209# define FP_INHIBIT_RESULTS 0
d876f532
UD
210#endif
211
212#define FP_SET_EXCEPTION(ex) \
213 _fex |= (ex)
fe2dcbcc 214
ae251b0b
DM
215#define FP_CUR_EXCEPTIONS \
216 (_fex)
217
218#ifndef FP_TRAPPING_EXCEPTIONS
71b4dea7 219# define FP_TRAPPING_EXCEPTIONS 0
ae251b0b
DM
220#endif
221
8edc4a11
JM
222/* A file using soft-fp may define FP_NO_EXCEPTIONS before including
223 soft-fp.h to indicate that, although a macro used there could raise
224 exceptions, or do rounding and potentially thereby raise
225 exceptions, for some arguments, for the particular arguments used
226 in that file no exceptions or rounding can occur. Such a file
227 should not itself use macros relating to handling exceptions and
228 rounding modes; this is only for indirect uses (in particular, in
229 _FP_FROM_INT and the macros it calls). */
230#ifdef FP_NO_EXCEPTIONS
231
71b4dea7
JM
232# undef FP_SET_EXCEPTION
233# define FP_SET_EXCEPTION(ex) do {} while (0)
8edc4a11 234
71b4dea7
JM
235# undef FP_CUR_EXCEPTIONS
236# define FP_CUR_EXCEPTIONS 0
8edc4a11 237
71b4dea7
JM
238# undef FP_TRAPPING_EXCEPTIONS
239# define FP_TRAPPING_EXCEPTIONS 0
8edc4a11 240
71b4dea7
JM
241# undef FP_ROUNDMODE
242# define FP_ROUNDMODE FP_RND_ZERO
8edc4a11 243
ace614b8
JM
244# undef _FP_TININESS_AFTER_ROUNDING
245# define _FP_TININESS_AFTER_ROUNDING 0
246
8edc4a11
JM
247#endif
248
43059f42
JM
249/* A file using soft-fp may define FP_NO_EXACT_UNDERFLOW before
250 including soft-fp.h to indicate that, although a macro used there
251 could allow for the case of exact underflow requiring the underflow
252 exception to be raised if traps are enabled, for the particular
253 arguments used in that file no exact underflow can occur. */
254#ifdef FP_NO_EXACT_UNDERFLOW
255# undef FP_TRAPPING_EXCEPTIONS
256# define FP_TRAPPING_EXCEPTIONS 0
257#endif
258
1e145589
JM
259#define _FP_ROUND_NEAREST(wc, X) \
260 do \
261 { \
51ca9e29
JM
262 if ((_FP_FRAC_LOW_##wc (X) & 15) != _FP_WORK_ROUND) \
263 _FP_FRAC_ADDI_##wc (X, _FP_WORK_ROUND); \
1e145589
JM
264 } \
265 while (0)
d876f532 266
51ca9e29 267#define _FP_ROUND_ZERO(wc, X) (void) 0
d876f532 268
51ca9e29
JM
269#define _FP_ROUND_PINF(wc, X) \
270 do \
271 { \
272 if (!X##_s && (_FP_FRAC_LOW_##wc (X) & 7)) \
273 _FP_FRAC_ADDI_##wc (X, _FP_WORK_LSB); \
274 } \
1e145589
JM
275 while (0)
276
277#define _FP_ROUND_MINF(wc, X) \
278 do \
279 { \
51ca9e29
JM
280 if (X##_s && (_FP_FRAC_LOW_##wc (X) & 7)) \
281 _FP_FRAC_ADDI_##wc (X, _FP_WORK_LSB); \
1e145589
JM
282 } \
283 while (0)
d876f532
UD
284
285#define _FP_ROUND(wc, X) \
1e145589
JM
286 do \
287 { \
51ca9e29 288 if (_FP_FRAC_LOW_##wc (X) & 7) \
1e145589 289 { \
51ca9e29 290 FP_SET_EXCEPTION (FP_EX_INEXACT); \
1e145589
JM
291 switch (FP_ROUNDMODE) \
292 { \
293 case FP_RND_NEAREST: \
51ca9e29 294 _FP_ROUND_NEAREST (wc, X); \
1e145589
JM
295 break; \
296 case FP_RND_ZERO: \
51ca9e29 297 _FP_ROUND_ZERO (wc, X); \
1e145589
JM
298 break; \
299 case FP_RND_PINF: \
51ca9e29 300 _FP_ROUND_PINF (wc, X); \
1e145589
JM
301 break; \
302 case FP_RND_MINF: \
51ca9e29 303 _FP_ROUND_MINF (wc, X); \
1e145589
JM
304 break; \
305 } \
306 } \
307 } \
308 while (0)
d876f532
UD
309
310#define FP_CLS_NORMAL 0
311#define FP_CLS_ZERO 1
312#define FP_CLS_INF 2
313#define FP_CLS_NAN 3
314
51ca9e29 315#define _FP_CLS_COMBINE(x, y) (((x) << 2) | (y))
d876f532
UD
316
317#include "op-1.h"
318#include "op-2.h"
319#include "op-4.h"
320#include "op-8.h"
321#include "op-common.h"
322
323/* Sigh. Silly things longlong.h needs. */
324#define UWtype _FP_W_TYPE
325#define W_TYPE_SIZE _FP_W_TYPE_SIZE
326
51ca9e29
JM
327typedef int QItype __attribute__ ((mode (QI)));
328typedef int SItype __attribute__ ((mode (SI)));
329typedef int DItype __attribute__ ((mode (DI)));
330typedef unsigned int UQItype __attribute__ ((mode (QI)));
331typedef unsigned int USItype __attribute__ ((mode (SI)));
332typedef unsigned int UDItype __attribute__ ((mode (DI)));
d876f532 333#if _FP_W_TYPE_SIZE == 32
51ca9e29 334typedef unsigned int UHWtype __attribute__ ((mode (HI)));
d876f532
UD
335#elif _FP_W_TYPE_SIZE == 64
336typedef USItype UHWtype;
337#endif
338
ae8e81f5 339#ifndef CMPtype
71b4dea7 340# define CMPtype int
ae8e81f5
JJ
341#endif
342
51ca9e29
JM
343#define SI_BITS (__CHAR_BIT__ * (int) sizeof (SItype))
344#define DI_BITS (__CHAR_BIT__ * (int) sizeof (DItype))
fe0b1e85 345
d876f532 346#ifndef umul_ppmm
71b4dea7
JM
347# ifdef _LIBC
348# include <stdlib/longlong.h>
349# else
350# include "longlong.h"
351# endif
d876f532
UD
352#endif
353
a2f8be9c 354#endif /* !SOFT_FP_H */