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 <leandro.pereira@intel.com>
This commit is contained in:
Leandro Pereira 2018-10-18 16:14:01 -07:00 committed by Andrew Boie
commit a71c365180

View file

@ -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 <xtensa/config/core-isa.h>")
cprint("#include <misc/util.h>")
cprint("#include <sw_isr_table.h>")
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("")