I just wrote this Python script to generate a module that has all the data hard-coded as Rust structs and string/number literals:
outpath = sys.argv[1]
insns = json.load(urlopen('https://raw.githubusercontent.com/ThinkOpenly/RISC-V_ISA/main/src/ISA.json'))['instructions']
def render_instruction(ins):
lines = [f' {key}: r#"{value}"#,' for key, value in ins.items() if isinstance(value, str)]
extensions = f' extensions: &[{", ".join("r#\"" + ext +"\"#" for ext in ins["extensions"])}],'
operands = f' operands: &[\n{"".join(" Operand { name: r#\"" + op["name"] + "\"#, type_: r#\"" + op["type"] + "\"# },\n" for op in ins["operands"])} ],'
fields = f' fields: &[\n{"".join(" Field { field: r#\"" + f["field"] + "\"#, size: " + str(f["size"]) + " },\n" for f in ins["fields"])} ],'
lines.extend([
extensions,
operands,
fields,
])
return ' Instruction {\n' + '\n'.join(lines) + '\n },\n'
with open(outpath, 'wt') as outstream:
outstream.write(textwrap.dedent('''
#[derive(Clone, Copy, Debug)]
pub struct Instruction {
pub mnemonic: &'static str,
pub name: &'static str,
pub operands: &'static [Operand],
pub syntax: &'static str,
pub format: &'static str,
pub fields: &'static [Field],
pub extensions: &'static [&'static str],
pub function: &'static str,
pub description: &'static str,
}
#[derive(Clone, Copy, Debug)]
pub struct Operand {
pub name: &'static str,
pub type_: &'static str,
}
#[derive(Clone, Copy, Debug)]
pub struct Field {
pub field: &'static str,
pub size: usize,
}
'''))
outstream.write('static INSTRUCTIONS: &[Instruction] = &[\n')
for ins in insns:
outstream.write(render_instruction(ins))
outstream.write('];\n')
outstream.write(textwrap.dedent('''
fn main() {
dbg!(&INSTRUCTIONS[0..3]);
}
'''))
It generates a Rust source file at the path specified by the only command-line argument. On my machine, the Rust file compiled in less than half a second with optimizations fully enabled:
$ time rustc -C opt-level=3 ~/Downloads/instructions.rs -o ~/Downloads/instructions
> 0.38s user 0.06s system 110% cpu 0.398 total
The whole 3 MB source file is 80 kB gzipped: here it is.