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

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

Re: [avr-gcc-list] gcc builds wrong code?


From: Theodore A. Roth
Subject: Re: [avr-gcc-list] gcc builds wrong code?
Date: Sun, 25 Jul 2004 14:02:26 -0700 (PDT)

On Sun, 25 Jul 2004, Klaus Rudolph wrote:

> Hi all,
>
> I wrote the following testcode and found that if a table of pointers to
> functions
> recides in flash "attribute progmem" the code is not correct.
>
> Is the compiler doing the wrong or am I the problem :-)
>
> Compiler Version:
> avr-gcc (GCC) 3.4.0
>
> Build my code with:
> avr-gcc -O2 -g -mmcu=at90s8515 test.c -c
> avr-gcc -O2 -g -mmcu=at90s8515 test.o -o go
>
> The code generation is wrong if version 1 is enabled, with version 2 the
> code is
> correct.
>
> Thanks
>     Klaus
>
> ///////////////////////////////// test.c /////////////////////////////
>
>
> #ifdef __AVR__
> #include <avr/io.h>
> #endif
>
> int f2(int a) {
>     return a+1;
> }
>
> int f3(int a) {
>     return a*2;
> }
>
> int f4(int a) {
>     return a*2+1;
> }
>
>
>
> volatile int all=0;
>
> typedef int(*fp_t)(int) ;
>
> // Version 1 fail
> const fp_t __attribute__ ((progmem)) fp[]={f2,f3,f4,0} ;
> //Version 2 ok
> //const fp_t fp[]={f2,f3,f4,0} ;
>
>
> int main() {
>     int index=1;
>     int tmp=1;
>
>     while (fp[index]) {
>         tmp+=(fp[index++])(tmp);
>     }
>
>     all=tmp;
>
>     return 0;
> }

I seem to recall there being a rather long discussion about exactly this
issue a week or two ago. No one every posted a tested, working example.

Attached is a tested working example. I've tried to reduce it down to
the bare minimum example. The variable "func" in the inner loop is not
needed, I only did that to force the compiler to not use registers so
as to make it easier to debug with gdb using 'display func'.

Tested on a mega128 with a stk500/501. Compliled with these commands:

  $ avr-gcc -g -Os -Wall -mmcu=atmega128 -c -o f_ptr_pgm.o f_ptr_pgm.c
  $ avr-gcc -g -Os -Wall -mmcu=atmega128 -Wl,-Map,f_ptr_pgm.map  -o 
f_ptr_pgm.elf f_ptr_pgm.o

The part that may or may not be a bug in gcc is the 'fp += 2;' statement
to increment the fp variable. You would think that 'fp++;' would do the
right thing, but gcc seems to want to convert the byte address to a word
address and only increment by one instead of the expected 2.

Hope that helps.

---
Ted Roth
PGP Key ID: 0x18F846E9
Jabber ID: address@hidden

Attachment: f_ptr_pgm.c
Description: Text document


reply via email to

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