I have looked at fix for the function pointer arithmetic bug :
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35013
This is due to avr-gcc not recognizing an address of the form foo+k
as a program memory location. So a table of address for foo, foo()+1 and
foo()+2 ends up as:
46 0006 0000 .word pm(foo)
47 0008 0000 .word foo+1
48 000a 0000 .word foo+2
The patch I created now correctly treats addresses of the form address +
constant as program memory addresses.
79 0006 0000 .word pm(foo)
80 0008 0000 .word pm(foo+1)
81 000a 0000 .word pm(foo+2)
However, the assembler does not seem to cope with the resultant
expressions pm(address+k) and gives me error:
pmaddr.o:(.data+0x8): warning: internal error: out of range error
How do I get around this?
Andy
Andrew Hutchinson wrote:
There is a bug!
Backend (avr part) creates special "pm()" annotation by looking at
RTL. This is done in avr.c by this function:
static bool
avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
debug_rtx(x); /*ADDED TO DEBUG*/
fprintf(stderr,"size=%d align=%d\n\n",size,aligned_p); /*ADDED TO DEBUG*/
if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
&& ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
|| GET_CODE (x) == LABEL_REF))
{
fputs ("\t.word\tpm(", asm_out_file);
output_addr_const (asm_out_file, x);
fputs (")\n", asm_out_file);
return true;
}
return default_assemble_integer (x, size, aligned_p);
}
(I added 2 lines to debug it)
You will see it looks symbol_ref or label_ref - otherwise it does not
use pm.
So I ran it with following testcase to see what argument get sent:
//Dummy func
int table[]= {1,2};
char ctable[]= {3,4};
void foo(void) {}
//Table with address manipulation
void (* const pFuncTable[]) (void) = {
foo + 0,
(foo + 1),
foo +2
};
....and we get the following:
(const_int 1 [0x1])
size=2 align=1
(const_int 2 [0x2])
size=2 align=1
(const_int 3 [0x3])
size=1 align=1
(const_int 4 [0x4])
size=1 align=1
(symbol_ref:HI ("foo") [flags 0x3] <function_decl 0x7fdcf030 foo>)
size=2 align=1
(const:HI (plus:HI (symbol_ref:HI ("foo") [flags 0x3] <function_decl
0x7fdcf030 foo>)
(const_int 1 [0x1])))
size=2 align=1
(const:HI (plus:HI (symbol_ref:HI ("foo") [flags 0x3] <function_decl
0x7fdcf030 foo>)
(const_int 2 [0x2])))
size=2 align=1
You will see last two cases are an expression with outer code as
const:HI so it will not match, it does not add pm().
Please report as bug. Other may suggest the correct way of fixing
this. I am not sure why the test is so specific.
Andy
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list