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.