------- Comment #5 from wvangulik at xs4all dot nl 2007-11-01 21:50 -------
It seems that this is caused by the fact that eeprom_read_word is actually a
piece of inline assembler returning it's value in the Z register, using z as
"pointer class" description.
This then somehow eliminates the compiler's ability allocate a pointer.
Here is my test file source:
compile using: -Wall, -Os -mmcu=atmega16
===========================================================
#define u16 unsigned int
//If both are defined it will not compile
#define EXTRA_VAR //Use this to create extra variable parsing
#define USE_REG_Z //Use this to make use of Z register
static inline u16 eeprom_read_word(u16* p)
{
#ifdef USE_REG_Z
register u16 result asm("r30");
#else
register u16 result asm("r24");
#endif
asm volatile (
" ; Do nothing, just fake write to result"
: "+x" (p),
"=r" (result)
: );
return result;
}
extern void foo( u16 in0,
u16 in1,
u16 in2,
u16 in3,
u16 in4,
#ifdef EXTRA_VAR
u16 in5,
#endif
u16 in6);
void bar(void)
{
u16 in0 = eeprom_read_word((u16*)0);
u16 in1 = eeprom_read_word((u16*)1);
u16 in2 = eeprom_read_word((u16*)2);
u16 in3 = eeprom_read_word((u16*)3);
u16 in4 = eeprom_read_word((u16*)4);
u16 in5 = eeprom_read_word((u16*)5);
u16 in6 = eeprom_read_word((u16*)6);
foo( in0,
in1,
in2,
in3,
in4,
#ifdef EXTRA_VAR
in5,
#endif
in6 );
foo( in0,
in1,
in2,
in3,
in4,
#ifdef EXTRA_VAR
in5,
#endif
in6 );
}
When compiling you can see that adding an extra variable gives the problem. But
then changing the return variable to r24 solves the problem.
Hmm while typing I found another fishy thing:
Compiling for r24 with and without extra_var gives pushes of all registers.
However r12 is not used when compiled for non extra var. But using extra stack
instead
And trying -mcall-prologues does not invoke the prologue call when using extra
var and r24... it does for the other 2 ok compiling combinations.
I hope someone can make something out of this.
Oh and the r30 instead of z gives the following (more descriptive) error:
(insn 14 12 16 0 (set (reg/v:HI 54 [ in0 ])
(reg/v:HI 30 r30 [ result ])) 12 {*movhi} (insn_list:REG_DEP_TRUE 12
(ni
l))
(expr_list:REG_DEAD (reg/v:HI 30 r30 [ result ])
(nil)))
test.c:67: confused by earlier errors, bailing out
This involves movhi* which is in other bugreports as well, maybe this is the
vital clue?
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31644