Vincent Trouilliez wrote:
I replaced the '&' operator with the more appropriate '&&' one.... works
much better... 5 instructions instead of 115 (3 + 6*18 + 4) for the
previous code.
Unfortunately, '&&' and '&' are very different. '&' is the correct bit
operator to use, '&&' will check the result of an expression. So
if ( address && 0x00040000)
is always true if address is not null.
The assembly output is much smaller since the optimizer took away '&&
0x00040000' since this part is always true! I gess that if you look at
the full assembly, you'll see 'address' being loaded in r18-r21. So the
compiler just checks that 'address' is not null... (r1 is always at zero
for avr-gcc).
Now your problem with 'address & 0x00040000' is a real one: avr-gcc is
not yet very good with 32 bits operators (BTW what version of avr-gcc do
you use?).
To solve such speed problems, you have to tell the compiler that you
want to perform just a 8 bit operation. So use something like:
----
union {
uint32_t my_ulong;;
struct {
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
} my_bytes;
} value;
value.my_ulong=address;
if(value.my_bytes.c & 0x40)
----
This is very dirty:
- it is not portable since it relies on the endieness of the target and
compiler (note that it may be value.my_bytes.b to test to have the code
really working, I did not test!)
- It's a pain to maintain since some other people will look at this code
in a few weeks/months/years and think that the person who wrote it was
nut unless it is very well documented.
- In a later version of the compiler it can have the opposite effect and
be less efficient than to have the compiler do correctly its job.
Now it solves your problem today, so it's up to you to decide to use it
or not.
Bernard
_______________________________________________
AVR-GCC-list mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list