1169689Skan/* Software floating-point emulation. 2169689Skan Copyright (C) 1997,1998,1999,2000,2002,2003,2005,2006 3169689Skan Free Software Foundation, Inc. 4169689Skan This file is part of the GNU C Library. 5169689Skan Contributed by Richard Henderson (rth@cygnus.com), 6169689Skan Jakub Jelinek (jj@ultra.linux.cz), 7169689Skan David S. Miller (davem@redhat.com) and 8169689Skan Peter Maydell (pmaydell@chiark.greenend.org.uk). 9169689Skan 10169689Skan The GNU C Library is free software; you can redistribute it and/or 11169689Skan modify it under the terms of the GNU Lesser General Public 12169689Skan License as published by the Free Software Foundation; either 13169689Skan version 2.1 of the License, or (at your option) any later version. 14169689Skan 15169689Skan In addition to the permissions in the GNU Lesser General Public 16169689Skan License, the Free Software Foundation gives you unlimited 17169689Skan permission to link the compiled version of this file into 18169689Skan combinations with other programs, and to distribute those 19169689Skan combinations without any restriction coming from the use of this 20169689Skan file. (The Lesser General Public License restrictions do apply in 21169689Skan other respects; for example, they cover modification of the file, 22169689Skan and distribution when not linked into a combine executable.) 23169689Skan 24169689Skan The GNU C Library is distributed in the hope that it will be useful, 25169689Skan but WITHOUT ANY WARRANTY; without even the implied warranty of 26169689Skan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 27169689Skan Lesser General Public License for more details. 28169689Skan 29169689Skan You should have received a copy of the GNU Lesser General Public 30169689Skan License along with the GNU C Library; if not, write to the Free 31169689Skan Software Foundation, 51 Franklin Street, Fifth Floor, Boston, 32169689Skan MA 02110-1301, USA. */ 33169689Skan 34169689Skan#ifndef SOFT_FP_H 35169689Skan#define SOFT_FP_H 36169689Skan 37169689Skan#ifdef _LIBC 38169689Skan#include <sfp-machine.h> 39169689Skan#else 40169689Skan#include "sfp-machine.h" 41169689Skan#endif 42169689Skan 43169689Skan/* Allow sfp-machine to have its own byte order definitions. */ 44169689Skan#ifndef __BYTE_ORDER 45169689Skan#ifdef _LIBC 46169689Skan#include <endian.h> 47169689Skan#else 48169689Skan#error "endianness not defined by sfp-machine.h" 49169689Skan#endif 50169689Skan#endif 51169689Skan 52169689Skan#define _FP_WORKBITS 3 53169689Skan#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) 54169689Skan#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) 55169689Skan#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) 56169689Skan#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) 57169689Skan 58169689Skan#ifndef FP_RND_NEAREST 59169689Skan# define FP_RND_NEAREST 0 60169689Skan# define FP_RND_ZERO 1 61169689Skan# define FP_RND_PINF 2 62169689Skan# define FP_RND_MINF 3 63169689Skan#endif 64169689Skan#ifndef FP_ROUNDMODE 65169689Skan# define FP_ROUNDMODE FP_RND_NEAREST 66169689Skan#endif 67169689Skan 68169689Skan/* By default don't care about exceptions. */ 69169689Skan#ifndef FP_EX_INVALID 70169689Skan#define FP_EX_INVALID 0 71169689Skan#endif 72169689Skan#ifndef FP_EX_OVERFLOW 73169689Skan#define FP_EX_OVERFLOW 0 74169689Skan#endif 75169689Skan#ifndef FP_EX_UNDERFLOW 76169689Skan#define FP_EX_UNDERFLOW 0 77169689Skan#endif 78169689Skan#ifndef FP_EX_DIVZERO 79169689Skan#define FP_EX_DIVZERO 0 80169689Skan#endif 81169689Skan#ifndef FP_EX_INEXACT 82169689Skan#define FP_EX_INEXACT 0 83169689Skan#endif 84169689Skan#ifndef FP_EX_DENORM 85169689Skan#define FP_EX_DENORM 0 86169689Skan#endif 87169689Skan 88169689Skan#ifdef _FP_DECL_EX 89169689Skan#define FP_DECL_EX \ 90169689Skan int _fex = 0; \ 91169689Skan _FP_DECL_EX 92169689Skan#else 93169689Skan#define FP_DECL_EX int _fex = 0 94169689Skan#endif 95169689Skan 96169689Skan#ifndef FP_INIT_ROUNDMODE 97169689Skan#define FP_INIT_ROUNDMODE do {} while (0) 98169689Skan#endif 99169689Skan 100169689Skan#ifndef FP_HANDLE_EXCEPTIONS 101169689Skan#define FP_HANDLE_EXCEPTIONS do {} while (0) 102169689Skan#endif 103169689Skan 104169689Skan#ifndef FP_INHIBIT_RESULTS 105169689Skan/* By default we write the results always. 106169689Skan * sfp-machine may override this and e.g. 107169689Skan * check if some exceptions are unmasked 108169689Skan * and inhibit it in such a case. 109169689Skan */ 110169689Skan#define FP_INHIBIT_RESULTS 0 111169689Skan#endif 112169689Skan 113169689Skan#define FP_SET_EXCEPTION(ex) \ 114169689Skan _fex |= (ex) 115169689Skan 116169689Skan#define FP_UNSET_EXCEPTION(ex) \ 117169689Skan _fex &= ~(ex) 118169689Skan 119169689Skan#define FP_CLEAR_EXCEPTIONS \ 120169689Skan _fex = 0 121169689Skan 122169689Skan#define _FP_ROUND_NEAREST(wc, X) \ 123169689Skando { \ 124169689Skan if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ 125169689Skan _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ 126169689Skan} while (0) 127169689Skan 128169689Skan#define _FP_ROUND_ZERO(wc, X) (void)0 129169689Skan 130169689Skan#define _FP_ROUND_PINF(wc, X) \ 131169689Skando { \ 132169689Skan if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ 133169689Skan _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ 134169689Skan} while (0) 135169689Skan 136169689Skan#define _FP_ROUND_MINF(wc, X) \ 137169689Skando { \ 138169689Skan if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ 139169689Skan _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ 140169689Skan} while (0) 141169689Skan 142169689Skan#define _FP_ROUND(wc, X) \ 143169689Skando { \ 144169689Skan if (_FP_FRAC_LOW_##wc(X) & 7) \ 145169689Skan FP_SET_EXCEPTION(FP_EX_INEXACT); \ 146169689Skan switch (FP_ROUNDMODE) \ 147169689Skan { \ 148169689Skan case FP_RND_NEAREST: \ 149169689Skan _FP_ROUND_NEAREST(wc,X); \ 150169689Skan break; \ 151169689Skan case FP_RND_ZERO: \ 152169689Skan _FP_ROUND_ZERO(wc,X); \ 153169689Skan break; \ 154169689Skan case FP_RND_PINF: \ 155169689Skan _FP_ROUND_PINF(wc,X); \ 156169689Skan break; \ 157169689Skan case FP_RND_MINF: \ 158169689Skan _FP_ROUND_MINF(wc,X); \ 159169689Skan break; \ 160169689Skan } \ 161169689Skan} while (0) 162169689Skan 163169689Skan#define FP_CLS_NORMAL 0 164169689Skan#define FP_CLS_ZERO 1 165169689Skan#define FP_CLS_INF 2 166169689Skan#define FP_CLS_NAN 3 167169689Skan 168169689Skan#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) 169169689Skan 170169689Skan#include "op-1.h" 171169689Skan#include "op-2.h" 172169689Skan#include "op-4.h" 173169689Skan#include "op-8.h" 174169689Skan#include "op-common.h" 175169689Skan 176169689Skan/* Sigh. Silly things longlong.h needs. */ 177169689Skan#define UWtype _FP_W_TYPE 178169689Skan#define W_TYPE_SIZE _FP_W_TYPE_SIZE 179169689Skan 180169689Skantypedef int QItype __attribute__((mode(QI))); 181169689Skantypedef int SItype __attribute__((mode(SI))); 182169689Skantypedef int DItype __attribute__((mode(DI))); 183169689Skantypedef unsigned int UQItype __attribute__((mode(QI))); 184169689Skantypedef unsigned int USItype __attribute__((mode(SI))); 185169689Skantypedef unsigned int UDItype __attribute__((mode(DI))); 186169689Skan#if _FP_W_TYPE_SIZE == 32 187169689Skantypedef unsigned int UHWtype __attribute__((mode(HI))); 188169689Skan#elif _FP_W_TYPE_SIZE == 64 189169689Skantypedef USItype UHWtype; 190169689Skan#endif 191169689Skan 192169689Skan#define SI_BITS (__CHAR_BIT__ * (int)sizeof(SItype)) 193169689Skan#define DI_BITS (__CHAR_BIT__ * (int)sizeof(DItype)) 194169689Skan 195169689Skan#ifndef umul_ppmm 196169689Skan#ifdef _LIBC 197169689Skan#include <stdlib/longlong.h> 198169689Skan#else 199169689Skan#include "longlong.h" 200169689Skan#endif 201169689Skan#endif 202169689Skan 203169689Skan#ifdef _LIBC 204169689Skan#include <stdlib.h> 205169689Skan#else 206169689Skanextern void abort (void); 207169689Skan#endif 208169689Skan 209169689Skan#endif 210