Problems with gcc-4.2.2. Are those known bugs ?

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

I found 2 different problems with gcc, I don't know if they are new or not.

The compiler I use is:
avr-gcc -v
Using built-in specs.
Target: avr
Configured with: ../../source/gcc-4.2.2/configure -v --target=avr --disable-nls --prefix=/usr/local/avr --with-gnu-ld --with-gnu-as --enable-languages=c,c++ --quiet --disable-libssp --with-dwarf2
Thread model: single
gcc version 4.2.2

I built it with the script: build-avr-gcc-4.2.2-libc-1.6.2-makeinfo-fixed.tar.gz

The first problem is related to the use of FUSES with ATmega48, the second is a code generation issue I found with ATtiny861, but I believe is target independent.

This is the first problem:
On the ATmega48, FUSE_MEMORY_SIZE is undefined.
----------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include

/* ATmega48 */
FUSES =
{
.low = (FUSE_CKDIV8 & FUSE_SUT0 & FUSE_CKSEL3), /* 0x67 */
.high = HFUSE_DEFAULT,
.extended = EFUSE_DEFAULT,
};

int
main (void)
{
}
----------------------------------------------------------
make

-------- begin --------
avr-gcc (GCC) 4.2.2
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiling C: bug1.c
avr-gcc -c -mmcu=atmega48 -I. -gstabs -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./bug1.lst -std=gnu99 -Wundef -MMD -MP -MF .dep/bug1.o.d bug1.c -o bug1.o
bug1.c:10: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__fuse'
make: *** [bug1.o] Error 1
----------------------------------------------------------

This is the second problem.

I show here 2 versions of the same program. The first version shows the problem. (BTW removing the "volatile" does not change the code). The second version is an work around that produces what I would expect to see.
---------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include

volatile uint8_t x __attribute__ ((section (".noinit")));
volatile uint8_t y __attribute__ ((section (".noinit")));

int
main (void)
{
if ((x & 0xE0) >= 0xC0)
y = 1;
}
---------------------------------------------------------
int
main (void)
{
if ((x & 0xE0) >= 0xC0)
5e: 80 91 60 00 lds r24, 0x0060
62: 90 e0 ldi r25, 0x00
64: 80 7e andi r24, 0xE0
66: 90 70 andi r25, 0x00
68: 80 3c cpi r24, 0xC0
6a: 91 05 cpc r25, r1
6c: 1c f0 brlt .+6 ; 0x74
y = 1;
6e: 81 e0 ldi r24, 0x01
70: 80 93 61 00 sts 0x0061, r24
}
74: 80 e0 ldi r24, 0x00
76: 90 e0 ldi r25, 0x00
78: 08 95 ret

0000007a <_exit>:
7a: ff cf rjmp .-2 ; 0x7a <_exit>
----------------------------------------------------------
#include
#include
#include
#include
#include
#include
#include
#include

volatile uint8_t x __attribute__ ((section (".noinit")));
volatile uint8_t x2 __attribute__ ((section (".noinit")));
volatile uint8_t y __attribute__ ((section (".noinit")));

int
main (void)
{
x2 = x & 0xE0;
if (x2 >= 0xC0)
y = 1;
}
----------------------------------------------------------
int
main (void)
{
x2 = x & 0xE0;
5e: 80 91 60 00 lds r24, 0x0060
62: 80 7e andi r24, 0xE0
64: 80 93 61 00 sts 0x0061, r24
if (x2 >= 0xC0)
68: 80 91 61 00 lds r24, 0x0061
6c: 80 3c cpi r24, 0xC0
6e: 18 f0 brcs .+6 ; 0x76
y = 1;
70: 81 e0 ldi r24, 0x01
72: 80 93 62 00 sts 0x0062, r24
}
76: 80 e0 ldi r24, 0x00
78: 90 e0 ldi r25, 0x00
7a: 08 95 ret

0000007c <_exit>:
7c: ff cf rjmp .-2 ; 0x7c <_exit>
---------------------------------------------------------

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

Quote:
The first problem is related to the use of FUSES with ATmega48

As far as I know, avr-gcc knows nothing about fuses. Fuses are usually set by the programming tool, not the compiler.

Quote:
The first version shows the problem.

You'll have to be more clear about what the problem is. I see nothing wrong with the program (aside from the fact that the program does nothing).

Regards,
Steve A.

The Board helps those that help themselves.

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

Ok, The FUSES is an avr-libc feature. There is a problem with the header files for ATmega48.

On the second problem, the program is not supposed to do anything. It is just to show the compiler generates 2 compare instructions in a row, and the branch will not match the condition in the source code.

Edmar

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

Quote:

It is just to show the compiler generates 2 compare instructions in a row

Yes, and the second one is a cpc (compare with carry) which takes into account some of the effects of the first cpi (compare with immediate). As the AVR is an 8-bit machine it needs to do two compares to actually compare a 16-bit integer.

In the second program I suspect that the first comparison (for the low bytes?) is gotten as a side effect of the previous machine instructions, but I have not dug deep enough into it to be certain. My curiosity isn't as big as my laziness... :wink:

Quote:
the branch will not match the condition in the source code

If you by this mean that the generated machine code does not match the C code that it is adjacent to then this is quite normal, as you're compiling with the -Os switch, activating the optimizer. Optimizing implies shuffling around the code in a manner that it will not map to the C code anymore, but still keeping the C codes semantics.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

I am sorry, my bad. I did not realized that CPC would take into account the Z bit from previous compare.

Thanks
Edmar

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

In the first example everything is promoted to int width, perhaps due to the complex expression involved. In the second example the compiler recognized that each broken-out step could be done in 8 bits.

I prefer not to make my head hurt by doing a theological thesis on C promotion rules, and whether they are politically-correct or not. But just as a guess perhaps 0xNN is treated like an int. If you cast one or both of the constants in the first example to 8 bits, does it then generate the 8-bit case?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

I'm on my first evening of vacation, and might stay away from 'freaks intermittently. Won't matter to anyone... Even if all the usual avr-gcc folks took a trip to the moon and back it would go unnoticed as Lee now handles most of the avr-gcc/avrlibc questions anyway. I guess he's slowly going cheap... 8)

Take care all, and see you in the war thread eventually!

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

You can read this-
http://www.nongnu.org/avr-libc/u...

then just live with the fact that unless you do as you did in the second version, you will probably get promoted to an int on that bitwise comparison. Casting as the FAQ suggests never works for me. Most of the time its not worth the work to make sure those stay at 8bit comparisons.

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

edmarwjr wrote:

This is the first problem:
On the ATmega48, FUSE_MEMORY_SIZE is undefined.

Edmar! You made it here! :)

Can you re-build avr-libc from the latest snapshot? The fuse and signature information was added to the ATmega48 header file (iom48.h) on 2008-06-18, after 1.6.2 was released. There hasn't been a new avr-libc release yet. Sorry for the hassle.

Hey, all: Give Edmar a warm welcome here on AVR Freaks! I know Edmar personally. He's fairly new to AVRs, but he knows a lot about GCC on another port.

Eric Weddington