From a71c36518094fc5c8b49c050dcb775387a292e35 Mon Sep 17 00:00:00 2001 From: Leandro Pereira Date: Thu, 18 Oct 2018 16:14:01 -0700 Subject: [PATCH] arch: xtensa: Reduce size of interrupt handling routines This patch reduces the size of ISRs by changing the script to generate the dispatcher per level to, instead of generating an indirect call per mask match, do that just once at the function end. For ESP32, this provides ~380bytes of savings in a (very) hot path (text, just for the matcher functions generated by xtensa_intgen.py, drop from 2197 bytes to 1817 bytes). The generated code also uses the BIT() macro, which shifts 1UL instead of 1. Shifting a signed integer is UB in C. Signed-off-by: Leandro Pereira --- arch/xtensa/core/xtensa_intgen.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/arch/xtensa/core/xtensa_intgen.py b/arch/xtensa/core/xtensa_intgen.py index 8984acd33c5..965bd5acc1a 100755 --- a/arch/xtensa/core/xtensa_intgen.py +++ b/arch/xtensa/core/xtensa_intgen.py @@ -24,6 +24,9 @@ ints_by_lvl = {} cindent = 0 def cprint(s): global cindent + if s.endswith(":"): + print(s) + return if s.find("}") >= 0: cindent -= 1 for xx in range(cindent): @@ -39,11 +42,10 @@ def emit_int_handler(ints): # handler pointer and argument as literals, saving a few # instructions and avoiding the need to link in # _sw_isr_table entirely. - cprint("if (mask & (1 << " + str(i) + ")) {") - cprint("struct _isr_table_entry *e = &_sw_isr_table[" + str(i) + "];") - print(""); - cprint("e->isr(e->arg);") - cprint("return 1 << " + str(i) + ";") + cprint("if (mask & BIT(%d)) {" % i) + cprint("mask = BIT(%d);" % i) + cprint("irq = %d;" % i) + cprint("goto handle_irq;") cprint("}") else: half = int(len(ints)/2) @@ -93,6 +95,7 @@ cprint("") # Re-include the core-isa header and be sure our definitions match, for sanity cprint("#include ") +cprint("#include ") cprint("#include ") cprint("") for l in ints_by_lvl: @@ -120,10 +123,16 @@ for lvl in ints_by_lvl: cprint("static inline int _xtensa_handle_one_int" + str(lvl) + "(unsigned int mask)") cprint("{") + cprint("int irq;") + print("") + ints_by_lvl[lvl].sort() emit_int_handler(ints_by_lvl[lvl]) cprint("return 0;") + cprint("handle_irq:") + cprint("_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);") + cprint("return mask;") cprint("}") cprint("")