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

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

Re: [avr-gcc-list] May avr-gcc emit EIJMP/EICALL?


From: Georg-Johann Lay
Subject: Re: [avr-gcc-list] May avr-gcc emit EIJMP/EICALL?
Date: Sun, 23 Oct 2011 20:48:40 +0200
User-agent: Mozilla Thunderbird 1.0.7 (Windows/20050923)

Georg-Johann Lay a écrit:
avr-gcc currenly emits EICALL/EIJMP instructions without caring for EIND, e.g. avr.md:3630:

(define_insn "call_insn"
  [...]
  ""
  "@
    %!icall
    %~call %x0
    %!ijmp
    %~jmp %x0"
    ...)

where %! resolves to 'e' for targets with > 128k of flash.

IMO that is not okay because the compiler does not care for EIND and even if he (or the user) did that approch is it not IRQ-save.

Instead, programs for big targets should use linker relaxation and jump to the generated jumping pad by means of IJMP/ICALL instead.

Thoughts?

This is PR50820 now: http://gcc.gnu.org/PR50820

PR50820 will be fixed in 4.6.2 and 4.7.0

As far as I can see, after the changes under PR50820 the situation
is as follows:

== EICALL, EIJMP and EIND on devices with more than 128 KiB
   of program memory ==

* The compiler never sets EIND.

* The startup code from libgcc never sets EIND.

* Notice that startup code is a blend of code from libgcc and avr-libc.
  For the impact of avr-libc on EIND, see avr-libc documentation.

* The compiler uses EIND in EICALL/EIJMP instructions or might read
  EIND directly.

* The compiler assumes that EIND is not changed during startup code or
  run of the application. In particular, EIND is not saved restored in
  function or interrupt service routine prologue/epilogue.

* It is legitimate for user-specific startup code to setup EIND
  early, for example in section .init1 prior to general startup code.

* For indirect calls to functions and computed goto, the linker will
  generate jump pads.  The indirect call/jump will forward to such
  a jump pad. The jump pad then jump to the desired address by
  means of a direct jump.

* Jump pads will be generated if the address of a function/label
  is taken and if the final location of that function/label
  is in a code segment *outside* the segment where EIND points to.

* Addresses of labals are taken in the following situations:
  - Indirect function calls, more precisely: taking address of
    respective function
  - Computed goto
  - If prologue-save function is used, see  -mcall-prologues
    command line option
  - Switch/case dispatch tables. If you do not want such dispatch
    tables, specify the -fno-jump-tables command line option.
  - C and C++ constructors called during startup
  - C and C++ destructors called during shutdown

* The default linker script is arranged for code with EIND = 0.
  If code is supposed to work for a setup with EIND != 0 a custom
  linker script has to be used to put sections whose name start
  with .trampolines to the segment where EIND points to.

* Jumping to a non-symbolic addresse like so

        int main (void)
        {
            // Call function at word address 0x2
            return ((int(*)(void)) 0x2)();
        }

  is /not/ supported. Instead, a jump pad has to be set up like so

        int main (void)
        {
            extern int func_4 (void);

            // Call function at byte address 0x4
            return func_4();
        }

   and the application be linked with -Wl,-defsym=func_4=0x4

==

Text like above should be added to GCC's documentation.

If there is something missing, incorrect or bad style, please suggest.

In my understanding, caveats are no problem.  But problems will arise if
caveats are not documented and one is not aware of them.

Johann




reply via email to

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