2 changes: 1 addition & 1 deletion VEX/priv/guest_amd64_defs.h
Expand Up @@ -381,7 +381,7 @@ extern void amd64g_dirtyhelper_AESKEYGENASSIST (
(2) When passing the thunk components to an evaluation function
(calculate_condition, calculate_eflags, calculate_eflags_c) the
IRCallee's mcx_mask must be set so as to exclude from
IRCallee's mcx_masks must be set so as to exclude from
consideration all passed args except CC_DEP1 and CC_DEP2.
Strictly speaking only (2) is necessary for correctness. However,
Expand Down
24 changes: 19 additions & 5 deletions VEX/priv/guest_amd64_toIR.c
Expand Up @@ -1746,7 +1746,7 @@ static IRExpr* mk_amd64g_calculate_rflags_all ( void )
);
/* Exclude OP and NDEP from definedness checking. We're only
interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand All @@ -1769,8 +1769,22 @@ static IRExpr* mk_amd64g_calculate_condition ( AMD64Condcode cond )
args
);
/* Exclude the requested condition, OP and NDEP from definedness
checking. We're only interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
checking. We're only interested in DEP1 and DEP2 usually. */
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<1) | (1<<4));

// The mask that mk_mcx_masks made is surely large enough to include
vassert(call->Iex.CCall.cee->mcx_masks.count >= 2);
switch (cond) {
case AMD64CondS:
case AMD64CondNS:
/* Only the MSB matters when looking at the sign bit so mark all others
* as excluded. */
call->Iex.CCall.cee->mcx_masks.masks[2] = (~((ULong)0) >> 1);
break;
default:
/* TODO: Add more here. */
break;
}
return unop(Iop_64to1, call);
}

Expand All @@ -1792,7 +1806,7 @@ static IRExpr* mk_amd64g_calculate_rflags_c ( void )
);
/* Exclude OP and NDEP from definedness checking. We're only
interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand Down Expand Up @@ -21897,7 +21911,7 @@ Long dis_ESC_0F (
case 0x46: /* CMOVBEb/CMOVNAb (cmov below or equal) */
case 0x47: /* CMOVNBEb/CMOVAb (cmov not below or equal) */
case 0x48: /* CMOVSb (cmov negative) */
case 0x49: /* CMOVSb (cmov not negative) */
case 0x49: /* CMOVNSb (cmov not negative) */
case 0x4A: /* CMOVP (cmov parity even) */
case 0x4B: /* CMOVNP (cmov parity odd) */
case 0x4C: /* CMOVLb/CMOVNGEb (cmov less) */
Expand Down
8 changes: 4 additions & 4 deletions VEX/priv/guest_arm64_toIR.c
Expand Up @@ -1787,7 +1787,7 @@ static IRExpr* mk_arm64g_calculate_condition_dyn ( IRExpr* cond )

/* Exclude the requested condition, OP and NDEP from definedness
checking. We're only interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand Down Expand Up @@ -1826,7 +1826,7 @@ static IRExpr* mk_arm64g_calculate_flag_c ( void )
);
/* Exclude OP and NDEP from definedness checking. We're only
interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand All @@ -1850,7 +1850,7 @@ static IRExpr* mk_arm64g_calculate_flag_c ( void )
//ZZ );
//ZZ /* Exclude OP and NDEP from definedness checking. We're only
//ZZ interested in DEP1 and DEP2. */
//ZZ call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
//ZZ call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
//ZZ return call;
//ZZ }

