From: Florian Krohm Date: Mon, 20 Aug 2012 13:44:29 +0000 (+0000) Subject: Fix insn selection for Iop_Shr8/16 and Iop_Sar8/16 on s390. X-Git-Tag: svn/VALGRIND_3_9_0^2~289 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d32f1d592f84c128a4b131598fac44eb0f94cab7;p=thirdparty%2Fvalgrind.git Fix insn selection for Iop_Shr8/16 and Iop_Sar8/16 on s390. git-svn-id: svn://svn.valgrind.org/vex/trunk@2472 --- diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index 6d019713ba..237b755f65 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -1105,7 +1105,28 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) h1 = s390_isel_int_expr(env, arg1); /* Process 1st operand */ op2 = s390_isel_int_expr_RMI(env, arg2); /* Process 2nd operand */ res = newVRegI(env); - addInstr(env, s390_insn_move(size, res, h1)); + + /* As right shifts of one/two byte opreands are implemented using a + 4-byte shift op, we first need to zero/sign-extend the shiftee. */ + switch (expr->Iex.Binop.op) { + case Iop_Shr8: + insn = s390_insn_unop(4, S390_ZERO_EXTEND_8, res, s390_opnd_reg(h1)); + break; + case Iop_Shr16: + insn = s390_insn_unop(4, S390_ZERO_EXTEND_16, res, s390_opnd_reg(h1)); + break; + case Iop_Sar8: + insn = s390_insn_unop(4, S390_SIGN_EXTEND_8, res, s390_opnd_reg(h1)); + break; + case Iop_Sar16: + insn = s390_insn_unop(4, S390_SIGN_EXTEND_16, res, s390_opnd_reg(h1)); + break; + default: + insn = s390_insn_move(size, res, h1); + break; + } + addInstr(env, insn); + insn = s390_insn_alu(size, opkind, res, op2); addInstr(env, insn);