From: Julian Seward Date: Tue, 27 Dec 2005 14:22:25 +0000 (+0000) Subject: Merge vx1482 (fix for: ppc32: lfsu f5, -4(r11) and various others) X-Git-Tag: svn/VALGRIND_3_1_1^2~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71f8d0acca69d2cc4d2a9ec5129b2b315d1afd91;p=thirdparty%2Fvalgrind.git Merge vx1482 (fix for: ppc32: lfsu f5, -4(r11) and various others) git-svn-id: svn://svn.valgrind.org/vex/branches/VEX_3_1_BRANCH@1514 --- diff --git a/VEX/priv/guest-ppc32/toIR.c b/VEX/priv/guest-ppc32/toIR.c index f601f7c54e..7460ecdb25 100644 --- a/VEX/priv/guest-ppc32/toIR.c +++ b/VEX/priv/guest-ppc32/toIR.c @@ -54,6 +54,12 @@ - lvxl,stvxl: load/store with 'least recently used' hint - vexptefp, vlogefp + Floating Point + - Single precision stores are rounded twice - once by F64toF32, + and then again by the backend for storeBE( F32 ), giving a loss + of precision. + + LIMITATIONS: Various, including: @@ -4062,16 +4068,16 @@ static Bool dis_fp_load ( UInt theInstr ) putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkexpr(EA))) ); break; -//zz case 0x31: // lfsu (Load Float Single with Update, PPC32 p442) -//zz if (rA_addr == 0) { -//zz vex_printf("dis_fp_load(PPC32)(instr,lfsu)\n"); -//zz return False; -//zz } -//zz DIP("lfsu fr%d,%d(r%d)\n", frD_addr, d_simm16, rA_addr); -//zz assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA)) ); -//zz putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkexpr(EA))) ); -//zz putIReg( rA_addr, mkexpr(EA) ); -//zz break; + case 0x31: // lfsu (Load Float Single with Update, PPC32 p442) + if (rA_addr == 0) { + vex_printf("dis_fp_load(PPC32)(instr,lfsu)\n"); + return False; + } + DIP("lfsu fr%u,%d(r%u)\n", frD_addr, d_simm16, rA_addr); + assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA_or_0)) ); + putFReg( frD_addr, unop(Iop_F32toF64, loadBE(Ity_F32, mkexpr(EA))) ); + putIReg( rA_addr, mkexpr(EA) ); + break; case 0x32: // lfd (Load Float Double, PPC32 p437) DIP("lfd fr%d,%d(r%d)\n", frD_addr, d_simm16, rA_addr); @@ -4181,17 +4187,17 @@ static Bool dis_fp_store ( UInt theInstr ) binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) ); break; -//zz case 0x35: // stfsu (Store Float Single with Update, PPC32 p519) -//zz if (rA_addr == 0) { -//zz vex_printf("dis_fp_store(PPC32)(instr,stfsu)\n"); -//zz return False; -//zz } -//zz DIP("stfsu fr%d,%d(r%d)\n", frS_addr, d_simm16, rA_addr); -//zz assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA)) ); -//zz storeBE( mkexpr(EA), -//zz binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) ); -//zz putIReg( rA_addr, mkexpr(EA) ); -//zz break; + case 0x35: // stfsu (Store Float Single with Update, PPC32 p519) + if (rA_addr == 0) { + vex_printf("dis_fp_store(PPC32)(instr,stfsu)\n"); + return False; + } + DIP("stfsu fr%u,%d(r%u)\n", frS_addr, d_simm16, rA_addr); + assign( EA, binop(Iop_Add32, mkU32(d_simm16), mkexpr(rA_or_0)) ); + storeBE( mkexpr(EA), + binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) ); + putIReg( rA_addr, mkexpr(EA) ); + break; case 0x36: // stfd (Store Float Double, PPC32 p513) DIP("stfd fr%d,%d(r%d)\n", frS_addr, d_simm16, rA_addr); @@ -4217,24 +4223,24 @@ static Bool dis_fp_store ( UInt theInstr ) } switch(opc2) { - case 0x297: // stfsx (Store Float Single Indexed, PPC32 p521) - DIP("stfsx fr%d,r%d,r%d\n", frS_addr, rA_addr, rB_addr); - assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA_or_0)) ); - storeBE( mkexpr(EA), - binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) ); - break; - -//zz case 0x2B7: // stfsux (Store Float Single with Update Indexed, PPC32 p520) -//zz if (rA_addr == 0) { -//zz vex_printf("dis_fp_store(PPC32)(instr,stfsux)\n"); -//zz return False; -//zz } -//zz DIP("stfsux fr%d,r%d,r%d\n", frS_addr, rA_addr, rB_addr); -//zz assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA)) ); -//zz storeBE( mkexpr(EA), -//zz binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) ); -//zz putIReg( rA_addr, mkexpr(EA) ); -//zz break; + case 0x297: // stfsx (Store Float Single Indexed, PPC32 p521) + DIP("stfsx fr%u,r%u,r%u\n", frS_addr, rA_addr, rB_addr); + assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA_or_0)) ); + storeBE( mkexpr(EA), + binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) ); + break; + + case 0x2B7: // stfsux (Store Float Single with Update Indexed, PPC32 p520) + if (rA_addr == 0) { + vex_printf("dis_fp_store(PPC32)(instr,stfsux)\n"); + return False; + } + DIP("stfsux fr%u,r%u,r%u\n", frS_addr, rA_addr, rB_addr); + assign( EA, binop(Iop_Add32, mkexpr(rB), mkexpr(rA)) ); + storeBE( mkexpr(EA), + binop(Iop_F64toF32, get_roundingmode(), mkexpr(frS)) ); + putIReg( rA_addr, mkexpr(EA) ); + break; case 0x2D7: // stfdx (Store Float Double Indexed, PPC32 p516) DIP("stfdx fr%d,r%d,r%d\n", frS_addr, rA_addr, rB_addr);