ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp
(Generate patch)

Comparing BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp (file contents):
Revision 1.3 by gbeauche, 2002-09-15T18:21:13Z vs.
Revision 1.9 by gbeauche, 2003-05-28T10:17:43Z

# Line 80 | Line 80
80   fpu_t fpu;
81  
82   /* -------------------------------------------------------------------------- */
83 /* --- Endianness                                                         --- */
84 /* -------------------------------------------------------------------------- */
85
86 // Taken from glibc 2.1.x: endian.h
87 #define UAE_LITTLE_ENDIAN               1234
88 #define UAE_BIG_ENDIAN                  4321
89
90 #if WORDS_BIGENDIAN
91 #define UAE_BYTE_ORDER                  UAE_BIG_ENDIAN
92 #else
93 #define UAE_BYTE_ORDER                  UAE_LITTLE_ENDIAN
94 #endif
95
96 // Some machines may need to use a different endianness for floating point values
97 // e.g. ARM in which case it is big endian
98 #define UAE_FLOAT_WORD_ORDER    UAE_BYTE_ORDER
99
100 /* -------------------------------------------------------------------------- */
83   /* --- Scopes Definition                                                  --- */
84   /* -------------------------------------------------------------------------- */
85  
# Line 198 | Line 180 | PRIVATE inline fpu_register FFPU make_si
180   #if 1
181          // Use a single, otherwise some checks for NaN, Inf, Zero would have to
182          // be performed
183 <        fpu_single result;
183 >        fpu_single result = 0; // = 0 to workaround a compiler bug on SPARC
184          fp_declare_init_shape(srp, result, single);
185          srp->ieee.negative      = (value >> 31) & 1;
186          srp->ieee.exponent      = (value >> 23) & FP_SINGLE_EXP_MAX;
# Line 269 | Line 251 | PRIVATE inline fpu_register FFPU make_ex
251                  return 0.0;
252  
253          fpu_register result;
254 < #ifndef USE_LONG_DOUBLE
254 > #if USE_QUAD_DOUBLE
255 >        // is it NaN?
256 >        if ((wrd1 & 0x7fff0000) == 0x7fff0000 && wrd2 != 0 && wrd3 != 0) {
257 >                make_nan(result);
258 >                return result;
259 >        }
260 >        // is it inf?
261 >        if ((wrd1 & 0x7ffff000) == 0x7fff0000 && wrd2 == 0 && wrd3 == 0) {
262 >                if ((wrd1 & 0x80000000) == 0)
263 >                        make_inf_positive(result);
264 >                else
265 >                        make_inf_negative(result);
266 >                return result;
267 >        }
268 >        fp_declare_init_shape(srp, result, extended);
269 >        srp->ieee.negative  = (wrd1 >> 31) & 1;
270 >        srp->ieee.exponent  = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
271 >        srp->ieee.mantissa0 = (wrd2 >> 16) & 0xffff;
272 >        srp->ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff);
273 >        srp->ieee.mantissa2 = (wrd3 & 0xffff) << 16;
274 >        srp->ieee.mantissa3 = 0;
275 > #elif USE_LONG_DOUBLE
276 >        fp_declare_init_shape(srp, result, extended);
277 >        srp->ieee.negative      = (wrd1 >> 31) & 1;
278 >        srp->ieee.exponent      = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
279 >        srp->ieee.mantissa0     = wrd2;
280 >        srp->ieee.mantissa1     = wrd3;
281 > #else
282          uae_u32 sgn = (wrd1 >> 31) & 1;
283          uae_u32 exp = (wrd1 >> 16) & 0x7fff;
284  
# Line 303 | Line 312 | PRIVATE inline fpu_register FFPU make_ex
312          // drop the explicit integer bit
313          srp->ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11;
314          srp->ieee.mantissa1 = (wrd2 << 21) | (wrd3 >> 11);
306 #elif USE_QUAD_DOUBLE
307        fp_declare_init_shape(srp, result, extended);
308        srp->ieee.negative  = (wrd1 >> 31) & 1;
309        srp->ieee.exponent  = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
310        srp->ieee.mantissa0 = (wrd2 >> 16) & 0xffff;
311        srp->ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff);
312        srp->ieee.mantissa2 = (wrd3 & 0xffff) << 16;
313 #else
314        fp_declare_init_shape(srp, result, extended);
315        srp->ieee.negative      = (wrd1 >> 31) & 1;
316        srp->ieee.exponent      = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
317        srp->ieee.mantissa0     = wrd2;
318        srp->ieee.mantissa1     = wrd3;
315   #endif
316          fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result));
317          return result;
# Line 340 | Line 336 | PRIVATE inline void FFPU make_extended_n
336                  make_nan(result);
337                  return;
338          }
339 < #ifndef USE_LONG_DOUBLE
339 > #if USE_QUAD_DOUBLE
340 >        // is it inf?
341 >        if ((wrd1 & 0x7ffff000) == 0x7fff0000 && wrd2 == 0 && wrd3 == 0) {
342 >                if ((wrd1 & 0x80000000) == 0)
343 >                        make_inf_positive(result);
344 >                else
345 >                        make_inf_negative(result);
346 >                return;
347 >        }
348 >        fp_declare_init_shape(srp, result, extended);
349 >        srp->ieee.negative  = (wrd1 >> 31) & 1;
350 >        srp->ieee.exponent  = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
351 >        srp->ieee.mantissa0 = (wrd2 >> 16) & 0xffff;
352 >        srp->ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff);
353 >        srp->ieee.mantissa2 = (wrd3 & 0xffff) << 16;
354 >        srp->ieee.mantissa3 = 0;
355 > #elif USE_LONG_DOUBLE
356 >        fp_declare_init_shape(srp, result, extended);
357 >        srp->ieee.negative      = (wrd1 >> 31) & 1;
358 >        srp->ieee.exponent      = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
359 >        srp->ieee.mantissa0     = wrd2;
360 >        srp->ieee.mantissa1     = wrd3;
361 > #else
362          uae_u32 exp = (wrd1 >> 16) & 0x7fff;
363          if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS)
364                  exp = 0;
# Line 355 | Line 373 | PRIVATE inline void FFPU make_extended_n
373          // drop the explicit integer bit
374          srp->ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11;
375          srp->ieee.mantissa1 = (wrd2 << 21) | (wrd3 >> 11);
358 #else
359        // FIXME: USE_QUAD_DOUBLE
360        fp_declare_init_shape(srp, result, extended);
361        srp->ieee.negative      = (wrd1 & 0x80000000) != 0;
362        srp->ieee.exponent      = (wrd1 >> 16) & 0x7fff;
363        srp->ieee.mantissa0     = wrd2;
364        srp->ieee.mantissa1     = wrd3;
376   #endif
377          fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result));
378   }
# Line 375 | Line 386 | PRIVATE inline void FFPU extract_extende
386                  *wrd1 = *wrd2 = *wrd3 = 0;
387                  return;
388          }
389 < #ifndef USE_LONG_DOUBLE
389 > #if USE_QUAD_DOUBLE
390 >        // FIXME: deal with denormals?
391 >        fp_declare_init_shape(srp, src, extended);
392 >        *wrd1 = (srp->ieee.negative << 31) | (srp->ieee.exponent << 16);
393 >        // always set the explicit integer bit.
394 >        *wrd2 = 0x80000000 | (srp->ieee.mantissa0 << 15) | ((srp->ieee.mantissa1 & 0xfffe0000) >> 17);
395 >        *wrd3 = (srp->ieee.mantissa1 << 15) | ((srp->ieee.mantissa2 & 0xfffe0000) >> 17);
396 > #elif USE_LONG_DOUBLE
397 >        uae_u32 *p = (uae_u32 *)&src;
398 > #ifdef WORDS_BIGENDIAN
399 >        *wrd1 = p[0];
400 >        *wrd2 = p[1];
401 >        *wrd3 = p[2];
402 > #else
403 >        *wrd3 = p[0];
404 >        *wrd2 = p[1];
405 >        *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16;
406 > #endif
407 > #else
408          fp_declare_init_shape(srp, src, double);
409          fpu_debug(("extract_extended (%d,%d,%X,%X)\n",
410                             srp->ieee.negative , srp->ieee.exponent,
# Line 392 | Line 421 | PRIVATE inline void FFPU extract_extende
421          // always set the explicit integer bit.
422          *wrd2 = 0x80000000 | (srp->ieee.mantissa0 << 11) | ((srp->ieee.mantissa1 & 0xffe00000) >> 21);
423          *wrd3 = srp->ieee.mantissa1 << 11;
395 #else
396        // FIXME: USE_QUAD_DOUBLE
397 #ifdef WORDS_BIGENDIAN
398        *wrd1 = p[0];
399        *wrd2 = p[1];
400        *wrd3 = p[2];
401 #else
402        *wrd3 = p[0];
403        *wrd2 = p[1];
404        *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16;
405 #endif
424   #endif
425          fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3));
426   }
# Line 1608 | Line 1626 | void FFPU fpuop_arithmetic(uae_u32 opcod
1626                                  FPU registers[reg] = 1.0e256;
1627                                  fpu_debug(("FP const: 1.0e256\n"));
1628                                  break;
1629 < #if USE_LONG_DOUBLE
1629 > #if USE_LONG_DOUBLE || USE_QUAD_DOUBLE
1630                          case 0x3c:
1631 <                                FPU registers[reg] = 1.0e512;
1631 >                                FPU registers[reg] = 1.0e512L;
1632                                  fpu_debug(("FP const: 1.0e512\n"));
1633                                  break;
1634                          case 0x3d:
1635 <                                FPU registers[reg] = 1.0e1024;
1635 >                                FPU registers[reg] = 1.0e1024L;
1636                                  fpu_debug(("FP const: 1.0e1024\n"));
1637                                  break;
1638                          case 0x3e:
1639 <                                FPU registers[reg] = 1.0e2048;
1639 >                                FPU registers[reg] = 1.0e2048L;
1640                                  fpu_debug(("FP const: 1.0e2048\n"));
1641                                  break;
1642                          case 0x3f:
1643 <                                FPU registers[reg] = 1.0e4096;
1643 >                                FPU registers[reg] = 1.0e4096L;
1644                                  fpu_debug(("FP const: 1.0e4096\n"));
1645   #endif
1646                                  break;
# Line 1984 | Line 2002 | void FFPU fpuop_arithmetic(uae_u32 opcod
2002                                  // an overflow or underflow always results.
2003                                  // Here (int) cast is okay.
2004                                  int scale_factor = (int)fp_round_to_zero(src);
2005 < #ifndef USE_LONG_DOUBLE
2005 > #if USE_LONG_DOUBLE || USE_QUAD_DOUBLE
2006 >                                fp_declare_init_shape(sxp, FPU registers[reg], extended);
2007 >                                sxp->ieee.exponent += scale_factor;
2008 > #else
2009                                  fp_declare_init_shape(sxp, FPU registers[reg], double);
2010                                  uae_u32 exp = sxp->ieee.exponent + scale_factor;
2011                                  if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS)
# Line 1994 | Line 2015 | void FFPU fpuop_arithmetic(uae_u32 opcod
2015                                  else
2016                                          exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS;
2017                                  sxp->ieee.exponent = exp;
1997 #else
1998                                fp_declare_init_shape(sxp, FPU registers[reg], extended);
1999                                sxp->ieee.exponent += scale_factor;
2018   #endif
2019                          }
2020                          else if (fl_source.infinity) {
# Line 2087 | Line 2105 | PUBLIC void FFPU fpu_init (bool integral
2105   #if defined(FPU_USE_X86_ROUNDING)
2106          // Initial state after boot, reset and frestore(null frame)
2107          x86_control_word = CW_INITIAL;
2108 < #elif defined(__i386__) && defined(X86_ASSEMBLY)
2108 > #elif defined(USE_X87_ASSEMBLY)
2109          volatile unsigned short int cw;
2110          __asm__ __volatile__("fnstcw %0" : "=m" (cw));
2111          cw &= ~0x0300; cw |= 0x0300; // CW_PC_EXTENDED

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines