From: Petar Jovanovic Date: Wed, 12 Oct 2016 15:25:45 +0000 (+0000) Subject: mips: fix incorrect implementation of luxc1/suxc1 instructions X-Git-Tag: svn/VALGRIND_3_12_0^2~7^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=09a66070f99f38d2f503652f803b801a21bc33d6;p=thirdparty%2Fvalgrind.git mips: fix incorrect implementation of luxc1/suxc1 instructions Support correct execution of luxc1 and suxc1 instructions on MIPS32 and MIPS64 platforms with the respect for FPU mode. Patch by Aleksandra Karadzic. git-svn-id: svn://svn.valgrind.org/vex/trunk@3262 --- diff --git a/VEX/priv/guest_mips_toIR.c b/VEX/priv/guest_mips_toIR.c index 2d0a2df162..f1d5754336 100644 --- a/VEX/priv/guest_mips_toIR.c +++ b/VEX/priv/guest_mips_toIR.c @@ -13530,14 +13530,22 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, } case 0x5: /* Load Doubleword Indexed Unaligned to Floating Point - LUXC1; - MIPS32r2 */ + MIPS32r2 and MIPS64 */ DIP("luxc1 f%u, r%u(r%u)", fd, rt, rs); - t0 = newTemp(Ity_I64); - t1 = newTemp(Ity_I64); - assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt))); - assign(t1, binop(Iop_And64, mkexpr(t0), - mkU64(0xfffffffffffffff8ULL))); - putFReg(fd, load(Ity_F64, mkexpr(t1))); + if ((mode64 || VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) + && fp_mode64) { + t0 = newTemp(ty); + t1 = newTemp(ty); + assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, + getIReg(rs), getIReg(rt))); + assign(t1, binop(mode64 ? Iop_Add64 : Iop_And32, + mkexpr(t0), + mode64 ? mkU64(0xfffffffffffffff8ULL) + : mkU32(0xfffffff8ULL))); + putFReg(fd, load(Ity_F64, mkexpr(t1))); + } else { + ILLEGAL_INSTRUCTON; + } break; case 0x8: { /* Store Word Indexed from Floating Point - SWXC1 */ @@ -13563,11 +13571,20 @@ static DisResult disInstr_MIPS_WRK ( Bool(*resteerOkFn) (/*opaque */void *, case 0xD: /* Store Doubleword Indexed Unaligned from Floating Point - SUXC1; MIPS64 MIPS32r2 */ DIP("suxc1 f%u, r%u(r%u)", fd, rt, rs); - t0 = newTemp(Ity_I64); - t1 = newTemp(Ity_I64); - assign(t0, binop(Iop_Add64, getIReg(rs), getIReg(rt))); - assign(t1, binop(Iop_And64, mkexpr(t0), mkU64(0xfffffffffffffff8ULL))); - store(mkexpr(t1), getFReg(fs)); + if ((mode64 || VEX_MIPS_CPU_HAS_MIPS32R2(archinfo->hwcaps)) + && fp_mode64) { + t0 = newTemp(ty); + t1 = newTemp(ty); + assign(t0, binop(mode64 ? Iop_Add64 : Iop_Add32, + getIReg(rs), getIReg(rt))); + assign(t1, binop(mode64 ? Iop_Add64 : Iop_And32, + mkexpr(t0), + mode64 ? mkU64(0xfffffffffffffff8ULL) + : mkU32(0xfffffff8ULL))); + store(mkexpr(t1), getFReg(fs)); + } else { + ILLEGAL_INSTRUCTON; + } break; case 0x0F: {