162306a36Sopenharmony_ci/* Software floating-point emulation. 262306a36Sopenharmony_ci Copyright (C) 1997,1998,1999 Free Software Foundation, Inc. 362306a36Sopenharmony_ci This file is part of the GNU C Library. 462306a36Sopenharmony_ci Contributed by Richard Henderson (rth@cygnus.com), 562306a36Sopenharmony_ci Jakub Jelinek (jj@ultra.linux.cz), 662306a36Sopenharmony_ci David S. Miller (davem@redhat.com) and 762306a36Sopenharmony_ci Peter Maydell (pmaydell@chiark.greenend.org.uk). 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci The GNU C Library is free software; you can redistribute it and/or 1062306a36Sopenharmony_ci modify it under the terms of the GNU Library General Public License as 1162306a36Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 1262306a36Sopenharmony_ci License, or (at your option) any later version. 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci The GNU C Library is distributed in the hope that it will be useful, 1562306a36Sopenharmony_ci but WITHOUT ANY WARRANTY; without even the implied warranty of 1662306a36Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1762306a36Sopenharmony_ci Library General Public License for more details. 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci You should have received a copy of the GNU Library General Public 2062306a36Sopenharmony_ci License along with the GNU C Library; see the file COPYING.LIB. If 2162306a36Sopenharmony_ci not, write to the Free Software Foundation, Inc., 2262306a36Sopenharmony_ci 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#ifndef __MATH_EMU_SOFT_FP_H__ 2562306a36Sopenharmony_ci#define __MATH_EMU_SOFT_FP_H__ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#include <asm/sfp-machine.h> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* Allow sfp-machine to have its own byte order definitions. */ 3062306a36Sopenharmony_ci#ifndef __BYTE_ORDER 3162306a36Sopenharmony_ci#include <endian.h> 3262306a36Sopenharmony_ci#endif 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define _FP_WORKBITS 3 3562306a36Sopenharmony_ci#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) 3662306a36Sopenharmony_ci#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) 3762306a36Sopenharmony_ci#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) 3862306a36Sopenharmony_ci#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#ifndef FP_RND_NEAREST 4162306a36Sopenharmony_ci# define FP_RND_NEAREST 0 4262306a36Sopenharmony_ci# define FP_RND_ZERO 1 4362306a36Sopenharmony_ci# define FP_RND_PINF 2 4462306a36Sopenharmony_ci# define FP_RND_MINF 3 4562306a36Sopenharmony_ci#ifndef FP_ROUNDMODE 4662306a36Sopenharmony_ci# define FP_ROUNDMODE FP_RND_NEAREST 4762306a36Sopenharmony_ci#endif 4862306a36Sopenharmony_ci#endif 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci/* By default don't care about exceptions. */ 5162306a36Sopenharmony_ci#ifndef FP_EX_INVALID 5262306a36Sopenharmony_ci#define FP_EX_INVALID 0 5362306a36Sopenharmony_ci#endif 5462306a36Sopenharmony_ci#ifndef FP_EX_INVALID_SNAN 5562306a36Sopenharmony_ci#define FP_EX_INVALID_SNAN 0 5662306a36Sopenharmony_ci#endif 5762306a36Sopenharmony_ci/* inf - inf */ 5862306a36Sopenharmony_ci#ifndef FP_EX_INVALID_ISI 5962306a36Sopenharmony_ci#define FP_EX_INVALID_ISI 0 6062306a36Sopenharmony_ci#endif 6162306a36Sopenharmony_ci/* inf / inf */ 6262306a36Sopenharmony_ci#ifndef FP_EX_INVALID_IDI 6362306a36Sopenharmony_ci#define FP_EX_INVALID_IDI 0 6462306a36Sopenharmony_ci#endif 6562306a36Sopenharmony_ci/* 0 / 0 */ 6662306a36Sopenharmony_ci#ifndef FP_EX_INVALID_ZDZ 6762306a36Sopenharmony_ci#define FP_EX_INVALID_ZDZ 0 6862306a36Sopenharmony_ci#endif 6962306a36Sopenharmony_ci/* inf * 0 */ 7062306a36Sopenharmony_ci#ifndef FP_EX_INVALID_IMZ 7162306a36Sopenharmony_ci#define FP_EX_INVALID_IMZ 0 7262306a36Sopenharmony_ci#endif 7362306a36Sopenharmony_ci#ifndef FP_EX_OVERFLOW 7462306a36Sopenharmony_ci#define FP_EX_OVERFLOW 0 7562306a36Sopenharmony_ci#endif 7662306a36Sopenharmony_ci#ifndef FP_EX_UNDERFLOW 7762306a36Sopenharmony_ci#define FP_EX_UNDERFLOW 7862306a36Sopenharmony_ci#endif 7962306a36Sopenharmony_ci#ifndef FP_EX_DIVZERO 8062306a36Sopenharmony_ci#define FP_EX_DIVZERO 0 8162306a36Sopenharmony_ci#endif 8262306a36Sopenharmony_ci#ifndef FP_EX_INEXACT 8362306a36Sopenharmony_ci#define FP_EX_INEXACT 0 8462306a36Sopenharmony_ci#endif 8562306a36Sopenharmony_ci#ifndef FP_EX_DENORM 8662306a36Sopenharmony_ci#define FP_EX_DENORM 0 8762306a36Sopenharmony_ci#endif 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci#ifdef _FP_DECL_EX 9062306a36Sopenharmony_ci#define FP_DECL_EX \ 9162306a36Sopenharmony_ci int _fex = 0; \ 9262306a36Sopenharmony_ci _FP_DECL_EX 9362306a36Sopenharmony_ci#else 9462306a36Sopenharmony_ci#define FP_DECL_EX int _fex = 0 9562306a36Sopenharmony_ci#endif 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci#ifndef FP_INIT_ROUNDMODE 9862306a36Sopenharmony_ci#define FP_INIT_ROUNDMODE do {} while (0) 9962306a36Sopenharmony_ci#endif 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci#ifndef FP_HANDLE_EXCEPTIONS 10262306a36Sopenharmony_ci#define FP_HANDLE_EXCEPTIONS do {} while (0) 10362306a36Sopenharmony_ci#endif 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* By default we never flush denormal input operands to signed zero. */ 10662306a36Sopenharmony_ci#ifndef FP_DENORM_ZERO 10762306a36Sopenharmony_ci#define FP_DENORM_ZERO 0 10862306a36Sopenharmony_ci#endif 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci#ifndef FP_INHIBIT_RESULTS 11162306a36Sopenharmony_ci/* By default we write the results always. 11262306a36Sopenharmony_ci * sfp-machine may override this and e.g. 11362306a36Sopenharmony_ci * check if some exceptions are unmasked 11462306a36Sopenharmony_ci * and inhibit it in such a case. 11562306a36Sopenharmony_ci */ 11662306a36Sopenharmony_ci#define FP_INHIBIT_RESULTS 0 11762306a36Sopenharmony_ci#endif 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci#ifndef FP_TRAPPING_EXCEPTIONS 12062306a36Sopenharmony_ci#define FP_TRAPPING_EXCEPTIONS 0 12162306a36Sopenharmony_ci#endif 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci#define FP_SET_EXCEPTION(ex) \ 12462306a36Sopenharmony_ci _fex |= (ex) 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci#define FP_UNSET_EXCEPTION(ex) \ 12762306a36Sopenharmony_ci _fex &= ~(ex) 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#define FP_CUR_EXCEPTIONS \ 13062306a36Sopenharmony_ci (_fex) 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci#define FP_CLEAR_EXCEPTIONS \ 13362306a36Sopenharmony_ci _fex = 0 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci#define _FP_ROUND_NEAREST(wc, X) \ 13662306a36Sopenharmony_cido { \ 13762306a36Sopenharmony_ci if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ 13862306a36Sopenharmony_ci _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ 13962306a36Sopenharmony_ci} while (0) 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci#define _FP_ROUND_ZERO(wc, X) (void)0 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci#define _FP_ROUND_PINF(wc, X) \ 14462306a36Sopenharmony_cido { \ 14562306a36Sopenharmony_ci if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ 14662306a36Sopenharmony_ci _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ 14762306a36Sopenharmony_ci} while (0) 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci#define _FP_ROUND_MINF(wc, X) \ 15062306a36Sopenharmony_cido { \ 15162306a36Sopenharmony_ci if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ 15262306a36Sopenharmony_ci _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ 15362306a36Sopenharmony_ci} while (0) 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci#define _FP_ROUND(wc, X) \ 15662306a36Sopenharmony_cido { \ 15762306a36Sopenharmony_ci if (_FP_FRAC_LOW_##wc(X) & 7) \ 15862306a36Sopenharmony_ci FP_SET_EXCEPTION(FP_EX_INEXACT); \ 15962306a36Sopenharmony_ci switch (FP_ROUNDMODE) \ 16062306a36Sopenharmony_ci { \ 16162306a36Sopenharmony_ci case FP_RND_NEAREST: \ 16262306a36Sopenharmony_ci _FP_ROUND_NEAREST(wc,X); \ 16362306a36Sopenharmony_ci break; \ 16462306a36Sopenharmony_ci case FP_RND_ZERO: \ 16562306a36Sopenharmony_ci _FP_ROUND_ZERO(wc,X); \ 16662306a36Sopenharmony_ci break; \ 16762306a36Sopenharmony_ci case FP_RND_PINF: \ 16862306a36Sopenharmony_ci _FP_ROUND_PINF(wc,X); \ 16962306a36Sopenharmony_ci break; \ 17062306a36Sopenharmony_ci case FP_RND_MINF: \ 17162306a36Sopenharmony_ci _FP_ROUND_MINF(wc,X); \ 17262306a36Sopenharmony_ci break; \ 17362306a36Sopenharmony_ci } \ 17462306a36Sopenharmony_ci} while (0) 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci#define FP_CLS_NORMAL 0 17762306a36Sopenharmony_ci#define FP_CLS_ZERO 1 17862306a36Sopenharmony_ci#define FP_CLS_INF 2 17962306a36Sopenharmony_ci#define FP_CLS_NAN 3 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci#include <math-emu/op-1.h> 18462306a36Sopenharmony_ci#include <math-emu/op-2.h> 18562306a36Sopenharmony_ci#include <math-emu/op-4.h> 18662306a36Sopenharmony_ci#include <math-emu/op-8.h> 18762306a36Sopenharmony_ci#include <math-emu/op-common.h> 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci/* Sigh. Silly things longlong.h needs. */ 19062306a36Sopenharmony_ci#define UWtype _FP_W_TYPE 19162306a36Sopenharmony_ci#define W_TYPE_SIZE _FP_W_TYPE_SIZE 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_citypedef int SItype __attribute__((mode(SI))); 19462306a36Sopenharmony_citypedef int DItype __attribute__((mode(DI))); 19562306a36Sopenharmony_citypedef unsigned int USItype __attribute__((mode(SI))); 19662306a36Sopenharmony_citypedef unsigned int UDItype __attribute__((mode(DI))); 19762306a36Sopenharmony_ci#if _FP_W_TYPE_SIZE == 32 19862306a36Sopenharmony_citypedef unsigned int UHWtype __attribute__((mode(HI))); 19962306a36Sopenharmony_ci#elif _FP_W_TYPE_SIZE == 64 20062306a36Sopenharmony_citypedef USItype UHWtype; 20162306a36Sopenharmony_ci#endif 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci#ifndef umul_ppmm 20462306a36Sopenharmony_ci#include <stdlib/longlong.h> 20562306a36Sopenharmony_ci#endif 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci#endif /* __MATH_EMU_SOFT_FP_H__ */ 208