five32-instruction-set 0.1.0

Definitions for an implementation of the RISC-V instruction set.
Documentation
// This is the bulk of the business logic.
pub mod instr;

// We're allowing dead_code here because there's lots of flags and masks that aren't used.
#[allow(dead_code)]
mod instr_masks;

#[cfg(test)]
mod tests {
    use std::collections::HashMap;
    use std::fs::read_to_string;
    use std::path::Path;

    use serde::{Deserialize};

    use crate::rv32i::instr::Instruction;

    /// This comes from a .json file mapping an instruction to some of its properties.
    /// ```json
    ///      "ADD": {
    ///         "pattern": "0000000----------000-----0110011",
    ///         "pattern_mask": "0xfe00707f",
    ///         "pattern_match": "0x33",
    ///         "example": "00000000000000000000000000110011"
    ///       },
    /// ```
    /// For the purposes of this unit test, we're simply checking if the 'example' can be parsed
    /// and is recognized as the correct instruction.
    #[derive(Deserialize)]
    struct InstructionSpec {
        pub example: String
    }

    /// This unit test tries to decode all instructions in the RV32I instruction set.
    #[test]
    fn instruction_parsing() {
        let instr_reference: HashMap<String, InstructionSpec> = {
            let contents_path = Path::new("src/rv32i/instr_spec.json");
            let contents = read_to_string(contents_path).unwrap();
            serde_json::from_str(contents.as_str()).unwrap()
        };

        for (name, spec) in &instr_reference {
            let instr_raw = u32::from_str_radix(spec.example.as_str(), 2).unwrap();
            let instr_decoded = Instruction::parse_from_word(instr_raw).unwrap();
            assert_eq!(instr_decoded.get_name(), *name);
        }
    }
}