Good testing. However would you be willing to try something a bit different? Please try this:
int main () { while (1) { PORTC.OUT = 0x00; PORTD.OUT = 0xff; } } And the corresponding flat register access: int main () { while (1) { PORTC_OUT = 0x00; PORTD_OUT = 0xff; } } Thanks, Eric Weddington > -----Original Message----- > From: Erik Walthinsen [mailto:om...@omegacs.net] > Sent: Monday, June 07, 2010 5:13 PM > To: Weddington, Eric > Cc: avr-libc-dev@nongnu.org > Subject: Re: [avr-libc-dev] XMEGA > > 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