Re: [bug] cbi optimization error for 8-bit AVRs
David Brown <[email protected]>
| Newsgroups | gmane.comp.hardware.avr.gcc |
|---|---|
| Message-ID | <[email protected]> |
On 08/11/14 01:32, Szikra István wrote:
> Hi everyone!
>
> My problem in sort: I’m getting
> in r24, 0x18
> ldi r25, 0x00
> andi r24, 0xEF
> out 0x18, r24
> instead of
> cbi 0x18, 4
> .
>
> I’m trying to write efficient modern C/C++ code for multiple platforms
> including AVR 8 bit controllers.
>
> Unfortunately GCC support for AVR (among other things) is not always
> flawless. And it changes from versions to version (and not always for
> the better).
> Since I’m a long time AVR developer I have a lot of compiler versions
> installed (WinAVR 2006-2010, and Atmel Studio 6.2 with GCC 4.8.1), but I
> could test my code with only one (the latest).
>
> I run into some trouble with clearing port bits not translating from C
> into cbi in assembler. It is caused by my bits template, but I do not
> know why. It seems to me like a bug in GCC. Maybe someone here can shed
> some light on the reason, or suggest a fix.
>
> Here is the code:
>
> #include <avr/io.h>
> //#include <bits.hpp>
>
> template<typename T>
> constexpr unsigned int bits(T idx1)
> {
> return (1<<idx1);
> }
> template <typename T, typename... Rest>
> constexpr unsigned int bits(T idx1, Rest... r)
> {
> return (1<<idx1) | bits(r...);
> }
>
Just an idea that might be worth trying - try replacing the "unsigned
int" return type with "uint8_t" (/always/ use <stdint.h> types with
defined bit sizes!). AVR gcc has quite a number of optimisations and
special case patterns for dealing with 8-bit types, especially uint8_t,
and it often gives tighter code if you've used uint8_t even if uint16_t
gives the same actual values.
Secondly, consider making your templates based on the value of idx1
rather than the type - the type will always be an int (or promoted to an
int in the shift expression). Alternatively, drop the template entirely.