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(...) */
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)");
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;