[Top][All Lists]
[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
f_ptr_pgm.c
Description: Text document