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.





_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to