|
From: <sv...@va...> - 2013-01-16 14:56:17
|
sewardj 2013-01-16 14:56:06 +0000 (Wed, 16 Jan 2013)
New Revision: 2639
Log:
ppc32/64 equivalents to r2636: fix up the ppc back end to be in sync
with infrastructural changes w.r.t. conditional dirty helpers that
return values. Does not actually handle such cases since the ppc
front end does not generate them.
Modified files:
branches/COMEM/priv/host_ppc_defs.c
branches/COMEM/priv/host_ppc_defs.h
branches/COMEM/priv/host_ppc_isel.c
Modified: branches/COMEM/priv/host_ppc_isel.c (+48 -13)
===================================================================
--- branches/COMEM/priv/host_ppc_isel.c 2013-01-16 09:29:37 +00:00 (rev 2638)
+++ branches/COMEM/priv/host_ppc_isel.c 2013-01-16 14:56:06 +00:00 (rev 2639)
@@ -1,5 +1,4 @@
-
/*---------------------------------------------------------------*/
/*--- begin host_ppc_isel.c ---*/
/*---------------------------------------------------------------*/
@@ -672,7 +671,8 @@
static
void doHelperCall ( ISelEnv* env,
Bool passBBP,
- IRExpr* guard, IRCallee* cee, IRExpr** args )
+ IRExpr* guard, IRCallee* cee, IRExpr** args,
+ RetLoc rloc )
{
PPCCondCode cc;
HReg argregs[PPC_N_REGPARMS];
@@ -902,7 +902,7 @@
toUInt(Ptr_to_ULong(cee->addr));
/* Finally, the call itself. */
- addInstr(env, PPCInstr_Call( cc, (Addr64)target, argiregs ));
+ addInstr(env, PPCInstr_Call( cc, (Addr64)target, argiregs, rloc ));
}
@@ -2008,6 +2008,9 @@
break;
case Iop_BCDtoDPB: {
+ /* the following is only valid in 64 bit mode */
+ if (!mode64) break;
+
PPCCondCode cc;
UInt argiregs;
HReg argregs[1];
@@ -2026,13 +2029,17 @@
cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
fdescr = (HWord*)h_BCDtoDPB;
- addInstr(env, PPCInstr_Call( cc, (Addr64)(fdescr[0]), argiregs ) );
+ addInstr(env, PPCInstr_Call( cc, (Addr64)(fdescr[0]),
+ argiregs, RetLocInt) );
addInstr(env, mk_iMOVds_RR(r_dst, argregs[0]));
return r_dst;
}
case Iop_DPBtoBCD: {
+ /* the following is only valid in 64 bit mode */
+ if (!mode64) break;
+
PPCCondCode cc;
UInt argiregs;
HReg argregs[1];
@@ -2051,7 +2058,8 @@
cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
fdescr = (HWord*)h_DPBtoBCD;
- addInstr(env, PPCInstr_Call( cc, (Addr64)(fdescr[0]), argiregs ) );
+ addInstr(env, PPCInstr_Call( cc, (Addr64)(fdescr[0]),
+ argiregs, RetLocInt ) );
addInstr(env, mk_iMOVds_RR(r_dst, argregs[0]));
return r_dst;
@@ -2100,14 +2108,15 @@
HReg r_dst = newVRegI(env);
vassert(ty == Ity_I32);
- /* be very restrictive for now. Only 32/64-bit ints allowed
- for args, and 32 bits for return type. */
+ /* be very restrictive for now. Only 32/64-bit ints allowed for
+ args, and 32 bits for return type. Don't forget to change +
+ the RetLoc if more return types are allowed in future. */
if (e->Iex.CCall.retty != Ity_I32)
goto irreducible;
/* Marshal args, do the call, clear stack. */
doHelperCall( env, False, NULL,
- e->Iex.CCall.cee, e->Iex.CCall.args );
+ e->Iex.CCall.cee, e->Iex.CCall.args, RetLocInt );
/* GPR3 now holds the destination address from Pin_Goto */
addInstr(env, mk_iMOVds_RR(r_dst, hregPPC_GPR3(mode64)));
@@ -3262,7 +3271,8 @@
cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE );
target = toUInt( Ptr_to_ULong(h_BCDtoDPB ) );
- addInstr( env, PPCInstr_Call( cc, (Addr64)target, argiregs ) );
+ addInstr( env, PPCInstr_Call( cc, (Addr64)target,
+ argiregs, RetLoc2Int ) );
addInstr( env, mk_iMOVds_RR( tHi, argregs[argreg-1] ) );
addInstr( env, mk_iMOVds_RR( tLo, argregs[argreg] ) );
@@ -3301,7 +3311,8 @@
target = toUInt( Ptr_to_ULong( h_DPBtoBCD ) );
- addInstr(env, PPCInstr_Call( cc, (Addr64)target, argiregs ) );
+ addInstr(env, PPCInstr_Call( cc, (Addr64)target,
+ argiregs, RetLoc2Int ) );
addInstr(env, mk_iMOVds_RR(tHi, argregs[argreg-1]));
addInstr(env, mk_iMOVds_RR(tLo, argregs[argreg]));
@@ -4973,7 +4984,6 @@
/* --------- Call to DIRTY helper --------- */
case Ist_Dirty: {
- IRType retty;
IRDirty* d = stmt->Ist.Dirty.details;
Bool passBBP = False;
@@ -4981,15 +4991,38 @@
vassert(!d->needsBBP);
passBBP = toBool(d->nFxState > 0 && d->needsBBP);
+ /* Figure out the return type, if any. */
+ IRType retty = Ity_INVALID;
+ if (d->tmp != IRTemp_INVALID)
+ retty = typeOfIRTemp(env->type_env, d->tmp);
+
+ /* Marshal args, do the call, clear stack, set the return value
+ to 0x555..555 if this is a conditional call that returns a
+ value and the call is skipped. We need to set the ret-loc
+ correctly in order to implement the IRDirty semantics that
+ the return value is 0x555..555 if the call doesn't happen. */
+ RetLoc rloc = RetLocINVALID;
+ switch (retty) {
+ case Ity_INVALID: /* function doesn't return anything */
+ rloc = RetLocNone; break;
+ case Ity_I64:
+ rloc = mode64 ? RetLocInt : RetLoc2Int; break;
+ case Ity_I32: case Ity_I16: case Ity_I8:
+ rloc = RetLocInt; break;
+ default:
+ break;
+ }
+ if (rloc == RetLocINVALID)
+ break; /* will go to stmt_fail: */
+
/* Marshal args, do the call, clear stack. */
- doHelperCall( env, passBBP, d->guard, d->cee, d->args );
+ doHelperCall( env, passBBP, d->guard, d->cee, d->args, rloc );
/* Now figure out what to do with the returned value, if any. */
if (d->tmp == IRTemp_INVALID)
/* No return value. Nothing to do. */
return;
- retty = typeOfIRTemp(env->type_env, d->tmp);
if (!mode64 && retty == Ity_I64) {
HReg r_dstHi, r_dstLo;
/* The returned value is in %r3:%r4. Park it in the
@@ -4997,6 +5030,7 @@
lookupIRTempPair( &r_dstHi, &r_dstLo, env, d->tmp);
addInstr(env, mk_iMOVds_RR(r_dstHi, hregPPC_GPR3(mode64)));
addInstr(env, mk_iMOVds_RR(r_dstLo, hregPPC_GPR4(mode64)));
+ vassert(rloc == RetLoc2Int);
return;
}
if (retty == Ity_I8 || retty == Ity_I16 ||
@@ -5005,6 +5039,7 @@
associated with tmp. */
HReg r_dst = lookupIRTemp(env, d->tmp);
addInstr(env, mk_iMOVds_RR(r_dst, hregPPC_GPR3(mode64)));
+ vassert(rloc == RetLocInt);
return;
}
break;
Modified: branches/COMEM/priv/host_ppc_defs.h (+2 -1)
===================================================================
--- branches/COMEM/priv/host_ppc_defs.h 2013-01-16 09:29:37 +00:00 (rev 2638)
+++ branches/COMEM/priv/host_ppc_defs.h 2013-01-16 14:56:06 +00:00 (rev 2639)
@@ -616,6 +616,7 @@
PPCCondCode cond;
Addr64 target;
UInt argiregs;
+ RetLoc rloc; /* where the return value will be */
} Call;
/* Update the guest CIA value, then exit requesting to chain
to it. May be conditional. Use of Addr64 in order to cope
@@ -971,7 +972,7 @@
extern PPCInstr* PPCInstr_Unary ( PPCUnaryOp op, HReg dst, HReg src );
extern PPCInstr* PPCInstr_MulL ( Bool syned, Bool hi32, Bool sz32, HReg, HReg, HReg );
extern PPCInstr* PPCInstr_Div ( Bool extended, Bool syned, Bool sz32, HReg dst, HReg srcL, HReg srcR );
-extern PPCInstr* PPCInstr_Call ( PPCCondCode, Addr64, UInt );
+extern PPCInstr* PPCInstr_Call ( PPCCondCode, Addr64, UInt, RetLoc );
extern PPCInstr* PPCInstr_XDirect ( Addr64 dstGA, PPCAMode* amCIA,
PPCCondCode cond, Bool toFastEP );
extern PPCInstr* PPCInstr_XIndir ( HReg dstGA, PPCAMode* amCIA,
Modified: branches/COMEM/priv/host_ppc_defs.c (+15 -1)
===================================================================
--- branches/COMEM/priv/host_ppc_defs.c 2013-01-16 09:29:37 +00:00 (rev 2638)
+++ branches/COMEM/priv/host_ppc_defs.c 2013-01-16 14:56:06 +00:00 (rev 2639)
@@ -839,16 +839,18 @@
return i;
}
PPCInstr* PPCInstr_Call ( PPCCondCode cond,
- Addr64 target, UInt argiregs ) {
+ Addr64 target, UInt argiregs, RetLoc rloc ) {
UInt mask;
PPCInstr* i = LibVEX_Alloc(sizeof(PPCInstr));
i->tag = Pin_Call;
i->Pin.Call.cond = cond;
i->Pin.Call.target = target;
i->Pin.Call.argiregs = argiregs;
+ i->Pin.Call.rloc = rloc;
/* Only r3 .. r10 inclusive may be used as arg regs. Hence: */
mask = (1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10);
vassert(0 == (argiregs & ~mask));
+ vassert(rloc != RetLocINVALID);
return i;
}
PPCInstr* PPCInstr_XDirect ( Addr64 dstGA, PPCAMode* amCIA,
@@ -1553,6 +1555,8 @@
vex_printf(",");
}
}
+ vex_printf(",");
+ ppRetLoc(i->Pin.Call.rloc);
vex_printf("] }");
break;
}
@@ -3908,6 +3912,16 @@
}
case Pin_Call: {
+ if (i->Pin.Call.cond.test != Pct_ALWAYS
+ && i->Pin.Call.rloc != RetLocNone) {
+ /* The call might not happen (it isn't unconditional) and it
+ returns a result. In this case we will need to generate a
+ control flow diamond to put 0x555..555 in the return
+ register(s) in the case where the call doesn't happen. If
+ this ever becomes necessary, maybe copy code from the ARM
+ equivalent. Until that day, just give up. */
+ goto bad;
+ }
PPCCondCode cond = i->Pin.Call.cond;
UInt r_dst = 10;
/* As per detailed comment for Pin_Call in
|