Thanks for information and link!
I believe the wiki is misleading or refers to an earlier version of avr-gcc
For 256 devices avr-gcc uses linker trampolines to allow 16 bit function
pointers to reach any function located anywhere in address map.
The EIND is set to zero by gcc. (Trampolines are located in lower memory)
When a function pointer is assigned the address of function (in upper
memory), a full sized jump to the function is added to trampoline table.
The function pointer gets the 16 bit address of this entry.
When the jump occurs - using EICALL, it will jump to trampoline using 16
bit address and EIND set to zero. The trampoline JMP will then take it
to the function.
If the function is in lower memory, the trampoline is not created by
linker (though I have not checked that!)
This basic mechanism could use ICALL or IJMP - since they work on lower
memory.
Only if you want to have trampolines above first 64Kwords or want to
call directly a function without trampoline, then EICALL is essential
and EIND has to change.
Somehow boot loaders fall into this category and AVR-GCC thus uses
EICALL to support this.
There are a couple of oddities - which I hope to resolve.
First is that function pointer arithmetic of any kind is doomed - the
handling is gcc is wrong and will give differing results depending on
constructs used and optimization.
Secondly, there are a few missed optimization of jump/call - where a
direct call could be used instead of EICALL.
Andy
Dusan Ferbas wrote:
Hi, your case is, that a bootloader (BL) uses trampolines.
I described a case in this list (June 2008 and Mar 2009), where an
application calls a BL, where eicall resides.
There is a wiki page about it:
http://www.ethernut.de/nutwiki/Nut/ATmega256x
Because of enabled interrupts during time, when BL is called, we are
using:
#ifdef atmega2561
unsigned char eind_local; // asm ("r17");
eind_local = EIND;
EIND = 0x3F800 >> (16 + 1); //highest bit (for atmega2561 ==
1, because in words)
#endif
BootInfoHeader->fn[BootInfoHeader->SectionID](BootInfoHeader->address,
(unsigned short *)received_data_p, BootInfoHeader->pagesize);
#ifdef atmega2561
EIND = eind_local;
#endif
Dusan
At 14:35 15.12.2009, andrewhutchin...@cox.net wrote:
Thanks, it would be nice if this was documented.
I noticed it when reviewing addressing modes and a omission in call
patterns.
void (*fptr)();
fptr = main;
(*fptr)(); //Will use EICALL - should be CALL main
which become readily apparent with inlined code.
Andy
---- Sean D'Epagnier <geckosena...@gmail.com> wrote:
> On 12/14/09, Andrew Hutchinson <andrewhutchin...@cox.net> wrote:
> > The patterns for AVR mega 256 use EICALL an EIJMP
> >
> > Both require EIND to be set to provide upper address bits
> >
> > However, we are using linker trampolines for both, so in either
case the
> > 16 bit jump or call is to the trampolines.
> >
> > Are not the trampolines always located in first 128Kbytes? Thus we
> > should be using ICALL and IJMP and not needing to set use EIND at
all.
> >
> > What have I miss-understood?
> >
>
> Hi,
>
> Yes this confused me a lot too, but the reason is because the
> trampoline is not in the first 128kbytes for a bootloader, so if the
> compiler uses eijmp and eicall, then it is possible to do indirect
> calls there too, but it still works fine in normal code.
>
> Sean
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list