Expand All @@ -1873,7 +1873,7 @@ static IRExpr* mk_arm64g_calculate_flags_nzcv ( void )
);
/* Exclude OP and NDEP from definedness checking. We're only
interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand Down
8 changes: 4 additions & 4 deletions VEX/priv/guest_arm_toIR.c
Expand Up @@ -1181,7 +1181,7 @@ static IRExpr* mk_armg_calculate_condition_dyn ( IRExpr* cond )

/* Exclude the requested condition, OP and NDEP from definedness
checking. We're only interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand Down Expand Up @@ -1220,7 +1220,7 @@ static IRExpr* mk_armg_calculate_flag_c ( void )
);
/* Exclude OP and NDEP from definedness checking. We're only
interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand All @@ -1244,7 +1244,7 @@ static IRExpr* mk_armg_calculate_flag_v ( void )
);
/* Exclude OP and NDEP from definedness checking. We're only
interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand All @@ -1267,7 +1267,7 @@ static IRExpr* mk_armg_calculate_flags_nzcv ( void )
);
/* Exclude OP and NDEP from definedness checking. We're only
interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand Down
28 changes: 14 additions & 14 deletions VEX/priv/guest_s390_toIR.c
Expand Up @@ -983,7 +983,7 @@ s390_call_calculate_cc(void)

/* Exclude OP and NDEP from definedness checking. We're only
interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));

return call;
}
Expand Down Expand Up @@ -1019,7 +1019,7 @@ s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)

/* Exclude the requested condition, OP and NDEP from definedness
checking. We're only interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<1) | (1<<4));

return call;
}
Expand All @@ -1043,7 +1043,7 @@ s390_call_calculate_cond(UInt m)

/* Exclude the requested condition, OP and NDEP from definedness
checking. We're only interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<1) | (1<<4));

return call;
}
Expand Down Expand Up @@ -9269,7 +9269,7 @@ s390_call_pfpo_helper(IRExpr *gr0)
call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
"s390_do_pfpo", &s390_do_pfpo, args);
/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand Down Expand Up @@ -15082,7 +15082,7 @@ s390_call_cvb(IRExpr *in)
"s390_do_cvb", &s390_do_cvb, args);

/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand Down Expand Up @@ -15114,7 +15114,7 @@ s390_call_cvd(IRExpr *in)
"s390_do_cvd", &s390_do_cvd, args);

/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand Down Expand Up @@ -15617,7 +15617,7 @@ s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
"s390_do_cu21", &s390_do_cu21, args);

/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand Down Expand Up @@ -15744,7 +15744,7 @@ s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
"s390_do_cu24", &s390_do_cu24, args);

/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand Down Expand Up @@ -15851,7 +15851,7 @@ s390_call_cu42(IRExpr *srcval)
"s390_do_cu42", &s390_do_cu42, args);

/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand Down Expand Up @@ -15945,7 +15945,7 @@ s390_call_cu41(IRExpr *srcval)
"s390_do_cu41", &s390_do_cu41, args);

/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand Down Expand Up @@ -16036,7 +16036,7 @@ s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
&s390_do_cu12_cu14_helper1, args);

/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand All @@ -16051,7 +16051,7 @@ s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
"s390_do_cu12_helper2", &s390_do_cu12_helper2, args);

/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand All @@ -16066,7 +16066,7 @@ s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
"s390_do_cu14_helper2", &s390_do_cu14_helper2, args);

/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand Down Expand Up @@ -16223,7 +16223,7 @@ s390_call_ecag(IRExpr *op2addr)
"s390_do_ecag", &s390_do_ecag, args);

/* Nothing is excluded from definedness checking. */
call->Iex.CCall.cee->mcx_mask = 0;
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks(0);

return call;
}
Expand Down
4 changes: 2 additions & 2 deletions VEX/priv/guest_x86_defs.h
Expand Up @@ -240,7 +240,7 @@ extern VexEmNote
(2) When passing the thunk components to an evaluation function
(calculate_condition, calculate_eflags, calculate_eflags_c) the
IRCallee's mcx_mask must be set so as to exclude from
IRCallee's mcx_masks must be set so as to exclude from
consideration all passed args except CC_DEP1 and CC_DEP2.
Strictly speaking only (2) is necessary for correctness. However,
Expand Down Expand Up @@ -323,7 +323,7 @@ extern VexEmNote
helper function. They are not part of this scheme. The helper
function takes the value to be rotated, the rotate amount and the
old flags, and returns the new flags and the rotated value.
Since the helper's mcx_mask does not have any set bits, Memcheck
Since the helper's mcx_masks does not have any set bits, Memcheck
will lazily propagate undefinedness from any of the 3 args into
both results (flags and actual value).
*/
Expand Down
6 changes: 3 additions & 3 deletions VEX/priv/guest_x86_toIR.c
Expand Up @@ -795,7 +795,7 @@ static IRExpr* mk_x86g_calculate_eflags_all ( void )
);
/* Exclude OP and NDEP from definedness checking. We're only
interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand All @@ -819,7 +819,7 @@ static IRExpr* mk_x86g_calculate_condition ( X86Condcode cond )
);
/* Exclude the requested condition, OP and NDEP from definedness
checking. We're only interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<1) | (1<<4));
return unop(Iop_32to1, call);
}

Expand All @@ -841,7 +841,7 @@ static IRExpr* mk_x86g_calculate_eflags_c ( void )
);
/* Exclude OP and NDEP from definedness checking. We're only
interested in DEP1 and DEP2. */
call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
call->Iex.CCall.cee->mcx_masks = mk_mcx_masks((1<<0) | (1<<3));
return call;
}

