This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: rs6000.c: extract_M[BE] clarifications/optimizations
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: DJ Delorie <dj at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org, David Edelsohn <dje at watson dot ibm dot com>
- Date: Mon, 14 Jun 2004 10:04:14 +0930
- Subject: Re: rs6000.c: extract_M[BE] clarifications/optimizations
- References: <200405290034.i4T0Y4UG013961@greed.delorie.com>
On Fri, May 28, 2004 at 08:34:04PM -0400, DJ Delorie wrote:
>
> extract_MB and _ME use loops to find leading bits. Any reason why
> they don't use floor_log2 instead?
No, just nobody thought of using it..
> new:
>
> int
> extract_MB (rtx op)
> int i;
> unsigned long val = INT_LOWPART (op);
>
> /* If the high bit is zero, the value is the first 1 bit we find
> from the left. */
> if ((val & 0x80000000) == 0)
> return 31 - floor_log2 (val);
>
> /* If the high bit is set and the low bit is not, or the mask is all
> 1's, the value is zero. */
> if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
> return 0;
>
> /* Otherwise we have a wrap-around mask. Look for the first 0 bit
> from the right. */
> return 31 - log2_floor (~(val + 1) & val);
> }
Apart from obvious typos, this version looks good, and gives exactly the
same results except for an (invalid) zero input.
> even simpler (but less obvious):
>
> int
> new_extract_MB (int val)
> {
> /* If there are LSBs, mask off all but the LSBs */
> if (val & 0x1)
> val = ~(val + 1) & val;
> /* Count clear MSBs. */
> return (31 - log2_floor(val));
> }
This sneaky little function works too, at least for all valid mask
values. It does give different results for values like 5, that aren't
valid masks. That's OK though, since extract_MB is only called when
mask_operand will return true. I think this version is OK.
--
Alan Modra
IBM OzLabs - Linux Technology Centre