avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] Re: gcc's avr implementation does not appear to be in


From: Marek Michalkiewicz
Subject: Re: [avr-libc-dev] Re: gcc's avr implementation does not appear to be interrupt safe!
Date: Wed, 19 Jan 2005 19:56:10 +0100
User-agent: Mutt/1.5.6+20040907i

On Wed, Jan 19, 2005 at 11:07:50AM -0700, E. Weddington wrote:
> Paul Schlie wrote:
> 
> >Hey guys, just to give you a heads up, as there are routines implemented
> >in both avr.c and avr.md that temporarily utilize r1 without disabling
> >interrupts around these sections; 
> >
> Please provide examples (functions, line numbers, etc.) of what you mean.

Yes, this happens a few times - for example, MUL instructions return
their result in r1:r0.  But interrupts are not a problem here, because
interrupt/signal prologue saves r1 on stack and then clears it (and
epilogue restores it before returning to the main program).

> >The only reasonable solution to this problem that I see is to remove the
> >presumption that r1 == 0, and let the complier allocate what ever values it
> >deems necessary to generate efficient code; as otherwise the requirement to
> >block interrupts around these otherwise critical sections doesn't seem like
> >a good idea, as it's neither efficient code-wise, or helpful minimizing
> >interrupt latencies. (the compiler will tend to allocate and maintain any
> >frequently required value, the avr port should likely just let the compiler
> >do it's job).

The use of fixed registers r0 and r1 (__tmp_reg__ and __zero_reg__)
dates back to the beginning of avr-gcc (a few years ago).  One big
problem with changing this is with restrictions on movM patterns:

     Therefore, when given such a pair of operands, the pattern must
     generate RTL which needs no reloading and needs no temporary
     registers--no registers other than the operands.  [...]

In some cases (loading constants to lower 16 registers not allowed
for "ldi") r31 is used as an extra temporary register, but it is
saved in __tmp_reg__ first, and GCC knows nothing about this.
Yes, this is a hack, but the alternative is to load the constant
with "lds" - a waste of RAM (usually more valuable than flash).

> >(now that I think of it, to my vague recollection, I recall that stack
> >pointer manipulation may also not be interrupt save, but haven't checked
> >the code yet)

If you check it, you will see that interrupts are disabled around
any stack pointer changes.  SREG is restored (possibly re-enabling
interrupts, if enabled before) between changing SPH and SPL, but
enabling interrupts takes effect only after the next instruction.
There is a -mtiny-stack option for cases where the stack fits within
one 256-byte page (SPH never changes or simply doesn't exist), and
also -mno-interrupts for code that runs with interrupts disabled.

> And next time please post to a mailing list, preferrably avr-libc-dev 
> (which I've CC'd) where the GCC maintainers (or at least one of them) is 
> listening in.

Not very actively recently - but yes, I'm still alive :)

Marek





reply via email to

[Prev in Thread] Current Thread [Next in Thread]