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

Comparing BasiliskII/src/uae_cpu/fpp.cpp (file contents):
Revision 1.7 by cebix, 1999-11-03T10:56:38Z vs.
Revision 1.8 by cebix, 2000-07-14T21:29:16Z

# Line 43 | Line 43
43   * FDBcc:
44   *  The loop termination condition was wrong.
45   *  Possible leak from int16 to int32 fixed.
46 < * Now fpcr high 16 bits are always read as zeores, no matter what was
46 > * get_fp_value:
47 > *  Immediate addressing mode && Operation Length == Byte ->
48 > *  Use the low-order byte of the extension word.
49 > * Now fpcr high 16 bits are always read as zeroes, no matter what was
50   * written to them.
51   *
52   * Other:
# Line 377 | Line 380 | static __inline__ double to_exten(uae_u3
380                  if( wrd2 | wrd3 ) {
381                          // mantissa, not fraction.
382                          uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3;
383 <                        while( (man & UVAL64(0x8000000000000000)) == 0 ) {
383 >                        while( exp > 0 && (man & UVAL64(0x8000000000000000)) == 0 ) {
384                                  man <<= 1;
385                                  exp--;
386                          }
# Line 412 | Line 415 | static __inline__ double to_exten(uae_u3
415          return(result);
416   }
417  
418 + /*
419 +        Would be so much easier with full size floats :(
420 +        ... this is so vague.
421 + */
422 + static __inline__ void to_exten_no_normalize(
423 +        uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3, uae_u32 *p
424 + )
425 + {
426 +        // double result;
427 +        // uae_u32 *p = (uae_u32 *)&result;
428 +
429 +        // Is it zero?
430 +  if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) {
431 +                MAKE_ZERO_POSITIVE(p);
432 +                return;
433 +        }
434 +
435 +        // Is it NaN?
436 +        if( (wrd1 & 0x7FFF0000) == 0x7FFF0000 ) {
437 +                if( (wrd1 & 0x0000FFFF) || wrd2 || wrd3 ) {
438 +                        MAKE_NAN( p );
439 +                        return;
440 +                }
441 +        }
442 +
443 +        uae_u32 sign =  wrd1 & 0x80000000;
444 +        uae_u32 exp  = (wrd1 >> 16) & 0x7fff;
445 +
446 +        if(exp < 16383 - 1023) {
447 +                // should set underflow.
448 +                exp = 0;
449 +        } else if(exp > 16383 + 1023) {
450 +                // should set overflow.
451 +                exp = 2047;
452 +        } else {
453 +                exp = exp + 1023 - 16383;
454 +        }
455 +
456 +        // drop the explicit integer bit.
457 +        p[FLO] = (wrd2 << 21) | (wrd3 >> 11);
458 +        p[FHI] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11);
459 +
460 +        D(bug("to_exten (%X,%X,%X) = %.04f\r\n",wrd1,wrd2,wrd3,(float)(*(double *)p)));
461 +
462 +        // return(result);
463 + }
464 +
465   static __inline__ void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
466   {
467          uae_u32 *p = (uae_u32 *)&src;
# Line 459 | Line 509 | static __inline__ double to_double(uae_u
509  
510   static __inline__ void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2)
511   {
512 + /*
513    if (src == 0.0) {
514                  *wrd1 = *wrd2 = 0;
515                  return;
516    }
517 + */
518          uae_u32 *p = (uae_u32 *)&src;
519          *wrd2 = p[FLO];
520          *wrd1 = p[FHI];
# Line 801 | Line 853 | static __inline__ int get_fp_value (uae_
853                                  case 4:
854                              ad = m68k_getpc ();
855                                          m68k_setpc (ad + sz2[size]);
856 +                                        // Immediate addressing mode && Operation Length == Byte ->
857 +                                        // Use the low-order byte of the extension word.
858 +                                        if(size == 6) ad++;
859                                          break;
860                                  default:
861                                          return 0;
# Line 1053 | Line 1108 | static __inline__ int get_fp_ad(uae_u32
1108    return 1;
1109   }
1110  
1111 < static __inline__ int fpp_cond(uae_u32 opcode, int contition)
1111 > static __inline__ int fpp_cond(uae_u32 opcode, int condition)
1112   {
1113 <  int N = (regs.fpsr & 0x8000000) != 0;
1114 <  int Z = (regs.fpsr & 0x4000000) != 0;
1115 <  /* int I = (regs.fpsr & 0x2000000) != 0; */
1116 <  int NotANumber = (regs.fpsr & 0x1000000) != 0;
1113 > #define N ((regs.fpsr & 0x8000000) != 0)
1114 > #define Z ((regs.fpsr & 0x4000000) != 0)
1115 > #define I ((regs.fpsr & 0x2000000) != 0)
1116 > #define NotANumber ((regs.fpsr & 0x1000000) != 0)
1117  
1118 <  switch (contition) {
1118 >  switch (condition) {
1119      case 0x00:
1120                          CONDRET("False",0);
1121      case 0x01:
# Line 1126 | Line 1181 | static __inline__ int fpp_cond(uae_u32 o
1181                          CONDRET("Signaling Not Equal",!Z);
1182      case 0x1f:
1183                          CONDRET("Signaling True",1);
1184 +        default:
1185 +                        CONDRET("",-1);
1186    }
1187 <        CONDRET("",-1);
1187 > #undef N
1188 > #undef Z
1189 > #undef I
1190 > #undef NotANumber
1191   }
1192  
1193 < void fdbcc_opp(uae_u32 opcode, uae_u16 extra)
1193 > void REGPARAM2 fdbcc_opp(uae_u32 opcode, uae_u16 extra)
1194   {
1195    uaecptr pc = (uae_u32) m68k_getpc ();
1196    uae_s32 disp = (uae_s32) (uae_s16) next_iword();
# Line 1161 | Line 1221 | void fdbcc_opp(uae_u32 opcode, uae_u16 e
1221    }
1222   }
1223  
1224 < void fscc_opp(uae_u32 opcode, uae_u16 extra)
1224 > void REGPARAM2 fscc_opp(uae_u32 opcode, uae_u16 extra)
1225   {
1226    uae_u32 ad;
1227    int cc;
# Line 1184 | Line 1244 | void fscc_opp(uae_u32 opcode, uae_u16 ex
1244    }
1245   }
1246  
1247 < void ftrapcc_opp(uae_u32 opcode, uaecptr oldpc)
1247 > void REGPARAM2 ftrapcc_opp(uae_u32 opcode, uaecptr oldpc)
1248   {
1249    int cc;
1250  
# Line 1200 | Line 1260 | void ftrapcc_opp(uae_u32 opcode, uaecptr
1260   }
1261  
1262   // NOTE that we get here also when there is a FNOP (nontrapping false, displ 0)
1263 < void fbcc_opp(uae_u32 opcode, uaecptr pc, uae_u32 extra)
1263 > void REGPARAM2 fbcc_opp(uae_u32 opcode, uaecptr pc, uae_u32 extra)
1264   {
1265    int cc;
1266  
# Line 1219 | Line 1279 | void fbcc_opp(uae_u32 opcode, uaecptr pc
1279  
1280   // FSAVE has no post-increment
1281   // 0x1f180000 == IDLE state frame, coprocessor version number 1F
1282 < void fsave_opp(uae_u32 opcode)
1282 > void REGPARAM2 fsave_opp(uae_u32 opcode)
1283   {
1284    uae_u32 ad;
1285    int incr = (opcode & 0x38) == 0x20 ? -1 : 1;
# Line 1278 | Line 1338 | void fsave_opp(uae_u32 opcode)
1338   }
1339  
1340   // FRESTORE has no pre-decrement
1341 < void frestore_opp(uae_u32 opcode)
1341 > void REGPARAM2 frestore_opp(uae_u32 opcode)
1342   {
1343    uae_u32 ad;
1344    uae_u32 d;
# Line 1607 | Line 1667 | void fpp_opp(uae_u32 opcode, uae_u16 ext
1667                                                  uae_u32 wrd1, wrd2, wrd3;
1668                                                  if( list & 0x80 ) {
1669                                                          from_exten(regs.fp[reg],&wrd1, &wrd2, &wrd3);
1670 <                                                        put_long (ad, wrd3);
1670 >                                                        put_long (ad, wrd1);
1671                                                          ad += 4;
1672                                                          put_long (ad, wrd2);
1673                                                          ad += 4;
1674 <                                                        put_long (ad, wrd1);
1674 >                                                        put_long (ad, wrd3);
1675                                                          ad += 4;
1676                                                  }
1677                                                  list <<= 1;
1678                                          }
1679                                  }
1680  
1621                                /*
1622                                while (list) {
1623                                        uae_u32 wrd1, wrd2, wrd3;
1624                                        if (incr < 0) {
1625                                                from_exten(regs.fp[fpp_movem_index2[list]],
1626                                                 &wrd1, &wrd2, &wrd3);
1627                                                ad -= 4;
1628                                                put_long (ad, wrd3);
1629                                                ad -= 4;
1630                                                put_long (ad, wrd2);
1631                                                ad -= 4;
1632                                                put_long (ad, wrd1);
1633                                        } else {
1634                                                from_exten(regs.fp[fpp_movem_index1[list]],
1635                                                 &wrd1, &wrd2, &wrd3);
1636                                                put_long (ad, wrd1);
1637                                                ad += 4;
1638                                                put_long (ad, wrd2);
1639                                                ad += 4;
1640                                                put_long (ad, wrd3);
1641                                                ad += 4;
1642                                        }
1643                                        list = fpp_movem_next[list];
1644                                }
1645                                */
1681                                  if ((opcode & 0x38) == 0x18) // post-increment?
1682                                          m68k_areg (regs, opcode & 7) = ad;
1683                                  if ((opcode & 0x38) == 0x20) // pre-decrement?
# Line 1685 | Line 1720 | void fpp_opp(uae_u32 opcode, uae_u16 ext
1720                                          for(reg=7; reg>=0; reg--) {
1721                                                  uae_u32 wrd1, wrd2, wrd3;
1722                                                  if( list & 0x80 ) {
1688                                                        wrd1 = get_long (ad);
1689                                                        ad -= 4;
1690                                                        wrd2 = get_long (ad);
1723                                                          ad -= 4;
1724                                                          wrd3 = get_long (ad);
1725                                                          ad -= 4;
1726 <                                                        regs.fp[reg] = to_exten (wrd1, wrd2, wrd3);
1726 >                                                        wrd2 = get_long (ad);
1727 >                                                        ad -= 4;
1728 >                                                        wrd1 = get_long (ad);
1729 >                                                        // regs.fp[reg] = to_exten (wrd1, wrd2, wrd3);
1730 >                                                        to_exten_no_normalize (wrd1, wrd2, wrd3, (uae_u32 *)&regs.fp[reg]);
1731                                                  }
1732                                                  list <<= 1;
1733                                          }
# Line 1705 | Line 1741 | void fpp_opp(uae_u32 opcode, uae_u16 ext
1741                                                          ad += 4;
1742                                                          wrd3 = get_long (ad);
1743                                                          ad += 4;
1744 <                                                        regs.fp[reg] = to_exten (wrd1, wrd2, wrd3);
1744 >                                                        // regs.fp[reg] = to_exten (wrd1, wrd2, wrd3);
1745 >                                                        to_exten_no_normalize (wrd1, wrd2, wrd3, (uae_u32 *)&regs.fp[reg]);
1746                                                  }
1747                                                  list <<= 1;
1748                                          }
1749                                  }
1713                                /**/
1714
1715                                /*
1716                                while (list) {
1717                                        uae_u32 wrd1, wrd2, wrd3;
1718                                        if (incr < 0) {
1719                                                ad -= 4;
1720                                                wrd3 = get_long (ad);
1721                                                ad -= 4;
1722                                                wrd2 = get_long (ad);
1723                                                ad -= 4;
1724                                                wrd1 = get_long (ad);
1725                                                regs.fp[fpp_movem_index2[list]] = to_exten (wrd1, wrd2, wrd3);
1726                            } else {
1727                                                wrd1 = get_long (ad);
1728                                                ad += 4;
1729                                                wrd2 = get_long (ad);
1730                                                ad += 4;
1731                                                wrd3 = get_long (ad);
1732                                                ad += 4;
1733                                                regs.fp[fpp_movem_index1[list]] = to_exten (wrd1, wrd2, wrd3);
1734                                        }
1735                                        list = fpp_movem_next[list];
1736                                }
1737                                */
1750                                  if ((opcode & 0x38) == 0x18) // post-increment?
1751                              m68k_areg (regs, opcode & 7) = ad;
1752                                  if ((opcode & 0x38) == 0x20) // pre-decrement?
# Line 1865 | Line 1877 | void fpp_opp(uae_u32 opcode, uae_u16 ext
1877                                  dump_fp_regs( "END  ");
1878                                  return;
1879                          }
1880 +                        D(bug("returned from get_fp_value m68k_getpc()=%X\r\n",m68k_getpc()));
1881  
1882                          switch (extra & 0x7f) {
1883                                  case 0x00:              /* FMOVE */
# Line 1983 | Line 1996 | void fpp_opp(uae_u32 opcode, uae_u16 ext
1996                                          MAKE_FPSR(regs.fpsr,regs.fp[reg]);
1997                                          break;
1998                                  case 0x18:              /* FABS */
1999 +                                case 0x58:              /* single precision rounding */
2000 +                                case 0x5C:              /* double precision rounding */
2001                                          D(bug("FABS %.04f\r\n",(float)src));
2002                                          regs.fp[reg] = src < 0 ? -src : src;
2003                                          MAKE_FPSR(regs.fpsr,regs.fp[reg]);
# Line 2065 | Line 2080 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2080                                  }
2081                                  break;
2082                          case 0x22:              /* FADD */
2083 +                        case 0x62:              /* single */
2084 +                        case 0x66:              /* double */
2085                                  D(bug("FADD %.04f\r\n",(float)src));
2086                                  regs.fp[reg] += src;
2087                                  MAKE_FPSR(regs.fpsr,regs.fp[reg]);
# Line 2206 | Line 2223 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2223                                          }
2224                                  } else {
2225                                          double tmp = regs.fp[reg] - src;
2226 <                                        regs.fpsr = (regs.fpsr & 0x00FFFFFF) | (tmp == 0 ? 0x4000000 : 0) | (tmp < 0 ? 0x8000000 : 0);
2226 >                                        // regs.fpsr = (regs.fpsr & 0x00FFFFFF) | (tmp == 0 ? 0x4000000 : 0) | (tmp < 0 ? 0x8000000 : 0);
2227 >                                        regs.fpsr = (tmp == 0 ? 0x4000000 : 0) | (tmp < 0 ? 0x8000000 : 0);
2228                                  }
2229   #else
2230                                  {
# Line 2226 | Line 2244 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2244                                  op_illg (opcode);
2245                                  break;
2246                  }
2247 +                D(bug("END m68k_getpc()=%X\r\n",m68k_getpc()));
2248                  dump_fp_regs( "END  ");
2249                  return;
2250    }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines