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

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

[avr-libc-dev] [bug #38021] pgm_read macros don't model the memory acces


From: Georg-Johann Lay
Subject: [avr-libc-dev] [bug #38021] pgm_read macros don't model the memory accesses
Date: Fri, 04 Jan 2013 13:05:38 +0000
User-agent: Opera/9.80 (Windows NT 5.0; U; de) Presto/2.6.30 Version/10.63

URL:
  <http://savannah.nongnu.org/bugs/?38021>

                 Summary: pgm_read macros don't model the memory accesses
                 Project: AVR C Runtime Library
            Submitted by: gjlayde
            Submitted on: Fr 04 Jan 2013 13:05:37 GMT
                Category: Header
                Severity: 3 - Normal
                Priority: 5 - Normal
              Item Group: Header files
                  Status: None
        Percent Complete: 0%
             Assigned to: None
        Originator Email: 
             Open/Closed: Open
         Discussion Lock: Any
                 Release: 1.8.0
           Fixed Release: None

    _______________________________________________________

Details:

The current (1.8.0) implementation of the pgm_read inline assembler does not
model the memory accesses it performs.  This can lead to problems in the
following situations:

1) The memory location is const volatile
2) If ELPM is issued, RAMPZ is changed unnoticed
3) Setting RAMPZ to values other than 0 is not compatible with avr-gcc 4.7+
and xmega with > 64k RAM, cf. "Handling of the RAMP* Special Function
Registers" in http://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html

1) Will raise problems together with code that uses SPM like the following. 
The code is not exactly the same as in pgmspace.h but nevertheless can serve
as a test case to show the problem:



static __inline__ __attribute__((__always_inline__))
int func (int x)
{
    int result;
    __asm__ ("; %0 = some code (%1)"
             : "=r" (result)
             : "r" (x));
    return result;
}

void f (void)
{
    extern void uses_SPM (void);
    while (func (0))
        uses_SPM();
}



With avr-gcc 4.7 you will see code similar to this:



f:
        ...
/* #APP */
        ; r28 = some code (r28)
/* #NOAPP */
        rjmp .L2
.L3:
        call uses_SPM
.L2:
        sbiw r28,0
        brne .L3
        ...



Notice that the inline assembler code is outside the loop.  This will work
with const* addresses but nit with const volatile* stuff.

A possible fix is to make the asm volatile and clobber memory. A second fix is
to make the memory access explicit like so:



static __inline__ __attribute__((__always_inline__))
int func (int x)
{
    int result;
    int *p = (int*) x;
    __asm__ ("; %0 = some code (%1)"
             : "=r" (result)
             : "r" (x), "m" (*p)
             : "memory");
    return result;
}



Notice the asm is inside the loop now:



f:
        ...
        rjmp .L2
.L3:
        call uses_SPM
.L2:
/* #APP */
        ; r24 = some code (r28)
/* #NOAPP */
        or r24,r25
        brne .L3
        ...



2) and 3) can be solved by clearing RAMPZ at the end of the asm so that there
is no net effect on RAMPZ.





    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/bugs/?38021>

_______________________________________________
  Nachricht gesendet von/durch Savannah
  http://savannah.nongnu.org/




reply via email to

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