[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/
- [avr-libc-dev] [bug #38021] pgm_read macros don't model the memory accesses,
Georg-Johann Lay <=