[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [avr-libc-dev] XMEGA
From: |
Weddington, Eric |
Subject: |
RE: [avr-libc-dev] XMEGA |
Date: |
Mon, 7 Jun 2010 18:39:03 -0600 |
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:address@hidden
> Sent: Monday, June 07, 2010 5:13 PM
> To: Weddington, Eric
> Cc: address@hidden
> 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.
>