Blame soft-fp/soft-fp.h

Packit 6c4009
/* Software floating-point emulation.
Packit 6c4009
   Copyright (C) 1997-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
   Contributed by Richard Henderson (rth@cygnus.com),
Packit 6c4009
		  Jakub Jelinek (jj@ultra.linux.cz),
Packit 6c4009
		  David S. Miller (davem@redhat.com) and
Packit 6c4009
		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   In addition to the permissions in the GNU Lesser General Public
Packit 6c4009
   License, the Free Software Foundation gives you unlimited
Packit 6c4009
   permission to link the compiled version of this file into
Packit 6c4009
   combinations with other programs, and to distribute those
Packit 6c4009
   combinations without any restriction coming from the use of this
Packit 6c4009
   file.  (The Lesser General Public License restrictions do apply in
Packit 6c4009
   other respects; for example, they cover modification of the file,
Packit 6c4009
   and distribution when not linked into a combine executable.)
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#ifndef SOFT_FP_H
Packit 6c4009
#define SOFT_FP_H	1
Packit 6c4009
Packit 6c4009
#ifdef _LIBC
Packit 6c4009
# include <sfp-machine.h>
Packit 6c4009
#elif defined __KERNEL__
Packit 6c4009
/* The Linux kernel uses asm/ names for architecture-specific
Packit 6c4009
   files.  */
Packit 6c4009
# include <asm/sfp-machine.h>
Packit 6c4009
#else
Packit 6c4009
# include "sfp-machine.h"
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Allow sfp-machine to have its own byte order definitions.  */
Packit 6c4009
#ifndef __BYTE_ORDER
Packit 6c4009
# ifdef _LIBC
Packit 6c4009
#  include <endian.h>
Packit 6c4009
# else
Packit 6c4009
#  error "endianness not defined by sfp-machine.h"
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* For unreachable default cases in switch statements over bitwise OR
Packit 6c4009
   of FP_CLS_* values.  */
Packit 6c4009
#if (defined __GNUC__							\
Packit 6c4009
     && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)))
Packit 6c4009
# define _FP_UNREACHABLE	__builtin_unreachable ()
Packit 6c4009
#else
Packit 6c4009
# define _FP_UNREACHABLE	abort ()
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#if ((defined __GNUC__							\
Packit 6c4009
      && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))	\
Packit 6c4009
     || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L))
Packit 6c4009
# define _FP_STATIC_ASSERT(expr, msg)		\
Packit 6c4009
  _Static_assert ((expr), msg)
Packit 6c4009
#else
Packit 6c4009
# define _FP_STATIC_ASSERT(expr, msg)					\
Packit 6c4009
  extern int (*__Static_assert_function (void))				\
