Skip to content

Commit

Permalink
Semantics of x86 uplifting: reduce 'Repeat' ops (#4559)
Browse files Browse the repository at this point in the history
* Semantics of x86 uplifting: reduce 'Repeat' ops

- Replaced Repeat with bitwise operations for parity calculation.
- Simplified rotate and shift calculations.
- Enhanced static analysis feasibility.

* Update IL outputs of affected tests
  • Loading branch information
kui8shi authored Jul 30, 2024
1 parent ae491d6 commit 6d45cbd
Show file tree
Hide file tree
Showing 7 changed files with 669 additions and 704 deletions.
37 changes: 11 additions & 26 deletions librz/arch/isa/x86/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -889,36 +889,21 @@ RZ_IPI RzILOpBool *x86_il_is_sub_underflow(RZ_OWN RZ_NONNULL RzILOpPure *res, RZ
return or ;
}

struct x86_parity_helper_t {
RzILOpBool *val; ///< value of parity
RzILOpEffect *eff; ///< RzILOpEffect used to find the parity
};

/**
* \brief Find the parity of lower 8 bits of \p val
*
* \param val
*/
struct x86_parity_helper_t x86_il_get_parity(RZ_OWN RzILOpPure *val) {
RzILOpBool *x86_il_get_parity(RZ_OWN RzILOpPure *val) {
// assumed that val is an 8-bit wide value
RzILOpEffect *setvar = SETL("_popcnt", U8(0));
setvar = SEQ2(setvar, SETL("_val", val));

/* We can stop shifting the "_val" once it is zero,
since the value of "_popcnt" wouldn't change any further */
RzILOpBool *condition = NON_ZERO(VARL("_val"));

RzILOpEffect *popcnt = SETL("_popcnt", ADD(VARL("_popcnt"), BOOL_TO_BV(LSB(VARL("_val")), 8)));
popcnt = SEQ2(popcnt, SETL("_val", SHIFTR0(VARL("_val"), U8(1))));

RzILOpEffect *repeat_eff = REPEAT(condition, popcnt);

struct x86_parity_helper_t ret = {
.val = IS_ZERO(MOD(VARL("_popcnt"), U8(2))),
.eff = SEQ2(setvar, repeat_eff)
};

return ret;
// A parity calculation can be reduced to nested shift-right and xor operations.
// see https://github.com/BinaryAnalysisPlatform/bap/blob/master/plugins/x86/x86_lifter.ml#L215
RzILOpPure *accumulate = LET("_val", val,
LET("_c4", LOGXOR(VARLP("_val"), SHIFTR0(VARLP("_val"), U8(4))),
LET("_c2", LOGXOR(VARLP("_c4"), SHIFTR0(VARLP("_c4"), U8(2))),
LOGXOR(VARLP("_c2"), SHIFTR0(VARLP("_c2"), U8(1))))));
return INV(LSB(accumulate));
}

/**
Expand All @@ -928,12 +913,12 @@ RZ_IPI RzILOpEffect *x86_il_set_result_flags_bits(RZ_OWN RZ_NONNULL RzILOpPure *
rz_return_val_if_fail(result, NULL);

RzILOpEffect *set = SETL("_result", result);
struct x86_parity_helper_t pf = x86_il_get_parity(UNSIGNED(8, VARL("_result")));
RzILOpBool *pf = x86_il_get_parity(UNSIGNED(8, VARL("_result")));
RzILOpBool *zf = IS_ZERO(VARL("_result"));
RzILOpBool *sf = MSB(VARL("_result"));

return SEQ5(set, pf.eff,
SETG(EFLAGS(PF), pf.val),
return SEQ4(set,
SETG(EFLAGS(PF), pf),
SETG(EFLAGS(ZF), zf),
SETG(EFLAGS(SF), sf));
}
Expand Down
Loading

0 comments on commit 6d45cbd

Please sign in to comment.