diff --git a/src/main.rs b/src/main.rs index 64f37a3..562ef00 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,10 +5,10 @@ use simulator::mem_cmp; fn main() { let mut m = Machine::_init_machine(); - let path = "memoryJump.txt".to_string(); + let path = "memoryComp.txt".to_string(); let checker = mem_cmp::MemChecker::from(&path); mem_cmp::MemChecker::fill_memory_from_mem_checker(&checker, &mut m); //mem_cmp::Mem_Checker::print_Mem_Checker(&checker); //Machine::print_memory(&mut m, 0x400000, 0x405000); - //Machine::run(m); + Machine::run(&mut m); } diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index 47ee672..55d13ab 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -68,7 +68,8 @@ pub struct Machine { pub int_reg : Register, pub fp_reg : Register, pub main_memory : Vec, - pub shiftmask : [u64 ; 64] + pub shiftmask : [u64 ; 64], + pub registers_trace : String // for tests // futur taille à calculer int memSize = g_cfg->NumPhysPages * g_cfg->PageSize; //creer une struct cfg(configuration) qui s'initialise avec valeur dans un fichier cfg } @@ -86,15 +87,18 @@ impl Machine { value >>= 1; } - Machine { + let mut ret = Machine { pc : 0, sp: 0, int_reg : Register::::init(), fp_reg : Register::::init(), main_memory : vec![0; MEM_SIZE], - shiftmask - } - + shiftmask, + registers_trace : String::from("") + }; + + ret.int_reg.set_reg(10, -1); + ret } /// Read from main memory of the machine @@ -153,12 +157,10 @@ impl Machine { pub fn print_machine_status(machine: &mut Machine) { println!("######### Machine status #########"); for i in (0..32).step_by(3) { - print!(">{0: <4} : {1:<8x}", print::REG_X[i], machine.int_reg.get_reg(i)); - print!("\t"); - print!(">{0: <4} : {1:<8x}", print::REG_X[i+1], machine.int_reg.get_reg(i+1)); - print!("\t"); + print!(">{0: <4} : {1:<16x} ", print::REG_X[i], machine.int_reg.get_reg(i)); + print!(">{0: <4} : {1:<16x} ", print::REG_X[i+1], machine.int_reg.get_reg(i+1)); if i+2 < 32 { - print!(">{0: <4} : {1:<8x}", print::REG_X[i+2], machine.int_reg.get_reg(i+2)); + print!(">{0: <4} : {1:<16x} ", print::REG_X[i+2], machine.int_reg.get_reg(i+2)); } println!(); } @@ -170,14 +172,22 @@ impl Machine { println!("##################################"); } + pub fn string_registers(machine: &mut Machine) -> String { + let mut s = String::from(""); + for i in 0..32 { + s.push_str(format!("{} ", machine.int_reg.get_reg(i)).as_str()); + } + s + } + /// Execute the instructions table of a machine putted in param /// /// ### Parameters /// /// - **machine** which contains a table of instructions - pub fn run(machine : Machine){ - let mut m = machine; - while Machine::one_instruction(&mut m) == 0 {} + pub fn run(machine : &mut Machine){ + while Machine::one_instruction(machine) == 0 {} + println!("trace : \n{}", machine.registers_trace); } /// execute the current instruction @@ -212,8 +222,10 @@ impl Machine { Self::print_machine_status(machine); println!("executing instruction : {:016x} at pc {:x}", val, machine.pc); println!("{}", print::print(decode(val), machine.pc as i32)); + let trace = Self::string_registers(machine); + machine.registers_trace.push_str(format!("{}\n", trace).as_str()); - + machine.pc += 4; match inst.opcode { RISCV_LUI => { @@ -633,7 +645,6 @@ impl Machine { _ => { panic!("{:x} opcode non géré pc : {:x}", inst.opcode, machine.pc)}, } - machine.pc += 4; return 0; } @@ -654,8 +665,10 @@ impl Machine { } #[cfg(test)] - mod test { - use crate::simulator::machine::Machine; +mod test { + use std::fs; + + use crate::simulator::{machine::Machine, mem_cmp}; #[test] fn test_read_memory() { @@ -677,4 +690,140 @@ impl Machine { assert_eq!(43, m.main_memory[10]); assert_eq!(150, m.main_memory[11]); } + + #[test] + fn test_comp() { + let mut m = Machine::_init_machine(); + let path_before = "memoryComp.txt".to_string(); + let path_after = "memoryCompEnd.txt".to_string(); + let memory_before = mem_cmp::MemChecker::from(&path_before); + let memory_after = mem_cmp::MemChecker::from(&path_after); + mem_cmp::MemChecker::fill_memory_from_mem_checker(&memory_before, &mut m); + Machine::run(&mut m); + + let path_trace = "memoryCompTrace.txt".to_string(); + let expected_trace = fs::read_to_string(path_trace).unwrap(); + + assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m)); + assert!(expected_trace.contains(m.registers_trace.as_str())); + } + + #[test] + fn test_div() { + let mut m = Machine::_init_machine(); + let path_before = "memoryDiv.txt".to_string(); + let path_after = "memoryDivEnd.txt".to_string(); + let memory_before = mem_cmp::MemChecker::from(&path_before); + let memory_after = mem_cmp::MemChecker::from(&path_after); + mem_cmp::MemChecker::fill_memory_from_mem_checker(&memory_before, &mut m); + Machine::run(&mut m); + + let path_trace = "memoryDivTrace.txt".to_string(); + let expected_trace = fs::read_to_string(path_trace).unwrap(); + + assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m)); + assert!(expected_trace.contains(m.registers_trace.as_str())); + } + + #[test] + fn test_if() { + let mut m = Machine::_init_machine(); + let path_before = "memoryIf.txt".to_string(); + let path_after = "memoryIfEnd.txt".to_string(); + let memory_before = mem_cmp::MemChecker::from(&path_before); + let memory_after = mem_cmp::MemChecker::from(&path_after); + mem_cmp::MemChecker::fill_memory_from_mem_checker(&memory_before, &mut m); + Machine::run(&mut m); + + let path_trace = "memoryIfTrace.txt".to_string(); + let expected_trace = fs::read_to_string(path_trace).unwrap(); + + assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m)); + assert!(expected_trace.contains(m.registers_trace.as_str())); + } + + #[test] + fn test_jump() { + let mut m = Machine::_init_machine(); + let path_before = "memoryJump.txt".to_string(); + let path_after = "memoryJumpEnd.txt".to_string(); + let memory_before = mem_cmp::MemChecker::from(&path_before); + let memory_after = mem_cmp::MemChecker::from(&path_after); + mem_cmp::MemChecker::fill_memory_from_mem_checker(&memory_before, &mut m); + Machine::run(&mut m); + + let path_trace = "memoryJumpTrace.txt".to_string(); + let expected_trace = fs::read_to_string(path_trace).unwrap(); + + assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m)); + assert!(expected_trace.contains(m.registers_trace.as_str())); + } + + #[test] + fn test_mul() { + let mut m = Machine::_init_machine(); + let path_before = "memoryMul.txt".to_string(); + let path_after = "memoryMulEnd.txt".to_string(); + let memory_before = mem_cmp::MemChecker::from(&path_before); + let memory_after = mem_cmp::MemChecker::from(&path_after); + mem_cmp::MemChecker::fill_memory_from_mem_checker(&memory_before, &mut m); + Machine::run(&mut m); + + let path_trace = "memoryMulTrace.txt".to_string(); + let expected_trace = fs::read_to_string(path_trace).unwrap(); + + assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m)); + assert!(expected_trace.contains(m.registers_trace.as_str())); + } + + #[test] + fn test_ret() { + let mut m = Machine::_init_machine(); + let path_before = "memoryRet.txt".to_string(); + let path_after = "memoryRetEnd.txt".to_string(); + let memory_before = mem_cmp::MemChecker::from(&path_before); + let memory_after = mem_cmp::MemChecker::from(&path_after); + mem_cmp::MemChecker::fill_memory_from_mem_checker(&memory_before, &mut m); + Machine::run(&mut m); + + let path_trace = "memoryRetTrace.txt".to_string(); + let expected_trace = fs::read_to_string(path_trace).unwrap(); + + assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m)); + assert!(expected_trace.contains(m.registers_trace.as_str())); + } + + #[test] + fn test_sub() { + let mut m = Machine::_init_machine(); + let path_before = "memorySub.txt".to_string(); + let path_after = "memorySubEnd.txt".to_string(); + let memory_before = mem_cmp::MemChecker::from(&path_before); + let memory_after = mem_cmp::MemChecker::from(&path_after); + mem_cmp::MemChecker::fill_memory_from_mem_checker(&memory_before, &mut m); + Machine::run(&mut m); + + let path_trace = "memorySubTrace.txt".to_string(); + let expected_trace = fs::read_to_string(path_trace).unwrap(); + + assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m)); + assert!(expected_trace.contains(m.registers_trace.as_str())); + } + + #[test] + fn test_switch() { + let mut m = Machine::_init_machine(); + let path_before = "memorySwitch.txt".to_string(); + let path_after = "memorySwitchEnd.txt".to_string(); + let memory_before = mem_cmp::MemChecker::from(&path_before); + let memory_after = mem_cmp::MemChecker::from(&path_after); + mem_cmp::MemChecker::fill_memory_from_mem_checker(&memory_before, &mut m); + Machine::run(&mut m); + + let path_trace = "memorySwitchTrace.txt".to_string(); + let expected_trace = fs::read_to_string(path_trace).unwrap(); + + assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m)); + assert!(expected_trace.contains(m.registers_trace.as_str())); + } } diff --git a/src/simulator/mem_cmp.rs b/src/simulator/mem_cmp.rs index 9c4d1da..70f86f5 100644 --- a/src/simulator/mem_cmp.rs +++ b/src/simulator/mem_cmp.rs @@ -2,6 +2,7 @@ use std::fs; use std::io::BufRead; use std::io::BufReader; use std::io::Lines; +use std::io::Read; use crate::Machine; const MEM_SIZE : usize = 4096; @@ -186,7 +187,7 @@ impl MemChecker{ pub fn fill_memory_from_mem_checker(m_c: &MemChecker, machine: &mut Machine){ machine.sp = m_c.sp; - machine.int_reg.set_reg(2, m_c.pc as i64); + machine.int_reg.set_reg(2, m_c.sp as i64); machine.pc = m_c.pc as u64; @@ -228,11 +229,10 @@ impl MemChecker{ /// - **machine** contains the main memory pub fn compare_machine_memory(m_c: &MemChecker, machine: &Machine) -> bool { m_c.sections.iter().map(|section| { - !(0..section.len).into_iter().all(|i| machine.main_memory[section.addr + i] == section.content[i]) - }).all(|e| e == true) + (0..section.len).into_iter().all(|i| machine.main_memory[section.addr + i] == section.content[i]) + }).all(|e| e) } - }