{"id":26756946,"url":"https://github.com/ddrcode/riscv-isa","last_synced_at":"2025-03-28T15:22:04.403Z","repository":{"id":284199716,"uuid":"942578487","full_name":"ddrcode/riscv-isa","owner":"ddrcode","description":"RISC-V instructions model and disassembler written in Rust","archived":false,"fork":false,"pushed_at":"2025-03-24T16:50:50.000Z","size":19,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T17:49:49.709Z","etag":null,"topics":["disassembler","isa","risc-v","rust","rust-lang"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ddrcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-04T10:25:58.000Z","updated_at":"2025-03-24T15:22:31.000Z","dependencies_parsed_at":"2025-03-24T17:49:53.572Z","dependency_job_id":"952833d8-10e3-4952-92b2-9887f23c9b7a","html_url":"https://github.com/ddrcode/riscv-isa","commit_stats":null,"previous_names":["ddrcode/riscv-isa"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddrcode%2Friscv-isa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddrcode%2Friscv-isa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddrcode%2Friscv-isa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ddrcode%2Friscv-isa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ddrcode","download_url":"https://codeload.github.com/ddrcode/riscv-isa/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246049681,"owners_count":20715513,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["disassembler","isa","risc-v","rust","rust-lang"],"created_at":"2025-03-28T15:22:01.358Z","updated_at":"2025-03-28T15:22:04.392Z","avatar_url":"https://github.com/ddrcode.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RISC-V ISA (Rust library)\n\nA Rust library for representing the RISC-V Instruction Set Architecture (ISA) and for disassembling RISC-V binary code. This project aims to provide a rock‑solid, type‑safe model for RISC-V instructions, along with a disassembler that leverages this model to produce human‑readable assembly.\n\n**Note** - the library is still under heavy development, and the API can change from version to version, providing breaking changes.\n\n## Features\n\n- **RISC-V ISA Representation**\n  - Strongly typed models for various instruction components: opcodes, funct3, funct7, immediate values, and registers.\n  - Use of Rust’s advanced type system to ensure that only valid values can be constructed.\n\n- **Disassembler**\n  - An iterator-based disassembler that reads a binary source and produces structured instruction representations.\n  - Extensible design to support custom instructions and extensions.\n  - Error handling via custom error types that wrap both I/O and RISC-V–specific errors.\n\n- **Idiomatic Rust Design**\n  - Minimal runtime overhead with extensive compile-time checks.\n\n## Current limitations\n\nThe current version of the library has some limitations, that are planned to be addressed\nin the future versions:\n\n- support for compressed instruction (16-bit instructions),\n- support for custom instructions of size different from 32-bits,\n- assembly code parsing\n\n## Examples of use\n\nThe code below demonstrates how to use the library to build a simple CLI tool\nthat takes RISC-V binary as an input and prints disassembled code to the console.\n\n\n```Rust\nuse std::env;\nuse std::fs::File;\nuse std::io::{BufReader, Result};\nuse riscv_isa::Disasm;\n\nfn main() -\u003e Result\u003c()\u003e {\n    let args: Vec\u003cString\u003e = env::args().collect();\n    if args.len() \u003c 2 {\n        eprintln!(\"Usage: {} \u003cfilename\u003e\", args[0]);\n        std::process::exit(1);\n    }\n    let filename = \u0026args[1];\n\n    let file = File::open(filename)?;\n    let reader = BufReader::new(file);\n\n    let disasm = Disasm::new(reader);\n    for result in disasm {\n        match result {\n            Ok(record) =\u003e println!(\"{}\", record),\n            Err(e) =\u003e {\n                eprintln!(\"Error disassembling instruction: {:?}\", e);\n                break;\n            }\n        }\n    }\n\n    Ok(())\n}\n```\n\nThe above example could be simplified even further, by skipping the loop entirely:\n\n``` Rust\n    let mut disasm = Disasm::new(reader);\n    if let Err(e) = disasm.print_all() {\n        eprintln!(\"Error disassembling instruction: {:?}\", e);\n    }\n```\n\nA developer has a full control over how the disassembled code is formatted:\n\n```Rust\n    let mut config = DisasmConfig::default();\n    config.mnemonic_uppercase = false;\n    config.register_separator = \"\\t\".to_string();\n    config.immediate_format = |imm: i32| format!(\"{:08x}\", imm);\n\n    let mut disasm = Disasm::with_config(reader, config);\n    disasm.print_all()?;\n```\n\nBesides disassembly, the library can be also used to build instructions from scratch\nand produce instruction binary (so it's possible to build an assembler with it).\nThe code below creates an I-type instruction (`LBU s1, 0xff(a0)`):\n\n```Rust\n    let opcode = Opcode::try_from(0b0000011u32)?;\n    let rs1 = Register::a0();\n    let rd = Register::try_from(9)?; // s1\n    let funct3 = Funct3::try_from(0b100u8)?;\n    let imm = Immediate::\u003c0, 11\u003e::try_from(0xff)?;\n    let instr = IInstruction::new(opcode, rs1, rd, funct3, imm)?;\n\n    let instr_binary = u32::from(instr);\n    let instr_bytes = instr_binary.to_le_bytes();\n```\n\nThe above example can be written much more elegantly with `InstructionBuilder`:\n\n```Rust\n    let instr = InstructionBuilder::new()\n        .set_opcode(Opcode::try_from(0b0000011u32)?)\n        .set_rs1(Register::a0())\n        .set_rd(Register::s1())\n        .set_funct3(Funct3::try_from(0b100u8)?)\n        .set_immediate(0xff)\n        .build()?;\n```\n\nAn individual instruction structure can be created directly from instruction binary,\nwithout calling disassembler:\n\n```Rust\n    let instr = Instruction::try_from(0x00a5d463)?;\n    assert_eq!(\"B\", instr.format().to_string());\n    assert_eq!(\"BLT a1, a0, 0x101c4\", instr.to_string());\n```\n\n## License\n\nLicensed under MIT license\n   ([LICENSE](LICENSE) or [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fddrcode%2Friscv-isa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fddrcode%2Friscv-isa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fddrcode%2Friscv-isa/lists"}