@@ -416,6 +416,8 @@ static int simplify_lsr(struct instruction *insn, pseudo_t pseudo, long long val
{
struct instruction *def;
unsigned long long mask;
+ unsigned int width;
+ pseudo_t old;
if (!value)
return replace_with_pseudo(insn, pseudo);
@@ -434,6 +436,21 @@ static int simplify_lsr(struct instruction *insn, pseudo_t pseudo, long long val
insn->opcode = OP_AND;
insn->src2 = value_pseudo(mask >> value);
return REPEAT_CSE;
+ case OP_SHL:
+ // replace (A << S) >> S
+ // by A & (Mask(size) >> S)
+ def = insn->src1->def;
+ if (!constant(def->src2))
+ break;
+ if (def->src2->value != value)
+ break;
+ width = insn->size - value;
+ insn->src2 = value_pseudo((1ULL << width) - 1);
+ insn->opcode = OP_AND;
+ old = insn->src1;
+ use_pseudo(insn, def->src1, &insn->src1);
+ remove_usage(old, &insn->src1);
+ return REPEAT_CSE;
}
return 0;
}
More exactly, transform it into: A & (Mask(size) >> S) which is equivalent to: A & Mask(size - S) where Mask(X) is ((1 << X) - 1) This transformation is especially usefull when simplifying code accessing bitfields or for other masking manipulations. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> --- simplify.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)