Gcc bug? missing castu.b in gcc 4.2.2-atmel.1.0.8

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi everybody.
I've been trying the latest buildroot from http://atmel.no/buildroot.
All of the previous apps worked except from one. Looking for the problematic line or a possible mistake I found that, given the conditions, a function like:

void myfunc( unsigned char c )
{
   printf("%u\n", (unsigned int) c );
}

would return values greater than 255. In fact, I get values near 0xFFFFFFFF which means that the parameter is probably getting passed the wrong way.
I found that adding a simple nop for loop after calling myfunc() can fix things. I still don't know if it is a bug or not, but the program runs alright on the pc or an older toolchain).
I did the listings and it looks as if gcc forgets to add a castu.b before passing the parameter to myfunc(). A full word OR is done with negative values before calling it, so that explains why.
Here I attach a test case.
'make' makes the target for the avr32, 'make host' makes it for the host.

I don't know if there is a newer toolchain however nor if the same problem applies, I hope this helps.

By default the avr32 version should reproduce the error ( with gcc v4.2.2-atmel.1.0.8 ). To make it go right line 78 on lcd.c should be commented and line 74 uncommented (see the comments nearby, there are other ways to make it work too).

thanks
Carlos

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can you provide a simple test case with a single C file?

Hans-Christian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes, here it is.
Now by default it should print the error (it should print numbers like 64 and 42245677 or something similar to the console).
If you comment out line 55 and uncomment line 51 or 48 then it should do fine.
Another way to avoid the error is to declare a global variable and assign something to it, just like:

volatile int myvar = 0;
#define	LCD_setX( x )	do { LCD_writeInst( (1<<7) | (7<<3) | (x) ); myvar = 1234; } while(0)

I think there is no need for the variable to be volatile.
Also, this won't work:

#define	LCD_setX( x )	do { LCD_writeInst( (1<<7) | (7<<3) | (x) );} while(0)

Oh, to compile it I did:

avr32-linux-gcc -O2 main.c -g -Wa,-ahl=main.lst -o test_avr32

Thanks,
Carlos

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Confirmed using 4.2.2-atmel.1.0.8 from the Google buildroot fork. castu.b is missing if compiled using anything else then -O0

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Seems like a bug with sign extending an unsigned variable.

Attached is a really stripped down test code which exposes the problem.

To compile: avr32-linux-gcc -g3 -Wall -O2 -o printftest_O2 printftest.c

Attachment(s): 

Hans-Christian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Indeed a bug, identified and fixed. Hopefully I will have a patch on Monday to post here. Buildroot will be updated as well.

Hans-Christian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try the attached patch :)

Attachment(s): 

Hans-Christian