1 /* Software floating-point emulation. 2 Copyright (C) 1997,1998,1999 Free Software Foundation, Inc. 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 10 modify it under the terms of the GNU Library General Public License as 11 published by the Free Software Foundation; either version 2 of the 12 License, or (at your option) any later version. 13 14 The GNU C Library is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 Library General Public License for more details. 18 19 You should have received a copy of the GNU Library General Public 20 License along with the GNU C Library; see the file COPYING.LIB. If 21 not, write to the Free Software Foundation, Inc., 22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 23 24 #ifndef __MATH_EMU_SOFT_FP_H__ 25 #define __MATH_EMU_SOFT_FP_H__ 26 27 #include <asm/sfp-machine.h> 28 29 /* Allow sfp-machine to have its own byte order definitions. */ 30 #ifndef __BYTE_ORDER 31 #include <endian.h> 32 #endif 33 34 /* Whether the architecture determines tininess of a floating-point 35 result after rounding rather than before it. IEEE 754 permits either 36 but requires the same choice for every operation, so this has to agree 37 with what the hardware does for the results it produces itself. */ 38 #ifndef _FP_TININESS_AFTER_ROUNDING 39 #define _FP_TININESS_AFTER_ROUNDING 0 40 #endif 41 42 #define _FP_WORKBITS 3 43 #define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) 44 #define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2) 45 #define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1) 46 #define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0) 47 48 #ifndef FP_RND_NEAREST 49 # define FP_RND_NEAREST 0 50 # define FP_RND_ZERO 1 51 # define FP_RND_PINF 2 52 # define FP_RND_MINF 3 53 #ifndef FP_ROUNDMODE 54 # define FP_ROUNDMODE FP_RND_NEAREST 55 #endif 56 #endif 57 58 /* By default don't care about exceptions. */ 59 #ifndef FP_EX_INVALID 60 #define FP_EX_INVALID 0 61 #endif 62 #ifndef FP_EX_INVALID_SNAN 63 #define FP_EX_INVALID_SNAN 0 64 #endif 65 /* inf - inf */ 66 #ifndef FP_EX_INVALID_ISI 67 #define FP_EX_INVALID_ISI 0 68 #endif 69 /* inf / inf */ 70 #ifndef FP_EX_INVALID_IDI 71 #define FP_EX_INVALID_IDI 0 72 #endif 73 /* 0 / 0 */ 74 #ifndef FP_EX_INVALID_ZDZ 75 #define FP_EX_INVALID_ZDZ 0 76 #endif 77 /* inf * 0 */ 78 #ifndef FP_EX_INVALID_IMZ 79 #define FP_EX_INVALID_IMZ 0 80 #endif 81 #ifndef FP_EX_OVERFLOW 82 #define FP_EX_OVERFLOW 0 83 #endif 84 #ifndef FP_EX_UNDERFLOW 85 #define FP_EX_UNDERFLOW 86 #endif 87 #ifndef FP_EX_DIVZERO 88 #define FP_EX_DIVZERO 0 89 #endif 90 #ifndef FP_EX_INEXACT 91 #define FP_EX_INEXACT 0 92 #endif 93 #ifndef FP_EX_DENORM 94 #define FP_EX_DENORM 0 95 #endif 96 97 #ifdef _FP_DECL_EX 98 #define FP_DECL_EX \ 99 int _fex = 0; \ 100 _FP_DECL_EX 101 #else 102 #define FP_DECL_EX int _fex = 0 103 #endif 104 105 #ifndef FP_INIT_ROUNDMODE 106 #define FP_INIT_ROUNDMODE do {} while (0) 107 #endif 108 109 #ifndef FP_HANDLE_EXCEPTIONS 110 #define FP_HANDLE_EXCEPTIONS do {} while (0) 111 #endif 112 113 /* By default we never flush denormal input operands to signed zero. */ 114 #ifndef FP_DENORM_ZERO 115 #define FP_DENORM_ZERO 0 116 #endif 117 118 #ifndef FP_INHIBIT_RESULTS 119 /* By default we write the results always. 120 * sfp-machine may override this and e.g. 121 * check if some exceptions are unmasked 122 * and inhibit it in such a case. 123 */ 124 #define FP_INHIBIT_RESULTS 0 125 #endif 126 127 #ifndef FP_TRAPPING_EXCEPTIONS 128 #define FP_TRAPPING_EXCEPTIONS 0 129 #endif 130 131 #define FP_SET_EXCEPTION(ex) \ 132 _fex |= (ex) 133 134 #define FP_UNSET_EXCEPTION(ex) \ 135 _fex &= ~(ex) 136 137 #define FP_CUR_EXCEPTIONS \ 138 (_fex) 139 140 #define FP_CLEAR_EXCEPTIONS \ 141 _fex = 0 142 143 #define _FP_ROUND_NEAREST(wc, X) \ 144 do { \ 145 if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND) \ 146 _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \ 147 } while (0) 148 149 #define _FP_ROUND_ZERO(wc, X) (void)0 150 151 #define _FP_ROUND_PINF(wc, X) \ 152 do { \ 153 if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ 154 _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ 155 } while (0) 156 157 #define _FP_ROUND_MINF(wc, X) \ 158 do { \ 159 if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \ 160 _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \ 161 } while (0) 162 163 #define _FP_ROUND(wc, X) \ 164 do { \ 165 if (_FP_FRAC_LOW_##wc(X) & 7) \ 166 FP_SET_EXCEPTION(FP_EX_INEXACT); \ 167 switch (FP_ROUNDMODE) \ 168 { \ 169 case FP_RND_NEAREST: \ 170 _FP_ROUND_NEAREST(wc,X); \ 171 break; \ 172 case FP_RND_ZERO: \ 173 _FP_ROUND_ZERO(wc,X); \ 174 break; \ 175 case FP_RND_PINF: \ 176 _FP_ROUND_PINF(wc,X); \ 177 break; \ 178 case FP_RND_MINF: \ 179 _FP_ROUND_MINF(wc,X); \ 180 break; \ 181 } \ 182 } while (0) 183 184 #define FP_CLS_NORMAL 0 185 #define FP_CLS_ZERO 1 186 #define FP_CLS_INF 2 187 #define FP_CLS_NAN 3 188 189 #define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y)) 190 191 #include <math-emu/op-1.h> 192 #include <math-emu/op-2.h> 193 #include <math-emu/op-4.h> 194 #include <math-emu/op-8.h> 195 #include <math-emu/op-common.h> 196 197 /* Sigh. Silly things longlong.h needs. */ 198 #define UWtype _FP_W_TYPE 199 #define W_TYPE_SIZE _FP_W_TYPE_SIZE 200 201 typedef int SItype __attribute__((mode(SI))); 202 typedef int DItype __attribute__((mode(DI))); 203 typedef unsigned int USItype __attribute__((mode(SI))); 204 typedef unsigned int UDItype __attribute__((mode(DI))); 205 #if _FP_W_TYPE_SIZE == 32 206 typedef unsigned int UHWtype __attribute__((mode(HI))); 207 #elif _FP_W_TYPE_SIZE == 64 208 typedef USItype UHWtype; 209 #endif 210 211 #ifndef umul_ppmm 212 #include <stdlib/longlong.h> 213 #endif 214 215 #endif /* __MATH_EMU_SOFT_FP_H__ */ 216