#!/usr/bin/env python3
import re
import fileinput

# Pass an Xtensa core-isa.h file on stdin or the command line, emits a
# C file on output containing optimized interrupt dispatch routines.

# FIXME: looking at the assembly generated by the ESP-32 toolchain,
# this isn't as optimal as I'd hoped.  the individual cases are tested
# using a L32R + BNONE (i.e. a full mask test) instead of a BBSI, and
# the handlers are being invoked with CALL8 instead of CALL4,
# inexplicably wasting four words of stack.  Maybe this should be
# emitting assembly instead.  Wouldn't be much more complicated and
# would share all the same structure.

# My manual count of instructions says that a linear search becomes
# faster on average when there are three or fewer bits to test.  Would
# be four, if the compiler would generate BBSI instructions.
MAX_TESTS = 3

ints_by_lvl = {}

# print() wrapper that automatically handles indentation levels
cindent = 0
def cprint(s):
    global cindent
    if s.endswith(":"):
        print(s)
        return
    if s.find("}") >= 0:
        cindent -= 1
    for xx in range(cindent):
        s = "\t" + s
    print(s)
    if s.find("{") >= 0:
        cindent += 1

def emit_int_handler(ints):
    if len(ints) <= MAX_TESTS:
        for i in ints:
            # FIXME: a little work could allow us to extract the
            # handler pointer and argument as literals, saving a few
            # instructions and avoiding the need to link in
            # _sw_isr_table entirely.
            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)

        m = 0
        for i in ints[0:half]:
            m |= 1 << i
        cprint("if (mask & " + ("0x%x" % (m)) + ") {")
        emit_int_handler(ints[0:half])
        cprint("} else {")
        emit_int_handler(ints[half:])
        cprint("}")

########################################################################

# Annoyingly need to join lines and remove #-marked annotations.  Some
# versions of the preprocessor (ahem, esp32 SDK) like to include
# newlines in the output where the original expressions are expanded
# from 100% single line macros.  Slurp it into a single string and
# parse via whitespace.
blob = ""
for l in fileinput.input():
    l = l if l.find("#") < 0 else l[0:l.find("#")]
    blob += l.rstrip() + " "

for match in re.finditer(r'__xtensa_int_level_magic__\s+(\d+)\s+(\d+)', blob):
    irq = int(match.group(1))
    lvl = int(match.group(2))

    if not lvl in ints_by_lvl:
        ints_by_lvl[lvl] = []

    ints_by_lvl[lvl].append(irq)

cprint("/*")
cprint(" * THIS FILE WAS AUTOMATICALLY GENERATED.  DO NOT EDIT.")
cprint(" *")
cprint(" * Functions here are designed to produce efficient code to")
cprint(" * search an Xtensa bitmask of interrupts, inspecting only those bits")
cprint(" * declared to be associated with a given interrupt level.  Each")
cprint(" * dispatcher will handle exactly one flagged interrupt, in numerical")
cprint(" * order (low bits first) and will return a mask of that bit that can")
cprint(" * then be cleared by the calling code.  Unrecognized bits for the")
cprint(" * level will invoke an error handler.")
cprint(" */")
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:
    for i in ints_by_lvl[l]:
        v = "XCHAL_INT" + str(i) + "_LEVEL"
        cprint("#if !defined(" + v + ") || " + str(v) + " != " + str(l))
        cprint("#error core-isa.h interrupt level does not match dispatcher!")
        cprint("#endif")
cprint("")

# Populate empty levels just for sanity.  The second-to-last interrupt
# level (usually "debug") typically doesn't have any associated
# vectors, but we don't have any way to know that a-prioi.
max = 0
for lvl in ints_by_lvl:
    if lvl > max:
        max = lvl

for lvl in range(0, max+1):
    if not lvl in ints_by_lvl:
        ints_by_lvl[lvl] = []

# Emit the handlers
for lvl in ints_by_lvl:
    cprint("static inline int _xtensa_handle_one_int" + str(lvl) + "(unsigned int mask)")
    cprint("{")

    if not ints_by_lvl[lvl]:
        cprint("return 0;")
        cprint("}")
        continue

    cprint("int irq;")
    print("")

    emit_int_handler(sorted(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("")
