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 Mon, Aug 20, 2018 at 05:51:54PM +0100, Ramsay Jones wrote:
> On 17/08/18 22:17, Luc Van Oostenryck wrote:
> > On Fri, Aug 17, 2018 at 08:45:02PM +0100, Ramsay Jones wrote:
> >> 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.
> > 
> > Yes, sorry.
> > All this merits much better documentation.
> > OP(x, C) that I'm using here stand (or will stand) for either:
> > * AND(x, M) and then mask = M
> > * LSR(x, S) and then mask = (-1 << S)
> > * SHL(x, S) and then mask = (-1 >> S)
> > * TRUNC(x)  and then mask = $mask(newbitsize) = (1 << newbitsize) - 1
> 
> [Sorry for the delay; $LIFE is hectic at the moment.]

No worries, please. It's already really great that you're
reviewing conscienciouslty all these patches.
I'll never be able to thank you enough.

> So, are you saying that the 'mask' given above is M' (or omask
> in the code) and M is the function parameter 'mask'. ;-)
> 
> So src2->value in the above instructions are all 'mask' values
> rather than (say) the shift count S? Hmm, so, Huh! :-D

No, sorry.
In comments & explanations I use uppercase letters for constants:
'M' for a constant mask, 'S' for a constant shift, 'N' for a constant
number of bits and 'C' for others constants. I also sometimes
use '$mask(N)' for ((1 << N) -1), and (-1 << S) as a shorthand for
'(-1 << S) truncated to the size of the instruction'.
Also M is (normaly) reserved for the outer mask, I use M', M'', ...
for other masks if present.
Lowercase letters 'a', 'b', 'x', 'y' are for other variables/pseudos.

For the code here, the variable 'mask' n the code correspond to a
known/constant mask and is represented as 'M' in the formulae.
* if OP(_,_) is AND(x, M), obviously M is M is mask.
* if OP(_,_) is TRUNC(x, N) then mask is ((1 << N) -1),
  that I also note as '$mask(N)', where N is the new size.
* if OP(_,_) is LSR(x, S) then mask is (-1 << S) (truncated to
  the size of the instruction). 
* if OP(_,_) is SHL(x, S) then mask is (-1 >> S).

This is done because:
* TRUNC(x, N) is always equivalent to TRUNC(AND(x, ((1 << N) -1)))
* LSR(X, S)   is always equivalent to LSR(AND(x, (-1 << S)), S)
* SHL(X, S)   is always equivalent to SHL(AND(x, (-1 >> S)), S)
In other words:
* TRUNC(x, N) simplify the same as AND(x, ((1 << N) - 1))
* LSR(x, S)   simplify the same as AND(x, (-1 << N))
* SHL(x, S)   simplify the same as AND(x, (-1 >> N))
or equivalently:
* to TRUNC(x, N) correspond an equivalent mask ((1 << N) -1)
* to LSR(x, S)   correspond an equivalent mask (-1 << S)
* to SHL(x, S)   correspond an equivalent mask (-1 >> S)
and so I use the notation 'OP(x, C)' for all these operations
and sometimes I abuse the notation and directly use 'OP(x, M)'
where M is the the mask corresponding to OP(x, C).

For completeness, ZEXT() is a no-op as outer mask but as it
has the equivalent mask ((1 << oldsize) -1).

I hope this make things a bit more clear.

-- Luc



[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