#!/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
    s = cindent*"\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 lvl not 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 <sys/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("")