Packit 6c4009
    [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* In the Linux kernel, some architectures have a single function that
Packit 6c4009
   uses different kinds of unpacking and packing depending on the
Packit 6c4009
   instruction being emulated, meaning it is not readily visible to
Packit 6c4009
   the compiler that variables from _FP_DECL and _FP_FRAC_DECL_*
Packit 6c4009
   macros are only used in cases where they were initialized.  */
Packit 6c4009
#ifdef __KERNEL__
Packit 6c4009
# define _FP_ZERO_INIT		= 0
Packit 6c4009
#else
Packit 6c4009
# define _FP_ZERO_INIT
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#define _FP_WORKBITS		3
Packit 6c4009
#define _FP_WORK_LSB		((_FP_W_TYPE) 1 << 3)
Packit 6c4009
#define _FP_WORK_ROUND		((_FP_W_TYPE) 1 << 2)
Packit 6c4009
#define _FP_WORK_GUARD		((_FP_W_TYPE) 1 << 1)
Packit 6c4009
#define _FP_WORK_STICKY		((_FP_W_TYPE) 1 << 0)
Packit 6c4009
Packit 6c4009
#ifndef FP_RND_NEAREST
Packit 6c4009
# define FP_RND_NEAREST		0
Packit 6c4009
# define FP_RND_ZERO		1
Packit 6c4009
# define FP_RND_PINF		2
Packit 6c4009
# define FP_RND_MINF		3
Packit 6c4009
#endif
Packit 6c4009
#ifndef FP_ROUNDMODE
Packit 6c4009
# define FP_ROUNDMODE		FP_RND_NEAREST
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* By default don't care about exceptions.  */
Packit 6c4009
#ifndef FP_EX_INVALID
Packit 6c4009
# define FP_EX_INVALID		0
Packit 6c4009
#endif
Packit 6c4009
#ifndef FP_EX_OVERFLOW
Packit 6c4009
# define FP_EX_OVERFLOW		0
Packit 6c4009
#endif
Packit 6c4009
#ifndef FP_EX_UNDERFLOW
Packit 6c4009
# define FP_EX_UNDERFLOW	0
Packit 6c4009
#endif
Packit 6c4009
#ifndef FP_EX_DIVZERO
Packit 6c4009
# define FP_EX_DIVZERO		0
Packit 6c4009
#endif
Packit 6c4009
#ifndef FP_EX_INEXACT
Packit 6c4009
# define FP_EX_INEXACT		0
Packit 6c4009
#endif
Packit 6c4009
#ifndef FP_EX_DENORM
Packit 6c4009
# define FP_EX_DENORM		0
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Sub-exceptions of "invalid".  */
Packit 6c4009
/* Signaling NaN operand.  */
Packit 6c4009
#ifndef FP_EX_INVALID_SNAN
Packit 6c4009
# define FP_EX_INVALID_SNAN	0
Packit 6c4009
#endif
Packit 6c4009
/* Inf * 0.  */
Packit 6c4009
#ifndef FP_EX_INVALID_IMZ
Packit 6c4009
# define FP_EX_INVALID_IMZ	0
Packit 6c4009
#endif
Packit 6c4009
/* fma (Inf, 0, c).  */
Packit 6c4009
#ifndef FP_EX_INVALID_IMZ_FMA
Packit 6c4009
# define FP_EX_INVALID_IMZ_FMA	0
Packit 6c4009
#endif
Packit 6c4009
/* Inf - Inf.  */
Packit 6c4009
#ifndef FP_EX_INVALID_ISI
Packit 6c4009
# define FP_EX_INVALID_ISI	0
Packit 6c4009
#endif
Packit 6c4009
/* 0 / 0.  */
Packit 6c4009
#ifndef FP_EX_INVALID_ZDZ
Packit 6c4009
# define FP_EX_INVALID_ZDZ	0
Packit 6c4009
#endif
Packit 6c4009
/* Inf / Inf.  */
Packit 6c4009
#ifndef FP_EX_INVALID_IDI
Packit 6c4009
# define FP_EX_INVALID_IDI	0
Packit 6c4009
#endif
Packit 6c4009
/* sqrt (negative).  */
Packit 6c4009
#ifndef FP_EX_INVALID_SQRT
Packit 6c4009
# define FP_EX_INVALID_SQRT	0
Packit 6c4009
#endif
Packit 6c4009
/* Invalid conversion to integer.  */
Packit 6c4009
#ifndef FP_EX_INVALID_CVI
Packit 6c4009
# define FP_EX_INVALID_CVI	0
Packit 6c4009
#endif
Packit 6c4009
/* Invalid comparison.  */
Packit 6c4009
#ifndef FP_EX_INVALID_VC
Packit 6c4009
# define FP_EX_INVALID_VC	0
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* _FP_STRUCT_LAYOUT may be defined as an attribute to determine the
Packit 6c4009
   struct layout variant used for structures where bit-fields are used
Packit 6c4009
   to access specific parts of binary floating-point numbers.  This is
Packit 6c4009
   required for systems where the default ABI uses struct layout with
Packit 6c4009
   differences in how consecutive bit-fields are laid out from the
Packit 6c4009
   default expected by soft-fp.  */
Packit 6c4009
#ifndef _FP_STRUCT_LAYOUT
Packit 6c4009
# define _FP_STRUCT_LAYOUT
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef _FP_DECL_EX
Packit 6c4009
# define FP_DECL_EX					\
Packit 6c4009
  int _fex = 0;						\
Packit 6c4009
  _FP_DECL_EX
Packit 6c4009
#else
Packit 6c4009
# define FP_DECL_EX int _fex = 0
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Initialize any machine-specific state used in FP_ROUNDMODE,
Packit 6c4009
   FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS.  */
Packit 6c4009
#ifndef FP_INIT_ROUNDMODE
Packit 6c4009
# define FP_INIT_ROUNDMODE do {} while (0)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Initialize any machine-specific state used in
Packit 6c4009
   FP_TRAPPING_EXCEPTIONS or FP_HANDLE_EXCEPTIONS.  */
Packit 6c4009
#ifndef FP_INIT_TRAPPING_EXCEPTIONS
Packit 6c4009
# define FP_INIT_TRAPPING_EXCEPTIONS FP_INIT_ROUNDMODE
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Initialize any machine-specific state used in
Packit 6c4009
   FP_HANDLE_EXCEPTIONS.  */
Packit 6c4009
#ifndef FP_INIT_EXCEPTIONS
Packit 6c4009
# define FP_INIT_EXCEPTIONS FP_INIT_TRAPPING_EXCEPTIONS
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifndef FP_HANDLE_EXCEPTIONS
Packit 6c4009
# define FP_HANDLE_EXCEPTIONS do {} while (0)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* Whether to flush subnormal inputs to zero with the same sign.  */
Packit 6c4009
#ifndef FP_DENORM_ZERO
Packit 6c4009
# define FP_DENORM_ZERO 0
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifndef FP_INHIBIT_RESULTS
Packit 6c4009
/* By default we write the results always.
Packit 6c4009
   sfp-machine may override this and e.g.
Packit 6c4009
   check if some exceptions are unmasked
Packit 6c4009
   and inhibit it in such a case.  */
Packit 6c4009
# define FP_INHIBIT_RESULTS 0
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#define FP_SET_EXCEPTION(ex)				\
Packit 6c4009
  _fex |= (ex)
Packit 6c4009
Packit 6c4009
#define FP_CUR_EXCEPTIONS				\
Packit 6c4009
  (_fex)
Packit 6c4009
Packit 6c4009
#ifndef FP_TRAPPING_EXCEPTIONS
Packit 6c4009
# define FP_TRAPPING_EXCEPTIONS 0
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* A file using soft-fp may define FP_NO_EXCEPTIONS before including
Packit 6c4009
   soft-fp.h to indicate that, although a macro used there could raise
Packit 6c4009
   exceptions, or do rounding and potentially thereby raise
Packit 6c4009
   exceptions, for some arguments, for the particular arguments used
Packit 6c4009
   in that file no exceptions or rounding can occur.  Such a file
Packit 6c4009
   should not itself use macros relating to handling exceptions and
Packit 6c4009
   rounding modes; this is only for indirect uses (in particular, in
Packit 6c4009
   _FP_FROM_INT and the macros it calls).  */
Packit 6c4009
#ifdef FP_NO_EXCEPTIONS
Packit 6c4009
Packit 6c4009
# undef FP_SET_EXCEPTION
Packit 6c4009
# define FP_SET_EXCEPTION(ex) do {} while (0)
Packit 6c4009
Packit 6c4009
# undef FP_CUR_EXCEPTIONS
Packit 6c4009
# define FP_CUR_EXCEPTIONS 0
Packit 6c4009
Packit 6c4009
# undef FP_TRAPPING_EXCEPTIONS
Packit 6c4009
# define FP_TRAPPING_EXCEPTIONS 0
Packit 6c4009
Packit 6c4009
# undef FP_ROUNDMODE
Packit 6c4009
# define FP_ROUNDMODE FP_RND_ZERO
Packit 6c4009
Packit 6c4009
# undef _FP_TININESS_AFTER_ROUNDING
Packit 6c4009
# define _FP_TININESS_AFTER_ROUNDING 0
Packit 6c4009
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* A file using soft-fp may define FP_NO_EXACT_UNDERFLOW before
Packit 6c4009
   including soft-fp.h to indicate that, although a macro used there
Packit 6c4009
   could allow for the case of exact underflow requiring the underflow
Packit 6c4009
   exception to be raised if traps are enabled, for the particular
Packit 6c4009
   arguments used in that file no exact underflow can occur.  */
Packit 6c4009
#ifdef FP_NO_EXACT_UNDERFLOW
Packit 6c4009
# undef FP_TRAPPING_EXCEPTIONS
Packit 6c4009
# define FP_TRAPPING_EXCEPTIONS 0
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#define _FP_ROUND_NEAREST(wc, X)				\
Packit 6c4009
  do								\
Packit 6c4009
    {								\
Packit 6c4009
      if ((_FP_FRAC_LOW_##wc (X) & 15) != _FP_WORK_ROUND)	\
Packit 6c4009
	_FP_FRAC_ADDI_##wc (X, _FP_WORK_ROUND);			\
Packit 6c4009
    }								\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
#define _FP_ROUND_ZERO(wc, X)		(void) 0
Packit 6c4009
Packit 6c4009
#define _FP_ROUND_PINF(wc, X)				\
Packit 6c4009
  do							\
Packit 6c4009
    {							\
Packit 6c4009
      if (!X##_s && (_FP_FRAC_LOW_##wc (X) & 7))	\
Packit 6c4009
	_FP_FRAC_ADDI_##wc (X, _FP_WORK_LSB);		\
Packit 6c4009
    }							\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
#define _FP_ROUND_MINF(wc, X)			\
Packit 6c4009
  do						\
Packit 6c4009
    {						\
Packit 6c4009
      if (X##_s && (_FP_FRAC_LOW_##wc (X) & 7))	\
Packit 6c4009
	_FP_FRAC_ADDI_##wc (X, _FP_WORK_LSB);	\
Packit 6c4009
    }						\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
#define _FP_ROUND(wc, X)			\
Packit 6c4009
  do						\
Packit 6c4009
    {						\
Packit 6c4009
      if (_FP_FRAC_LOW_##wc (X) & 7)		\
Packit 6c4009
	{					\
Packit 6c4009
	  FP_SET_EXCEPTION (FP_EX_INEXACT);	\
Packit 6c4009
	  switch (FP_ROUNDMODE)			\
Packit 6c4009
	    {					\
Packit 6c4009
	    case FP_RND_NEAREST:		\
Packit 6c4009
	      _FP_ROUND_NEAREST (wc, X);	\
Packit 6c4009
	      break;				\
Packit 6c4009
	    case FP_RND_ZERO:			\
Packit 6c4009
	      _FP_ROUND_ZERO (wc, X);		\
Packit 6c4009
	      break;				\
Packit 6c4009
	    case FP_RND_PINF:			\
Packit 6c4009
	      _FP_ROUND_PINF (wc, X);		\
Packit 6c4009
	      break;				\
Packit 6c4009
	    case FP_RND_MINF:			\
Packit 6c4009
	      _FP_ROUND_MINF (wc, X);		\
Packit 6c4009
	      break;				\
Packit 6c4009
	    }					\
Packit 6c4009
	}					\
Packit 6c4009
    }						\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
#define FP_CLS_NORMAL		0
Packit 6c4009
#define FP_CLS_ZERO		1
Packit 6c4009
#define FP_CLS_INF		2
Packit 6c4009
#define FP_CLS_NAN		3
Packit 6c4009
Packit 6c4009
#define _FP_CLS_COMBINE(x, y)	(((x) << 2) | (y))
Packit 6c4009
Packit 6c4009
#include "op-1.h"
Packit 6c4009
#include "op-2.h"
Packit 6c4009
#include "op-4.h"
Packit 6c4009
#include "op-8.h"
Packit 6c4009
#include "op-common.h"
Packit 6c4009
Packit 6c4009
/* Sigh.  Silly things longlong.h needs.  */
Packit 6c4009
#define UWtype		_FP_W_TYPE
Packit 6c4009
#define W_TYPE_SIZE	_FP_W_TYPE_SIZE
Packit 6c4009
Packit 6c4009
typedef int QItype __attribute__ ((mode (QI)));
Packit 6c4009
typedef int SItype __attribute__ ((mode (SI)));
Packit 6c4009
typedef int DItype __attribute__ ((mode (DI)));
Packit 6c4009
typedef unsigned int UQItype __attribute__ ((mode (QI)));
Packit 6c4009
typedef unsigned int USItype __attribute__ ((mode (SI)));
Packit 6c4009
typedef unsigned int UDItype __attribute__ ((mode (DI)));
Packit 6c4009
#if _FP_W_TYPE_SIZE == 32
Packit 6c4009
typedef unsigned int UHWtype __attribute__ ((mode (HI)));
Packit 6c4009
#elif _FP_W_TYPE_SIZE == 64
Packit 6c4009
typedef USItype UHWtype;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifndef CMPtype
Packit 6c4009
# define CMPtype	int
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#define SI_BITS		(__CHAR_BIT__ * (int) sizeof (SItype))
Packit 6c4009
#define DI_BITS		(__CHAR_BIT__ * (int) sizeof (DItype))
Packit 6c4009
Packit 6c4009
#ifndef umul_ppmm
Packit 6c4009
# ifdef _LIBC
Packit 6c4009
#  include <stdlib/longlong.h>
Packit 6c4009
# else
Packit 6c4009
#  include "longlong.h"
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#endif /* !SOFT_FP_H */