From: Julian Seward Date: Wed, 27 Nov 2019 07:52:45 +0000 (+0100) Subject: 'grail' fixes for ppc32 and ppc64: X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d072997a1dc701bb8c436a7181302d351cacd3c1;p=thirdparty%2Fvalgrind.git 'grail' fixes for ppc32 and ppc64: * do_minimal_initial_iropt_BB: for ppc64, flatten rather than assert flatness. (Kludge. Sigh.) * priv/host_ppc_isel.c iselCondCode_wrk(): handle And1 and Or1, the not-particularly-optimal way * priv/host_ppc_isel.c iselCondCode_wrk(): handle Ico_U1(0). --- diff --git a/VEX/priv/host_ppc_isel.c b/VEX/priv/host_ppc_isel.c index 5e2a3b80c8..9c954dafef 100644 --- a/VEX/priv/host_ppc_isel.c +++ b/VEX/priv/host_ppc_isel.c @@ -3095,13 +3095,15 @@ static PPCCondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e, vassert(typeOfIRExpr(env->type_env,e) == Ity_I1); /* Constant 1:Bit */ - if (e->tag == Iex_Const && e->Iex.Const.con->Ico.U1 == True) { - // Make a compare that will always be true: + if (e->tag == Iex_Const) { + // Make a compare that will always be true (or always false): + vassert(e->Iex.Const.con->Ico.U1 == True || e->Iex.Const.con->Ico.U1 == False); HReg r_zero = newVRegI(env); addInstr(env, PPCInstr_LI(r_zero, 0, env->mode64)); addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/, 7/*cr*/, r_zero, PPCRH_Reg(r_zero))); - return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ ); + return mk_PPCCondCode( e->Iex.Const.con->Ico.U1 ? Pct_TRUE : Pct_FALSE, + Pcf_7EQ ); } /* Not1(...) */ @@ -3260,6 +3262,29 @@ static PPCCondCode iselCondCode_wrk ( ISelEnv* env, const IRExpr* e, return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ ); } + /* --- And1(x,y), Or1(x,y) --- */ + /* FIXME: We could (and probably should) do a lot better here, by using the + iselCondCode_C/_R scheme used in the amd64 insn selector. */ + if (e->tag == Iex_Binop + && (e->Iex.Binop.op == Iop_And1 || e->Iex.Binop.op == Iop_Or1)) { + HReg x_as_int = newVRegI(env); + PPCCondCode cc_x = iselCondCode(env, e->Iex.Binop.arg1, IEndianess); + addInstr(env, PPCInstr_Set(cc_x, x_as_int)); + + HReg y_as_int = newVRegI(env); + PPCCondCode cc_y = iselCondCode(env, e->Iex.Binop.arg2, IEndianess); + addInstr(env, PPCInstr_Set(cc_y, y_as_int)); + + HReg tmp = newVRegI(env); + PPCAluOp op = e->Iex.Binop.op == Iop_And1 ? Palu_AND : Palu_OR; + addInstr(env, PPCInstr_Alu(op, tmp, x_as_int, PPCRH_Reg(y_as_int))); + + addInstr(env, PPCInstr_Alu(Palu_AND, tmp, tmp, PPCRH_Imm(False,1))); + addInstr(env, PPCInstr_Cmp(False/*unsigned*/, True/*32bit cmp*/, + 7/*cr*/, tmp, PPCRH_Imm(False,1))); + return mk_PPCCondCode( Pct_TRUE, Pcf_7EQ ); + } + vex_printf("iselCondCode(ppc): No such tag(%u)\n", e->tag); ppIRExpr(e); vpanic("iselCondCode(ppc)"); diff --git a/VEX/priv/ir_opt.c b/VEX/priv/ir_opt.c index 7f399244cc..c5b7a2feaa 100644 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@ -6682,7 +6682,16 @@ IRSB* do_iropt_BB( processed by do_minimal_initial_iropt_BB. And that will have flattened them out. */ // FIXME Remove this assertion once the 'grail' machinery seems stable - vassert(isFlatIRSB(bb0)); + // FIXME2 The TOC-redirect-hacks generators in m_translate.c -- gen_PUSH() + // and gen_PO() -- don't generate flat IR, and so cause this assertion + // to fail. For the time being, hack around this by flattening, + // rather than asserting for flatness, on the afflicted platforms. + // This is a kludge, yes. + if (guest_arch == VexArchPPC64) { + bb0 = flatten_BB(bb0); // Kludge! + } else { + vassert(isFlatIRSB(bb0)); // How it Really Should Be (tm). + } /* If at level 0, stop now. */ if (vex_control.iropt_level <= 0) return bb0;