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

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

Re: [avr-gcc-list] inline assembler problem


From: Ewout Boks
Subject: Re: [avr-gcc-list] inline assembler problem
Date: Sun, 25 Jan 2004 09:58:35 +0100
User-agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.5) Gecko/20031109

Theodore A. Roth wrote:

On Tue, 20 Jan 2004, Ewout Boks wrote:



That is the inline asm problem I asked Joerg about yesterday. It is an
unecessary warning since your code looks perfectly allright.

I believe that it has been solved in post 3.3.1 versions of avr-gcc, so
update the compiler is your solution.


The warning are correct and the posted code will not work as he expects.
The reason it won't work is discussed in this FAQ entry:

  http://jubal.westnet.com/AVR/doc/avr-libc-user-manual/FAQ.html#faq_port_pass


Since some of you wanted to view the whole testprogram in order to help
me track the error I've struggeling with, I post it here. The compiler
I'm using is still the avr-gcc-3.3.1.
The functions in the code below I did implement in order to have some
simple functions to learn from.


#include <inttypes.h>

#define PORT_A 0x1B
#define DDR_A 0x1A
#define PIN_A 0x19


Change these to:

#define PORT_A PORTA
#define DDR_A DDRA
#define PIN_A PINA


uint8_t read(const uint8_t adr) {


In order to pass the io reg, it must be done via a pointer, change this
to:

uint8_t read (volatile uint8_t *adr) {


 uint8_t p;
 asm volatile ("in %0, %1" : "=r" (p) : "I" (adr));
 return p;
}


This is impossible. Read the FAQ entry linked above.



I understand that, in order to access the value at the port address, you need to pass the address of the port. The above code is clearly wrong in that respect : one should use the 'ld' mnemonic with the port address loaded into X.

However, I think the following is done clearly wrong by the compiler: (this example comes from the avr-libc FAQ):

7.4.1 GCC asm Statement
Let's start with a simple example of reading a value from port D:

asm("in %0, %1" : "=r" (value) : "I" (PORTD) : );


When I attempt to do this, I first get a complaint from avr-gcc saying that :

avrHardware.c: In function `avrInportByte':
avrHardware.c:27: error: parse error before ')' token
gmake: *** [avrHardware.o] Error 1

For some reason, the assembler has trouble with the 3rd colon in the statement (no clobber list possible ?). When I remove the 3rd colon, I get this:

avrHardware.c: In function `avrInportByte':
avrHardware.c:27: warning: asm operand 1 probably doesn't match constraints
avrHardware.c:27: error: impossible constraint in `asm'
gmake: *** [avrHardware.o] Error 1


Now this I clearly call a compiler deficiency/error. The compiler should have no trouble inserting something like:

in r24,0x1b


Ewout



uint8_t fastSBI(const uint8_t port, const uint8_t bit) {
 asm volatile("sbi %0, %1" : : "I" (port), "I" (bit));
}

int main(void) {
 uint8_t port_a = PORT_A;
 uint8_t ddr_a = DDR_A;
 uint8_t pin = 3;
 uint8_t data;

 data = read(port_a);
 fastSBI(ddr_a, pin);

 return 0;
}

When trying to compile this I get the following errors:
inlasm.c: In function `read':
inlasm.c:11: warning: asm operand 1 probably doesn't match constraints
inlasm.c:11: error: impossible constraint in `asm'
inlasm.c: In function `fastSBI':
inlasm.c:17: warning: asm operand 0 probably doesn't match constraints
inlasm.c:17: warning: asm operand 1 probably doesn't match constraints


I don't think that gcc is lying to you about the "impossible
constraint".

Ted Roth






reply via email to

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