On 15.06.2017 14:43, Georg-Johann Lay wrote:
https://gcc.gnu.org/PR20296

is about speeding up "small" ISRs, and is open for 12 years now...

Anyone familiar with avr-gcc knows that a fix would be high effort and risk, and that's the major reason for why PR20296 is still open (and even classified "suspended").

In some forum discussion (again!) on that issue, there was the following proposal to approach that PR:

1) Let GCC emit directives / pseudo-instructions in non-naked ISR prologue / epilogue

2) Let GAS scan the code and replace the directives with code as needed.

Currently,

#include <avr/io.h>
#include <avr/interrupt.h>

ISR (INT0_vect)
{
     __asm ("; Code");
}

emit something like:


__vector_1:
     push r1
     push r0
     in r0,__SREG__
     push r0
     clr __zero_reg__
.L__stack_usage = 3

     ; Code

     pop r0
     out __SREG__,r0
     pop r0
     pop r1
     reti


which would change to:


__vector_1:
     .maybe_isr_prologue 123
     ;; Rest of prologue

     ; Code

     ;; Rest of epilogue
     .maybe_isr_epilogue 123
     reti

GAS would then scan the code associated to the function and replace the .maybe by appropriate sequence to safe / init / restore tmp-reg, zero-reg and SREG. Other registers like R24 are handled by GCC as usual. For example, if the scan reveals that tmp-reg is not needed but zero-reg is (which will imply SREG due to the CLR) the replacement code would be:


__vector_1:
     push r1
     in r1,__SREG__
     push r1
     clr __zero_reg__

     ; Code

     pop r1
     out __SREG__,r1
     pop r1
     reti


Maybe someone is interested in implementing the GAS part, and if that is the case and the proposal is feasible, I would take care of the GCC part.

Caveats:

a) .L__stack_usage can no more be computed by GCC

b) It's hard to find the end of the relevant code. We might have interleaved sections (like with dispatch tables), there might be code that is emit after the epilogue, there might be more than 1 epilogue, dunno if GAS can infer whether JMP is local or non-local.

We could add a new GCC pass that filters out situations that are pointless to scan like code with dispatch tables or function calls, and fall back to classical prologue / epilogue in such cases.

The .maybe gets function-unique identifiers (123 in the example) so that GAS knows which epilogue belongs to which .prologue provided that's helpful.

I am not familiar with Binutils / GAS though and don't know if it's easy to add the 2 new passes: One to scan and one to replace the .maybe with appropriate code. IIUC GAS only works on sections, and the scan would be on BFD internal representation (like relaxing) after the parser read in the asm sources?

FYI, I just went ahead any typed down these lines for GAS.


If someone wants to give it a try, it's here:

https://sourceware.org/bugzilla/show_bug.cgi?id=21683#c2

Binutils manual didn't catch up with master yet.  If so, you should
see a new "AVR Pseudo Instructions" entry in

https://sourceware.org/binutils/docs/as/AVR_002dDependent.html

that adds some documentation / specification.

Johann


The GCC change would add a new option, configure test whether GAS supports this, let ISR prologue and epilogue emit new unspec_volatile pseudo insns and add a scan pass to detect situations that are pointless should fall back to old code, like when dispatch tables, calls or non-local goto is seen.

Johann

_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to