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.5 by gbeauche, 2002-09-19T16:02:13Z vs.
Revision 1.10 by asvitkine, 2012-03-30T01:45:08Z

# Line 1 | Line 1
1   /*
2 < * UAE - The Un*x Amiga Emulator
2 > *  fpu/fpu_ieee.cpp
3   *
4 < * MC68881/MC68040 emulation
4 > *  Basilisk II (C) 1997-2008 Christian Bauer
5   *
6 < * Copyright 1996 Herman ten Brugge
6 > *  MC68881/68040 fpu emulation
7   *
8 + *  Original UAE FPU, copyright 1996 Herman ten Brugge
9 + *  Rewrite for x86, copyright 1999-2000 Lauri Pesonen
10 + *  New framework, copyright 2000 Gwenole Beauchesne
11 + *  Adapted for JIT compilation (c) Bernd Meyer, 2000
12 + *  
13 + *  This program is free software; you can redistribute it and/or modify
14 + *  it under the terms of the GNU General Public License as published by
15 + *  the Free Software Foundation; either version 2 of the License, or
16 + *  (at your option) any later version.
17   *
18 + *  This program is distributed in the hope that it will be useful,
19 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 + *  GNU General Public License for more details.
22 + *
23 + *  You should have received a copy of the GNU General Public License
24 + *  along with this program; if not, write to the Free Software
25 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 + */
27 +
28 + /*
29   * Following fixes by Lauri Pesonen, July 1999:
30   *
31   * FMOVEM list handling:
# Line 180 | Line 200 | PRIVATE inline fpu_register FFPU make_si
200   #if 1
201          // Use a single, otherwise some checks for NaN, Inf, Zero would have to
202          // be performed
203 <        fpu_single result;
203 >        fpu_single result = 0; // = 0 to workaround a compiler bug on SPARC
204          fp_declare_init_shape(srp, result, single);
205          srp->ieee.negative      = (value >> 31) & 1;
206          srp->ieee.exponent      = (value >> 23) & FP_SINGLE_EXP_MAX;
# Line 251 | Line 271 | PRIVATE inline fpu_register FFPU make_ex
271                  return 0.0;
272  
273          fpu_register result;
274 < #ifndef USE_LONG_DOUBLE
274 > #if USE_QUAD_DOUBLE
275 >        // is it NaN?
276 >        if ((wrd1 & 0x7fff0000) == 0x7fff0000 && wrd2 != 0 && wrd3 != 0) {
277 >                make_nan(result);
278 >                return result;
279 >        }
280 >        // is it inf?
281 >        if ((wrd1 & 0x7ffff000) == 0x7fff0000 && wrd2 == 0 && wrd3 == 0) {
282 >                if ((wrd1 & 0x80000000) == 0)
283 >                        make_inf_positive(result);
284 >                else
285 >                        make_inf_negative(result);
286 >                return result;
287 >        }
288 >        fp_declare_init_shape(srp, result, extended);
289 >        srp->ieee.negative  = (wrd1 >> 31) & 1;
290 >        srp->ieee.exponent  = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
291 >        srp->ieee.mantissa0 = (wrd2 >> 16) & 0xffff;
292 >        srp->ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff);
293 >        srp->ieee.mantissa2 = (wrd3 & 0xffff) << 16;
294 >        srp->ieee.mantissa3 = 0;
295 > #elif USE_LONG_DOUBLE
296 >        fp_declare_init_shape(srp, result, extended);
297 >        srp->ieee.negative      = (wrd1 >> 31) & 1;
298 >        srp->ieee.exponent      = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
299 >        srp->ieee.mantissa0     = wrd2;
300 >        srp->ieee.mantissa1     = wrd3;
301 > #else
302          uae_u32 sgn = (wrd1 >> 31) & 1;
303          uae_u32 exp = (wrd1 >> 16) & 0x7fff;
304  
# Line 285 | Line 332 | PRIVATE inline fpu_register FFPU make_ex
332          // drop the explicit integer bit
333          srp->ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11;
334          srp->ieee.mantissa1 = (wrd2 << 21) | (wrd3 >> 11);
288 #elif USE_QUAD_DOUBLE
289        fp_declare_init_shape(srp, result, extended);
290        srp->ieee.negative  = (wrd1 >> 31) & 1;
291        srp->ieee.exponent  = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
292        srp->ieee.mantissa0 = (wrd2 >> 16) & 0xffff;
293        srp->ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff);
294        srp->ieee.mantissa2 = (wrd3 & 0xffff) << 16;
295 #else
296        fp_declare_init_shape(srp, result, extended);
297        srp->ieee.negative      = (wrd1 >> 31) & 1;
298        srp->ieee.exponent      = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
299        srp->ieee.mantissa0     = wrd2;
300        srp->ieee.mantissa1     = wrd3;
335   #endif
336          fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result));
337          return result;
# Line 322 | Line 356 | PRIVATE inline void FFPU make_extended_n
356                  make_nan(result);
357                  return;
358          }
359 < #ifndef USE_LONG_DOUBLE
359 > #if USE_QUAD_DOUBLE
360 >        // is it inf?
361 >        if ((wrd1 & 0x7ffff000) == 0x7fff0000 && wrd2 == 0 && wrd3 == 0) {
362 >                if ((wrd1 & 0x80000000) == 0)
363 >                        make_inf_positive(result);
364 >                else
365 >                        make_inf_negative(result);
366 >                return;
367 >        }
368 >        fp_declare_init_shape(srp, result, extended);
369 >        srp->ieee.negative  = (wrd1 >> 31) & 1;
370 >        srp->ieee.exponent  = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
371 >        srp->ieee.mantissa0 = (wrd2 >> 16) & 0xffff;
372 >        srp->ieee.mantissa1 = ((wrd2 & 0xffff) << 16) | ((wrd3 >> 16) & 0xffff);
373 >        srp->ieee.mantissa2 = (wrd3 & 0xffff) << 16;
374 >        srp->ieee.mantissa3 = 0;
375 > #elif USE_LONG_DOUBLE
376 >        fp_declare_init_shape(srp, result, extended);
377 >        srp->ieee.negative      = (wrd1 >> 31) & 1;
378 >        srp->ieee.exponent      = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
379 >        srp->ieee.mantissa0     = wrd2;
380 >        srp->ieee.mantissa1     = wrd3;
381 > #else
382          uae_u32 exp = (wrd1 >> 16) & 0x7fff;
383          if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS)
384                  exp = 0;
# Line 337 | Line 393 | PRIVATE inline void FFPU make_extended_n
393          // drop the explicit integer bit
394          srp->ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11;
395          srp->ieee.mantissa1 = (wrd2 << 21) | (wrd3 >> 11);
340 #else
341        // FIXME: USE_QUAD_DOUBLE
342        fp_declare_init_shape(srp, result, extended);
343        srp->ieee.negative      = (wrd1 & 0x80000000) != 0;
344        srp->ieee.exponent      = (wrd1 >> 16) & 0x7fff;
345        srp->ieee.mantissa0     = wrd2;
346        srp->ieee.mantissa1     = wrd3;
396   #endif
397          fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result));
398   }
# Line 357 | Line 406 | PRIVATE inline void FFPU extract_extende
406                  *wrd1 = *wrd2 = *wrd3 = 0;
407                  return;
408          }
409 < #ifndef USE_LONG_DOUBLE
409 > #if USE_QUAD_DOUBLE
410 >        // FIXME: deal with denormals?
411 >        fp_declare_init_shape(srp, src, extended);
412 >        *wrd1 = (srp->ieee.negative << 31) | (srp->ieee.exponent << 16);
413 >        // always set the explicit integer bit.
414 >        *wrd2 = 0x80000000 | (srp->ieee.mantissa0 << 15) | ((srp->ieee.mantissa1 & 0xfffe0000) >> 17);
415 >        *wrd3 = (srp->ieee.mantissa1 << 15) | ((srp->ieee.mantissa2 & 0xfffe0000) >> 17);
416 > #elif USE_LONG_DOUBLE
417 >        uae_u32 *p = (uae_u32 *)&src;
418 > #ifdef WORDS_BIGENDIAN
419 >        *wrd1 = p[0];
420 >        *wrd2 = p[1];
421 >        *wrd3 = p[2];
422 > #else
423 >        *wrd3 = p[0];
424 >        *wrd2 = p[1];
425 >        *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16;
426 > #endif
427 > #else
428          fp_declare_init_shape(srp, src, double);
429          fpu_debug(("extract_extended (%d,%d,%X,%X)\n",
430                             srp->ieee.negative , srp->ieee.exponent,
# Line 374 | Line 441 | PRIVATE inline void FFPU extract_extende
441          // always set the explicit integer bit.
442          *wrd2 = 0x80000000 | (srp->ieee.mantissa0 << 11) | ((srp->ieee.mantissa1 & 0xffe00000) >> 21);
443          *wrd3 = srp->ieee.mantissa1 << 11;
377 #else
378        // FIXME: USE_QUAD_DOUBLE
379        uae_u32 *p = (uae_u32 *)&src;
380 #ifdef WORDS_BIGENDIAN
381        *wrd1 = p[0];
382        *wrd2 = p[1];
383        *wrd3 = p[2];
384 #else
385        *wrd3 = p[0];
386        *wrd2 = p[1];
387        *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16;
388 #endif
444   #endif
445          fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3));
446   }
# Line 1593 | Line 1648 | void FFPU fpuop_arithmetic(uae_u32 opcod
1648                                  break;
1649   #if USE_LONG_DOUBLE || USE_QUAD_DOUBLE
1650                          case 0x3c:
1651 <                                FPU registers[reg] = 1.0e512;
1651 >                                FPU registers[reg] = 1.0e512L;
1652                                  fpu_debug(("FP const: 1.0e512\n"));
1653                                  break;
1654                          case 0x3d:
1655 <                                FPU registers[reg] = 1.0e1024;
1655 >                                FPU registers[reg] = 1.0e1024L;
1656                                  fpu_debug(("FP const: 1.0e1024\n"));
1657                                  break;
1658                          case 0x3e:
1659 <                                FPU registers[reg] = 1.0e2048;
1659 >                                FPU registers[reg] = 1.0e2048L;
1660                                  fpu_debug(("FP const: 1.0e2048\n"));
1661                                  break;
1662                          case 0x3f:
1663 <                                FPU registers[reg] = 1.0e4096;
1663 >                                FPU registers[reg] = 1.0e4096L;
1664                                  fpu_debug(("FP const: 1.0e4096\n"));
1665   #endif
1666                                  break;
# Line 2070 | Line 2125 | PUBLIC void FFPU fpu_init (bool integral
2125   #if defined(FPU_USE_X86_ROUNDING)
2126          // Initial state after boot, reset and frestore(null frame)
2127          x86_control_word = CW_INITIAL;
2128 < #elif defined(__i386__) && defined(X86_ASSEMBLY)
2128 > #elif defined(USE_X87_ASSEMBLY)
2129          volatile unsigned short int cw;
2130          __asm__ __volatile__("fnstcw %0" : "=m" (cw));
2131          cw &= ~0x0300; cw |= 0x0300; // CW_PC_EXTENDED

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines