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.2 by cebix, 1999-10-27T16:59:54Z vs.
Revision 1.7 by cebix, 1999-11-03T10:56:38Z

# Line 71 | Line 71
71   #include "memory.h"
72   #include "readcpu.h"
73   #include "newcpu.h"
74 + #include "main.h"
75  
76   #define DEBUG 0
77   #include "debug.h"
# Line 79 | Line 80
80   // Only define if you have IEEE 64 bit doubles.
81   #define HAVE_IEEE_DOUBLE 1
82  
83 + #ifdef WORDS_BIGENDIAN
84 + #define FLO 1
85 + #define FHI 0
86 + #else
87 + #define FLO 0
88 + #define FHI 1
89 + #endif
90 +
91   // fpcr rounding modes
92   #define ROUND_TO_NEAREST                        0
93   #define ROUND_TO_ZERO                           0x10
# Line 173 | Line 182 | double_flags fl_dest, fl_source;
182  
183   static __inline__ uae_u32 IS_NAN(uae_u32 *p)
184   {
185 <        if( (p[1] & 0x7FF00000) == 0x7FF00000 ) {
185 >        if( (p[FHI] & 0x7FF00000) == 0x7FF00000 ) {
186                  // logical or is faster here.
187 <                if( (p[1] & 0x000FFFFF) || p[0] ) {
187 >                if( (p[FHI] & 0x000FFFFF) || p[FLO] ) {
188                          return(1);
189                  }
190          }
# Line 184 | Line 193 | static __inline__ uae_u32 IS_NAN(uae_u32
193  
194   static __inline__ uae_u32 IS_INFINITY(uae_u32 *p)
195   {
196 <        if( ((p[1] & 0x7FF00000) == 0x7FF00000) && p[0] == 0 ) {
196 >        if( ((p[FHI] & 0x7FF00000) == 0x7FF00000) && p[FLO] == 0 ) {
197                  return(1);
198          }
199          return(0);
# Line 192 | Line 201 | static __inline__ uae_u32 IS_INFINITY(ua
201  
202   static __inline__ uae_u32 IS_NEGATIVE(uae_u32 *p)
203   {
204 <        return( (p[1] & 0x80000000) != 0 );
204 >        return( (p[FHI] & 0x80000000) != 0 );
205   }
206  
207   static __inline__ uae_u32 IS_ZERO(uae_u32 *p)
208   {
209 <        return( ((p[1] & 0x7FF00000) == 0) && p[0] == 0 );
209 >        return( ((p[FHI] & 0x7FF00000) == 0) && p[FLO] == 0 );
210   }
211  
212   // This should not touch the quotient.
# Line 236 | Line 245 | static __inline__ void GET_SOURCE_FLAGS(
245  
246   static __inline__ void MAKE_NAN(uae_u32 *p)
247   {
248 <        p[0] = 0xFFFFFFFF;
249 <        p[1] = 0x7FFFFFFF;
248 >        p[FLO] = 0xFFFFFFFF;
249 >        p[FHI] = 0x7FFFFFFF;
250   }
251  
252   static __inline__ void MAKE_ZERO_POSITIVE(uae_u32 *p)
253   {
254 <        p[0] = p[1] = 0;
254 >        p[FLO] = p[FHI] = 0;
255   }
256  
257   static __inline__ void MAKE_ZERO_NEGATIVE(uae_u32 *p)
258   {
259 <        p[0] = 0;
260 <        p[1] = 0x80000000;
259 >        p[FLO] = 0;
260 >        p[FHI] = 0x80000000;
261   }
262  
263   static __inline__ void MAKE_INF_POSITIVE(uae_u32 *p)
264   {
265 <        p[0] = 0;
266 <        p[1] = 0x7FF00000;
265 >        p[FLO] = 0;
266 >        p[FHI] = 0x7FF00000;
267   }
268  
269   static __inline__ void MAKE_INF_NEGATIVE(uae_u32 *p)
270   {
271 <        p[0] = 0;
272 <        p[1] = 0xFFF00000;
271 >        p[FLO] = 0;
272 >        p[FHI] = 0xFFF00000;
273   }
274  
275   static __inline__ void FAST_SCALE(uae_u32 *p, int add)
276   {
277          int exp;
278  
279 <        exp = (p[1] & 0x7FF00000) >> 20;
279 >        exp = (p[FHI] & 0x7FF00000) >> 20;
280          // TODO: overflow flags
281          exp += add;
282          if(exp >= 2047) {
283                  MAKE_INF_POSITIVE(p);
284          } else if(exp < 0) {
285                  // keep sign (+/- 0)
286 <                p[1] &= 0x80000000;
286 >                p[FHI] &= 0x80000000;
287          } else {
288 <                p[1] = (p[1] & 0x800FFFFF) | ((uae_u32)exp << 20);
288 >                p[FHI] = (p[FHI] & 0x800FFFFF) | ((uae_u32)exp << 20);
289          }
290   }
291  
292   static __inline__ double FAST_FGETEXP(uae_u32 *p)
293   {
294 <        int exp = (p[1] & 0x7FF00000) >> 20;
294 >        int exp = (p[FHI] & 0x7FF00000) >> 20;
295          return( exp - 1023 );
296   }
297  
298   // Normalize to range 1..2
299   static __inline__ void FAST_REMOVE_EXPONENT(uae_u32 *p)
300   {
301 <        p[1] = (p[1] & 0x800FFFFF) | 0x3FF00000;
301 >        p[FHI] = (p[FHI] & 0x800FFFFF) | 0x3FF00000;
302   }
303  
304   // The sign of the quotient is the exclusive-OR of the sign bits
305   // of the source and destination operands.
306   static __inline__ uae_u32 GET_QUOTIENT_SIGN(uae_u32 *a, uae_u32 *b)
307   {
308 <        return( ((a[1] ^ b[1]) & 0x80000000) ? 0x800000 : 0);
308 >        return( ((a[FHI] ^ b[FHI]) & 0x80000000) ? 0x800000 : 0);
309   }
310  
311   // Quotient Byte is loaded with the sign and least significant
# Line 319 | Line 328 | static __inline__ double to_single (uae_
328          uae_u32 sign = (value & 0x80000000);
329          uae_u32 exp  = ((value & 0x7F800000) >> 23) + 1023 - 127;
330  
331 <        p[0] = value << 29;
332 <        p[1] = sign | (exp << 20) | ((value & 0x007FFFFF) >> 3);
331 >        p[FLO] = value << 29;
332 >        p[FHI] = sign | (exp << 20) | ((value & 0x007FFFFF) >> 3);
333  
334          D(bug("to_single (%X) = %.04f\r\n",value,(float)result));
335  
# Line 334 | Line 343 | static __inline__ uae_u32 from_single (d
343  
344    if (src == 0.0) return 0;
345  
346 <        uae_u32 sign = (p[1] & 0x80000000);
347 <        uae_u32 exp  = (p[1] & 0x7FF00000) >> 20;
346 >        uae_u32 sign = (p[FHI] & 0x80000000);
347 >        uae_u32 exp  = (p[FHI] & 0x7FF00000) >> 20;
348  
349          if(exp + 127 < 1023) {
350                  exp = 0;
# Line 345 | Line 354 | static __inline__ uae_u32 from_single (d
354                  exp = exp + 127 - 1023;
355          }
356  
357 <        result = sign | (exp << 23) | ((p[1] & 0x000FFFFF) << 3) | (p[0] >> 29);
357 >        result = sign | (exp << 23) | ((p[FHI] & 0x000FFFFF) << 3) | (p[FLO] >> 29);
358  
359          D(bug("from_single (%.04f) = %X\r\n",(float)src,result));
360  
# Line 368 | Line 377 | static __inline__ double to_exten(uae_u3
377                  if( wrd2 | wrd3 ) {
378                          // mantissa, not fraction.
379                          uae_u64 man = ((uae_u64)wrd2 << 32) | wrd3;
380 <                        while( (man & 0x8000000000000000LL) == 0 ) {
380 >                        while( (man & UVAL64(0x8000000000000000)) == 0 ) {
381                                  man <<= 1;
382                                  exp--;
383                          }
# Line 395 | Line 404 | static __inline__ double to_exten(uae_u3
404          }
405  
406          // drop the explicit integer bit.
407 <        p[0] = (wrd2 << 21) | (wrd3 >> 11);
408 <        p[1] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11);
407 >        p[FLO] = (wrd2 << 21) | (wrd3 >> 11);
408 >        p[FHI] = sign | (exp << 20) | ((wrd2 & 0x7FFFFFFF) >> 11);
409  
410          D(bug("to_exten (%X,%X,%X) = %.04f\r\n",wrd1,wrd2,wrd3,(float)result));
411  
# Line 412 | Line 421 | static __inline__ void from_exten(double
421                  return;
422    }
423  
424 <        D(bug("from_exten (%X,%X)\r\n",p[0],p[1]));
424 >        D(bug("from_exten (%X,%X)\r\n",p[FLO],p[FHI]));
425  
426 <        uae_u32 sign =  p[1] & 0x80000000;
426 >        uae_u32 sign =  p[FHI] & 0x80000000;
427  
428 <        uae_u32 exp  = ((p[1] >> 20) & 0x7ff);
428 >        uae_u32 exp  = ((p[FHI] >> 20) & 0x7ff);
429          // Check for maximum
430          if(exp == 0x7FF) {
431                  exp = 0x7FFF;
# Line 426 | Line 435 | static __inline__ void from_exten(double
435  
436          *wrd1 = sign | (exp << 16);
437          // always set the explicit integer bit.
438 <        *wrd2 = 0x80000000 | ((p[1] & 0x000FFFFF) << 11) | ((p[0] & 0xFFE00000) >> 21);
439 <        *wrd3 = p[0] << 11;
438 >        *wrd2 = 0x80000000 | ((p[FHI] & 0x000FFFFF) << 11) | ((p[FLO] & 0xFFE00000) >> 21);
439 >        *wrd3 = p[FLO] << 11;
440  
441          D(bug("from_exten (%.04f) = %X,%X,%X\r\n",(float)src,*wrd1,*wrd2,*wrd3));
442   }
# Line 440 | Line 449 | static __inline__ double to_double(uae_u
449    if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0) return 0.0;
450  
451          p = (uae_u32 *)&result;
452 <        p[0] = wrd2;
453 <        p[1] = wrd1;
452 >        p[FLO] = wrd2;
453 >        p[FHI] = wrd1;
454  
455          D(bug("to_double (%X,%X) = %.04f\r\n",wrd1,wrd2,(float)result));
456  
# Line 455 | Line 464 | static __inline__ void from_double(doubl
464                  return;
465    }
466          uae_u32 *p = (uae_u32 *)&src;
467 <        *wrd2 = p[0];
468 <        *wrd1 = p[1];
467 >        *wrd2 = p[FLO];
468 >        *wrd1 = p[FHI];
469  
470          D(bug("from_double (%.04f) = %X,%X\r\n",(float)src,*wrd1,*wrd2));
471   }
# Line 863 | Line 872 | static __inline__ int put_fp_value (doub
872    int mode;
873    int reg;
874    uae_u32 ad;
875 <  static int sz1[8] =
876 <  {4, 4, 12, 12, 2, 8, 1, 0};
868 <  static int sz2[8] =
869 <  {4, 4, 12, 12, 2, 8, 2, 0};
875 >  static int sz1[8] = {4, 4, 12, 12, 2, 8, 1, 0};
876 >  static int sz2[8] = {4, 4, 12, 12, 2, 8, 2, 0};
877  
878          // D(bug("put_fp_value(%.04f,%X,%X)\r\n",(float)value,(int)opcode,(int)extra));
879  
# Line 1226 | Line 1233 | void fsave_opp(uae_u32 opcode)
1233                  return;
1234    }
1235          
1236 <        // Put 28 byte IDLE frame.
1237 <        // NOTE!!! IDLE frame is only 4 bytes on a 68040!!
1238 <
1239 <  if (incr < 0) {
1240 <          D(bug("fsave_opp pre-decrement\r\n"));
1241 <                ad -= 4;
1242 <                // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1243 <                put_long (ad, 0x70000000);
1237 <                for (i = 0; i < 5; i++) {
1238 <            ad -= 4;
1239 <            put_long (ad, 0x00000000);
1240 <                }
1241 <                ad -= 4;
1242 <                put_long (ad, 0x1f180000); // IDLE, vers 1f
1243 <  } else {
1244 <                put_long (ad, 0x1f180000); // IDLE, vers 1f
1245 <                ad += 4;
1246 <                for (i = 0; i < 5; i++) {
1247 <            put_long (ad, 0x00000000);
1248 <            ad += 4;
1236 >        if (CPUType == 4) {
1237 >                // Put 4 byte 68040 IDLE frame.
1238 >                if (incr < 0) {
1239 >                        ad -= 4;
1240 >                        put_long (ad, 0x41000000);
1241 >                } else {
1242 >                        put_long (ad, 0x41000000);
1243 >                        ad += 4;
1244                  }
1245 <                // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1246 <                put_long (ad, 0x70000000);
1247 <                ad += 4;
1248 <  }
1245 >        } else {
1246 >                // Put 28 byte 68881 IDLE frame.
1247 >          if (incr < 0) {
1248 >                  D(bug("fsave_opp pre-decrement\r\n"));
1249 >                        ad -= 4;
1250 >                        // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1251 >                        put_long (ad, 0x70000000);
1252 >                        for (i = 0; i < 5; i++) {
1253 >                    ad -= 4;
1254 >                    put_long (ad, 0x00000000);
1255 >                        }
1256 >                        ad -= 4;
1257 >                        put_long (ad, 0x1f180000); // IDLE, vers 1f
1258 >          } else {
1259 >                        put_long (ad, 0x1f180000); // IDLE, vers 1f
1260 >                        ad += 4;
1261 >                        for (i = 0; i < 5; i++) {
1262 >                    put_long (ad, 0x00000000);
1263 >                    ad += 4;
1264 >                        }
1265 >                        // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1266 >                        put_long (ad, 0x70000000);
1267 >                        ad += 4;
1268 >          }
1269 >        }
1270    if ((opcode & 0x38) == 0x18) {
1271                  m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881
1272            D(bug("PROBLEM: fsave_opp post-increment\r\n"));
# Line 1261 | Line 1277 | void fsave_opp(uae_u32 opcode)
1277          }
1278   }
1279  
1280 < // FSAVE has no pre-decrement
1280 > // FRESTORE has no pre-decrement
1281   void frestore_opp(uae_u32 opcode)
1282   {
1283    uae_u32 ad;
# Line 1276 | Line 1292 | void frestore_opp(uae_u32 opcode)
1292                  return;
1293    }
1294  
1295 <  if (incr < 0) {
1296 <
1297 <          D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
1298 <
1299 <                // this may be wrong, but it's never called.
1300 <                ad -= 4;
1301 <                d = get_long (ad);
1302 <                if ((d & 0xff000000) != 0) {
1303 <            if ((d & 0x00ff0000) == 0x00180000)
1304 <                                ad -= 6 * 4;
1305 <            else if ((d & 0x00ff0000) == 0x00380000)
1306 <                                ad -= 14 * 4;
1307 <            else if ((d & 0x00ff0000) == 0x00b40000)
1308 <                                ad -= 45 * 4;
1295 >        if (CPUType == 4) {
1296 >                // 68040
1297 >                if (incr < 0) {
1298 >                  D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
1299 >                        // this may be wrong, but it's never called.
1300 >                        ad -= 4;
1301 >                        d = get_long (ad);
1302 >                        if ((d & 0xff000000) != 0) { // Not a NULL frame?
1303 >                                if ((d & 0x00ff0000) == 0) { // IDLE
1304 >                                  D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1305 >                                } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP
1306 >                                  D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4));
1307 >                                        ad -= 44;
1308 >                                } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
1309 >                                  D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1310 >                                        ad -= 92;
1311 >                                }
1312 >                        }
1313 >                } else {
1314 >                        d = get_long (ad);
1315 >                  D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
1316 >                        ad += 4;
1317 >                        if ((d & 0xff000000) != 0) { // Not a NULL frame?
1318 >                                if ((d & 0x00ff0000) == 0) { // IDLE
1319 >                                  D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1320 >                                } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP
1321 >                                  D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4));
1322 >                                        ad += 44;
1323 >                                } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
1324 >                                  D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1325 >                                        ad += 92;
1326 >                                }
1327 >                        }
1328                  }
1329 <  } else {
1330 <                d = get_long (ad);
1331 <
1332 <          D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
1333 <
1334 <                ad += 4;
1335 <                if ((d & 0xff000000) != 0) { // Not a NULL frame?
1336 <            if ((d & 0x00ff0000) == 0x00180000) { // IDLE
1337 <                          D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1338 <                                ad += 6 * 4;
1339 <            } else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C?
1340 <                                ad += 14 * 4;
1341 <                          D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4));
1342 <            } else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY
1343 <                          D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1344 <                                ad += 45 * 4;
1329 >        } else {
1330 >                // 68881
1331 >          if (incr < 0) {
1332 >                  D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
1333 >                        // this may be wrong, but it's never called.
1334 >                        ad -= 4;
1335 >                        d = get_long (ad);
1336 >                        if ((d & 0xff000000) != 0) {
1337 >                    if ((d & 0x00ff0000) == 0x00180000)
1338 >                                        ad -= 6 * 4;
1339 >                    else if ((d & 0x00ff0000) == 0x00380000)
1340 >                                        ad -= 14 * 4;
1341 >                    else if ((d & 0x00ff0000) == 0x00b40000)
1342 >                                        ad -= 45 * 4;
1343 >                        }
1344 >          } else {
1345 >                        d = get_long (ad);
1346 >                  D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
1347 >                        ad += 4;
1348 >                        if ((d & 0xff000000) != 0) { // Not a NULL frame?
1349 >                    if ((d & 0x00ff0000) == 0x00180000) { // IDLE
1350 >                                  D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1351 >                                        ad += 6 * 4;
1352 >                    } else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C?
1353 >                                        ad += 14 * 4;
1354 >                                  D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4));
1355 >                    } else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY
1356 >                                  D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1357 >                                        ad += 45 * 4;
1358 >                                }
1359                          }
1360                  }
1361    }
# Line 2022 | Line 2071 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2071                                  break;
2072                          case 0x23:              /* FMUL */
2073                                  D(bug("FMUL %.04f\r\n",(float)src));
2074 + #if HAVE_IEEE_DOUBLE
2075                                  GET_DEST_FLAGS((uae_u32 *)&regs.fp[reg]);
2076                                  GET_SOURCE_FLAGS((uae_u32 *)&src);
2077                                  if(fl_dest.in_range && fl_source.in_range) {
# Line 2048 | Line 2098 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2098                                                  MAKE_INF_POSITIVE((uae_u32 *)&regs.fp[reg]);
2099                                          }
2100                                  }
2101 + #else
2102 +                                D(bug("FMUL %.04f\r\n",(float)src));
2103 +                                regs.fp[reg] *= src;
2104 + #endif
2105                                  MAKE_FPSR(regs.fpsr,regs.fp[reg]);
2106                                  break;
2107                          case 0x24:              /* FSGLDIV */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines