[Top][All Lists]

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

Re: [avr-gcc-list] Function Address fixup missing?

From: Mau
Subject: Re: [avr-gcc-list] Function Address fixup missing?
Date: Sat, 27 Jun 2009 12:37:12 +0200
User-agent: Thunderbird (Windows/20090605)

Stu Bell wrote:
>> Stu Bell wrote:
>>> Trampolines work only for statically linked functions, not function 
>>> pointers.
>> Sorry, but I don't understand this.
>> I believe that there is no problem with statically linked functions.
> And that's what I said. There is not a problem with statically linked
> functions.

Sorry, I meant that the trampolines have nothing to do with direct calls.
As I understood the AtMega core have assembly instructions for direct
call and jump with full 24 bit address within the instruction code. So
no trampoline is needed and neither extension registers like EIND. I
also believe that GCC is able to generate such correct code for direct
calls and jumps anywhere.

> At this point, "puntatore" is a function pointer.  Unless the GCC gods
> disagree with me (in which case I have been doing a lot of work for
> nothing for the last 2 years), GCC only understands puntatore as a
> 16-bit entity.  Further, it will *not* use the trampoline for this call.
I don't agree with this, but maybe some GCC guru can clarify further.
I'll try to explain now, as I showed you in the code in my last mail.

I believe that GCC assumes two things:
- Register EIND is always zero, and nobody ever touches it
- Trampolines are always in lower flash (<128K)

With these assumptions it is possible to use 16bit pointers to functions
(the default pointers in AVR-GCC) to reach functions anywhere.

I'll try to explain what I have understood, and please tell me if and
where I am wrong.

When in the code there is a request for the address of a function which
is over 128K, this is what I believe happens:

1) a trampoline il lower memory is generated. This trampoline contains a
single jump to the full 24 bit address of function.
2) The address of the trampoline is returned instead. This is important
so I repeat: "The address of the trampoline is returned instead". This
address is still a full 24 bit address, but since the trampoline is in
lower memory, the upper 8 bits are zero. So this pointer is "safely"
stored into a 16Bit variable, without loosing information.

When, in the code, there is a call to the function through its pointer
(stored into a 16bit variable), this is what I think happens:

1) The GCC generates the load of the pointer contents, which is the low
part of the trampoline address, and generates also a eicall instruction.
2) When this code executes, during the eicall processing, the EIND
register is used to extend the 16bit address, but EIND is zero, and the
24bit address resulting from this concatenation operation results in the
24bit address of the trampoline.
3) The eicall places a 24bit return address into the stack, and the PC
is loaded with the address of the trampoline so the execution continue there
4) The trampoline contains the full address of function, so the PC is
again loaded with the correct function address (and the EIND register is
not involved anymore).
5) When the function will return, it will find the full return address
on the stack so it will return to the point after the eicall.

This magic works, in my understanding, without any penalty for code
below 128K, and with only a small penalty in time and space, but only
for functions accessed through a pointer.
And all this using only 16bit pointers!
Or maybe I am completely wrong, but to my support there is the small
code that I sent to the list in my mail, that works exactly as I described.

My original question was related to a possible implementation bug, while
you were trying to explain to me that the whole trampoline stuff is not
working for a design problem (16 bit pointers and so ...).

Can you comment on this?

As a last comment, I can say that I can place all my functions where a
pointer is needed in lower memory, and indeed this was my first attempt.
Unfortunately the library code is always placed last, so over 128K, and
functions like fputc do use function pointers (I assume to manage open
file descriptors), and so I need that the trampoline stuff works, or
some other workaround.

Thanks all.

reply via email to

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