-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Updates for S4EMac Extension (PoC for custom register support) #99
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
921a634
riscv_instr_info: introduce attr_helper func
PhilippvK ec74cf9
riscv_instr_info: emit Uses/Defs attrs
PhilippvK 7084abf
flow: move detect_registers transform to earlier point in time
PhilippvK 425954a
add new backend (and pass) for riscv_register_info patches
PhilippvK 6c7e825
model: extend Seal5Register and Seal5RegisterGroup classes
PhilippvK e1db571
model: add USES and DEFS attrs for instructions
PhilippvK f199af8
converter: do not drop scalars
PhilippvK 6ccf3f2
detect_inouts: collect uses and defs for custom regs
PhilippvK c92ddd1
model: extend Seal5Register and Seal5RegisterGroup classes 2
PhilippvK 2a8fa43
lint code
PhilippvK 98024f4
fix typo in s4e-mac.yml
PhilippvK 2e10a7d
add missing license headers and file docstrings
PhilippvK be743e6
resolve merge conflict
PhilippvK 56a5b68
Merge remote-tracking branch 'origin/main' into support-s4e
PhilippvK File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# | ||
# Copyright (c) 2023 TUM Department of Electrical and Computer Engineering. | ||
# | ||
# This file is part of Seal5. | ||
# See https://github.com/tum-ei-eda/seal5.git for further info. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
"""Templates for RISCVRegisterInfo.td patches""" | ||
import pathlib | ||
|
||
template_dir = pathlib.Path(__file__).parent.resolve() |
48 changes: 48 additions & 0 deletions
48
seal5/backends/riscv_register_info/templates/registers_tablegen.mako
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// class RVInst_${name}<dag outs, dag ins> : RVInst<outs, ins, "cv.add.h", "$rd, $rs1, $rs2", [], InstFormatOther> { | ||
class RVInst_${name}<dag outs, dag ins> : Instruction, Sched<${sched_str}> { | ||
// General | ||
let Namespace = "RISCV"; | ||
let Size = ${xlen // 8}; | ||
bits<32> SoftFail = 0; | ||
bits<${xlen}> Inst; | ||
|
||
// Operands | ||
% for operand in operands: | ||
bits<${operand.length}> ${operand.name}; | ||
% endfor | ||
|
||
// Attributes | ||
% for key, value in attrs.items(): | ||
let ${key} = ${value}; | ||
% endfor | ||
|
||
// Encoding | ||
% for enc in fields: | ||
|
||
% if enc.length == 1: | ||
% if enc.extra is None: | ||
let Inst{${enc.start}} = ${enc.name}; | ||
% else: | ||
let Inst{${enc.start}} = ${bin(enc.extra)};${" // " + enc.name if enc.name else ""} | ||
% endif | ||
% else: | ||
% if enc.extra is None: | ||
let Inst{${enc.start+enc.length-1}-${enc.start}} = ${enc.name}; | ||
% else: | ||
let Inst{${enc.start+enc.length-1}-${enc.start}} = ${f"0b{enc.extra:0{enc.length}b}"};${" // " + enc.name if enc.name else ""} | ||
% endif | ||
% endif | ||
% endfor | ||
|
||
dag OutOperandList = outs; | ||
dag InOperandList = ins; | ||
|
||
// Assembly | ||
let AsmString = "${real_name}\t${asm_str}"; | ||
|
||
% if len(constraints_str): | ||
// Constraints | ||
let Constraints = "${constraints_str}"; | ||
% endif | ||
} | ||
def ${name} : RVInst_${name}<(outs ${outs_str}), (ins ${ins_str})>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
# This file is part of the M2-ISA-R project: https://github.com/tum-ei-eda/M2-ISA-R | ||
# | ||
# Copyright (C) 2022 | ||
# Chair of Electrical Design Automation | ||
# Technical University of Munich | ||
|
||
"""Generate Patches for RISCVRegisterInfo.td.""" | ||
|
||
import argparse | ||
import logging | ||
import pathlib | ||
import pickle | ||
from typing import Union | ||
|
||
from m2isar.metamodel import arch | ||
|
||
from seal5.index import NamedPatch, write_index_yaml | ||
|
||
# from seal5.settings import ExtensionsSettings | ||
from seal5.model import Seal5RegisterClass | ||
|
||
logger = logging.getLogger("riscv_instr_info") | ||
|
||
|
||
def write_riscv_register_info(reg): | ||
# registers_template = Template(filename=str(template_dir / "registers_tablegen.mako")) | ||
|
||
# out_str = registers_template.render() | ||
out_str = f'def {reg.name} : RISCVReg<0, "{reg.name.lower()}">;' | ||
|
||
return out_str | ||
|
||
|
||
def gen_riscv_register_info_str(set_def): | ||
registers = set_def.registers | ||
register_groups = set_def.register_groups | ||
print("registers", registers) | ||
print("register_groups", register_groups) | ||
group_regs = {group_name: group.names for group_name, group in register_groups.items()} | ||
all_group_regs = [name for names in group_regs.values() for name in names] | ||
ret = [] | ||
for group_name, group in register_groups.items(): | ||
if group.reg_class == Seal5RegisterClass.GPR: | ||
continue # Already supported | ||
# TODO: check size and width | ||
elif group.reg_class == Seal5RegisterClass.FPR: | ||
raise NotImplementedError("Floating point registers not supported") | ||
elif group.reg_class == Seal5RegisterClass.CSR: | ||
raise NotImplementedError("CSR registers not yet supported") | ||
elif group.reg_class == Seal5RegisterClass.CUSTOM: | ||
raise NotImplementedError("Custom register goups not yet supported") | ||
else: | ||
raise ValueError(f"Unhandled case: {group.reg_class}") | ||
for reg_name, reg in registers.items(): | ||
if reg_name in all_group_regs: | ||
logger.debug("Skipping group register %s", reg_name) | ||
continue | ||
assert reg.reg_class not in [Seal5RegisterClass.GPR, Seal5RegisterClass.FPR, Seal5RegisterClass.CSR] | ||
if reg.reg_class == Seal5RegisterClass.CUSTOM: | ||
assert reg.size == 1 | ||
tablegen_str = write_riscv_register_info(reg) | ||
ret.append(tablegen_str) | ||
else: | ||
raise ValueError(f"Unhandled case: {reg.reg_class}") | ||
# width = reg.width | ||
# TODO: use width? | ||
print("ret", ret) | ||
return "\n".join(ret) | ||
|
||
|
||
def main(): | ||
"""Main app entrypoint.""" | ||
|
||
# read command line args | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument("top_level", help="A .m2isarmodel or .seal5model file.") | ||
parser.add_argument("--log", default="info", choices=["critical", "error", "warning", "info", "debug"]) | ||
parser.add_argument("--output", "-o", type=str, default=None) | ||
parser.add_argument("--splitted", action="store_true", help="Split per set") | ||
parser.add_argument("--formats", action="store_true", help="Also generate instruction formats") | ||
parser.add_argument("--metrics", default=None, help="Output metrics to file") | ||
parser.add_argument("--index", default=None, help="Output index to file") | ||
parser.add_argument("--ext", type=str, default="td", help="Default file extension (if using --splitted)") | ||
args = parser.parse_args() | ||
|
||
# initialize logging | ||
logging.basicConfig(level=getattr(logging, args.log.upper())) | ||
|
||
# resolve model paths | ||
top_level = pathlib.Path(args.top_level) | ||
# abs_top_level = top_level.resolve() | ||
|
||
is_seal5_model = False | ||
# print("top_level", top_level) | ||
# print("suffix", top_level.suffix) | ||
if top_level.suffix == ".seal5model": | ||
is_seal5_model = True | ||
if args.output is None: | ||
assert top_level.suffix in [".m2isarmodel", ".seal5model"], "Can not infer model type from file extension." | ||
raise NotImplementedError | ||
|
||
# out_path = top_level.parent / (top_level.stem + ".core_desc") | ||
else: | ||
out_path = pathlib.Path(args.output) | ||
|
||
logger.info("loading models") | ||
if not is_seal5_model: | ||
raise NotImplementedError | ||
|
||
# load models | ||
with open(top_level, "rb") as f: | ||
# models: "dict[str, arch.CoreDef]" = pickle.load(f) | ||
if is_seal5_model: | ||
model: "dict[str, Union[arch.InstructionSet, ...]]" = pickle.load(f) | ||
model["cores"] = {} | ||
else: # TODO: core vs. set! | ||
temp: "dict[str, Union[arch.InstructionSet, arch.CoreDef]]" = pickle.load(f) | ||
assert len(temp) > 0, "Empty model!" | ||
if isinstance(list(temp.values())[0], arch.CoreDef): | ||
model = {"cores": temp, "sets": {}} | ||
elif isinstance(list(temp.values())[0], arch.InstructionSet): | ||
model = {"sets": temp, "cores": {}} | ||
else: | ||
assert False | ||
|
||
metrics = { | ||
"n_sets": 0, | ||
"n_skipped": 0, | ||
"n_failed": 0, | ||
"n_success": 0, | ||
} | ||
# preprocess model | ||
# print("model", model) | ||
# settings = model.get("settings", None) | ||
artifacts = {} | ||
artifacts[None] = [] # used for global artifacts | ||
if args.splitted: | ||
raise NotImplementedError("--splitted not supported") | ||
else: | ||
content = "" | ||
for set_name, set_def in model["sets"].items(): | ||
content_ = gen_riscv_register_info_str(set_def) | ||
if len(content_) > 0: | ||
content += content_ | ||
with open(out_path, "w") as f: | ||
f.write(content) | ||
register_info_patch = NamedPatch( | ||
"llvm/lib/Target/RISCV/RISCVRegisterInfo.td", | ||
key="riscv_register_info", | ||
src_path=out_path, | ||
) | ||
artifacts[None].append(register_info_patch) | ||
if args.metrics: | ||
raise NotImplementedError("--metrics not implemented") | ||
metrics_file = args.metrics | ||
with open(metrics_file, "w") as f: | ||
f.write(",".join(metrics.keys())) | ||
f.write("\n") | ||
f.write(",".join(map(str, metrics.values()))) | ||
f.write("\n") | ||
if args.index: | ||
if sum(map(lambda x: len(x), artifacts.values())) > 0: | ||
global_artifacts = artifacts.get(None, []) | ||
set_artifacts = {key: value for key, value in artifacts.items() if key is not None} | ||
index_file = args.index | ||
write_index_yaml(index_file, global_artifacts, set_artifacts, content=True) | ||
else: | ||
logger.warning("No patches generated. No index file will be written.") | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
floor is surely safe, in that a size other than 32 or 64 seems unlikely, and even DSP-ish 24 is still sized in bytes. But maybe an assert of the assumption would be documentary? (size % 8 == 0)