|
From: <sv...@va...> - 2012-12-17 21:55:33
|
sewardj 2012-12-17 21:55:21 +0000 (Mon, 17 Dec 2012)
New Revision: 2595
Log:
ARM back end: handle IRDefaults in dirty helper calls.
Modified files:
branches/COMEM/priv/host_arm_defs.c
branches/COMEM/priv/host_arm_defs.h
branches/COMEM/priv/host_arm_isel.c
Modified: branches/COMEM/priv/host_arm_isel.c (+7 -6)
===================================================================
--- branches/COMEM/priv/host_arm_isel.c 2012-12-17 21:54:10 +00:00 (rev 2594)
+++ branches/COMEM/priv/host_arm_isel.c 2012-12-17 21:55:21 +00:00 (rev 2595)
@@ -379,7 +379,7 @@
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 @@
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 @@
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 @@
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 @@
/* 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 @@
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: */
Modified: branches/COMEM/priv/host_arm_defs.h (+2 -1)
===================================================================
--- branches/COMEM/priv/host_arm_defs.h 2012-12-17 21:54:10 +00:00 (rev 2594)
+++ branches/COMEM/priv/host_arm_defs.h 2012-12-17 21:55:21 +00:00 (rev 2595)
@@ -725,6 +725,7 @@
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 @@
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 );
Modified: branches/COMEM/priv/host_arm_defs.c (+37 -9)
===================================================================
--- branches/COMEM/priv/host_arm_defs.c 2012-12-17 21:54:10 +00:00 (rev 2594)
+++ branches/COMEM/priv/host_arm_defs.c 2012-12-17 21:55:21 +00:00 (rev 2595)
@@ -1227,13 +1227,14 @@
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 @@
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 @@
// 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 @@
= 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);
}
|