Skip to content

Commit b33b43f

Browse files
committed
Add label extractor to preprocessor
1 parent 449f1f2 commit b33b43f

File tree

9 files changed

+162
-15
lines changed

9 files changed

+162
-15
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ debug.json
1212
/src/debugger.mlog
1313
/src/config/*.mlog
1414
/src/peripherals/scrolling_display.mlog
15+
*.labels.mlog
1516

1617
node_modules/
1718

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ build/%.o: asm/%.s | build
5454
src/%.mlog: src/%.mlog.jinja
5555
python -m mlogv32.preprocessor file -o src/$*.mlog src/$*.mlog.jinja
5656

57+
src/init.mlog: src/main.labels.mlog
58+
59+
# only extract uppercase labels
60+
src/main.labels.mlog: src/main.mlog
61+
python -m mlogv32.preprocessor labels --filter '[^a-z]+' -o src/main.labels.mlog src/main.mlog
62+
5763
.PHONY: mlog-configs
5864
mlog-configs: src/config/configs.yaml
5965
python -m mlogv32.preprocessor configs src/config/configs.yaml

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ version = "0.1.0"
88
requires-python = ">=3.12"
99
dependencies = [
1010
"jinja2>=3.1.6",
11+
"lark[interegular]>=1.2.2",
1112
"pydantic>=2.11.5",
1213
"pymsch>=0.0.11",
1314
"pyperclip>=1.9.0",

python/src/mlogv32/preprocessor/app.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
1+
import re
12
from pathlib import Path
23
from typing import Annotated, Any, TypedDict
34

45
import yaml
56
from jinja2 import Environment, FileSystemLoader, StrictUndefined
67
from typer import Option, Typer
78

8-
from mlogv32.preprocessor.extensions import CommentStatement
9-
9+
from .extensions import CommentStatement
1010
from .filters import FILTERS
11+
from .parser.mlog import Label, Statement, parse_mlog
1112

1213
app = Typer(
1314
pretty_exceptions_show_locals=False,
1415
)
1516

1617

1718
@app.command(name="file")
18-
def command_file(
19+
def file_command(
1920
path: Path,
2021
output: Annotated[Path | None, Option("-o", "--output")] = None,
2122
):
@@ -32,6 +33,37 @@ def command_file(
3233
print(result)
3334

3435

36+
@app.command()
37+
def labels(
38+
path: Path,
39+
output: Annotated[Path | None, Option("-o", "--output")] = None,
40+
filter_str: Annotated[str | None, Option("--filter")] = None,
41+
):
42+
if filter_str:
43+
filter_re = re.compile(filter_str)
44+
else:
45+
filter_re = None
46+
47+
with path.open("r", encoding="utf-8") as f:
48+
lines = parse_mlog(f.read())
49+
50+
result_lines = list[str]()
51+
line_num = 0
52+
for line in lines:
53+
match line:
54+
case Label(name=name):
55+
if not filter_re or filter_re.fullmatch(name):
56+
result_lines.append(f"set {name} {line_num}")
57+
case Statement():
58+
line_num += 1
59+
result = "\n".join(result_lines)
60+
61+
if output:
62+
output.write_text(result, encoding="utf-8")
63+
else:
64+
print(result)
65+
66+
3567
@app.command()
3668
def configs(yaml_path: Path):
3769
with yaml_path.open("rb") as f:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
__all__ = [
2+
"Label",
3+
"Statement",
4+
"parse_mlog",
5+
]
6+
7+
from .mlog import Label, Statement, parse_mlog
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
start: (line? COMMENT? _NEWLINE)*
2+
3+
?line: LABEL -> label
4+
| statement
5+
6+
statement: TOKEN (TOKEN | LABEL | STRING)*
7+
8+
STRING.2: /"[^\n]*"/
9+
10+
LABEL.1: /[^\n #\t;]+:/
11+
12+
TOKEN: /[^\n #\t;]+/
13+
14+
COMMENT: /#[^\n]*/
15+
16+
_NEWLINE: /[\n;]+/
17+
18+
%ignore /[ \t]+/
19+
%ignore COMMENT
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from dataclasses import dataclass
2+
from importlib import resources
3+
from typing import TYPE_CHECKING, Callable
4+
5+
from lark import Lark, Token, Transformer
6+
7+
if TYPE_CHECKING:
8+
9+
def v_args[T](
10+
inline: bool = False,
11+
meta: bool = False,
12+
tree: bool = False,
13+
) -> Callable[[T], T]: ...
14+
else:
15+
from lark import v_args
16+
17+
18+
@dataclass
19+
class Label:
20+
name: str
21+
22+
23+
@dataclass
24+
class Statement:
25+
name: str
26+
args: list[str]
27+
28+
29+
@dataclass
30+
@v_args(inline=True)
31+
class MlogTransformer(Transformer[Token, list[Label | Statement]]):
32+
def start(self, *children: Label | Statement):
33+
return list(children)
34+
35+
def label(self, name: str):
36+
return Label(name[:-1])
37+
38+
def statement(self, name: str, *args: str):
39+
return Statement(name, list(args))
40+
41+
def TOKEN(self, token: Token):
42+
return str(token)
43+
44+
45+
GRAMMAR = (resources.files() / "mlog.lark").read_text("utf-8")
46+
47+
PARSER = Lark(
48+
GRAMMAR,
49+
parser="lalr",
50+
strict=True,
51+
)
52+
53+
54+
def parse_mlog(text: str):
55+
tree = PARSER.parse(text)
56+
return MlogTransformer().transform(tree)

