diff options
author | Andrew Waterman <andrew@sifive.com> | 2025-10-13 16:24:22 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-10-13 16:24:22 -0700 |
commit | 26e2c04c913a67ac51bf0a354f21f2d7d5c07c40 (patch) | |
tree | 7db4f4637f71f1777f86702a2228ccf3b9217a03 /src/riscv_opcodes/c_utils.py | |
parent | 433081c02368eb72e6dea5413e404a8ef231658e (diff) | |
download | riscv-opcodes-master.zip riscv-opcodes-master.tar.gz riscv-opcodes-master.tar.bz2 |
Add pyproject.toml (the modern alternative to requirements.txt), making this a proper Python package that can be installed via pip and potentially uploaded to PyPI.
This also loads the files using `importlib.resources` and installs them into the wheel. This means that when you create a wheel using `uv build` it will still be able to load all the opcodes and CSV files.
To avoid moving those resource files in the source repo, the Python build backend (hatchling) is instructed to move them to the right place when building a wheel, and the `resource_root()` function checks in both places so it always works. This is a little hacky but it works.
CI builds source and binary wheels (not actually binary) that can be uploaded to PyPI. If we do upload them then using this project is as simple as
```
uvx riscv_opcodes -c 'rv*'
```
Co-authored-by: Tim Hutt <timothy.hutt@codasip.com>
Diffstat (limited to 'src/riscv_opcodes/c_utils.py')
-rw-r--r-- | src/riscv_opcodes/c_utils.py | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/riscv_opcodes/c_utils.py b/src/riscv_opcodes/c_utils.py new file mode 100644 index 0000000..198a37f --- /dev/null +++ b/src/riscv_opcodes/c_utils.py @@ -0,0 +1,79 @@ +import logging +import os +import pprint + +from .constants import causes, csrs, csrs32 +from .resources import read_text_resource +from .shared_utils import InstrDict, arg_lut + +pp = pprint.PrettyPrinter(indent=2) +logging.basicConfig(level=logging.INFO, format="%(levelname)s:: %(message)s") + + +def make_c(instr_dict: InstrDict): + mask_match_str = "" + declare_insn_str = "" + for i in instr_dict: + mask_match_str += ( + f'#define MATCH_{i.upper().replace(".","_")} {instr_dict[i]["match"]}\n' + ) + mask_match_str += ( + f'#define MASK_{i.upper().replace(".","_")} {instr_dict[i]["mask"]}\n' + ) + declare_insn_str += f'DECLARE_INSN({i.replace(".","_")}, MATCH_{i.upper().replace(".","_")}, MASK_{i.upper().replace(".","_")})\n' + + csr_names_str = "" + declare_csr_str = "" + for num, name in csrs + csrs32: + csr_names_str += f"#define CSR_{name.upper()} {hex(num)}\n" + declare_csr_str += f"DECLARE_CSR({name}, CSR_{name.upper()})\n" + + causes_str = "" + declare_cause_str = "" + for num, name in causes: + causes_str += f"#define CAUSE_{name.upper().replace(' ', '_')} {hex(num)}\n" + declare_cause_str += ( + f"DECLARE_CAUSE(\"{name}\", CAUSE_{name.upper().replace(' ','_')})\n" + ) + + arg_str = "" + for name, rng in arg_lut.items(): + sanitized_name = name.replace(" ", "_").replace("=", "_eq_") + begin = rng[1] + end = rng[0] + mask = ((1 << (end - begin + 1)) - 1) << begin + arg_str += f"#define INSN_FIELD_{sanitized_name.upper()} {hex(mask)}\n" + + enc_header = read_text_resource("encoding.h") + + commit = os.popen('git log -1 --format="format:%h"').read() + + # Generate the output as a string + output_str = f"""/* SPDX-License-Identifier: BSD-3-Clause */ + +/* Copyright (c) 2023 RISC-V International */ + +/* + * This file is auto-generated by running 'make' in + * https://github.com/riscv/riscv-opcodes ({commit}) + */ + +{enc_header} +/* Automatically generated by parse_opcodes. */ +#ifndef RISCV_ENCODING_H +#define RISCV_ENCODING_H +{mask_match_str} +{csr_names_str} +{causes_str} +{arg_str}#endif +#ifdef DECLARE_INSN +{declare_insn_str}#endif +#ifdef DECLARE_CSR +{declare_csr_str}#endif +#ifdef DECLARE_CAUSE +{declare_cause_str}#endif +""" + + # Write the modified output to the file + with open("encoding.out.h", "w", encoding="utf-8") as enc_file: + enc_file.write(output_str) |