From: Petar Jovanovic Date: Mon, 13 Feb 2017 16:15:24 +0000 (+0000) Subject: mips64: do correct 32-bit comparison for Iop_CmpNE32 X-Git-Tag: svn/VALGRIND_3_13_0^2~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=81f3356be7bcb47d269f6a2d416536a46c88a0cc;p=thirdparty%2Fvalgrind.git mips64: do correct 32-bit comparison for Iop_CmpNE32 Make sure that we take into account 32-bit size of values in comparison on MIPS64-platforms. This is done either by sign extending these values before comparison or sign extending xored values (depending on what comparison we do). This should avoid false-positives like the one reported in BZ #341481. Patch based on code provided by Crestez Dan Leonard and Tamara Vlahovic. git-svn-id: svn://svn.valgrind.org/vex/trunk@3304 --- diff --git a/VEX/priv/host_mips_defs.c b/VEX/priv/host_mips_defs.c index ce202d121c..ac5b9a74b3 100644 --- a/VEX/priv/host_mips_defs.c +++ b/VEX/priv/host_mips_defs.c @@ -1584,8 +1584,15 @@ void getRegUsage_MIPSInstr(HRegUsage * u, const MIPSInstr * i, Bool mode64) addHRegUse(u, HRmWrite, i->Min.Shft.dst); return; case Min_Cmp: - addHRegUse(u, HRmRead, i->Min.Cmp.srcL); - addHRegUse(u, HRmRead, i->Min.Cmp.srcR); + if (i->Min.Cmp.sz32 && mode64 && + (i->Min.Cmp.cond != MIPScc_EQ) && + (i->Min.Cmp.cond != MIPScc_NE)) { + addHRegUse(u, HRmModify, i->Min.Cmp.srcL); + addHRegUse(u, HRmModify, i->Min.Cmp.srcR); + } else { + addHRegUse(u, HRmRead, i->Min.Cmp.srcL); + addHRegUse(u, HRmRead, i->Min.Cmp.srcR); + } addHRegUse(u, HRmWrite, i->Min.Cmp.dst); return; case Min_Unary: @@ -2754,35 +2761,68 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc, UInt r_srcL = iregNo(i->Min.Cmp.srcL, mode64); UInt r_srcR = iregNo(i->Min.Cmp.srcR, mode64); UInt r_dst = iregNo(i->Min.Cmp.dst, mode64); + Bool sz32 = i->Min.Cmp.sz32; switch (i->Min.Cmp.cond) { case MIPScc_EQ: /* xor r_dst, r_srcL, r_srcR sltiu r_dst, r_dst, 1 */ p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 38); + if (mode64 && sz32) { + /* sll r_dst, r_dst, 0 */ + p = mkFormS(p, 0, r_dst, 0, r_dst, 0, 0); + } p = mkFormI(p, 11, r_dst, r_dst, 1); break; case MIPScc_NE: /* xor r_dst, r_srcL, r_srcR sltu r_dst, zero, r_dst */ p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 38); + if (mode64 && sz32) { + /* sll r_dst, r_dst, 0 */ + p = mkFormS(p, 0, r_dst, 0, r_dst, 0, 0); + } p = mkFormR(p, 0, 0, r_dst, r_dst, 0, 43); break; case MIPScc_LT: + if (mode64 && sz32) { + /* sll r_srcL, r_srcL, 0 + sll r_srcR, r_srcR, 0 */ + p = mkFormS(p, 0, r_srcL, 0, r_srcL, 0, 0); + p = mkFormS(p, 0, r_srcR, 0, r_srcR, 0, 0); + } /* slt r_dst, r_srcL, r_srcR */ p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 42); break; case MIPScc_LO: + if (mode64 && sz32) { + /* sll r_srcL, r_srcL, 0 + sll r_srcR, r_srcR, 0 */ + p = mkFormS(p, 0, r_srcL, 0, r_srcL, 0, 0); + p = mkFormS(p, 0, r_srcR, 0, r_srcR, 0, 0); + } /* sltu r_dst, r_srcL, r_srcR */ p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 43); break; case MIPScc_LE: + if (mode64 && sz32) { + /* sll r_srcL, r_srcL, 0 + sll r_srcR, r_srcR, 0 */ + p = mkFormS(p, 0, r_srcL, 0, r_srcL, 0, 0); + p = mkFormS(p, 0, r_srcR, 0, r_srcR, 0, 0); + } /* slt r_dst, r_srcR, r_srcL xori r_dst, r_dst, 1 */ p = mkFormR(p, 0, r_srcR, r_srcL, r_dst, 0, 42); p = mkFormI(p, 14, r_dst, r_dst, 1); break; case MIPScc_LS: + if (mode64 && sz32) { + /* sll r_srcL, r_srcL, 0 + sll r_srcR, r_srcR, 0 */ + p = mkFormS(p, 0, r_srcL, 0, r_srcL, 0, 0); + p = mkFormS(p, 0, r_srcR, 0, r_srcR, 0, 0); + } /* sltu r_dst, rsrcR, r_srcL xori r_dsr, r_dst, 1 */ p = mkFormR(p, 0, r_srcR, r_srcL, r_dst, 0, 43); diff --git a/VEX/priv/host_mips_isel.c b/VEX/priv/host_mips_isel.c index 9e44dd4407..aa72318941 100644 --- a/VEX/priv/host_mips_isel.c +++ b/VEX/priv/host_mips_isel.c @@ -1000,7 +1000,7 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) break; case Iop_CmpNE64: cc = MIPScc_NE; - size32 = True; + size32 = False; break; case Iop_CmpLT32S: cc = MIPScc_LT; @@ -2080,7 +2080,7 @@ static MIPSCondCode iselCondCode_wrk(ISelEnv * env, IRExpr * e) break; case Iop_CmpNE64: cc = MIPScc_NE; - size32 = True; + size32 = False; break; case Iop_CmpLT32S: cc = MIPScc_LT;