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 22:41:25 +0100

 
> Try casting the expression (foo +1) to a function pointer. This may
> prove the point and correct the code in table - and elsewhere.
> 
> Arithmetic with function pointers is probably not well standardized - if
> at all.
> 

I agree. Although giving different results for the same statement is very
nasty.

I tried casting but I could not get any difference. When I tried to cast
both operands to a function pointer I got a message that + is not a legal
operation. Which seems ok and logical to me.

Is there anyway we can make this warning an error (by default)?
"main.c:14: warning: internal error: out of range error"

So the user knows something is broken in his code.

Thanks for the help

Wouter

> Andy
> 
> 
> Wouter van Gulik wrote:
> >> 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]