Although a bit wordy, the following produces good code under a lot of different circumstances. It allows the compiler to shove things around & optimize.
static inline uint16_t ByteSwap(uint16_t data) { union byteswap { uint16_t word; struct { uint8_t low; uint8_t high; }; } foo; foo.word = data; uint8_t t = foo.high; foo.high = foo.low; foo.low = t; return foo.word; } | -----Original Message----- | From: [EMAIL PROTECTED] [mailto:avr-gcc- | [EMAIL PROTECTED] On Behalf Of Shaun Jackman | Sent: Friday, November 17, 2006 3:31 PM | To: avr-gcc-list@nongnu.org; gcc@gcc.gnu.org | Subject: [avr-gcc-list] AVR byte swap optimization | | The following macro expands to some rather frightful code on the AVR: | | #define BSWAP_16(x) \ | ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) | | uint16_t bswap_16(uint16_t x) | { | 0: 9c 01 movw r18, r24 | 2: 89 2f mov r24, r25 | 4: 99 27 eor r25, r25 | 6: 32 2f mov r19, r18 | 8: 22 27 eor r18, r18 | return BSWAP_16(x); | } | a: 82 2b or r24, r18 | c: 93 2b or r25, r19 | e: 08 95 ret | | Ideally, this macro would expand to three mov instructions and a ret. | Is there anything I can do to help GCC along here? I'm using GCC 4.1.0 | with -O2. | | I won't bother to show bswap_32 here, which produces a real disaster! | Think 47 instructions, for what should be 6. | | Cheers, | Shaun | | $ avr-gcc --version |head -1 | avr-gcc (GCC) 4.1.0 | | | _______________________________________________ | AVR-GCC-list mailing list | AVR-GCC-list@nongnu.org | http://lists.nongnu.org/mailman/listinfo/avr-gcc-list _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list