aboutsummaryrefslogtreecommitdiff
path: root/main/VEX/priv/host_arm_isel.c
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2013-02-05 12:28:19 -0800
committerBen Cheng <bccheng@google.com>2013-02-05 12:33:33 -0800
commit6d67c5925dfb5eae9a15380403fa2a81e18a91ea (patch)
tree476ab9f3ab609c3c806232d12c76fc13ebe929a8 /main/VEX/priv/host_arm_isel.c
parent0545291109e6df688a3bae37e0de494f044a81ed (diff)
downloadvalgrind-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.c15
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));