> http://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/Pointer-Arith.html#Pointer- > Arith > > The elements to which function (and void) pointer refer are assumed to > be size 1 byte. > > So if you really want to mess with these pointers, you must treat as > byte address. >
Exactly what I thought. If I do nasty things I should know what I am doing. > That does not explain the other problems reported directly. However > given foo is a function pointer, what is the type of the expression foo > + 1.? Perhaps gcc treats such an expression as void? > Exactly the table is still messed up by gcc. Any idea how I/we can test this? I looked at the -da output but I could not find anything related to the table. Is the avr backend involved in generating the correct function pointer addresses? Where is this gs() coming from? I searched through the as documentation but I could not find it. Is it from ld? Are there other platforms supported by gcc having the same strange non equal data/program space? I know that the TI C54x series have a 8 bit program space, and a 16 bit data space. sizeof(char) == sizeof(int), both 16-bit!, but instructions and function addresses are in bytes .... Maybe we can find some hints there? HTH Wouter > Andy > > > > Andrew Hutchinson wrote: > > I think you highlight the problem for gcc. > > > > We are have to treat program memory as byte addressable to support LPM. > > > > Direct, function calls only want word address to form the correct > > opcode. But we use byte address labels and assembler removes the > > redundant bit to form the correct opcode. > > > > Indirect (icall) functions show up the anomaly as these are formed > > outside of the assembler. > > > > Gcc is assuming that the item that a function pointer points to is > > size 1. When in fact it is size 2. > > > > This is similar as having pointer to some other object such as long: > > > > long *ptr; > > x = ptr+1; /* x will be assinged byte address potr+4 */ > > > > So if we can correct that mistake, I believe the problem is resolved. > > Now, I am not sure how gcc determines that size! So I will look. > > > > Andy > > > > > > > > Wouter van Gulik wrote: > >> Compiling the following program ends up in "main.c:(.text+0x2): > >> warning: internal error: out of range error" > >> > >> ================= main.c ================ > >> > >> //Dummy func > >> void foo(void) {} > >> > >> //Table with address manipulation > >> void (* const pFuncTable[]) (void) = { > >> foo + 0, > >> foo + 1, //need odd offset > >> }; int main(int argc, char* argv[]) { > >> //Call table > >> pFuncTable[1](); > >> return 1; > >> } > >> Looking into the generated assembler gives: > >> > >> pFuncTable: > >> .word gs(foo) > >> .word foo+1 > >> > >> Which is wrong. It should have been gs(foo + 1) or perhaps gs(foo)+1 > >> > >> But the true wrong thing is that gcc out smarts the table (since it's > >> const) > >> and directly does: "call foo+1". This gives the internal error. > >> Even worse is that the compiler does not stop!! IMHO it should stop > >> here, > >> instead it generates this final assembly: 000000a6 <main>: > >> a6: 0e 94 00 00 call 0 ; 0x0 <__vectors> > >> aa: 81 e0 ldi r24, 0x01 ; 1 > >> ac: 90 e0 ldi r25, 0x00 ; 0 > >> ae: 08 95 ret > >> > >> > >> Before I post a note to the existing bug report (it's probably > >> related with > >> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27192 ) I want to know > >> what foo > >> + 1 is supposed to do. GCC seems to mix up byte address (for lpm) and > >> word > >> addresses (for ijmp/jmp//icall/call). > >> Is it supposed to increment the byte address or the word address? > >> I guess byte addresses are what it's supposed to be, since calling > >> foo + 2 > >> ends up in calling foo + 2 bytes. Leaving foo + 1 as illegal address. > >> > >> And I just found another nasty error: > >> > >> //Dummy func > >> void foo(void) {} > >> > >> //Table with address manipulation > >> void (* const pFuncTable[]) (void) = { > >> foo + 4, //need odd offset > >> }; int main(int argc, char* argv[]) { > >> //Call table > >> pFuncTable[0](); > >> return 1; > >> } > >> This will generate a correct call (4 bytes after foo) but the value > >> in the > >> table is not left shifted! Meaning that a call via the table will > >> generate a > >> call to the wrong address, while the original call is ok. > >> > >> Wouter > >> > >> > >> > >> _______________________________________________ > >> AVR-GCC-list mailing list > >> AVR-GCC-list@nongnu.org > >> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list > >> > > > > > > _______________________________________________ > > AVR-GCC-list mailing list > > AVR-GCC-list@nongnu.org > > http://lists.nongnu.org/mailman/listinfo/avr-gcc-list _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list