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

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

Re: [avr-libc-dev] volatile in pgmspace.h ?


From: Marek Michalkiewicz
Subject: Re: [avr-libc-dev] volatile in pgmspace.h ?
Date: Mon, 16 Jun 2003 22:20:03 +0200
User-agent: Mutt/1.4i

Hi,

On Mon, Jun 16, 2003 at 03:44:35PM +0000, E. Weddington wrote:
> Originally, the inline assembly had not been marked 
> volatile. However, I had gotten a bug report stating that 
> the GCC optimizer had rearranged the inline assembly to the 
> point where it wasn't working as defined. The fix was to 
> mark all the inline assembly macros as volatile so the 
> optimizer will leave them alone and have them work as 
> defined. It would be great if you have a better solution 
> that would work under all levels of optimization.

I've just looked at the current <avr/pgmspace.h> and I can see some
bugs - possibly hidden by using "volatile"...

__LPM_enhanced__ should use "lpm %0,Z" (not Z+).
__LPM_word_classic__ and __LPM_word_enhanced__ should tell GCC that
they change r31:r30, by using a dummy output operand.

I think the "asm" should look like this ("volatile" not needed):

    __asm__ (
        "lpm %A0, Z+" "\n\t"
        "lpm %B0, Z+"
        : "=r" (__result), "=z" (__addr16)
        : "1" (__addr16)
    );

 - operand 0: result, "=r" means "output in any general register"
 - operand 1: incrememted pointer, "=z" means "output in r31:r30"
 - operand 2: pointer, "1" means "input in the same register as operand 1"

The incremented pointer could be discarded, or used for the next LPM.

There may well be real GCC optimizer bugs, too.  But, in this case
I suspect the problem was with the "asm" not telling GCC the truth
which registers are changed.

Yes, GCC asm is tricky and gives you enough rope to shoot yourself :)

Hope this helps,
Marek





reply via email to

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