Boyapati, Anitha schrieb: > >> -----Original Message----- >> From: avr-gcc-list-bounces+anitha.boyapati=atmel....@nongnu.org >> [mailto:avr-gcc-list-bounces+anitha.boyapati=atmel....@nongnu.org] On >> Behalf Of Georg-Johann Lay >> Sent: Thursday, October 13, 2011 1:55 AM >> To: avr-gcc-list@nongnu.org >> Cc: Jörg Wunsch; Denis Chertykov >> Subject: [avr-gcc-list] May avr-gcc emit EIJMP/EICALL? >> >> 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. >> > > Yes. This is a bug. 'EIND' register is not set. > > Actually I have more such issues in queue: > > -> 'ELPM' instruction, emitted for functions in libgcc.S do not set RAMPZ > registers. > -> The case for generating ELPM instructions is not considered for > 'tablejump' patterns.
RAMPZ is a different issue, we shouldn't mix them up and solve the problems independently. RAMPZ is set in __do_copy_data, __do_global_ctors and __do_global_dtors and thus set appropriately in __tablejump_elpm__. __tablejump__ does not use ELPM and assumes that jump tables are located in the lower segment as arranged by the linker script, see section .progmem.gcc*. The jump targets in jump tables from switch_case/.ctors/.dtors are located in lower flash and their entries are gs() and use relaxation magic to have jumping pads generated. Or did I miss something? >> Instead, programs for big targets should use linker relaxation and jump >> to the generated jumping pad by means of IJMP/ICALL instead. >> >> Thoughts? > > But this works only when the range is below 128K bytes. EIJMP/EICALL are > required beyond that. I think a proper fix will be to generate {EIND, > EIJMP/EICALL} instructions and then apply relaxation. Why that? Indirect jump IJMP/ICALL will jump to a jumping pad located in the lower segment which redirects to the final jump target by a direct jump that might target all of the address space. The overhead an time is 2 ticks which is no worse that fiddling with EIND. That's the intention of relaxation and jumping pads and the mechanism is knocked out be EI instructions. Bottom line is that there is no need to ever touch or use EI gadgets, and EI should be removed from the compiler like so: Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 179843) +++ config/avr/avr.md (working copy) @@ -3635,9 +3635,9 @@ (define_insn "call_insn" ;; Operand 2 is 1 for tail-call, 0 otherwise. "" "@ - %!icall + icall %~call %x0 - %!ijmp + ijmp %~jmp %x0" [(set_attr "cc" "clobber") (set_attr_alternative "length" @@ -3659,9 +3659,9 @@ (define_insn "call_value_insn" ;; Operand 3 is 1 for tail-call, 0 otherwise. "" "@ - %!icall + icall %~call %x1 - %!ijmp + ijmp %~jmp %x1" [(set_attr "cc" "clobber") (set_attr_alternative "length" Index: config/avr/libgcc.S =================================================================== --- config/avr/libgcc.S (revision 179842) +++ config/avr/libgcc.S (working copy) @@ -740,11 +740,7 @@ DEFUN __prologue_saves__ out __SP_H__,r29 out __SREG__,__tmp_reg__ out __SP_L__,r28 -#if defined (__AVR_HAVE_EIJMP_EICALL__) - eijmp -#else ijmp -#endif ENDF __prologue_saves__ #endif /* defined (L_prologue) */ Johann > > Anitha > _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list