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