From: Dejan Jevtic Date: Tue, 25 Feb 2014 15:25:49 +0000 (+0000) Subject: mips32: Fix the problem with the floating point compare instruction on mips32. X-Git-Tag: svn/VALGRIND_3_10_1^2~145 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=937cc6f674834b12dc9de8570f4e849ebbf34892;p=thirdparty%2Fvalgrind.git mips32: Fix the problem with the floating point compare instruction on mips32. This patch is fixing the problem with emitting Iop_CmpF64. Problem was introduced while running Valgrind for mips with v8 javascript engine. git-svn-id: svn://svn.valgrind.org/vex/trunk@2825 --- diff --git a/VEX/priv/guest_mips_toIR.c b/VEX/priv/guest_mips_toIR.c index 94ec293318..d95d58303e 100644 --- a/VEX/priv/guest_mips_toIR.c +++ b/VEX/priv/guest_mips_toIR.c @@ -1697,22 +1697,22 @@ static IROp mkSzOp ( IRType ty, IROp op8 ) static const HChar* showCondCode(UInt code) { const HChar* ret; switch (code) { - case 0: ret = "F"; break; - case 1: ret = "UN"; break; - case 2: ret = "EQ"; break; - case 3: ret = "UEQ"; break; - case 4: ret = "OLT"; break; - case 5: ret = "ULT"; break; - case 6: ret = "OLE"; break; - case 7: ret = "ULE"; break; - case 8: ret = "SF"; break; - case 9: ret = "NGLE"; break; - case 10: ret = "SEQ"; break; - case 11: ret = "NGL"; break; - case 12: ret = "LT"; break; - case 13: ret = "NGE"; break; - case 14: ret = "LE"; break; - case 15: ret = "NGT"; break; + case 0: ret = "f"; break; + case 1: ret = "un"; break; + case 2: ret = "eq"; break; + case 3: ret = "ueq"; break; + case 4: ret = "olt"; break; + case 5: ret = "ult"; break; + case 6: ret = "ole"; break; + case 7: ret = "ule"; break; + case 8: ret = "sf"; break; + case 9: ret = "ngle"; break; + case 10: ret = "seq"; break; + case 11: ret = "ngl"; break; + case 12: ret = "lt"; break; + case 13: ret = "nge"; break; + case 14: ret = "le"; break; + case 15: ret = "ngt"; break; default: vpanic("showCondCode"); break; } return ret; @@ -1733,7 +1733,7 @@ static Bool dis_instr_CCondFmt ( UInt cins ) UInt fpc_cc = get_fpc_cc(cins); switch (fmt) { case 0x10: { /* C.cond.S */ - DIP("C.%s.S %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft); + DIP("c.%s.s %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft); if (fp_mode64) { t0 = newTemp(Ity_I32); t1 = newTemp(Ity_I32); @@ -1942,7 +1942,7 @@ static Bool dis_instr_CCondFmt ( UInt cins ) break; case 0x11: { /* C.cond.D */ - DIP("C.%s.D %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft); + DIP("c.%s.d %d, f%d, f%d", showCondCode(cond), fpc_cc, fs, ft); t0 = newTemp(Ity_I32); t1 = newTemp(Ity_I32); t2 = newTemp(Ity_I32); diff --git a/VEX/priv/host_mips_defs.c b/VEX/priv/host_mips_defs.c index e708434228..2e34b99d2b 100644 --- a/VEX/priv/host_mips_defs.c +++ b/VEX/priv/host_mips_defs.c @@ -802,8 +802,17 @@ const HChar *showMIPSFpOp(MIPSFpOp op) case Mfp_CEILLD: ret = "ceil.l.d"; break; - case Mfp_CMP: - ret = "C.cond.d"; + case Mfp_CMP_UN: + ret = "c.un.d"; + break; + case Mfp_CMP_EQ: + ret = "c.eq.d"; + break; + case Mfp_CMP_LT: + ret = "c.lt.d"; + break; + case Mfp_CMP_NGT: + ret = "c.ngt.d"; break; default: vex_printf("Unknown op: %d", op); @@ -1503,8 +1512,7 @@ MIPSInstr *MIPSInstr_FpConvert(MIPSFpOp op, HReg dst, HReg src) } -MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL, HReg srcR, - UChar cond1) +MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL, HReg srcR) { MIPSInstr *i = LibVEX_Alloc(sizeof(MIPSInstr)); i->tag = Min_FpCompare; @@ -1512,7 +1520,6 @@ MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL, HReg srcR, i->Min.FpCompare.dst = dst; i->Min.FpCompare.srcL = srcL; i->Min.FpCompare.srcR = srcR; - i->Min.FpCompare.cond1 = cond1; return i; } @@ -1817,7 +1824,6 @@ void ppMIPSInstr(MIPSInstr * i, Bool mode64) ppHRegMIPS(i->Min.FpCompare.srcL, mode64); vex_printf(","); ppHRegMIPS(i->Min.FpCompare.srcR, mode64); - vex_printf(" cond: %c", i->Min.FpCompare.cond1); return; case Min_FpMulAcc: vex_printf("%s ", showMIPSFpOp(i->Min.FpMulAcc.op)); @@ -3983,19 +3989,35 @@ Int emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc, } case Min_FpCompare: { - UInt r_dst = iregNo(i->Min.FpCompare.dst, mode64); + UInt r_dst = iregNo(i->Min.FpCompare.dst, mode64); UInt fr_srcL = dregNo(i->Min.FpCompare.srcL); UInt fr_srcR = dregNo(i->Min.FpCompare.srcR); + UInt op; switch (i->Min.FpConvert.op) { - case Mfp_CMP: - p = mkFormR(p, 0x11, 0x11, fr_srcL, fr_srcR, 0, - (i->Min.FpCompare.cond1 + 48)); - p = mkFormR(p, 0x11, 0x2, r_dst, 31, 0, 0); + case Mfp_CMP_UN: + op = 1; + break; + case Mfp_CMP_EQ: + op = 2; + break; + case Mfp_CMP_LT: + op = 12; break; + case Mfp_CMP_NGT: + op = 15; + break; default: goto bad; } + /* c.cond.d fr_srcL, fr_srcR + cfc1 r_dst, $31 + srl r_dst, r_dst, 23 + andi r_dst, r_dst, 1 */ + p = mkFormR(p, 0x11, 0x11, fr_srcL, fr_srcR, 0, op + 48); + p = mkFormR(p, 0x11, 0x2, r_dst, 31, 0, 0); + p = mkFormS(p, 0, r_dst, 0, r_dst, 23, 2); + p = mkFormI(p, 12, r_dst, r_dst, 1); goto done; } diff --git a/VEX/priv/host_mips_defs.h b/VEX/priv/host_mips_defs.h index dceb892b98..cc2b48fc64 100644 --- a/VEX/priv/host_mips_defs.h +++ b/VEX/priv/host_mips_defs.h @@ -366,8 +366,11 @@ typedef enum { Mfp_CVTSD, Mfp_CVTSW, Mfp_CVTWD, Mfp_CVTWS, Mfp_CVTDL, Mfp_CVTSL, Mfp_CVTLS, Mfp_CVTLD, Mfp_TRULS, Mfp_TRULD, Mfp_TRUWS, Mfp_TRUWD, Mfp_FLOORWS, Mfp_FLOORWD, Mfp_ROUNDWS, Mfp_ROUNDWD, - Mfp_CVTDW, Mfp_CMP, Mfp_CEILWS, Mfp_CEILWD, Mfp_CEILLS, Mfp_CEILLD, - Mfp_CVTDS, Mfp_ROUNDLD, Mfp_FLOORLD + Mfp_CVTDW, Mfp_CEILWS, Mfp_CEILWD, Mfp_CEILLS, Mfp_CEILLD, Mfp_CVTDS, + Mfp_ROUNDLD, Mfp_FLOORLD, + + /* FP compare */ + Mfp_CMP_UN, Mfp_CMP_EQ, Mfp_CMP_LT, Mfp_CMP_NGT } MIPSFpOp; @@ -664,7 +667,7 @@ extern MIPSInstr *MIPSInstr_FpTernary ( MIPSFpOp op, HReg dst, HReg src1, HReg src2, HReg src3 ); extern MIPSInstr *MIPSInstr_FpConvert(MIPSFpOp op, HReg dst, HReg src); extern MIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL, - HReg srcR, UChar cond1); + HReg srcR); extern MIPSInstr *MIPSInstr_FpMulAcc(MIPSFpOp op, HReg dst, HReg srcML, HReg srcMR, HReg srcAcc); extern MIPSInstr *MIPSInstr_FpLdSt(Bool isLoad, UChar sz, HReg, MIPSAMode *); diff --git a/VEX/priv/host_mips_isel.c b/VEX/priv/host_mips_isel.c index 088b808c4a..735386ccb2 100644 --- a/VEX/priv/host_mips_isel.c +++ b/VEX/priv/host_mips_isel.c @@ -1123,29 +1123,24 @@ static HReg iselWordExpr_R_wrk(ISelEnv * env, IRExpr * e) /* Create in dst, the IRCmpF64Result encoded result. */ /* chech for EQ */ - addInstr(env, MIPSInstr_FpCompare(Mfp_CMP, tmp, r_srcL, r_srcR, - toUChar(2))); - addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, r_ccMIPS, tmp, - MIPSRH_Imm(False, 22))); + addInstr(env, MIPSInstr_FpCompare(Mfp_CMP_EQ, tmp, r_srcL, r_srcR)); + addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, r_ccMIPS, tmp, + MIPSRH_Imm(False, 1))); /* chech for UN */ - addInstr(env, MIPSInstr_FpCompare(Mfp_CMP, tmp, r_srcL, r_srcR, - toUChar(1))); - addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tmp, tmp, - MIPSRH_Imm(False, 23))); + addInstr(env, MIPSInstr_FpCompare(Mfp_CMP_UN, tmp, r_srcL, r_srcR)); addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccMIPS, r_ccMIPS, MIPSRH_Reg(tmp))); /* chech for LT */ - addInstr(env, MIPSInstr_FpCompare(Mfp_CMP, tmp, r_srcL, r_srcR, - toUChar(12))); - addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tmp, - tmp, MIPSRH_Imm(False, 21))); + addInstr(env, MIPSInstr_FpCompare(Mfp_CMP_LT, tmp, r_srcL, r_srcR)); + addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tmp, + tmp, MIPSRH_Imm(False, 2))); addInstr(env, MIPSInstr_Alu(Malu_OR, r_ccMIPS, r_ccMIPS, MIPSRH_Reg(tmp))); /* chech for GT */ - addInstr(env, MIPSInstr_FpCompare(Mfp_CMP, tmp, r_srcL, r_srcR, - toUChar(15))); - addInstr(env, MIPSInstr_Shft(Mshft_SRA, True, tmp, tmp, - MIPSRH_Imm(False, 20))); + addInstr(env, MIPSInstr_FpCompare(Mfp_CMP_NGT, + tmp, r_srcL, r_srcR)); + addInstr(env, MIPSInstr_Shft(Mshft_SLL, True, tmp, tmp, + MIPSRH_Imm(False, 3))); addInstr(env, MIPSInstr_Alu(Malu_NOR, tmp, tmp, MIPSRH_Reg(tmp))); addInstr(env, MIPSInstr_Alu(Malu_AND, tmp, tmp,