On May 3, 11:12 am, "Bartc" <b...@[EMAIL PROTECTED]
> wrote:
> "Tom=E1s =D3 h=C9ilidhe" <t...@[EMAIL PROTECTED]
> wrote in
messagenews:851bdee4-=
c15c-4e07-bc62-166b346d2651@[EMAIL PROTECTED]
>
>
>
> > Ian Collins:
>
> >> > Suprisingly, the compiler produced more efficient code for the
latter=
,
> >> > presumably because it recognises the pattern of " x &=3D ~y" for
> >> > clearing a single bit.
>
> >> Odd, is x an unsigned 8 bit type?
>
> > Yes, it is.
>
> >> If so, the two expressions should
> >> generate identical code.
>
> > If I do:
>
> > y &=3D ~0x08u;
>
> > then I get the following assembler:
>
> > BCF y, 0x3 /* Clear the 4th bit of y */
>
> > If I do:
>
> > y &=3D 0x7Fu;
>
> > then I get the following assembler:
>
> > MOVLW 0x7f /* Load the ac***ulator with 0x7f */
> > ANDWF y, F /* AND y with the ac***ulator
> > and store the result in y */
>
> (You meant 0xF7 here?)
>
> Typically a compiler will reduce ~0x8u down to 0xF7u anyway, so there
> shouldn't be a difference.
>
> Unless ~0x8u actually generates 0xFFF7u? What's the default uint size on
Yes, ~0x8u, 0x8u would be 0xF...7 and not 0xF7. (I chose to put
ellipsis and not a number of F's because it's not possible to know how
many F's)
In the latter, 0xF7 would be int, and thus 0x00F7 and not 0xFFF7. Most
likely what the optimizer actually recognizes is all bits except one.
In the latter case it's not clear whether you're trying to clear the
4'th bit only or the other bits too (9-16th bit)
To understand,
unsigned int c;
c =3D UINT_MAX; /* all bits 1 */
printf("unsigned int context: %u, %u\n", c & ~0x8u, c & 0xF7u); /*
different output */
printf("unsigned char context: %hhu, %hhu\n", (unsigned char)(c &
~0x8u), (unsigned char)(c & 0xF7u)); /* same output */
So they are different, depending on type context. The compiler
optimizer just isn't that advanced to recognize that.


|