diff options
author | Ben Cheng <bccheng@google.com> | 2013-02-05 12:28:19 -0800 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2013-02-05 12:33:33 -0800 |
commit | 6d67c5925dfb5eae9a15380403fa2a81e18a91ea (patch) | |
tree | 476ab9f3ab609c3c806232d12c76fc13ebe929a8 /main/VEX/priv/host_arm_isel.c | |
parent | 0545291109e6df688a3bae37e0de494f044a81ed (diff) | |
download | valgrind-6d67c5925dfb5eae9a15380403fa2a81e18a91ea.tar.gz |
Add support for integer divide (sdiv and udiv) instructions.
With this patch Valgrind is working again on master with GCC 4.7 plus
-cpu=cortex-a15.
Change-Id: I4557b8a522c228e378fa8027358e57ed5ab3784f
Diffstat (limited to 'main/VEX/priv/host_arm_isel.c')
-rw-r--r-- | main/VEX/priv/host_arm_isel.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/main/VEX/priv/host_arm_isel.c b/main/VEX/priv/host_arm_isel.c index 62739fdd2..13c1f2d8c 100644 --- a/main/VEX/priv/host_arm_isel.c +++ b/main/VEX/priv/host_arm_isel.c @@ -1193,6 +1193,19 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) default: break; } + /* SDIV/UDIV */ + if (e->Iex.Binop.op == Iop_DivU32 || e->Iex.Binop.op == Iop_DivS32) { + HReg dst = newVRegI(env); + HReg argL = iselIntExpr_R(env, e->Iex.Binop.arg1); + HReg argR = iselIntExpr_R(env, e->Iex.Binop.arg2); + + addInstr(env, + ARMInstr_Div(e->Iex.Binop.op == Iop_DivU32 ? + ARMdiv_U : ARMdiv_S, + dst, argL, argR)); + return dst; + } + /* SHL/SHR/SAR */ switch (e->Iex.Binop.op) { case Iop_Shl32: sop = ARMsh_SHL; goto sh_binop; @@ -1889,7 +1902,7 @@ static void iselInt64Expr_wrk ( HReg* rHi, HReg* rLo, ISelEnv* env, IRExpr* e ) HReg argR = iselIntExpr_R(env, e->Iex.Binop.arg2); HReg tHi = newVRegI(env); HReg tLo = newVRegI(env); - ARMMulOp mop = e->Iex.Binop.op == Iop_MullS32 + ARMMulDivOp mop = e->Iex.Binop.op == Iop_MullS32 ? ARMmul_SX : ARMmul_ZX; addInstr(env, mk_iMOVds_RR(hregARM_R2(), argL)); addInstr(env, mk_iMOVds_RR(hregARM_R3(), argR)); |