blob: fce1b018d5ec7bd70501699195377b3746aa9dac [file] [log] [blame]
#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
"""mdbook preprocessor that generates ISA tables for the OTBN.
The preprocessor also handles `{{#otbn-insn-ref ... }}` links to the ISA Table.
"""
import json
import sys
import re
from pathlib import Path
import tempfile
import subprocess
from mdbook import utils as md_utils
REPO_TOP = Path(__file__).resolve().parents[1]
# We are looking to match on the following example strings
# {{#otbn-isa base }}
OTBN_ISA_BASE_PATTERN = re.compile(r'\{\{#otbn-isa\s+base\s*\}\}')
OTBN_ISA_BIGNUM_PATTERN = re.compile(r'\{\{#otbn-isa\s+bignum\s*\}\}')
# {{#otbn-insn-ref insn }}
OTBN_INSNREF_PATTERN = re.compile(r'\{\{#otbn-insn-ref\s+?(.+?)\s*?\}\}')
OTBN_SCRIPT = REPO_TOP / 'hw/ip/otbn/util/yaml_to_doc.py'
OTBN_CFG = REPO_TOP / 'hw/ip/otbn/data/insns.yml'
OTBN_IMPL = REPO_TOP / 'hw/ip/otbn/dv/otbnsim/sim/insn.py'
def main() -> None:
md_utils.supports_html_only()
(base_content, bignum_content) = get_listings()
# load both the context and the book from stdin
context, book = json.load(sys.stdin)
isa_book_path = None
for chapter in md_utils.chapters(book["sections"]):
if chapter["source_path"] is None:
continue
if OTBN_ISA_BASE_PATTERN.search(chapter["content"]) \
and OTBN_ISA_BIGNUM_PATTERN.search(chapter["content"]):
chapter["content"] = OTBN_ISA_BASE_PATTERN.sub(base_content, chapter["content"])
chapter["content"] = OTBN_ISA_BIGNUM_PATTERN.sub(bignum_content, chapter["content"])
isa_book_path = chapter["source_path"]
break
if isa_book_path is None:
sys.exit("No file was found with both {{#otbn-isa base}} and {{#otbn-isa bignum}}")
def ref_to_link(m: re.Match):
instr = m.group(1)
ref = instr.replace(".", "").lower()
return '<a href="/{}#{}"><code>{}</code></a>)'.format(isa_book_path, ref, instr)
for chapter in md_utils.chapters(book["sections"]):
chapter["content"] = \
OTBN_INSNREF_PATTERN.sub(
ref_to_link,
chapter["content"],
)
# dump the book into stdout
print(json.dumps(book))
def get_listings() -> (str, str):
"""Use the otbn utility scripts to generate the ISA listings."""
with tempfile.TemporaryDirectory() as tmpdir:
subprocess.run(
[str(OTBN_SCRIPT), str(OTBN_CFG), str(OTBN_IMPL), tmpdir],
check=True,
)
tmpdir = Path(tmpdir)
with open(tmpdir / "base.md") as f:
base_content = f.read()
with open(tmpdir / "bignum.md") as f:
bignum_content = f.read()
return (base_content, bignum_content)
if __name__ == "__main__":
main()