avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Bug35013 - Incomplete check for pm() annotation


From: Andrew Hutchinson
Subject: Re: [avr-gcc-list] Bug35013 - Incomplete check for pm() annotation
Date: Sat, 16 Feb 2008 16:23:19 -0500
User-agent: Thunderbird 2.0.0.9 (Windows/20071031)

Note that this bug is also related to:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27192

which has similar issue generating "byte address" instead of word
address. Oddly my patch appears to fix  that without problem, using :

 45 0014 80E0              ldi r24,lo8(pm(foo+512))
 46 0016 90E0              ldi r25,hi8(pm(foo+512))
 47 0018 9093 0000         sts (q)+1,r25
 48 001c 8093 0000         sts q,r24


So it would appear problem with pm(foo+1) is more complicated than it
appears.

Ideas?




Andrew Hutchinson wrote:
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
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list




reply via email to

[Prev in Thread] Current Thread [Next in Thread]