Skip to content

Latest commit

 

History

25 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RISC-V instruction decoder.

The main function is [Inst::decode], which will decode an instruction into the [Inst] enum. The [core::fmt::Display] impl of [Inst] provides disassembly functionality (note that the precise output of that implementation is not considered stable).

XLEN (Register size) support

RISC-V calls the parameter of the instruction size XLEN, and this crate refers to it as such.

This crate currenly only supports RV32 instructions. RV64 instructions that are the same between versions will still be decoded successfully, but the user has to be careful around sign-extended immediates to preserve the correct value when extending them to 64 bits.

RV64-specific instructions are not yet implemented, but will be in the future. The immediates will also be switched to u64 in the future to allow for easier usage of RV64.

RV128 is currently not intended to be supported.

Extension support

The decoder currently supports the following instructions:

  • Base RV32I instruction set
  • M standard extension
  • A standard extension
    • Zalrsc standard extension
    • Zaamo standard extension
  • C standard extension
  • Zihintpause standard extension
  • Zicsr standard extension (Control and Status Register instructions)
  • F standard extension (Single-Precision Floating-Point)
  • D standard extension (Double-Precision Floating-Point)

More extensions may be implemented in the future.

Examples

// addi sp, sp, -0x20 (compressed)
let x = 0x1101_u32;
let expected = rvdc::Inst::Addi { imm: rvdc::Imm::new_i32(-0x20), dest: rvdc::Reg::SP, src1: rvdc::Reg::SP };

let (inst, is_compressed) = rvdc::Inst::decode(x, rvdc::Xlen::Rv32).unwrap();
assert_eq!(inst, expected);
assert_eq!(is_compressed, rvdc::IsCompressed::Yes);
assert_eq!(format!("{inst}"), "addi sp, sp, -32")
// auipc t1, 0xa
let x = 0x0000a317;
let expected = rvdc::Inst::Auipc { uimm: rvdc::Imm::new_u32(0xa << 12), dest: rvdc::Reg::T1 };

let (inst, is_compressed) = rvdc::Inst::decode(x, rvdc::Xlen::Rv32).unwrap();
assert_eq!(inst, expected);
assert_eq!(is_compressed, rvdc::IsCompressed::No);
assert_eq!(format!("{inst}"), "auipc t1, 10")

no_std

This crate supports no_std without the alloc crate.

Panics

[Inst::decode] is guaranteed to never panic. This is ensured with a 32-bit exhaustive test.

Testing

This crate is tested by exhaustively going through all 32 bit values that are valid instructions and roundtripping the disassembly through the clang assembler, ensuring it remains the same. This is not yet done for compressed instructions.

Additionally, it's also tested as part of an emulator, which tests many different kinds of instructions.

MSRV

This crate targets the latest stable as its MSRV.

Goals

  • Decode/Encode RISC-V instructions
  • Support multiple ISA extensions (I, M, A, C, F, D)

Progress

  • Decoder implemented for RV32I, M, A, C, Zicsr, F, D
  • Extensive testing and documentation provided

AI assisted

About

RISC-V encoder and decoder

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages