Re: [PATCH v2 03/15] unify simplify_lsr_or() & simplify_and_or_mask()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 16/08/18 23:12, Luc Van Oostenryck wrote:
> Doing a LSR(X, N) will drop the N right bits.
> So any simplification that can be made when using an AND clearing
> the right N bits can also be used on LSR (as if its first operand
> would first be implicitly be ANDed with such a mask).
> 
> So, in order to not duplicate complex simplifications involving
> ANDs & ORs masks, merge these both function in a single one,
> using the mask corresponding to the operation.
> 
> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
> ---
>  simplify.c | 56 ++++++++++++++++++++++--------------------------------
>  1 file changed, 23 insertions(+), 33 deletions(-)
> 
> diff --git a/simplify.c b/simplify.c
> index ef98b205a..ce48b3a91 100644
> --- a/simplify.c
> +++ b/simplify.c
> @@ -546,6 +546,24 @@ undef:
>  	return NULL;
>  }
>  
> +static int simplify_mask_or_and(struct instruction *insn, unsigned long long mask,
> +	pseudo_t src, pseudo_t other)
> +{
> +	unsigned long long omask, nmask;
> +	pseudo_t src2 = src->def->src2;
> +
> +	if (!constant(src2))
> +		return 0;
> +	omask = src2->value;
> +	nmask = omask & mask;
> +	if (nmask != 0)
> +		return 0;
> +	// replace OP(((A & M') | B), C)

Huh?, should that be OP(((A & M') | B), C) & M ?
and ...
> +	// by      OP(B, C)

OP(B, C) & M ?

confused.

ATB,
Ramsay Jones

> +	// when	(M' & M) == 0
> +	return replace_pseudo(insn, &insn->src1, other);
> +}
> +
>  static long long check_shift_count(struct instruction *insn, unsigned long long uval)
>  {
>  	unsigned int size = insn->size;
> @@ -575,18 +593,6 @@ static long long check_shift_count(struct instruction *insn, unsigned long long
>  	return sval;
>  }
>  
> -static int simplify_or_lsr(struct instruction *insn, pseudo_t src, pseudo_t other, unsigned shift)
> -{
> -	// src->def->opcode == OP_AND
> -	pseudo_t src2 = src->def->src2;
> -
> -	if (!constant(src2))
> -		return 0;
> -	if (((unsigned long long) src2->value) >> shift)
> -		return 0;
> -	return replace_pseudo(insn, &insn->src1, other);
> -}
> -
>  static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long value)
>  {
>  	struct instruction *def;
> @@ -660,15 +666,13 @@ static int simplify_shift(struct instruction *insn, pseudo_t pseudo, long long v
>  		case OP_LSR:
>  			goto case_shift_shift;
>  		case OP_OR:
> -			// replace ((A & M) | B) >> S
> -			// by      (B >> S)
> -			// when	(M >> S) == 0
> +			mask = bits_mask(size - value) << value;
>  			src = def->src1;
>  			if (def_opcode(src) == OP_AND)
> -				return simplify_or_lsr(insn, src, def->src2, value);
> +				return simplify_mask_or_and(insn, mask, src, def->src2);
>  			src = def->src2;
>  			if (def_opcode(src) == OP_AND)
> -				return simplify_or_lsr(insn, src, def->src1, value);
> +				return simplify_mask_or_and(insn, mask, src, def->src1);
>  			break;
>  		case OP_SHL:
>  			// replace (A << S) >> S
> @@ -824,17 +828,6 @@ static int simplify_seteq_setne(struct instruction *insn, long long value)
>  	return 0;
>  }
>  
> -static int simplify_and_or_mask(struct instruction *insn, pseudo_t and, pseudo_t other, unsigned long long mask)
> -{
> -	struct instruction *def = and->def;
> -
> -	if (!constant(def->src2))
> -		return 0;
> -	if (def->src2->value & mask)
> -		return 0;
> -	return replace_pseudo(insn, &insn->src1, other);
> -}
> -
>  static int simplify_constant_mask(struct instruction *insn, unsigned long long mask)
>  {
>  	pseudo_t old = insn->src1;
> @@ -849,15 +842,12 @@ static int simplify_constant_mask(struct instruction *insn, unsigned long long m
>  		osize = 1;
>  		goto oldsize;
>  	case OP_OR:
> -		// Let's handle ((A & M') | B ) & M
> -		// or           (B | (A & M')) & M
> -		// when M' & M == 0
>  		src1 = def->src1;
>  		src2 = def->src2;
>  		if (def_opcode(src1) == OP_AND)
> -			return simplify_and_or_mask(insn, src1, src2, mask);
> +			return simplify_mask_or_and(insn, mask, src1, src2);
>  		if (def_opcode(src2) == OP_AND)
> -			return simplify_and_or_mask(insn, src2, src1, mask);
> +			return simplify_mask_or_and(insn, mask, src2, src1);
>  		break;
>  	case OP_ZEXT:
>  		osize = def->orig_type->bit_size;
> 



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux