Sat 31 Oct 2009 08:46:15 PM UTC, original submission:
Affected version: Debian avr-libc 1:1.6.2.cvs20080610-2
Current CVS most likely also affected, as macro didn't change.
At least on the atmega8515 _LPM_enhanced_ seems to modify Z, at least according to the disassembly.
#include <avr/pgmspace.h>
#include <stdint.h>
void try(uint8_t *p) {
uint16_t addr = 0;
uint8_t j;
for (j = 0; j < 10; j++) {
*p = _LPM_enhanced_(addr);
p++; addr++;
}
}
void try_asm(void) {
_asm_ __volatile__(
"lpm r18, Z+nt"
"lpm r18, Znt"
::);
}
avr-gcc -Wall -mmcu=atmega8515 -Os -g -DF_CPU=3686400 -c lpm-z-mod.c -o lpm-z-mod.o
gives:
- <try>:
0: dc 01 movw r26, r24
2: e0 e0 ldi r30, 0x00 ; 0
4: f0 e0 ldi r31, 0x00 ; 0
6: 84 91 lpm r24, Z+
8: 8d 93 st X+, r24
a: 31 96 adiw r30, 0x01 ; 1
c: ea 30 cpi r30, 0x0A ; 10
e: f1 05 cpc r31, r1
10: 01 f4 brne .+0 ; 0x12 <try+0x12>
12: 08 95 ret
00000014 <try_asm>:
14: 25 91 lpm r18, Z+
16: 24 91 lpm r18, Z+
18: 08 95 ret
Note the Z+.
Also note that the Z+ can be seen as a feature. The addr++ wouldn't be needed anymore. But providing this feature to C in a clean way doesn't look easy at all.
|