five32_instruction_set/rv32i/
mod.rs

1// This is the bulk of the business logic.
2pub mod instr;
3
4// We're allowing dead_code here because there's lots of flags and masks that aren't used.
5#[allow(dead_code)]
6mod instr_masks;
7
8#[cfg(test)]
9mod tests {
10    use std::collections::HashMap;
11    use std::fs::read_to_string;
12    use std::path::Path;
13
14    use serde::{Deserialize};
15
16    use crate::rv32i::instr::Instruction;
17
18    /// This comes from a .json file mapping an instruction to some of its properties.
19    /// ```json
20    ///      "ADD": {
21    ///         "pattern": "0000000----------000-----0110011",
22    ///         "pattern_mask": "0xfe00707f",
23    ///         "pattern_match": "0x33",
24    ///         "example": "00000000000000000000000000110011"
25    ///       },
26    /// ```
27    /// For the purposes of this unit test, we're simply checking if the 'example' can be parsed
28    /// and is recognized as the correct instruction.
29    #[derive(Deserialize)]
30    struct InstructionSpec {
31        pub example: String
32    }
33
34    /// This unit test tries to decode all instructions in the RV32I instruction set.
35    #[test]
36    fn instruction_parsing() {
37        let instr_reference: HashMap<String, InstructionSpec> = {
38            let contents_path = Path::new("src/rv32i/instr_spec.json");
39            let contents = read_to_string(contents_path).unwrap();
40            serde_json::from_str(contents.as_str()).unwrap()
41        };
42
43        for (name, spec) in &instr_reference {
44            let instr_raw = u32::from_str_radix(spec.example.as_str(), 2).unwrap();
45            let instr_decoded = Instruction::parse_from_word(instr_raw).unwrap();
46            assert_eq!(instr_decoded.get_name(), *name);
47        }
48    }
49}