|
From: | Bernard Fouché |
Subject: | Re: [avr-gcc-list] How to (efficeiently !!!) test a bit within a multi-byte integer ? |
Date: | Fri, 04 Nov 2005 13:49:15 +0100 |
User-agent: | Mozilla Thunderbird 1.0.2 (Windows/20050317) |
Vincent Trouilliez wrote:
Unfortunately, '&&' and '&' are very different. '&' is the correct bit operator to use, '&&' will check the result of an expression. SoI replaced the '&' operator with the more appropriate '&&' one.... works much better... 5 instructions instead of 115 (3 + 6*18 + 4) for the previous code.
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
[Prev in Thread] | Current Thread | [Next in Thread] |