avr-libc-dev
[Top][All Lists]
Advanced

[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.
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]