avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Strange inline asm bug or silly user?


From: David Carr
Subject: Re: [avr-gcc-list] Strange inline asm bug or silly user?
Date: Tue, 20 Jul 2010 07:52:09 -0400
User-agent: Thunderbird 2.0.0.24 (X11/20100411)

Georg and Niklas,

Thanks for the help!
You're both right in that adding "clr r1" to the end fixed the problem. I guess I figured that simply adding R1 to the clobber list would cause gcc to do that automatically. Silly me.

-DC

David Carr wrote:
I'm just learning to use inline assembly with avr-gcc, and I've encountered what seems to me to be a very strange bug (but may be user silliness).

In the test case below, I repeatedly change the first entry of the data array between 0xFF and 0x00. A short piece of assembly then moves data[0] into r0 and pushes it out to PORTB. This causes an LED to flash. This works.

However, when I change:

"ldd r0, %a1+0 \n\t"
"out %0, r0 \n\r"

to:

ldd r1, %a1+0 \n\t"
"out %0, r1 \n\r"

IE: replace r0 with r1, the LED just stays lit continuously.

Fine, so I look at the assembly listing generated by avr-objdump -h -S ads-tx.elf > ads-tx.lst
This is the diff between the working and non-working versions:

99,102c99,102
<   ae:    10 80           ld    r1, Z
<   b0:    15 b8           out    0x05, r1    ; 5
<            "ldd r1, %a1+0 \n\t"
<            "out %0, r1 \n\r"
---
>   ae:    00 80           ld    r0, Z
>   b0:    05 b8           out    0x05, r0    ; 5
>            "ldd r0, %a1+0 \n\t"
>            "out %0, r0 \n\r"
170,171c170,171
<   e4:    10 80           ld    r1, Z
<   e6:    15 b8           out    0x05, r1    ; 5
---
>   e4:    00 80           ld    r0, Z
>   e6:    05 b8           out    0x05, r0    ; 5
188,189c188,189
<   f0:    10 80           ld    r1, Z
<   f2:    15 b8           out    0x05, r1    ; 5
---
>   f0:    00 80           ld    r0, Z
>   f2:    05 b8           out    0x05, r0    ; 5

It looks to me like the only thing that has changed is R0/R1.

Even more strange is that using R2, R3, R13 all work. Just R1 fails. I am baffled.

Test code:

#include <stdint.h>
#include <avr/io.h>

#define F_CPU 8000000UL
#include <util/delay.h>

void send_packet(volatile uint8_t* data)
{
 asm volatile(
          //first load data in to RX
          "ldd r0, %a1+0 \n\t"
          "out %0, r0 \n\r"
          :
          :"I" (_SFR_IO_ADDR(PORTB)), "e" (data)
          : "r0", "r1", "r2", "r3", "r13");
}

void main(void)
{
 //this shouldn't need volatile, but gcc optimizes it out otherwise?
 volatile uint8_t data[14];
 DDRB = 0xFF;

 while (1)
   {
       data[0] = 0x00;
     send_packet(data);
     _delay_ms(20);
         data[0] = 0xFF;
     send_packet(data);
     _delay_ms(20);
   }
}

Thanks for the help,
-DC

_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list




reply via email to

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