On 06/07/2010 03:28 PM, Weddington, Eric wrote:
I would be very interested if someone shows conclusively that there are errors
with the structure-and-dot-offset register definitions.
So here's my test:
int main () {
while (1) {
PORTC.OUT = 0x00;
PORTC.OUT = 0xff;
}
}
avr-gcc -O0 -g -mmcu=atxmega128a1 test.c -o test -Wa,-almshd=test.lst
=====
5:test.c **** while (1) {
6:test.c **** PORTC.OUT = 0x00;
408 .LM1:
409 0008 E0E4 ldi r30,lo8(1600)
410 000a F6E0 ldi r31,hi8(1600)
411 000c 1482 std Z+4,__zero_reg__
7:test.c **** PORTC.OUT = 0xff;
413 .LM2:
414 000e E0E4 ldi r30,lo8(1600)
415 0010 F6E0 ldi r31,hi8(1600)
416 0012 8FEF ldi r24,lo8(-1)
417 0014 8483 std Z+4,r24
418 0016 00C0 rjmp .L2
=====
avr-gcc -Os -g -mmcu=atxmega128a1 test.c -o test -Wa,-almshd=test.lst
=====
5:test.c **** while (1) {
6:test.c **** PORTC.OUT = 0x00;
403 .LM1:
404 0000 E0E4 ldi r30,lo8(1600)
405 0002 F6E0 ldi r31,hi8(1600)
7:test.c **** PORTC.OUT = 0xff;
407 .LM2:
408 0004 8FEF ldi r24,lo8(-1)
409 .L2:
6:test.c **** PORTC.OUT = 0x00;
411 .LM3:
412 0006 1482 std Z+4,__zero_reg__
414 .LM4:
415 0008 8483 std Z+4,r24
416 000a 00C0 rjmp .L2
=====
avr-gcc -O2 -g -mmcu=atxmega128a1 test.c -o test -Wa,-almshd=test.lst
=====
5:test.c **** while (1) {
6:test.c **** PORTC.OUT = 0x00;
403 .LM1:
404 0000 E0E4 ldi r30,lo8(1600)
405 0002 F6E0 ldi r31,hi8(1600)
7:test.c **** PORTC.OUT = 0xff;
407 .LM2:
408 0004 8FEF ldi r24,lo8(-1)
409 .L2:
6:test.c **** PORTC.OUT = 0x00;
411 .LM3:
412 0006 1482 std Z+4,__zero_reg__
414 .LM4:
415 0008 8483 std Z+4,r24
416 000a 00C0 rjmp .L2
=====
avr-gcc -O6 -g -mmcu=atxmega128a1 test.c -o test -Wa,-almshd=test.lst
=====
5:test.c **** while (1) {
6:test.c **** PORTC.OUT = 0x00;
403 .LM1:
404 0000 E0E4 ldi r30,lo8(1600)
405 0002 F6E0 ldi r31,hi8(1600)
7:test.c **** PORTC.OUT = 0xff;
407 .LM2:
408 0004 8FEF ldi r24,lo8(-1)
409 .L2:
6:test.c **** PORTC.OUT = 0x00;
411 .LM3:
412 0006 1482 std Z+4,__zero_reg__
414 .LM4:
415 0008 8483 std Z+4,r24
416 000a 00C0 rjmp .L2
=====
In all cases there are two std's to Z+4. In fact, given the use of Z+4
to address into the register, there's the hope that it can be smart and
load (1600) once and allow you to write to several registers in the
structure that much faster. However, there appears to be an
optimization fault here:
int main () {
while (1) {
PORTC.DIR = 0xff;
PORTC.OUT = 0xff;
}
}
avr-gcc -Os -g -mmcu=atxmega128a1 test.c -o test -Wa,-almshd=test.lst
=====
5:test.c **** while (1) {
6:test.c **** PORTC.DIR = 0xff;
403 .LM1:
404 0000 E0E4 ldi r30,lo8(1600)
405 0002 F6E0 ldi r31,hi8(1600)
406 0004 8FEF ldi r24,lo8(-1)
407 .L2:
408 0006 8093 4006 sts 1600,r24
7:test.c **** PORTC.OUT = 0xff;
410 .LM2:
411 000a 8483 std Z+4,r24
412 000c 00C0 rjmp .L2
=====
For some unknown reason, even with -Os, it's insisting on doing a
two-word instruction to store into 1600 even though it just loaded Z
with the same value. All the optimization levels do this. Line 408
*should* read "st Z,r24"...
However, compare this to the _ version of the same:
avr-gcc -Os -g -mmcu=atxmega128a1 test.c -o test -Wa,-almshd=test.lst
=====
4:test.c **** while (1) {
5:test.c **** PORTC_DIR = 0xff;
408 .LM1:
409 0008 E0E4 ldi r30,lo8(1600)
410 000a F6E0 ldi r31,hi8(1600)
411 000c 8FEF ldi r24,lo8(-1)
412 000e 8083 st Z,r24
6:test.c **** PORTC_OUT = 0xff;
414 .LM2:
415 0010 E4E4 ldi r30,lo8(1604)
416 0012 F6E0 ldi r31,hi8(1604)
417 0014 8FEF ldi r24,lo8(-1)
418 0016 8083 st Z,r24
419 0018 00C0 rjmp .L2
=====
avr-gcc -Os -g -mmcu=atxmega128a1 test.c -o test -Wa,-almshd=test.lst
=====
4:test.c **** while (1) {
5:test.c **** PORTC_DIR = 0xff;
403 .LM1:
404 0000 8FEF ldi r24,lo8(-1)
405 .L2:
406 0002 8093 4006 sts 1600,r24
6:test.c **** PORTC_OUT = 0xff;
408 .LM2:
409 0006 8093 4406 sts 1604,r24
410 000a 00C0 rjmp .L2
=====
Either way it's only as good as or inferior, which means that not only
is the struct notation turning out fully correct (if not fully optimal),
it even comes out potentially faster/smaller.
_______________________________________________
AVR-libc-dev mailing list
AVR-libc-dev@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-libc-dev