Skip to content

Commit a631b1d

Browse files
committed
Add generator for capstone
1 parent cbcb87e commit a631b1d

File tree

2 files changed

+104
-2
lines changed

2 files changed

+104
-2
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Generate a C function mapping RISC-V CSR numbers to names using a switch statement.
4+
"""
5+
6+
import sys
7+
import os
8+
9+
# Add parent directory to path to import generator.py
10+
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
11+
sys.path.append(parent_dir)
12+
13+
# Import functions from generator.py
14+
from generator import load_csrs
15+
16+
17+
def generate_csr_switch(csrs, output_file):
18+
with open(output_file, "w", encoding="utf-8") as f:
19+
fn_str = """// This file is auto-generated by riscv-unified-db
20+
static const char *getCSRSystemRegisterName(unsigned CsrNo)
21+
{
22+
switch (CsrNo) {
23+
"""
24+
for addr, name in sorted(csrs.items()):
25+
fn_str += f'\tcase 0x{addr:04x}:\n\t\treturn "{name.lower()}";\n'
26+
27+
fn_str += """ }
28+
return NULL;
29+
}
30+
"""
31+
f.write(fn_str)
32+
33+
34+
def main():
35+
import argparse
36+
37+
parser = argparse.ArgumentParser(description="Generate C switch for RISC-V CSRs")
38+
parser.add_argument(
39+
"--csr-dir",
40+
default=os.path.abspath(
41+
os.path.join(os.path.dirname(__file__), "../../../arch/csr/")
42+
),
43+
help="Directory containing CSR YAML files",
44+
)
45+
parser.add_argument(
46+
"--extensions",
47+
default="",
48+
help="Comma-separated list of enabled extensions (default: all)",
49+
)
50+
parser.add_argument(
51+
"--arch",
52+
default="BOTH",
53+
choices=["RV32", "RV64", "BOTH"],
54+
help="Target architecture (RV32, RV64, BOTH)",
55+
)
56+
parser.add_argument(
57+
"--output",
58+
default=os.path.join(os.path.dirname(__file__), "csr_switch.c"),
59+
help="Output C file name",
60+
)
61+
args = parser.parse_args()
62+
63+
enabled_extensions = (
64+
[ext.strip() for ext in args.extensions.split(",") if ext.strip()]
65+
if args.extensions
66+
else []
67+
)
68+
include_all = not enabled_extensions
69+
csrs = load_csrs(args.csr_dir, enabled_extensions, include_all, args.arch)
70+
71+
generate_csr_switch(csrs, args.output)
72+
print(f"Generated: {args.output}")
73+
74+
75+
if __name__ == "__main__":
76+
main()

backends/generators/tasks.rake

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
# typed: false
12
# frozen_string_literal: true
23

34
require "udb/resolver"
4-
require 'json'
5-
require 'tempfile'
5+
require "json"
6+
require "tempfile"
67

78
directory "#{$root}/gen/go"
89
directory "#{$root}/gen/c_header"
910
directory "#{$root}/gen/sverilog"
11+
directory "#{$root}/gen/capstone"
1012

1113
def with_resolved_exception_codes(cfg_arch)
1214
# Process ERB templates in exception codes using Ruby ERB processing
@@ -127,4 +129,28 @@ namespace :gen do
127129
"--output=#{output_dir}riscv_decode_package.svh --include-all"
128130
end
129131
end
132+
133+
desc <<~DESC
134+
Generate Capstone CSR switch from RISC-V CSR definitions
135+
136+
Options:
137+
* CONFIG - Configuration name (defaults to "_")
138+
* OUTPUT_DIR - Output directory for generated Capstone code (defaults to "#{$root}/gen/capstone")
139+
DESC
140+
task capstone: "#{$root}/gen/capstone" do
141+
config_name = ENV["CONFIG"] || "_"
142+
output_dir = ENV["OUTPUT_DIR"] || "#{$root}/gen/capstone/"
143+
144+
# Ensure the output directory exists
145+
FileUtils.mkdir_p output_dir
146+
147+
# Get the arch paths based on the config
148+
resolver = Udb::Resolver.new
149+
cfg_arch = resolver.cfg_arch_for(config_name)
150+
inst_dir = cfg_arch.path / "inst"
151+
csr_dir = cfg_arch.path / "csr"
152+
153+
# Run the Capstone CSR switch generator Python script
154+
sh "#{$root}/.home/.venv/bin/python3 #{$root}/backends/generators/capstone/generate_csr_switch.py --csr-dir=#{csr_dir} --arch=BOTH --output=#{output_dir}csr_switch.c"
155+
end
130156
end

0 commit comments

Comments
 (0)