Hi,

Glad I could help - it's always nice to get one's "good deed for the day" over by morning coffee, and relax and do evil the rest of the day :-)

More importantly, I think clang is going to have to be taught about __tmp_reg__ anyway, because it is used in many places by avrlibc and inline assembly. However, while the gcc avr backend makes heavy use of __tmp_reg__, perhaps clang avr backend does not (I don't know any of the details around it). It's possible to have a local uint8_t variable here and pass that to the inline assembly for use as a temporary register, letting the compiler pick whichever one it likes.

mvh.,

David




On 15/10/2021 10:31, Marian Buschsieweke wrote:
Hi David,

that is an excellent idea. The attached patch implements that idea (slightly
different) and almost makes clang happy. It know fails with:

/usr/avr/include/avr/wdt.h:436:5: error: invalid operand for instruction
                                 "in __tmp_reg__,__SREG__" "\n\t"
                                 ^
<inline asm>:1:5: note: instantiated into assembly here
         in __tmp_reg__,__SREG__
            ^

So I guess for my application I know only have to teach clang the value of
__tmp_reg__ (and maybe also a few other constants) to get it compiling :-)

Kind regards,
Marian

On Fri, 15 Oct 2021 09:49:30 +0200
David Brown <da...@westcontrol.com> wrote:

On 13/10/2021 18:05, Marian Buschsieweke wrote:
Hi together,

parts of the avrlibc headers are not compatible with clang. (The use case is
not to compile avrlibc itself with clang, but rather an application using
a vanilla GCC compiled avrlibc.) However, the issues are not always trivial to
fix.

E.g. in avr/wdt.h there are several instances of code like this:
static __inline__
__attribute__ ((__always_inline__))
void wdt_enable (const uint8_t value)
{
        if (_SFR_IO_REG_P (_WD_CONTROL_REG))
        {
                __asm__ __volatile__ (
                                [...]
                                : /* no outputs */
                                : "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
                                [...]
                                : "r0"
                );
        }
        else {
                /* variant not using _WD_CONTROL_REG as immediate */
                [...]
}
  [...]

It's been a /long/ time since I have done anything with the AVR, and I
don't have a modern avr gcc compiler (or any clang avr compiler at all)
handy for testing.  However, I have an idea you can try:

        "I" (_SFR_IO_ADDR(_WD_CONTROL_REG) || 1)

If "_SFR_IO_ADDR(_WD_CONTROL_REG)" evaluates to false, then this
expression would give "1", which clang might be happier with.



Reply via email to