Expand Down
55 changes: 51 additions & 4 deletions VEX/priv/ir_defs.c
Expand Up @@ -96,8 +96,17 @@ void ppIRCallee ( const IRCallee* ce )
vex_printf("%s", ce->name);
if (ce->regparms > 0)
vex_printf("[rp=%d]", ce->regparms);
if (ce->mcx_mask > 0)
vex_printf("[mcx=0x%x]", ce->mcx_mask);
if (ce->mcx_masks.count > 0) {
Int i;
vex_printf("[mcx=");
for (i = 0; i < ce->mcx_masks.count; i++) {
if (i > 0) {
vex_printf(",");
}
vex_printf("0x%llx", ce->mcx_masks.masks[i]);
}
vex_printf("]");
}
vex_printf("{%p}", (void*)ce->addr);
}

Expand Down Expand Up @@ -2319,13 +2328,44 @@ IRConst* IRConst_V256 ( UInt con )

/* Constructors -- IRCallee */

static Int count_leading_zeros ( UInt x ) {
int n = 32;
UInt y;

y = x >>16; if (y != 0) { n = n -16; x = y; }
y = x >> 8; if (y != 0) { n = n - 8; x = y; }
y = x >> 4; if (y != 0) { n = n - 4; x = y; }
y = x >> 2; if (y != 0) { n = n - 2; x = y; }
y = x >> 1; if (y != 0) return n - 2;
return n - x;
}

McxMasks mk_mcx_masks ( UInt mcx_mask )
{
McxMasks mcx_masks;
Int i;

mcx_masks.mask = mcx_mask;
mcx_masks.count = 32 - count_leading_zeros(mcx_mask);
mcx_masks.masks = LibVEX_Alloc_inline(
sizeof(mcx_masks.masks[0]) *
mcx_masks.count);
for (i = 0; i < mcx_masks.count; i++) {
mcx_masks.masks[i] = 0;
if ((mcx_mask >> i) & 1) {
mcx_masks.masks[i] = ~mcx_masks.masks[i];
}
}
return mcx_masks;
}

IRCallee* mkIRCallee ( Int regparms, const HChar* name, void* addr )
{
IRCallee* ce = LibVEX_Alloc_inline(sizeof(IRCallee));
ce->regparms = regparms;
ce->name = name;
ce->addr = addr;
ce->mcx_mask = 0;
ce->mcx_masks = mk_mcx_masks(0);
vassert(regparms >= 0 && regparms <= 3);
vassert(name != NULL);
vassert(addr != 0);
Expand Down Expand Up @@ -2867,8 +2907,15 @@ IRConst* deepCopyIRConst ( const IRConst* c )

IRCallee* deepCopyIRCallee ( const IRCallee* ce )
{
int i;
IRCallee* ce2 = mkIRCallee(ce->regparms, ce->name, ce->addr);
ce2->mcx_mask = ce->mcx_mask;
ce2->mcx_masks.mask = ce->mcx_masks.mask;
ce2->mcx_masks.count = ce->mcx_masks.count;
ce2->mcx_masks.masks = LibVEX_Alloc_inline(
sizeof(ce->mcx_masks.masks[0]) * ce->mcx_masks.count);
for (i = 0; i < ce->mcx_masks.count; i++) {
ce2->mcx_masks.masks[i] = ce->mcx_masks.masks[i];
}
return ce2;
}

Expand Down