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.3 by cebix, 1999-10-27T17:50:08Z vs.
Revision 1.6 by cebix, 1999-10-31T23:18: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 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 1226 | Line 1235 | void fsave_opp(uae_u32 opcode)
1235                  return;
1236    }
1237          
1238 <        // Put 28 byte IDLE frame.
1239 <        // NOTE!!! IDLE frame is only 4 bytes on a 68040!!
1240 <
1241 <  if (incr < 0) {
1242 <          D(bug("fsave_opp pre-decrement\r\n"));
1243 <                ad -= 4;
1244 <                // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1245 <                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;
1238 >        if (CPUType == 4) {
1239 >                // Put 4 byte 68040 IDLE frame.
1240 >                if (incr < 0) {
1241 >                        ad -= 4;
1242 >                        put_long (ad, 0x41000000);
1243 >                } else {
1244 >                        put_long (ad, 0x41000000);
1245 >                        ad += 4;
1246                  }
1247 <                // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1248 <                put_long (ad, 0x70000000);
1249 <                ad += 4;
1250 <  }
1247 >        } else {
1248 >                // Put 28 byte 68881 IDLE frame.
1249 >          if (incr < 0) {
1250 >                  D(bug("fsave_opp pre-decrement\r\n"));
1251 >                        ad -= 4;
1252 >                        // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1253 >                        put_long (ad, 0x70000000);
1254 >                        for (i = 0; i < 5; i++) {
1255 >                    ad -= 4;
1256 >                    put_long (ad, 0x00000000);
1257 >                        }
1258 >                        ad -= 4;
1259 >                        put_long (ad, 0x1f180000); // IDLE, vers 1f
1260 >          } else {
1261 >                        put_long (ad, 0x1f180000); // IDLE, vers 1f
1262 >                        ad += 4;
1263 >                        for (i = 0; i < 5; i++) {
1264 >                    put_long (ad, 0x00000000);
1265 >                    ad += 4;
1266 >                        }
1267 >                        // What's this? Some BIU flags, or (incorrectly placed) command/condition?
1268 >                        put_long (ad, 0x70000000);
1269 >                        ad += 4;
1270 >          }
1271 >        }
1272    if ((opcode & 0x38) == 0x18) {
1273                  m68k_areg (regs, opcode & 7) = ad; // Never executed on a 68881
1274            D(bug("PROBLEM: fsave_opp post-increment\r\n"));
# Line 1261 | Line 1279 | void fsave_opp(uae_u32 opcode)
1279          }
1280   }
1281  
1282 < // FSAVE has no pre-decrement
1282 > // FRESTORE has no pre-decrement
1283   void frestore_opp(uae_u32 opcode)
1284   {
1285    uae_u32 ad;
# Line 1276 | Line 1294 | void frestore_opp(uae_u32 opcode)
1294                  return;
1295    }
1296  
1297 <  if (incr < 0) {
1298 <
1299 <          D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
1300 <
1301 <                // this may be wrong, but it's never called.
1302 <                ad -= 4;
1303 <                d = get_long (ad);
1304 <                if ((d & 0xff000000) != 0) {
1305 <            if ((d & 0x00ff0000) == 0x00180000)
1306 <                                ad -= 6 * 4;
1307 <            else if ((d & 0x00ff0000) == 0x00380000)
1308 <                                ad -= 14 * 4;
1309 <            else if ((d & 0x00ff0000) == 0x00b40000)
1310 <                                ad -= 45 * 4;
1297 >        if (CPUType == 4) {
1298 >                // 68040
1299 >                if (incr < 0) {
1300 >                  D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
1301 >                        // this may be wrong, but it's never called.
1302 >                        ad -= 4;
1303 >                        d = get_long (ad);
1304 >                        if ((d & 0xff000000) != 0) { // Not a NULL frame?
1305 >                                if ((d & 0x00ff0000) == 0) { // IDLE
1306 >                                  D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1307 >                                } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP
1308 >                                  D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4));
1309 >                                        ad -= 44;
1310 >                                } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
1311 >                                  D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1312 >                                        ad -= 92;
1313 >                                }
1314 >                        }
1315 >                } else {
1316 >                        d = get_long (ad);
1317 >                  D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
1318 >                        ad += 4;
1319 >                        if ((d & 0xff000000) != 0) { // Not a NULL frame?
1320 >                                if ((d & 0x00ff0000) == 0) { // IDLE
1321 >                                  D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1322 >                                } else if ((d & 0x00ff0000) == 0x00300000) { // UNIMP
1323 >                                  D(bug("PROBLEM: frestore_opp found UNIMP frame at %X\r\n",ad-4));
1324 >                                        ad += 44;
1325 >                                } else if ((d & 0x00ff0000) == 0x00600000) { // BUSY
1326 >                                  D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1327 >                                        ad += 92;
1328 >                                }
1329 >                        }
1330                  }
1331 <  } else {
1332 <                d = get_long (ad);
1333 <
1334 <          D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
1335 <
1336 <                ad += 4;
1337 <                if ((d & 0xff000000) != 0) { // Not a NULL frame?
1338 <            if ((d & 0x00ff0000) == 0x00180000) { // IDLE
1339 <                          D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1340 <                                ad += 6 * 4;
1341 <            } else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C?
1342 <                                ad += 14 * 4;
1343 <                          D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4));
1344 <            } else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY
1345 <                          D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1346 <                                ad += 45 * 4;
1331 >        } else {
1332 >                // 68881
1333 >          if (incr < 0) {
1334 >                  D(bug("PROBLEM: frestore_opp incr < 0\r\n"));
1335 >                        // this may be wrong, but it's never called.
1336 >                        ad -= 4;
1337 >                        d = get_long (ad);
1338 >                        if ((d & 0xff000000) != 0) {
1339 >                    if ((d & 0x00ff0000) == 0x00180000)
1340 >                                        ad -= 6 * 4;
1341 >                    else if ((d & 0x00ff0000) == 0x00380000)
1342 >                                        ad -= 14 * 4;
1343 >                    else if ((d & 0x00ff0000) == 0x00b40000)
1344 >                                        ad -= 45 * 4;
1345 >                        }
1346 >          } else {
1347 >                        d = get_long (ad);
1348 >                  D(bug("frestore_opp frame at %X = %X\r\n",ad,d));
1349 >                        ad += 4;
1350 >                        if ((d & 0xff000000) != 0) { // Not a NULL frame?
1351 >                    if ((d & 0x00ff0000) == 0x00180000) { // IDLE
1352 >                                  D(bug("frestore_opp found IDLE frame at %X\r\n",ad-4));
1353 >                                        ad += 6 * 4;
1354 >                    } else if ((d & 0x00ff0000) == 0x00380000) {// UNIMP? shouldn't it be 3C?
1355 >                                        ad += 14 * 4;
1356 >                                  D(bug("PROBLEM: frestore_opp found UNIMP? frame at %X\r\n",ad-4));
1357 >                    } else if ((d & 0x00ff0000) == 0x00b40000) {// BUSY
1358 >                                  D(bug("PROBLEM: frestore_opp found BUSY frame at %X\r\n",ad-4));
1359 >                                        ad += 45 * 4;
1360 >                                }
1361                          }
1362                  }
1363    }
# Line 2022 | Line 2073 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2073                                  break;
2074                          case 0x23:              /* FMUL */
2075                                  D(bug("FMUL %.04f\r\n",(float)src));
2076 + #if HAVE_IEEE_DOUBLE
2077                                  GET_DEST_FLAGS((uae_u32 *)&regs.fp[reg]);
2078                                  GET_SOURCE_FLAGS((uae_u32 *)&src);
2079                                  if(fl_dest.in_range && fl_source.in_range) {
# Line 2048 | Line 2100 | void fpp_opp(uae_u32 opcode, uae_u16 ext
2100                                                  MAKE_INF_POSITIVE((uae_u32 *)&regs.fp[reg]);
2101                                          }
2102                                  }
2103 + #else
2104 +                                D(bug("FMUL %.04f\r\n",(float)src));
2105 +                                regs.fp[reg] *= src;
2106 + #endif
2107                                  MAKE_FPSR(regs.fpsr,regs.fp[reg]);
2108                                  break;
2109                          case 0x24:              /* FSGLDIV */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines