Index: exec.h =================================================================== RCS file: /cvsroot/qemu/qemu/target-ppc/exec.h,v retrieving revision 1.9 diff -u -d -w -B -b -d -p -r1.9 exec.h --- exec.h 3 Jan 2005 23:42:39 -0000 1.9 +++ exec.h 18 Feb 2005 21:12:08 -0000 @@ -32,9 +32,6 @@ register uint32_t T2 asm(AREG3); #define FT0 (env->ft0) #define FT1 (env->ft1) #define FT2 (env->ft2) -#define FTS0 ((float)env->ft0) -#define FTS1 ((float)env->ft1) -#define FTS2 ((float)env->ft2) #if defined (DEBUG_OP) #define RETURN() __asm__ __volatile__("nop"); @@ -146,8 +143,6 @@ void do_fsqrte (void); void do_fsel (void); void do_fcmpu (void); void do_fcmpo (void); -void do_fabs (void); -void do_fnabs (void); void do_check_reservation (void); void do_icbi (void); Index: op.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-ppc/op.c,v retrieving revision 1.15 diff -u -d -w -B -b -d -p -r1.15 op.c --- op.c 15 Feb 2005 23:06:19 -0000 1.15 +++ op.c 18 Feb 2005 21:12:09 -0000 @@ -32,10 +32,6 @@ #define FT1 (env->ft1) #define FT2 (env->ft2) -#define FTS0 ((float)env->ft0) -#define FTS1 ((float)env->ft1) -#define FTS2 ((float)env->ft2) - #define PPC_OP(name) void glue(op_, name)(void) #define REG 0 @@ -1207,7 +1203,7 @@ PPC_OP(fadd) /* fadds - fadds. */ PPC_OP(fadds) { - FT0 = FTS0 + FTS1; + FT0 = (float)(FT0 + FT1); RETURN(); } @@ -1221,7 +1217,7 @@ PPC_OP(fsub) /* fsubs - fsubs. */ PPC_OP(fsubs) { - FT0 = FTS0 - FTS1; + FT0 = (float)(FT0 - FT1); RETURN(); } @@ -1235,21 +1231,23 @@ PPC_OP(fmul) /* fmuls - fmuls. */ PPC_OP(fmuls) { - FT0 = FTS0 * FTS1; + FT0 = (float)(FT0 * FT1); RETURN(); } /* fdiv - fdiv. */ +void do_fdiv (void); PPC_OP(fdiv) { - FT0 /= FT1; + do_fdiv(); RETURN(); } /* fdivs - fdivs. */ +void do_fdivs (void); PPC_OP(fdivs) { - FT0 = FTS0 / FTS1; + do_fdivs(); RETURN(); } @@ -1299,7 +1297,7 @@ PPC_OP(fmadd) /* fmadds - fmadds. */ PPC_OP(fmadds) { - FT0 = (FTS0 * FTS1) + FTS2; + FT0 = (float)((FT0 * FT1) + FT2); RETURN(); } @@ -1313,7 +1311,7 @@ PPC_OP(fmsub) /* fmsubs - fmsubs. */ PPC_OP(fmsubs) { - FT0 = (FTS0 * FTS1) - FTS2; + FT0 = (float)((FT0 * FT1) - FT2); RETURN(); } @@ -1385,6 +1382,7 @@ PPC_OP(fcmpo) /*** Floating-point move ***/ /* fabs */ +void do_fabs (void); PPC_OP(fabs) { do_fabs(); @@ -1392,6 +1390,7 @@ PPC_OP(fabs) } /* fnabs */ +void do_fnabs (void); PPC_OP(fnabs) { do_fnabs(); Index: op_helper.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-ppc/op_helper.c,v retrieving revision 1.11 diff -u -d -w -B -b -d -p -r1.11 op_helper.c --- op_helper.c 15 Feb 2005 23:06:19 -0000 1.11 +++ op_helper.c 18 Feb 2005 21:12:09 -0000 @@ -249,16 +249,21 @@ void do_fctiw (void) union { double d; uint64_t i; - } *p = (void *)&FT1; + } p; + /* XXX: higher bits are not supposed to be significant. + * to make tests easier, return the same as a real PPC 750 (aka G3) + */ + p.i = 0xFFF80000ULL << 32; if (FT0 > (double)0x7FFFFFFF) - p->i = 0x7FFFFFFFULL << 32; + p.i |= 0x7FFFFFFFULL; else if (FT0 < -(double)0x80000000) - p->i = 0x80000000ULL << 32; + p.i |= 0x80000000ULL; + else if (FT0 < 0.0 || FT0 == -0.0) + p.i |= 0x100000000ULL | (uint32_t)FT0; else - p->i = 0; - p->i |= (uint32_t)FT0; - FT0 = p->d; + p.i |= (uint32_t)FT0; + FT0 = p.d; } void do_fctiwz (void) @@ -266,18 +271,23 @@ void do_fctiwz (void) union { double d; uint64_t i; - } *p = (void *)&FT1; + } p; int cround = fegetround(); + /* XXX: higher bits are not supposed to be significant. + * to make tests easier, return the same as a real PPC 750 (aka G3) + */ + p.i = 0xFFF80000ULL << 32; fesetround(FE_TOWARDZERO); if (FT0 > (double)0x7FFFFFFF) - p->i = 0x7FFFFFFFULL << 32; + p.i |= 0x7FFFFFFFULL; else if (FT0 < -(double)0x80000000) - p->i = 0x80000000ULL << 32; + p.i |= 0x80000000ULL; + else if (FT0 < 0.0 || FT0 == -0.0) + p.i |= 0x100000000ULL | (uint32_t)FT0; else - p->i = 0; - p->i |= (uint32_t)FT0; - FT0 = p->d; + p.i |= (uint32_t)FT0; + FT0 = p.d; fesetround(cround); } @@ -293,12 +303,28 @@ void do_fnmsub (void) void do_fnmadds (void) { - FT0 = -((FTS0 * FTS1) + FTS2); + FT0 = (float)(-((FT0 * FT1) + FT2)); } void do_fnmsubs (void) { - FT0 = -((FTS0 * FTS1) - FTS2); + FT0 = (float)(-((FT0 * FT1) - FT2)); +} + +void do_fdiv (void) +{ + if (FT0 == -0.0 && FT1 == -0.0) + FT0 = 0.0 / 0.0; + else + FT0 /= FT1; +} + +void do_fdivs (void) +{ + if (FT0 == -0.0 && FT1 == -0.0) + FT0 = (float)(0.0 / 0.0); + else + FT0 = (float)(FT0 / FT1); } void do_fsqrt (void) @@ -308,12 +334,12 @@ void do_fsqrt (void) void do_fsqrts (void) { - FT0 = (float)sqrt((float)FT0); + FT0 = (float)sqrt(FT0); } void do_fres (void) { - FT0 = 1.0 / FT0; + FT0 = (float)(1.0 / FT0); } void do_fsqrte (void) @@ -324,9 +350,9 @@ void do_fsqrte (void) void do_fsel (void) { if (FT0 >= 0) - FT0 = FT2; - else FT0 = FT1; + else + FT0 = FT2; } void do_fcmpu (void) @@ -371,12 +397,18 @@ void do_fcmpo (void) void do_fabs (void) { - FT0 = fabsl(FT0); + if (FT0 == -0.0) + FT0 = +0.0; + else if (FT0 < 0.0) + FT0 = -FT0; } void do_fnabs (void) { - FT0 = -fabsl(FT0); + if (FT0 == +0.0) + FT0 = -0.0; + else if (FT0 >= +0.0) + FT0 = -FT0; } /* Instruction cache invalidation helper */ Index: translate.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-ppc/translate.c,v retrieving revision 1.27 diff -u -d -w -B -b -d -p -r1.27 translate.c --- translate.c 15 Feb 2005 23:06:19 -0000 1.27 +++ translate.c 18 Feb 2005 21:12:10 -0000 @@ -823,8 +823,8 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x0 gen_op_set_Rc1(); \ } -#define GEN_FLOAT_BS(name, op2) \ -GEN_HANDLER(f##name, 0x3F, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \ +#define GEN_FLOAT_BS(name, op1, op2) \ +GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \ { \ if (!ctx->fpu_enabled) { \ RET_EXCP(ctx, EXCP_NO_FP, 0); \ @@ -846,10 +846,10 @@ GEN_FLOAT_AB(div, 0x12, 0x000007C0); GEN_FLOAT_AC(mul, 0x19, 0x0000F800); /* fres */ -GEN_FLOAT_BS(res, 0x18); +GEN_FLOAT_BS(res, 0x3B, 0x18); /* frsqrte */ -GEN_FLOAT_BS(rsqrte, 0x1A); +GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A); /* fsel */ _GEN_FLOAT_ACB(sel, 0x3F, 0x17); @@ -857,7 +857,7 @@ _GEN_FLOAT_ACB(sel, 0x3F, 0x17); GEN_FLOAT_AB(sub, 0x14, 0x000007C0); /* Optional: */ /* fsqrt */ -GEN_FLOAT_BS(sqrt, 0x16); +GEN_FLOAT_BS(sqrt, 0x3F, 0x16); GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT) {