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

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

RE: [avr-gcc-list] (no subject)


From: Wouter van Gulik
Subject: RE: [avr-gcc-list] (no subject)
Date: Mon, 28 Jan 2008 21:31:47 +0100

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