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.2 by gbeauche, 2002-09-13T15:06:42Z vs.
Revision 1.3 by gbeauche, 2002-09-15T18:21:13Z

# Line 264 | Line 264 | PRIVATE inline uae_u32 FFPU extract_sing
264   // to_exten
265   PRIVATE inline fpu_register FFPU make_extended(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
266   {
267 < #if 1
268 <        // FIXME: USE_QUAD_DOUBLE
269 <        fpu_extended result;
270 <        fp_declare_init_shape(srp, result, extended);
271 <        srp->ieee.negative      = (wrd1 >> 31) & 1;
272 <        srp->ieee.exponent      = (wrd1 >> 16) & FP_EXTENDED_EXP_MAX;
273 <        srp->ieee.mantissa0     = wrd2;
274 <        srp->ieee.mantissa1     = wrd3;
275 <        fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result));
276 <        return result;
277 < #elif 0 /* original code */
267 >        // is it zero?
268          if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0)
269                  return 0.0;
270 <        
270 >
271          fpu_register result;
272 <        uae_u32 *p = (uae_u32 *)&result;
273 <        
274 <        uae_u32 sign =  wrd1 & 0x80000000;
285 <        uae_u32 exp  = (wrd1 >> 16) & 0x7fff;
272 > #ifndef USE_LONG_DOUBLE
273 >        uae_u32 sgn = (wrd1 >> 31) & 1;
274 >        uae_u32 exp = (wrd1 >> 16) & 0x7fff;
275  
276 <        // The explicit integer bit is not set, must normalize.
277 <        if((wrd2 & 0x80000000) == 0) {
276 >        // the explicit integer bit is not set, must normalize
277 >        if ((wrd2 & 0x80000000) == 0) {
278                  fpu_debug(("make_extended denormalized mantissa (%X,%X,%X)\n",wrd1,wrd2,wrd3));
279 <                if( wrd2 | wrd3 ) {
279 >                if (wrd2 | wrd3) {
280                          // mantissa, not fraction.
281                          uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3;
282 <                        while( exp > 0 && (man & UVAL64(0x8000000000000000)) == 0 ) {
282 >                        while (exp > 0 && (man & UVAL64(0x8000000000000000)) == 0) {
283                                  man <<= 1;
284                                  exp--;
285                          }
286 <                        wrd2 = (uae_u32)( man >> 32 );
287 <                        wrd3 = (uae_u32)( man & 0xFFFFFFFF );
299 <                } else {
300 <                        if(exp == 0x7FFF) {
301 <                                // Infinity.
302 <                        } else {
303 <                                // Zero
304 <                                exp = 16383 - 1023;
305 <                        }
286 >                        wrd2 = (uae_u32)(man >> 32);
287 >                        wrd3 = (uae_u32)(man & 0xFFFFFFFF);
288                  }
289 +                else if (exp != 0x7fff) // zero
290 +                        exp = FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS;
291          }
292  
293 <        if(exp < 16383 - 1023) {
310 <                // should set underflow.
293 >        if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS)
294                  exp = 0;
295 <        } else if(exp > 16383 + 1023) {
296 <                // should set overflow.
297 <                exp = 2047;
298 <        } else {
299 <                exp = exp + 1023 - 16383;
300 <        }
301 <
302 <        // drop the explicit integer bit.
303 <        p[FLO] = (wrd2 << 21) | (wrd3 >> 11);
304 <        p[FHI] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11);
305 <
306 <        fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result));
307 <
308 <        return(result);
295 >        else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS)
296 >                exp = FP_DOUBLE_EXP_MAX;
297 >        else
298 >                exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS;
299 >        
300 >        fp_declare_init_shape(srp, result, double);
301 >        srp->ieee.negative  = sgn;
302 >        srp->ieee.exponent  = exp;
303 >        // drop the explicit integer bit
304 >        srp->ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11;
305 >        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;
319   #endif
320 +        fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result));
321 +        return result;
322   }
323  
324   /*
# Line 335 | Line 330 | PRIVATE inline void FFPU make_extended_n
330          uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, fpu_register & result
331   )
332   {
333 < #if 1
333 >        // is it zero?
334 >        if ((wrd1 && 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) {
335 >                make_zero_positive(result);
336 >                return;
337 >        }
338 >        // is it NaN?
339 >        if ((wrd1 & 0x7fff0000) == 0x7fff0000 && wrd2 != 0 && wrd3 != 0) {
340 >                make_nan(result);
341 >                return;
342 >        }
343 > #ifndef USE_LONG_DOUBLE
344 >        uae_u32 exp = (wrd1 >> 16) & 0x7fff;
345 >        if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS)
346 >                exp = 0;
347 >        else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS)
348 >                exp = FP_DOUBLE_EXP_MAX;
349 >        else
350 >                exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS;
351 >        
352 >        fp_declare_init_shape(srp, result, double);
353 >        srp->ieee.negative  = (wrd1 >> 31) & 1;
354 >        srp->ieee.exponent  = exp;
355 >        // drop the explicit integer bit
356 >        srp->ieee.mantissa0 = (wrd2 & 0x7fffffff) >> 11;
357 >        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;
345 #elif 0 /* original code */
346        // Is it zero?
347        if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) {
348                make_zero_positive(result);
349                return;
350        }
351
352        // Is it NaN?
353        if( (wrd1 & 0x7FFF0000) == 0x7FFF0000 ) {
354                if( (wrd1 & 0x0000FFFF) || wrd2 || wrd3 ) {
355                        make_nan(result);
356                        return;
357                }
358        }
359        
360        uae_u32 sign =  wrd1 & 0x80000000;
361        uae_u32 exp  = (wrd1 >> 16) & 0x7fff;
362
363        if(exp < 16383 - 1023) {
364                // should set underflow.
365                exp = 0;
366        } else if(exp > 16383 + 1023) {
367                // should set overflow.
368                exp = 2047;
369        } else {
370                exp = exp + 1023 - 16383;
371        }
372
373        // drop the explicit integer bit.
374        uae_u32 *p = (uae_u32 *)&result;
375        p[FLO] = (wrd2 << 21) | (wrd3 >> 11);
376        p[FHI] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11);
377
378        fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(float)(*(double *)p)));
365   #endif
366 +        fpu_debug(("make_extended (%X,%X,%X) = %.04f\n",wrd1,wrd2,wrd3,(double)result));
367   }
368  
369   // from_exten
# Line 384 | Line 371 | PRIVATE inline void FFPU extract_extende
371          uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3
372   )
373   {
387 #if 1
388        // FIXME: USE_QUAD_DOUBLE and non little-endian specificities
389        uae_u32 *p = (uae_u32 *)&src;
390        *wrd3 = p[0];
391        *wrd2 = p[1];
392        *wrd1 = ( (uae_u32)*((uae_u16 *)&p[2]) ) << 16;
393        fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3));
394 #elif 0 /* original code */
374          if (src == 0.0) {
375                  *wrd1 = *wrd2 = *wrd3 = 0;
376                  return;
377          }
378 <        
379 <        uae_u32 *p = (uae_u32 *)&src;
380 <        
381 <        fpu_debug(("extract_extended (%X,%X)\n",p[FLO],p[FHI]));
378 > #ifndef USE_LONG_DOUBLE
379 >        fp_declare_init_shape(srp, src, double);
380 >        fpu_debug(("extract_extended (%d,%d,%X,%X)\n",
381 >                           srp->ieee.negative , srp->ieee.exponent,
382 >                           srp->ieee.mantissa0, srp->ieee.mantissa1));
383  
384 <        uae_u32 sign =  p[FHI] & 0x80000000;
384 >        uae_u32 exp = srp->ieee.exponent;
385  
386 <        uae_u32 exp  = ((p[FHI] >> 20) & 0x7ff);
387 <        // Check for maximum
388 <        if(exp == 0x7FF) {
389 <                exp = 0x7FFF;
410 <        } else {
411 <                exp  += 16383 - 1023;
412 <        }
386 >        if (exp == FP_DOUBLE_EXP_MAX)
387 >                exp = FP_EXTENDED_EXP_MAX;
388 >        else
389 >                exp += FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS;
390  
391 <        *wrd1 = sign | (exp << 16);
391 >        *wrd1 = (srp->ieee.negative << 31) | (exp << 16);
392          // always set the explicit integer bit.
393 <        *wrd2 = 0x80000000 | ((p[FHI] & 0x000FFFFF) << 11) | ((p[FLO] & 0xFFE00000) >> 21);
394 <        *wrd3 = p[FLO] << 11;
395 <
396 <        fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3));
393 >        *wrd2 = 0x80000000 | (srp->ieee.mantissa0 << 11) | ((srp->ieee.mantissa1 & 0xffe00000) >> 21);
394 >        *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
406   #endif
407 +        fpu_debug(("extract_extended (%.04f) = %X,%X,%X\n",(double)src,*wrd1,*wrd2,*wrd3));
408   }
409  
410   // to_double
# Line 425 | Line 412 | PRIVATE inline fpu_register FFPU make_do
412   {
413          union {
414                  fpu_double value;
415 <                uae_u32   parts[2];
415 >                uae_u32    parts[2];
416          } dest;
417   #ifdef WORDS_BIGENDIAN
418          dest.parts[0] = wrd1;
# Line 445 | Line 432 | PRIVATE inline void FFPU extract_double(
432   {
433          union {
434                  fpu_double value;
435 <                uae_u32   parts[2];
435 >                uae_u32    parts[2];
436          } dest;
437          dest.value = (fpu_double)src;
438   #ifdef WORDS_BIGENDIAN
# Line 1989 | Line 1976 | void FFPU fpuop_arithmetic(uae_u32 opcod
1976  
1977                  case 0x26:              /* FSCALE */
1978                          fpu_debug(("FSCALE %.04f\n",(double)src));
1979 <
1980 <                        // TODO:
1981 <                        // Overflow, underflow
1982 <
1996 <                        if( isinf(FPU registers[reg]) ) {
1997 <                                make_nan( FPU registers[reg] );
1998 <                        }
1999 <                        else {
1979 >                        // TODO: overflow flags
1980 >                        get_dest_flags(FPU registers[reg]);
1981 >                        get_source_flags(src);
1982 >                        if (fl_source.in_range && fl_dest.in_range) {
1983                                  // When the absolute value of the source operand is >= 2^14,
1984                                  // an overflow or underflow always results.
1985                                  // Here (int) cast is okay.
1986 <                                fast_scale( FPU registers[reg], (int)fp_round_to_zero(src) );
1986 >                                int scale_factor = (int)fp_round_to_zero(src);
1987 > #ifndef USE_LONG_DOUBLE
1988 >                                fp_declare_init_shape(sxp, FPU registers[reg], double);
1989 >                                uae_u32 exp = sxp->ieee.exponent + scale_factor;
1990 >                                if (exp < FP_EXTENDED_EXP_BIAS - FP_DOUBLE_EXP_BIAS)
1991 >                                        exp = 0;
1992 >                                else if (exp > FP_EXTENDED_EXP_BIAS + FP_DOUBLE_EXP_BIAS)
1993 >                                        exp = FP_DOUBLE_EXP_MAX;
1994 >                                else
1995 >                                        exp += FP_DOUBLE_EXP_BIAS - FP_EXTENDED_EXP_BIAS;
1996 >                                sxp->ieee.exponent = exp;
1997 > #else
1998 >                                fp_declare_init_shape(sxp, FPU registers[reg], extended);
1999 >                                sxp->ieee.exponent += scale_factor;
2000 > #endif
2001 >                        }
2002 >                        else if (fl_source.infinity) {
2003 >                                // Returns NaN for any Infinity source
2004 >                                make_nan( FPU registers[reg] );
2005                          }
2006                          make_fpsr(FPU registers[reg]);
2007                          break;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines