adds shebang to process_json.py
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
from abc import abstractmethod
|
#!/usr/bin/env python3
|
||||||
import argparse
|
import argparse
|
||||||
import json
|
import json
|
||||||
|
from abc import abstractmethod
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from jsonschema import validate, ValidationError
|
|
||||||
|
from jsonschema import ValidationError, validate
|
||||||
|
|
||||||
INSTRUCTION_SCHEMA = {
|
INSTRUCTION_SCHEMA = {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@@ -14,13 +16,13 @@ INSTRUCTION_SCHEMA = {
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"name": {"type": "string"},
|
"name": {"type": "string"},
|
||||||
"decoding": {"type": "string"}
|
"decoding": {"type": "string"},
|
||||||
|
},
|
||||||
|
"required": ["name", "decoding"],
|
||||||
},
|
},
|
||||||
"required": ["name", "decoding"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["instructions"]
|
"required": ["instructions"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -58,7 +60,11 @@ class Field(EncodingPart):
|
|||||||
return value_str + shift + shamt if self.pos - self.start else value_str
|
return value_str + shift + shamt if self.pos - self.start else value_str
|
||||||
|
|
||||||
def coredsl(self) -> str:
|
def coredsl(self) -> str:
|
||||||
middle = f"[{self.end}:{self.start}]" if self.size > 1 else f"[{self.end}:{self.end}]"
|
middle = (
|
||||||
|
f"[{self.end}:{self.start}]"
|
||||||
|
if self.size > 1
|
||||||
|
else f"[{self.end}:{self.end}]"
|
||||||
|
)
|
||||||
return self.name + middle
|
return self.name + middle
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
@@ -73,11 +79,11 @@ class Literal(EncodingPart):
|
|||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
shamt = str(self.pos)
|
shamt = str(self.pos)
|
||||||
value_str = format(self.value, f'#0{self.size+2}b')
|
value_str = format(self.value, f"#0{self.size + 2}b")
|
||||||
return value_str + " << " + shamt if self.pos else value_str
|
return value_str + " << " + shamt if self.pos else value_str
|
||||||
|
|
||||||
def coredsl(self) -> str:
|
def coredsl(self) -> str:
|
||||||
return format(self.value, f'#0{self.size+2}b')
|
return format(self.value, f"#0{self.size + 2}b")
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return "Literal: " + self.coredsl()
|
return "Literal: " + self.coredsl()
|
||||||
@@ -102,17 +108,27 @@ class Encoding:
|
|||||||
self.name = d["name"].upper()
|
self.name = d["name"].upper()
|
||||||
|
|
||||||
def _get_masked_enc(self) -> str:
|
def _get_masked_enc(self) -> str:
|
||||||
masked_enc = "".join([bin(elem.value)[2:].zfill(elem.size) if isinstance(
|
masked_enc = "".join(
|
||||||
elem, Literal) else elem.size*"x" for elem in self.parts])
|
[
|
||||||
|
bin(elem.value)[2:].zfill(elem.size)
|
||||||
|
if isinstance(elem, Literal)
|
||||||
|
else elem.size * "x"
|
||||||
|
for elem in self.parts
|
||||||
|
]
|
||||||
|
)
|
||||||
return masked_enc
|
return masked_enc
|
||||||
|
|
||||||
def _collapse_literals(self):
|
def _collapse_literals(self):
|
||||||
new_parts: list[EncodingPart] = []
|
new_parts: list[EncodingPart] = []
|
||||||
for part in self.parts:
|
for part in self.parts:
|
||||||
if isinstance(part, Literal) and new_parts and isinstance(new_parts[-1], Literal):
|
if (
|
||||||
|
isinstance(part, Literal)
|
||||||
|
and new_parts
|
||||||
|
and isinstance(new_parts[-1], Literal)
|
||||||
|
):
|
||||||
new_value = (new_parts[-1].value << part.size) + part.value
|
new_value = (new_parts[-1].value << part.size) + part.value
|
||||||
new_size = new_parts[-1].size + part.size
|
new_size = new_parts[-1].size + part.size
|
||||||
combined_val = format(new_value, f'#0{new_size+2}b')
|
combined_val = format(new_value, f"#0{new_size + 2}b")
|
||||||
collapsed = Literal(combined_val[2:])
|
collapsed = Literal(combined_val[2:])
|
||||||
new_parts[-1] = collapsed
|
new_parts[-1] = collapsed
|
||||||
else:
|
else:
|
||||||
@@ -141,15 +157,15 @@ class Encoding:
|
|||||||
else:
|
else:
|
||||||
return (2, name)
|
return (2, name)
|
||||||
|
|
||||||
field_names = [
|
field_names = [elem.name for elem in self.parts if isinstance(elem, Field)]
|
||||||
elem.name for elem in self.parts if isinstance(elem, Field)]
|
|
||||||
unique_field_names = list(dict.fromkeys(field_names))
|
unique_field_names = list(dict.fromkeys(field_names))
|
||||||
fields_str = ', '.join(sorted(unique_field_names, key=riscv_sort_key))
|
fields_str = ", ".join(sorted(unique_field_names, key=riscv_sort_key))
|
||||||
header = f".macro {self.name}{',' if len(unique_field_names) > 0 else ''} {fields_str}"
|
header = f".macro {self.name}{',' if len(unique_field_names) > 0 else ''} {fields_str}"
|
||||||
indent = " "
|
indent = " "
|
||||||
|
|
||||||
comment = "# Encoding parts: " + \
|
comment = "# Encoding parts: " + " ".join(
|
||||||
" ".join([elem.coredsl() for elem in self.parts])
|
[elem.coredsl() for elem in self.parts]
|
||||||
|
)
|
||||||
self._collapse_literals()
|
self._collapse_literals()
|
||||||
strs = [str(elem) for elem in self.parts]
|
strs = [str(elem) for elem in self.parts]
|
||||||
content = ".word " + " | ".join(strs)
|
content = ".word " + " | ".join(strs)
|
||||||
@@ -163,20 +179,18 @@ def parse_args():
|
|||||||
description="Generate assembler macros from CoreDSL2JSON output."
|
description="Generate assembler macros from CoreDSL2JSON output."
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"path",
|
"path", type=Path, help="Path to the JSON file generated by CoreDSL2JSON."
|
||||||
type=Path,
|
|
||||||
help="Path to the JSON file generated by CoreDSL2JSON."
|
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--name",
|
"--name",
|
||||||
type=str,
|
type=str,
|
||||||
help="Name of the instruction to generate the macro for (optional)."
|
help="Name of the instruction to generate the macro for (optional).",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--size",
|
"--size",
|
||||||
type=int,
|
type=int,
|
||||||
default=-1,
|
default=-1,
|
||||||
help="Instruction size in bits. If not set, checks lowest bits of the instruction and determines size according to default RISC-V specification."
|
help="Instruction size in bits. If not set, checks lowest bits of the instruction and determines size according to default RISC-V specification.",
|
||||||
)
|
)
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user