From ccde955892210881b70520764d5d4988a2a6556d Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Wed, 4 May 2011 09:50:48 +0000 Subject: [PATCH] Tighten up condition code handling in the back end, so as to placate IBM's BEAM checker. There is no error in the existing code. However BEAM doesn't know that when PPCCondCode::test == Pct_ALWAYS then the ::flag field is irrelevant, and so it believes it is being used uninitialised. Add a Pcf_NONE ::flag value for use in that case, and add assertions to match. (Untested!) git-svn-id: svn://svn.valgrind.org/vex/trunk@2144 --- VEX/priv/host_ppc_defs.c | 8 ++++++++ VEX/priv/host_ppc_defs.h | 9 +++++---- VEX/priv/host_ppc_isel.c | 4 ++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/VEX/priv/host_ppc_defs.c b/VEX/priv/host_ppc_defs.c index b0b9b08a76..2065824acf 100644 --- a/VEX/priv/host_ppc_defs.c +++ b/VEX/priv/host_ppc_defs.c @@ -286,6 +286,8 @@ HChar* showPPCCondCode ( PPCCondCode cond ) return (cond.test == Pct_TRUE) ? "cr7.gt=1" : "cr7.gt=0"; case Pcf_7LT: return (cond.test == Pct_TRUE) ? "cr7.lt=1" : "cr7.lt=0"; + case Pcf_NONE: + return "no-flag"; default: vpanic("ppPPCCondCode"); } } @@ -296,6 +298,11 @@ PPCCondCode mk_PPCCondCode ( PPCCondTest test, PPCCondFlag flag ) PPCCondCode cc; cc.flag = flag; cc.test = test; + if (test == Pct_ALWAYS) { + vassert(flag == Pcf_NONE); + } else { + vassert(flag != Pcf_NONE); + } return cc; } @@ -3152,6 +3159,7 @@ Int emit_PPCInstr ( UChar* buf, Int nbuf, PPCInstr* i, // Just load 1 to dst => li dst,1 p = mkFormD(p, 14, r_dst, 0, 1); } else { + vassert(cond.flag != Pcf_NONE); rot_imm = 1 + cond.flag; r_tmp = 0; // Not set in getAllocable, so no need to declare. diff --git a/VEX/priv/host_ppc_defs.h b/VEX/priv/host_ppc_defs.h index f93a2104c6..c2bde5cdd2 100644 --- a/VEX/priv/host_ppc_defs.h +++ b/VEX/priv/host_ppc_defs.h @@ -162,15 +162,16 @@ typedef Pcf_7LT = 28, /* neg | lt */ Pcf_7GT = 29, /* pos | gt */ Pcf_7EQ = 30, /* zero | equal */ - Pcf_7SO = 31 /* summary overflow */ + Pcf_7SO = 31, /* summary overflow */ + Pcf_NONE = 32 /* no condition; used with Pct_ALWAYS */ } PPCCondFlag; typedef enum { /* Maps bc bitfield BO */ - Pct_FALSE = 0x4, - Pct_TRUE = 0xC, - Pct_ALWAYS = 0x14 + Pct_FALSE = 0x4, /* associated PPCCondFlag must not be Pcf_NONE */ + Pct_TRUE = 0xC, /* associated PPCCondFlag must not be Pcf_NONE */ + Pct_ALWAYS = 0x14 /* associated PPCCondFlag must be Pcf_NONE */ } PPCCondTest; diff --git a/VEX/priv/host_ppc_isel.c b/VEX/priv/host_ppc_isel.c index 0f82e85c91..7ea8450518 100644 --- a/VEX/priv/host_ppc_isel.c +++ b/VEX/priv/host_ppc_isel.c @@ -785,7 +785,7 @@ void doHelperCall ( ISelEnv* env, } /* Fast scheme only applies for unconditional calls. Hence: */ - cc.test = Pct_ALWAYS; + cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE ); } else { @@ -828,7 +828,7 @@ void doHelperCall ( ISelEnv* env, because the argument computations could trash the condition codes. Be a bit clever to handle the common case where the guard is 1:Bit. */ - cc.test = Pct_ALWAYS; + cc = mk_PPCCondCode( Pct_ALWAYS, Pcf_NONE ); if (guard) { if (guard->tag == Iex_Const && guard->Iex.Const.con->tag == Ico_U1 -- 2.47.2