Georg-Johann Lay schrieb:
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
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.
The according avr-gcc feature is also upstream now. It adds a new
option -m[no-]gas-isr-prologues and a new function attribute to disable
__gcc_isr generation for individual ISRs:
http://gcc.gnu.org/onlinedocs/gcc/AVR-Function-Attributes.html
If you want to play around with it, you need Binutils that implement
PR20296 (e.g. Binutils GIT master or upcoming 2.29) and avr-gcc that
implements PR81268 (GCC SVN trunk r250093 or newer).
The feature is enabled per default for all optimization levels except
for -O0 and -Og.
Johann
_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list