"""Generate DROM fixed-point math lookup tables (`graphcalc_tables.h`) and bignum print sleds (`sled.S`).""" import math import sys from pathlib import Path def write_tables(hdr_path: Path) -> None: one32 = 1 << 32 lines = [ "// Auto-generated Q32.32 constants and CORDIC / log tables in DROM (.rodata).", "#pragma once", "#include ", "", f"#define Q32_ONE ({one32}LL)", f"#define Q32_PI ({round(math.pi * one32)}LL)", f"#define Q32_TWO_PI ({round(2.0 * math.pi * one32)}LL)", f"#define Q32_INV_TWO_PI ({round((1.0 / (2.0 * math.pi)) * one32)}LL)", f"#define Q32_HALF_PI ({round(0.5 * math.pi * one32)}LL)", f"#define Q32_E ({round(math.e * one32)}LL)", f"#define Q32_LN2 ({round(math.log(2.0) * one32)}LL)", f"#define Q32_INV_LN2 ({round((1.0 / math.log(2.0)) * one32)}LL)", f"#define Q32_LN10 ({round(math.log(10.0) * one32)}LL)", "", ] # CORDIC gain K = prod_{i=0}^{29} 1 / sqrt(1 + 2^{-2i}) k_gain = 1.0 atan_vals = [] for i in range(30): k_gain /= math.hypot(1.0, 2.0 ** (-i)) atan_vals.append(round(math.atan(2.0 ** (-i)) * one32)) lines.append(f"#define CORDIC_K ({round(k_gain * one32)}LL)") lines.append("static const int64_t CORDIC_ATAN[30] = {") for i in range(0, 30, 5): chunk = ", ".join(f"{v}LL" for v in atan_vals[i : i + 5]) lines.append(f" {chunk},") lines.append("};\n") # Shifted log table: ln(1 + 2^{-i}) for i = 1..30 in Q32.32 ln1p_vals = [0] + [round(math.log1p(2.0 ** (-i)) * one32) for i in range(1, 31)] lines.append("static const int64_t LN1P_POW2[31] = {") for i in range(0, 31, 5): chunk = ", ".join(f"{v}LL" for v in ln1p_vals[i : i + 5]) lines.append(f" {chunk},") lines.append("};\n") hdr_path.write_text("\n".join(lines), encoding="utf-8") def write_sled(sled_path: Path) -> None: out = [" .section .text", " .globl bn_sleds"] for r in range(8): out += [f"bn_sled{r}:"] + [f" .insn i 0x2B, 0, x{r}, x0, {k}" for k in range(127, -1, -1)] out += [" ret"] out += [" .section .rodata", " .align 2", "bn_sleds:"] out += [f" .word bn_sled{r}" for r in range(8)] sled_path.write_text("\n".join(out) + "\n", encoding="utf-8") if __name__ == "__main__": write_tables(Path(sys.argv[1])) write_sled(Path(sys.argv[2]))