src/main.mlog.jinja

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ done_pause_step:
273273
jump SLLI always
274274
jump SRLI always
275275
jump SRAI always
276-
jump illegal_instruction always # null + 64 would jump here
276+
jump ILLEGAL_INSTRUCTION always # null + 64 would jump here
277277
jump MLOGSYS always
278278
jump MLOGDRAW always
279279

@@ -332,7 +332,7 @@ default_mtvec_handler:
332332
printflush {{ERROR_OUTPUT}}
333333
jump halt always
334334

335-
illegal_instruction:
335+
ILLEGAL_INSTRUCTION:
336336
set mcause 2
337337
# TODO: return faulting instruction bits?
338338
# continue into trap_without_mtval
@@ -1734,7 +1734,7 @@ PRIV:
17341734
jump EBREAK equal imm 1
17351735
jump MRET equal imm 0b001100000010
17361736
jump end_instruction equal imm 0b000100000101 # WFI (no-op, ignore TW bit)
1737-
jump illegal_instruction always
1737+
jump ILLEGAL_INSTRUCTION always
17381738

17391739
ECALL:
17401740
# 0b1000 (8) = ecall from U-mode
@@ -1748,7 +1748,7 @@ EBREAK:
17481748
jump trap always
17491749

17501750
MRET:
1751-
jump illegal_instruction lessThan privilege_mode 0b11
1751+
jump ILLEGAL_INSTRUCTION lessThan privilege_mode 0b11
17521752

17531753
# set mstatus.MIE to mstatus.MPIE, set mstatus.MPIE to 1, set privilege_mode to mstatus.MPP, and set mstatus.MPP to U
17541754
op and mstatus.mie csr_mstatus 0b10000000
@@ -1839,15 +1839,15 @@ modify_csr:
18391839
# csr[9:8] encodes the lowest privilege level that can access the CSR
18401840
op shr csr_11_8 imm 8
18411841
op and required_privilege csr_11_8 0b1100000000
1842-
jump illegal_instruction lessThan privilege_mode required_privilege
1842+
jump ILLEGAL_INSTRUCTION lessThan privilege_mode required_privilege
18431843

18441844
# disable all supervisor and hypervisor CSRs
1845-
jump illegal_instruction equal required_privilege 0b01
1846-
jump illegal_instruction equal required_privilege 0b10
1845+
jump ILLEGAL_INSTRUCTION equal required_privilege 0b01
1846+
jump ILLEGAL_INSTRUCTION equal required_privilege 0b10
18471847

18481848
# 0x7b0-0x7bf are only visible to debug mode
18491849
op shr csr_11_4 imm 4
1850-
jump illegal_instruction equal csr_11_4 0x7b
1850+
jump ILLEGAL_INSTRUCTION equal csr_11_4 0x7b
18511851

18521852
# read
18531853

@@ -1878,7 +1878,7 @@ modify_csr__conditional_write:
18781878
jump end_instruction_with_rd equal rs1_id 0
18791879

18801880
modify_csr__always_write:
1881-
jump illegal_instruction equal readonly true
1881+
jump ILLEGAL_INSTRUCTION equal readonly true
18821882

18831883
set @counter modify_csr_write
18841884
# -----------------
@@ -1922,7 +1922,7 @@ modify_csr__read__not_machine:
19221922
jump modify_csr__read__not_timer notEqual tmp 0
19231923

19241924
# mcounteren is hardwired zero, so now that we know it's a timer, trap if we're not in M-mode
1925-
jump illegal_instruction lessThan privilege_mode 0b11
1925+
jump ILLEGAL_INSTRUCTION lessThan privilege_mode 0b11
19261926

19271927
jump modify_csr__mcycle equal csr_7_0 0x00
19281928
jump modify_csr__time equal imm 0xc01 # mtime doesn't exist
@@ -2066,7 +2066,7 @@ modify_csr__minstreth:
20662066

20672067
MLOGSYS:
20682068
# I-type: rs1, imm=funct12, rd_id
2069-
jump illegal_instruction greaterThan imm 3
2069+
jump ILLEGAL_INSTRUCTION greaterThan imm 3
20702070

20712071
# TODO: we could save an instruction if we used B-type instead of I-type
20722072
op mul jump imm 2
@@ -2108,7 +2108,7 @@ MLOGSYS__init_icache__loop:
21082108

21092109
MLOGDRAW:
21102110
# I-type: rs1, imm=funct12, rd_id
2111-
jump illegal_instruction greaterThan imm 15
2111+
jump ILLEGAL_INSTRUCTION greaterThan imm 15
21122112

21132113
read a1 {{REGISTERS}} 11
21142114
read a2 {{REGISTERS}} 12

uv.lock

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)