From: Julian Seward Date: Mon, 17 Dec 2012 21:55:21 +0000 (+0000) Subject: ARM back end: handle IRDefaults in dirty helper calls. X-Git-Tag: svn/VALGRIND_3_9_0^2~152^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=651e0774348a6c112b8817af239baf348e3ae9fb;p=thirdparty%2Fvalgrind.git ARM back end: handle IRDefaults in dirty helper calls. git-svn-id: svn://svn.valgrind.org/vex/branches/COMEM@2595 --- diff --git a/VEX/priv/host_arm_defs.c b/VEX/priv/host_arm_defs.c index 28808a5ab6..44cefaba5d 100644 --- a/VEX/priv/host_arm_defs.c +++ b/VEX/priv/host_arm_defs.c @@ -1227,13 +1227,14 @@ ARMInstr* ARMInstr_CMov ( ARMCondCode cond, HReg dst, ARMRI84* src ) { return i; } ARMInstr* ARMInstr_Call ( ARMCondCode cond, HWord target, Int nArgRegs, - RetLoc rloc ) { + RetLoc rloc, IRDefault dflt ) { ARMInstr* i = LibVEX_Alloc(sizeof(ARMInstr)); i->tag = ARMin_Call; i->ARMin.Call.cond = cond; i->ARMin.Call.target = target; i->ARMin.Call.nArgRegs = nArgRegs; i->ARMin.Call.rloc = rloc; + i->ARMin.Call.dflt = dflt; vassert(rloc != RetLocINVALID); return i; } @@ -1689,6 +1690,10 @@ void ppARMInstr ( ARMInstr* i ) { vex_printf("0x%lx [nArgRegs=%d, ", i->ARMin.Call.target, i->ARMin.Call.nArgRegs); ppRetLoc(i->ARMin.Call.rloc); + if (i->ARMin.Call.dflt != Idflt_None) { + vex_printf(", "); + ppIRDefault(i->ARMin.Call.dflt); + } vex_printf("]"); return; case ARMin_Mul: @@ -3388,10 +3393,16 @@ Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc, // preElse: // b after: // else: - // mvn r0, #0 // possibly - // mvn r1, #0 // possibly + // {mov,mvn} r0, #0 // possibly + // {mov,mvn} r1, #0 // possibly // after: + /* Since we're generating default-return code in the else: + clause, there had better be a sane default-value + specification. */ + vassert(i->ARMin.Call.dflt == Idflt_Zeroes + || i->ARMin.Call.dflt == Idflt_Ones); + // before: UInt* pBefore = p; @@ -3421,16 +3432,33 @@ Int emit_ARMInstr ( /*MB_MOD*/Bool* is_profInc, = XX______(1 ^ i->ARMin.Call.cond, X1010) | (delta & 0xFFFFFF); /* Do the 'else' actions */ + /* Useful: + e3a00000 mov r0, #0 + e3a01000 mov r1, #0 + e3e00000 mvn r0, #0 + e3e01000 mvn r1, #0 + */ switch (i->ARMin.Call.rloc) { - case RetLocInt: - *p++ = 0xE3E00000; break; // mvn r0, #0 - case RetLoc2Int: - // mvn r0, #0 ; mvn r1, #0 - vassert(0); //ATC - *p++ = 0xE3E00000; *p++ = 0xE3E01000; break; + case RetLocInt: { + switch (i->ARMin.Call.dflt) { + case Idflt_Ones: *p++ = 0xE3E00000; break; // mvn r0, #0 + case Idflt_Zeroes: *p++ = 0xE3A00000; break; // mov r0, #0 + default: goto elsefail; + } + break; + } + case RetLoc2Int: { + if (i->ARMin.Call.dflt == Idflt_Ones) { + // mvn r0, #0 ; mvn r1, #0 + vassert(0); //ATC + *p++ = 0xE3E00000; *p++ = 0xE3E01000; break; + } + goto elsefail; + } case RetLocNone: case RetLocINVALID: default: + elsefail: vassert(0); } diff --git a/VEX/priv/host_arm_defs.h b/VEX/priv/host_arm_defs.h index 6f780334ea..4341b3422e 100644 --- a/VEX/priv/host_arm_defs.h +++ b/VEX/priv/host_arm_defs.h @@ -725,6 +725,7 @@ typedef HWord target; Int nArgRegs; /* # regs carrying args: 0 .. 4 */ RetLoc rloc; /* where the return value will be */ + IRDefault dflt; /* default return, if conditional */ } Call; /* (PLAIN) 32 * 32 -> 32: r0 = r2 * r3 (ZX) 32 *u 32 -> 64: r1:r0 = r2 *u r3 @@ -970,7 +971,7 @@ extern ARMInstr* ARMInstr_XAssisted ( HReg dstGA, ARMAMode1* amR15T, ARMCondCode cond, IRJumpKind jk ); extern ARMInstr* ARMInstr_CMov ( ARMCondCode, HReg dst, ARMRI84* src ); extern ARMInstr* ARMInstr_Call ( ARMCondCode, HWord, Int nArgRegs, - RetLoc rloc ); + RetLoc rloc, IRDefault dflt ); extern ARMInstr* ARMInstr_Mul ( ARMMulOp op ); extern ARMInstr* ARMInstr_LdrEX ( Int szB ); extern ARMInstr* ARMInstr_StrEX ( Int szB ); diff --git a/VEX/priv/host_arm_isel.c b/VEX/priv/host_arm_isel.c index 31375af902..f9939441df 100644 --- a/VEX/priv/host_arm_isel.c +++ b/VEX/priv/host_arm_isel.c @@ -379,7 +379,7 @@ static Bool doHelperCall ( ISelEnv* env, Bool passBBP, IRExpr* guard, IRCallee* cee, IRExpr** args, - RetLoc rloc ) + RetLoc rloc, IRDefault dflt ) { ARMCondCode cc; HReg argregs[ARM_N_ARGREGS]; @@ -616,7 +616,7 @@ Bool doHelperCall ( ISelEnv* env, values. But that's too much hassle. */ /* Finally, the call itself. */ - addInstr(env, ARMInstr_Call( cc, target, nextArgReg, rloc )); + addInstr(env, ARMInstr_Call( cc, target, nextArgReg, rloc, dflt )); return True; /* success */ } @@ -1371,7 +1371,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) addInstr(env, mk_iMOVds_RR(hregARM_R0(), regL)); addInstr(env, mk_iMOVds_RR(hregARM_R1(), regR)); addInstr(env, ARMInstr_Call( ARMcc_AL, (HWord)Ptr_to_ULong(fn), - 2, RetLocInt )); + 2, RetLocInt, Idflt_None )); addInstr(env, mk_iMOVds_RR(res, hregARM_R0())); return res; } @@ -1659,7 +1659,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) HReg res = newVRegI(env); addInstr(env, mk_iMOVds_RR(hregARM_R0(), arg)); addInstr(env, ARMInstr_Call( ARMcc_AL, (HWord)Ptr_to_ULong(fn), - 1, RetLocInt )); + 1, RetLocInt, Idflt_None )); addInstr(env, mk_iMOVds_RR(res, hregARM_R0())); return res; } @@ -1722,7 +1722,7 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) /* Marshal args, do the call, clear stack. */ Bool ok = doHelperCall( env, False, NULL, e->Iex.CCall.cee, e->Iex.CCall.args, - RetLocInt ); + RetLocInt, Idflt_None ); if (ok) { addInstr(env, mk_iMOVds_RR(dst, hregARM_R0())); return dst; @@ -5929,7 +5929,8 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) if (rloc == RetLocINVALID) break; /* will go to stmt_fail: */ - Bool ok = doHelperCall( env, passBBP, d->guard, d->cee, d->args, rloc ); + Bool ok = doHelperCall( env, passBBP, d->guard, d->cee, d->args, + rloc, d->dflt ); if (!ok) break; /* will go to stmt_fail: */