diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index aa434b8..740ae94 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -144,11 +144,11 @@ impl Machine { /// ### Parameters /// /// - **machine** contains the memory - pub fn _extract_memory(machine: &mut Machine){ + pub fn extract_memory(&self){ let file_path = "burritos_memory.txt"; let write_to_file = |path| -> std::io::Result { let mut file = File::create(path)?; - file.write_all(&machine.main_memory)?; + file.write_all(&self.main_memory)?; Ok(file) }; match write_to_file(file_path) { @@ -162,20 +162,20 @@ impl Machine { /// ### Parameters /// /// - **machine** the machine to get the status from - pub fn print_machine_status(machine: &mut Machine) { + pub fn print_status(&self) { println!("######### Machine status #########"); - for i in (0..32 as usize).step_by(3) { - print!(">{0: <4} : {1:<16x} ", print::REG_X[i], machine.int_reg.get_reg(i as u8)); - print!(">{0: <4} : {1:<16x} ", print::REG_X[i+1], machine.int_reg.get_reg((i+1) as u8)); + for i in (0..32).step_by(3) { + print!(">{0: <4} : {1:<16x} ", print::REG_X[i], self.int_reg.get_reg(i as u8)); + print!(">{0: <4} : {1:<16x} ", print::REG_X[i+1], self.int_reg.get_reg((i+1) as u8)); if i+2 < 32 { - print!(">{0: <4} : {1:<16x} ", print::REG_X[i+2], machine.int_reg.get_reg((i+2) as u8)); + print!(">{0: <4} : {1:<16x} ", print::REG_X[i+2], self.int_reg.get_reg((i+2) as u8)); } println!(); } println!("________________SP________________"); - let sp_index = machine.int_reg.get_reg(2); + let sp_index = self.int_reg.get_reg(2); for i in 0..5 { - println!("SP+{:<2} : {:16x}", i*8, machine.read_memory(8, (sp_index + i*8) as usize)); + println!("SP+{:<2} : {:16x}", i*8, self.read_memory(8, (sp_index + i*8) as usize)); } println!("##################################"); } @@ -185,10 +185,10 @@ impl Machine { /// ### Parameters /// /// - **machine** the machine to read the registers from - pub fn string_registers(machine: &mut Machine) -> String { + pub fn string_registers(&self) -> String { let mut s = String::from(""); for i in 0..32 { - s.push_str(format!("{} ", machine.int_reg.get_reg(i)).as_str()); + s.push_str(format!("{} ", self.int_reg.get_reg(i)).as_str()); } s } @@ -198,9 +198,9 @@ impl Machine { /// ### Parameters /// /// - **machine** which contains a table of instructions - pub fn run(machine : &mut Machine){ - while let Ok(()) = Machine::one_instruction(machine) {} - println!("trace : \n{}", machine.registers_trace); + pub fn run(&mut self){ + while let Ok(()) = Machine::one_instruction(self) {} + println!("trace : \n{}", self.registers_trace); } /// Execute the current instruction @@ -208,114 +208,114 @@ impl Machine { /// ### Parameters /// /// - **machine** which contains a table of instructions and a pc to the actual instruction - pub fn one_instruction(machine :&mut Machine) -> Result<(), MachineError> { + pub fn one_instruction(&mut self) -> Result<(), MachineError> { - if machine.main_memory.len() <= machine.pc as usize { + if self.main_memory.len() <= self.pc as usize { panic!("ERROR : number max of instructions rushed"); } let mut val: [u8; 4] = [0; 4]; for i in 0..4 { - val[i] = machine.main_memory[machine.pc as usize + i]; + val[i] = self.main_memory[self.pc as usize + i]; } let val = u32::from_be_bytes(val) as u64; let inst : Instruction = decode(val); - 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()); + self.print_status(); + println!("executing instruction : {:016x} at pc {:x}", val, self.pc); + println!("{}", print::print(decode(val), self.pc as i32)); + let trace = Self::string_registers(self); + self.registers_trace.push_str(format!("{}\n", trace).as_str()); - machine.pc += 4; + self.pc += 4; match inst.opcode { RISCV_LUI => { - machine.int_reg.set_reg(inst.rd, inst.imm31_12 as i64); + self.int_reg.set_reg(inst.rd, inst.imm31_12 as i64); Ok(()) }, RISCV_AUIPC => { - machine.int_reg.set_reg(inst.rd,machine.pc as i64 - 4 + inst.imm31_12 as i64); + self.int_reg.set_reg(inst.rd, self.pc as i64 - 4 + inst.imm31_12 as i64); Ok(()) }, RISCV_JAL => { - machine.int_reg.set_reg(inst.rd, machine.pc as i64); - machine.pc = (machine.pc as i64 + inst.imm21_1_signed as i64 - 4) as u64; + self.int_reg.set_reg(inst.rd, self.pc as i64); + self.pc = (self.pc as i64 + inst.imm21_1_signed as i64 - 4) as u64; Ok(()) }, RISCV_JALR => { - let tmp = machine.pc; - machine.pc = (machine.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as u64 & 0xfffffffe; - machine.int_reg.set_reg(inst.rd, tmp as i64); + let tmp = self.pc; + self.pc = (self.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as u64 & 0xfffffffe; + self.int_reg.set_reg(inst.rd, tmp as i64); Ok(()) }, // Treatment for: BRANCH INSTRUCTIONS RISCV_BR => { - Self::branch_instruction(machine, inst) + self.branch_instruction(inst) }, // Treatment for: LOAD INSTRUCTIONS RISCV_LD => { - Self::load_instruction(machine, inst) + self.load_instruction(inst) }, // store instructions RISCV_ST => { - Self::store_instruction(machine, inst) + self.store_instruction(inst) }, // Treatment for: OPI INSTRUCTIONS RISCV_OPI => { - Self::opi_instruction(machine, inst) + self.opi_instruction(inst) }, RISCV_OP => { - Self::op_instruction(machine, inst) + self.op_instruction(inst) }, // Treatment for OPIW INSTRUCTIONS RISCV_OPIW => { - Self::opiw_instruction(machine, inst) + self.opiw_instruction(inst) }, // Treatment for: OPW INSTRUCTIONS - RISCV_OPW => Self::opw_instruction(machine, inst), + RISCV_OPW => self.opw_instruction(inst), // Treatment for: Simple floating point extension - RISCV_FP => Self::fp_instruction(machine, inst), + RISCV_FP => self.fp_instruction(inst), // Treatment for: System instructions RISCV_SYSTEM => { // temporary return value to stop the loop of run // before we can use system call - Err(MachineError::new(format!("{:x}: System opcode\npc: {:x}", inst.opcode, machine.pc).as_str())) + Err(MachineError::new(format!("{:x}: System opcode\npc: {:x}", inst.opcode, self.pc).as_str())) }, - _ => Err(MachineError::new(format!("{:x}: Unknown opcode\npc: {:x}", inst.opcode, machine.pc).as_str())) + _ => Err(MachineError::new(format!("{:x}: Unknown opcode\npc: {:x}", inst.opcode, self.pc).as_str())) } } /// Treatement for Branch instructions - fn branch_instruction(machine: &mut Machine, inst: Instruction) -> Result<(), MachineError> { + fn branch_instruction(&mut self, inst: Instruction) -> Result<(), MachineError> { match inst.funct3 { RISCV_BR_BEQ => { - if machine.int_reg.get_reg(inst.rs1) == machine.int_reg.get_reg(inst.rs2) { - machine.pc = (machine.pc as i64 + inst.imm13_signed as i64 - 4) as u64; + if self.int_reg.get_reg(inst.rs1) == self.int_reg.get_reg(inst.rs2) { + self.pc = (self.pc as i64 + inst.imm13_signed as i64 - 4) as u64; } }, RISCV_BR_BNE => { - if machine.int_reg.get_reg(inst.rs1) != machine.int_reg.get_reg(inst.rs2) { - machine.pc = (machine.pc as i64 + inst.imm13_signed as i64 - 4) as u64; + if self.int_reg.get_reg(inst.rs1) != self.int_reg.get_reg(inst.rs2) { + self.pc = (self.pc as i64 + inst.imm13_signed as i64 - 4) as u64; } }, RISCV_BR_BLT => { - if machine.int_reg.get_reg(inst.rs1) < machine.int_reg.get_reg(inst.rs2) { - machine.pc = (machine.pc as i64 + inst.imm13_signed as i64 - 4) as u64; + if self.int_reg.get_reg(inst.rs1) < self.int_reg.get_reg(inst.rs2) { + self.pc = (self.pc as i64 + inst.imm13_signed as i64 - 4) as u64; } }, RISCV_BR_BGE => { - if machine.int_reg.get_reg(inst.rs1) >= machine.int_reg.get_reg(inst.rs2) { - machine.pc = (machine.pc as i64 + inst.imm13_signed as i64 - 4) as u64; + if self.int_reg.get_reg(inst.rs1) >= self.int_reg.get_reg(inst.rs2) { + self.pc = (self.pc as i64 + inst.imm13_signed as i64 - 4) as u64; } }, RISCV_BR_BLTU => { - if machine.int_reg.get_reg(inst.rs1) < machine.int_reg.get_reg(inst.rs2) { - machine.pc = (machine.pc as i64 + inst.imm13_signed as i64 - 4) as u64; + if self.int_reg.get_reg(inst.rs1) < self.int_reg.get_reg(inst.rs2) { + self.pc = (self.pc as i64 + inst.imm13_signed as i64 - 4) as u64; } }, RISCV_BR_BGEU => { - if machine.int_reg.get_reg(inst.rs1) >= machine.int_reg.get_reg(inst.rs2) { - machine.pc = (machine.pc as i64 + inst.imm13_signed as i64 - 4) as u64; + if self.int_reg.get_reg(inst.rs1) >= self.int_reg.get_reg(inst.rs2) { + self.pc = (self.pc as i64 + inst.imm13_signed as i64 - 4) as u64; } }, _ => { @@ -326,23 +326,23 @@ impl Machine { } /// Executes RISC-V Load Instructions on the machine - fn load_instruction(machine: &mut Machine, inst: Instruction) -> Result<(), MachineError> { + fn load_instruction(&mut self, inst: Instruction) -> Result<(), MachineError> { match inst.funct3 { RISCV_LD_LB | RISCV_LD_LBU => { - let tmp = machine.read_memory(1, (machine.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as usize) as i64; - machine.int_reg.set_reg(inst.rd, tmp); + let tmp = self.read_memory(1, (self.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as usize) as i64; + self.int_reg.set_reg(inst.rd, tmp); }, RISCV_LD_LH | RISCV_LD_LHU => { - let tmp = machine.read_memory(2, (machine.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as usize) as i64; - machine.int_reg.set_reg(inst.rd, tmp); + let tmp = self.read_memory(2, (self.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as usize) as i64; + self.int_reg.set_reg(inst.rd, tmp); }, RISCV_LD_LW | RISCV_LD_LWU => { - let tmp = machine.read_memory(4, (machine.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as usize) as i64; - machine.int_reg.set_reg(inst.rd, tmp); + let tmp = self.read_memory(4, (self.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as usize) as i64; + self.int_reg.set_reg(inst.rd, tmp); }, RISCV_LD_LD => { - let tmp = machine.read_memory(8, (machine.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as usize) as i64; - machine.int_reg.set_reg(inst.rd, tmp); + let tmp = self.read_memory(8, (self.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64) as usize) as i64; + self.int_reg.set_reg(inst.rd, tmp); }, _ => panic!("In LD switch case, this should never happen... Instr was {}", inst.value) } @@ -350,30 +350,30 @@ impl Machine { } /// Executes RISC-V Store Instructions on the machine - fn store_instruction(machine: &mut Machine, inst: Instruction) -> Result<(), MachineError> { + fn store_instruction(&mut self, inst: Instruction) -> Result<(), MachineError> { match inst.funct3 { - RISCV_ST_STB => machine.write_memory(1, (machine.int_reg.get_reg(inst.rs1) + inst.imm12_S_signed as i64) as usize, machine.int_reg.get_reg(inst.rs2) as u64), - RISCV_ST_STH => machine.write_memory(2, (machine.int_reg.get_reg(inst.rs1) + inst.imm12_S_signed as i64) as usize, machine.int_reg.get_reg(inst.rs2) as u64), - RISCV_ST_STW => machine.write_memory(4, (machine.int_reg.get_reg(inst.rs1) + inst.imm12_S_signed as i64) as usize, machine.int_reg.get_reg(inst.rs2) as u64), - RISCV_ST_STD => machine.write_memory(8, (machine.int_reg.get_reg(inst.rs1) + inst.imm12_S_signed as i64) as usize, machine.int_reg.get_reg(inst.rs2) as u64), + RISCV_ST_STB => self.write_memory(1, (self.int_reg.get_reg(inst.rs1) + inst.imm12_S_signed as i64) as usize, self.int_reg.get_reg(inst.rs2) as u64), + RISCV_ST_STH => self.write_memory(2, (self.int_reg.get_reg(inst.rs1) + inst.imm12_S_signed as i64) as usize, self.int_reg.get_reg(inst.rs2) as u64), + RISCV_ST_STW => self.write_memory(4, (self.int_reg.get_reg(inst.rs1) + inst.imm12_S_signed as i64) as usize, self.int_reg.get_reg(inst.rs2) as u64), + RISCV_ST_STD => self.write_memory(8, (self.int_reg.get_reg(inst.rs1) + inst.imm12_S_signed as i64) as usize, self.int_reg.get_reg(inst.rs2) as u64), _ => panic!("In ST switch case, this should never happen... Instr was {}", inst.value) } Ok(()) } /// Executes RISC-V Integer Register-Immediate Instructions on the machine - fn opi_instruction(machine: &mut Machine, inst: Instruction) -> Result<(), MachineError> { + fn opi_instruction(&mut self, inst: Instruction) -> Result<(), MachineError> { match inst.funct3 { - RISCV_OPI_ADDI => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64), - RISCV_OPI_SLTI => machine.int_reg.set_reg(inst.rd, (machine.int_reg.get_reg(inst.rs1) < inst.imm12_I_signed as i64) as i64), - RISCV_OPI_XORI => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) ^ inst.imm12_I_signed as i64), - RISCV_OPI_ORI => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) | inst.imm12_I_signed as i64), - RISCV_OPI_ANDI => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) & inst.imm12_I_signed as i64), - RISCV_OPI_SLLI => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) << inst.shamt), + RISCV_OPI_ADDI => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) + inst.imm12_I_signed as i64), + RISCV_OPI_SLTI => self.int_reg.set_reg(inst.rd, (self.int_reg.get_reg(inst.rs1) < inst.imm12_I_signed as i64) as i64), + RISCV_OPI_XORI => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) ^ inst.imm12_I_signed as i64), + RISCV_OPI_ORI => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) | inst.imm12_I_signed as i64), + RISCV_OPI_ANDI => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) & inst.imm12_I_signed as i64), + RISCV_OPI_SLLI => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) << inst.shamt), RISCV_OPI_SRI => if inst.funct7_smaller == RISCV_OPI_SRI_SRLI { - machine.int_reg.set_reg(inst.rd, (machine.int_reg.get_reg(inst.rs1) >> inst.shamt) & machine.shiftmask[inst.shamt as usize] as i64); + self.int_reg.set_reg(inst.rd, (self.int_reg.get_reg(inst.rs1) >> inst.shamt) & self.shiftmask[inst.shamt as usize] as i64); } else { // SRAI - machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) >> inst.shamt); + self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) >> inst.shamt); }, _ => panic!("In OPI switch case, this should never happen... Instr was %x\n {}", inst.value) } @@ -381,60 +381,60 @@ impl Machine { } /// Executes simple RISC-V mathematical operations on the machine - fn op_instruction(machine: &mut Machine, inst: Instruction) -> Result<(), MachineError> { + fn op_instruction(&mut self, inst: Instruction) -> Result<(), MachineError> { let long_result: i128; let unsigned_reg1: u64; let unsigned_reg2: u64; if inst.funct7 == 1 { match inst.funct3 { RISCV_OP_M_MUL => { - long_result = (machine.int_reg.get_reg(inst.rs1) * machine.int_reg.get_reg(inst.rs2)) as i128; - machine.int_reg.set_reg(inst.rd, (long_result & 0xffffffffffffffff) as i64) + long_result = (self.int_reg.get_reg(inst.rs1) * self.int_reg.get_reg(inst.rs2)) as i128; + self.int_reg.set_reg(inst.rd, (long_result & 0xffffffffffffffff) as i64) }, RISCV_OP_M_MULH => { - long_result = (machine.int_reg.get_reg(inst.rs1) * machine.int_reg.get_reg(inst.rs2)) as i128; - machine.int_reg.set_reg(inst.rd, ((long_result >> 64) & 0xffffffffffffffff) as i64) + long_result = (self.int_reg.get_reg(inst.rs1) * self.int_reg.get_reg(inst.rs2)) as i128; + self.int_reg.set_reg(inst.rd, ((long_result >> 64) & 0xffffffffffffffff) as i64) }, RISCV_OP_M_MULHSU => { - unsigned_reg2 = machine.int_reg.get_reg(inst.rs2) as u64; - long_result = (machine.int_reg.get_reg(inst.rs1) as u64 * unsigned_reg2) as i128; - machine.int_reg.set_reg(inst.rd, ((long_result >> 64) & 0xffffffffffffffff) as i64) + unsigned_reg2 = self.int_reg.get_reg(inst.rs2) as u64; + long_result = (self.int_reg.get_reg(inst.rs1) as u64 * unsigned_reg2) as i128; + self.int_reg.set_reg(inst.rd, ((long_result >> 64) & 0xffffffffffffffff) as i64) }, RISCV_OP_M_MULHU => { - unsigned_reg1 = machine.int_reg.get_reg(inst.rs1) as u64; - unsigned_reg2 = machine.int_reg.get_reg(inst.rs2) as u64; + unsigned_reg1 = self.int_reg.get_reg(inst.rs1) as u64; + unsigned_reg2 = self.int_reg.get_reg(inst.rs2) as u64; long_result = (unsigned_reg1 * unsigned_reg2) as i128; - machine.int_reg.set_reg(inst.rd, ((long_result >> 64) & 0xffffffffffffffff) as i64); + self.int_reg.set_reg(inst.rd, ((long_result >> 64) & 0xffffffffffffffff) as i64); }, - RISCV_OP_M_DIV => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) / machine.int_reg.get_reg(inst.rs2)), + RISCV_OP_M_DIV => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) / self.int_reg.get_reg(inst.rs2)), _ => panic!("RISCV_OP : funct7 = 1 (Multiplication) :: Error\n") } } else { match inst.funct3 { RISCV_OP_ADD => if inst.funct7 == RISCV_OP_ADD_ADD { - machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) + machine.int_reg.get_reg(inst.rs2)) + self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) + self.int_reg.get_reg(inst.rs2)) } else { - machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) - machine.int_reg.get_reg(inst.rs2)) + self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) - self.int_reg.get_reg(inst.rs2)) }, - RISCV_OP_SLL => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) << (machine.int_reg.get_reg(inst.rs2) & 0x3f)), - RISCV_OP_SLT => if machine.int_reg.get_reg(inst.rs1) < machine.int_reg.get_reg(inst.rs2) { - machine.int_reg.set_reg(inst.rd, 1) + RISCV_OP_SLL => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) << (self.int_reg.get_reg(inst.rs2) & 0x3f)), + RISCV_OP_SLT => if self.int_reg.get_reg(inst.rs1) < self.int_reg.get_reg(inst.rs2) { + self.int_reg.set_reg(inst.rd, 1) } else { - machine.int_reg.set_reg(inst.rd, 0) + self.int_reg.set_reg(inst.rd, 0) }, RISCV_OP_SLTU => { - unsigned_reg1 = machine.int_reg.get_reg(inst.rs1) as u64; - unsigned_reg2 = machine.int_reg.get_reg(inst.rs2) as u64; + unsigned_reg1 = self.int_reg.get_reg(inst.rs1) as u64; + unsigned_reg2 = self.int_reg.get_reg(inst.rs2) as u64; if unsigned_reg1 < unsigned_reg2 { - machine.int_reg.set_reg(inst.rd, 1) + self.int_reg.set_reg(inst.rd, 1) } else { - machine.int_reg.set_reg(inst.rd, 0) + self.int_reg.set_reg(inst.rd, 0) } }, - RISCV_OP_XOR => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) ^ machine.int_reg.get_reg(inst.rs2)), - RISCV_OP_SR => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) >> machine.int_reg.get_reg(inst.rs2)), // RISCV_OP_SR_SRL inaccessible - RISCV_OP_OR => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) | machine.int_reg.get_reg(inst.rs2)), - RISCV_OP_AND => machine.int_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) & machine.int_reg.get_reg(inst.rs2)), + RISCV_OP_XOR => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) ^ self.int_reg.get_reg(inst.rs2)), + RISCV_OP_SR => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) >> self.int_reg.get_reg(inst.rs2)), // RISCV_OP_SR_SRL inaccessible + RISCV_OP_OR => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) | self.int_reg.get_reg(inst.rs2)), + RISCV_OP_AND => self.int_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) & self.int_reg.get_reg(inst.rs2)), _ => panic!("RISCV_OP undefined case\n") } } @@ -442,24 +442,24 @@ impl Machine { } /// Exectutes simple RISC-V *iw instructions on the machine - fn opiw_instruction(machine: &mut Machine, inst: Instruction) -> Result<(), MachineError> { - let local_data = machine.int_reg.get_reg(inst.rs1); + fn opiw_instruction(&mut self, inst: Instruction) -> Result<(), MachineError> { + let local_data = self.int_reg.get_reg(inst.rs1); match inst.funct3 { RISCV_OPIW_ADDIW => { let result = local_data + inst.imm12_I_signed as i64; - machine.int_reg.set_reg(inst.rd, result) + self.int_reg.set_reg(inst.rd, result) }, RISCV_OPIW_SLLIW => { let result = local_data << inst.shamt; - machine.int_reg.set_reg(inst.rd, result) + self.int_reg.set_reg(inst.rd, result) }, RISCV_OPIW_SRW => { let result = if inst.funct7 == RISCV_OPIW_SRW_SRLIW { - (local_data >> inst.shamt) & machine.shiftmask[32 + inst.shamt as usize] as i64 + (local_data >> inst.shamt) & self.shiftmask[32 + inst.shamt as usize] as i64 } else { // SRAIW local_data >> inst.shamt }; - machine.int_reg.set_reg(inst.rd, result) + self.int_reg.set_reg(inst.rd, result) }, _ => panic!("In OPI switch case, this should never happen... Instr was {}\n", inst.value), } @@ -467,37 +467,37 @@ impl Machine { } /// Executes simple RISC-V *w instructions on the machine - fn opw_instruction(machine: &mut Machine, inst: Instruction) -> Result<(), MachineError> { + fn opw_instruction(&mut self, inst: Instruction) -> Result<(), MachineError> { if inst.funct7 == 1 { // rv64m - let local_data_a = machine.int_reg.get_reg(inst.rs1) & 0xffffffff; - let local_data_b = machine.int_reg.get_reg(inst.rs2) & 0xffffffff; - let local_data_a_unsigned = machine.int_reg.get_reg(inst.rs1) & 0xffffffff; - let local_data_b_unsigned = machine.int_reg.get_reg(inst.rs2) & 0xffffffff; + let local_data_a = self.int_reg.get_reg(inst.rs1) & 0xffffffff; + let local_data_b = self.int_reg.get_reg(inst.rs2) & 0xffffffff; + let local_data_a_unsigned = self.int_reg.get_reg(inst.rs1) & 0xffffffff; + let local_data_b_unsigned = self.int_reg.get_reg(inst.rs2) & 0xffffffff; // Match case for multiplication operations (in standard extension RV32M) match inst.funct3 { - RISCV_OPW_M_MULW => machine.int_reg.set_reg(inst.rd, local_data_a * local_data_b), - RISCV_OPW_M_DIVW => machine.int_reg.set_reg(inst.rd, local_data_a / local_data_b), - RISCV_OPW_M_DIVUW => machine.int_reg.set_reg(inst.rd, local_data_a_unsigned / local_data_b_unsigned), - RISCV_OPW_M_REMW => machine.int_reg.set_reg(inst.rd, local_data_a % local_data_b), - RISCV_OPW_M_REMUW => machine.int_reg.set_reg(inst.rd, local_data_a_unsigned % local_data_b_unsigned), + RISCV_OPW_M_MULW => self.int_reg.set_reg(inst.rd, local_data_a * local_data_b), + RISCV_OPW_M_DIVW => self.int_reg.set_reg(inst.rd, local_data_a / local_data_b), + RISCV_OPW_M_DIVUW => self.int_reg.set_reg(inst.rd, local_data_a_unsigned / local_data_b_unsigned), + RISCV_OPW_M_REMW => self.int_reg.set_reg(inst.rd, local_data_a % local_data_b), + RISCV_OPW_M_REMUW => self.int_reg.set_reg(inst.rd, local_data_a_unsigned % local_data_b_unsigned), _ => panic!("this instruction ({}) doesn't exists", inst.value) } } else { // others rv64 OPW operations - let local_dataa = machine.int_reg.get_reg(inst.rs1) & 0xffffffff; - let local_datab = machine.int_reg.get_reg(inst.rs2) & 0xffffffff; + let local_dataa = self.int_reg.get_reg(inst.rs1) & 0xffffffff; + let local_datab = self.int_reg.get_reg(inst.rs2) & 0xffffffff; // Match case for base OP operation match inst.funct3 { RISCV_OPW_ADDSUBW => if inst.funct7 == RISCV_OPW_ADDSUBW_ADDW { - machine.int_reg.set_reg(inst.rd, local_dataa + local_datab); + self.int_reg.set_reg(inst.rd, local_dataa + local_datab); } else { // SUBW - machine.int_reg.set_reg(inst.rd, local_dataa - local_datab); + self.int_reg.set_reg(inst.rd, local_dataa - local_datab); }, - RISCV_OPW_SLLW => machine.int_reg.set_reg(inst.rd, local_dataa << (local_datab & 0x1f)), + RISCV_OPW_SLLW => self.int_reg.set_reg(inst.rd, local_dataa << (local_datab & 0x1f)), RISCV_OPW_SRW => if inst.funct7 == RISCV_OPW_SRW_SRLW { - machine.int_reg.set_reg(inst.rd, local_dataa >> (local_datab & 0x1f) & machine.shiftmask[32 + local_datab as usize] as i64) + self.int_reg.set_reg(inst.rd, local_dataa >> (local_datab & 0x1f) & self.shiftmask[32 + local_datab as usize] as i64) } else { // SRAW - machine.int_reg.set_reg(inst.rd, local_dataa >> (local_datab & 0x1f)) + self.int_reg.set_reg(inst.rd, local_dataa >> (local_datab & 0x1f)) }, _ => panic!("this instruction ({}) doesn't exists", inst.value) } @@ -506,71 +506,71 @@ impl Machine { } /// Executes simple RISC-V floating point instructions on the machine - fn fp_instruction(machine: &mut Machine, inst: Instruction) -> Result<(), MachineError> { + fn fp_instruction(&mut self, inst: Instruction) -> Result<(), MachineError> { match inst.funct7 { - RISCV_FP_ADD => machine.fp_reg.set_reg(inst.rd, machine.fp_reg.get_reg(inst.rs1) + machine.fp_reg.get_reg(inst.rs2)), - RISCV_FP_SUB => machine.fp_reg.set_reg(inst.rd, machine.fp_reg.get_reg(inst.rs1) - machine.fp_reg.get_reg(inst.rs2)), - RISCV_FP_MUL => machine.fp_reg.set_reg(inst.rd, machine.fp_reg.get_reg(inst.rs1) * machine.fp_reg.get_reg(inst.rs2)), - RISCV_FP_DIV => machine.fp_reg.set_reg(inst.rd, machine.fp_reg.get_reg(inst.rs1) / machine.fp_reg.get_reg(inst.rs2)), - RISCV_FP_SQRT => machine.fp_reg.set_reg(inst.rd, machine.fp_reg.get_reg(inst.rs1).sqrt()), + RISCV_FP_ADD => self.fp_reg.set_reg(inst.rd, self.fp_reg.get_reg(inst.rs1) + self.fp_reg.get_reg(inst.rs2)), + RISCV_FP_SUB => self.fp_reg.set_reg(inst.rd, self.fp_reg.get_reg(inst.rs1) - self.fp_reg.get_reg(inst.rs2)), + RISCV_FP_MUL => self.fp_reg.set_reg(inst.rd, self.fp_reg.get_reg(inst.rs1) * self.fp_reg.get_reg(inst.rs2)), + RISCV_FP_DIV => self.fp_reg.set_reg(inst.rd, self.fp_reg.get_reg(inst.rs1) / self.fp_reg.get_reg(inst.rs2)), + RISCV_FP_SQRT => self.fp_reg.set_reg(inst.rd, self.fp_reg.get_reg(inst.rs1).sqrt()), RISCV_FP_FSGN => { - let local_float = machine.fp_reg.get_reg(inst.rs1); + let local_float = self.fp_reg.get_reg(inst.rs1); match inst.funct3 { - RISCV_FP_FSGN_J => if machine.fp_reg.get_reg(inst.rs2) < 0f32 { - machine.fp_reg.set_reg(inst.rd, -local_float) + RISCV_FP_FSGN_J => if self.fp_reg.get_reg(inst.rs2) < 0f32 { + self.fp_reg.set_reg(inst.rd, -local_float) } else { - machine.fp_reg.set_reg(inst.rd, local_float) + self.fp_reg.set_reg(inst.rd, local_float) }, - RISCV_FP_FSGN_JN => if machine.fp_reg.get_reg(inst.rs2) < 0f32 { - machine.fp_reg.set_reg(inst.rd, local_float) + RISCV_FP_FSGN_JN => if self.fp_reg.get_reg(inst.rs2) < 0f32 { + self.fp_reg.set_reg(inst.rd, local_float) } else { - machine.fp_reg.set_reg(inst.rd, -local_float) + self.fp_reg.set_reg(inst.rd, -local_float) }, - RISCV_FP_FSGN_JX => if (machine.fp_reg.get_reg(inst.rs2) < 0.0 && machine.fp_reg.get_reg(inst.rs1) >= 0.0) || - (machine.fp_reg.get_reg(inst.rs2) >= 0.0 && machine.fp_reg.get_reg(inst.rs1) < 0.0) { - machine.fp_reg.set_reg(inst.rd, -local_float) + RISCV_FP_FSGN_JX => if (self.fp_reg.get_reg(inst.rs2) < 0.0 && self.fp_reg.get_reg(inst.rs1) >= 0.0) || + (self.fp_reg.get_reg(inst.rs2) >= 0.0 && self.fp_reg.get_reg(inst.rs1) < 0.0) { + self.fp_reg.set_reg(inst.rd, -local_float) } else { - machine.fp_reg.set_reg(inst.rd, local_float) + self.fp_reg.set_reg(inst.rd, local_float) }, _ => panic!("this instruction ({}) doesn't exists", inst.value) } }, RISCV_FP_MINMAX => { - let r1 = machine.fp_reg.get_reg(inst.rs1); - let r2 = machine.fp_reg.get_reg(inst.rs2); + let r1 = self.fp_reg.get_reg(inst.rs1); + let r2 = self.fp_reg.get_reg(inst.rs2); match inst.funct3 { - RISCV_FP_MINMAX_MIN => machine.fp_reg.set_reg(inst.rd, if r1 < r2 {r1} else {r2}), - RISCV_FP_MINMAX_MAX => machine.fp_reg.set_reg(inst.rd, if r1 > r2 {r1} else {r2}), + RISCV_FP_MINMAX_MIN => self.fp_reg.set_reg(inst.rd, if r1 < r2 {r1} else {r2}), + RISCV_FP_MINMAX_MAX => self.fp_reg.set_reg(inst.rd, if r1 > r2 {r1} else {r2}), _ => panic!("this instruction ({}) doesn't exists", inst.value) } }, RISCV_FP_FCVTW => { if inst.rs2 == RISCV_FP_FCVTW_W { - machine.int_reg.set_reg(inst.rd, machine.fp_reg.get_reg(inst.rs1) as i64) + self.int_reg.set_reg(inst.rd, self.fp_reg.get_reg(inst.rs1) as i64) } else { - machine.int_reg.set_reg(inst.rd, (machine.fp_reg.get_reg(inst.rs1) as u64) as i64) + self.int_reg.set_reg(inst.rd, (self.fp_reg.get_reg(inst.rs1) as u64) as i64) } }, RISCV_FP_FCVTS => { if inst.rs2 == RISCV_FP_FCVTS_W { - machine.fp_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) as f32); + self.fp_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) as f32); } else { - machine.fp_reg.set_reg(inst.rd, (machine.int_reg.get_reg(inst.rs1) as u32) as f32); + self.fp_reg.set_reg(inst.rd, (self.int_reg.get_reg(inst.rs1) as u32) as f32); } }, - RISCV_FP_FMVW => machine.fp_reg.set_reg(inst.rd, machine.int_reg.get_reg(inst.rs1) as f32), + RISCV_FP_FMVW => self.fp_reg.set_reg(inst.rd, self.int_reg.get_reg(inst.rs1) as f32), RISCV_FP_FMVXFCLASS => { if inst.funct3 == RISCV_FP_FMVXFCLASS_FMVX { - machine.int_reg.set_reg(inst.rd, machine.fp_reg.get_reg(inst.rs1) as i64); + self.int_reg.set_reg(inst.rd, self.fp_reg.get_reg(inst.rs1) as i64); } else { panic!("Fclass instruction is not handled in riscv simulator"); } }, RISCV_FP_FCMP => { match inst.funct3 { - RISCV_FP_FCMP_FEQ => machine.int_reg.set_reg(inst.rd, (machine.fp_reg.get_reg(inst.rs1) == machine.fp_reg.get_reg(inst.rs2)) as i64), - RISCV_FP_FCMP_FLT => machine.int_reg.set_reg(inst.rd, (machine.fp_reg.get_reg(inst.rs1) < machine.fp_reg.get_reg(inst.rs2)) as i64), - RISCV_FP_FCMP_FLE => machine.int_reg.set_reg(inst.rd, (machine.fp_reg.get_reg(inst.rs1) <= machine.fp_reg.get_reg(inst.rs2)) as i64), + RISCV_FP_FCMP_FEQ => self.int_reg.set_reg(inst.rd, (self.fp_reg.get_reg(inst.rs1) == self.fp_reg.get_reg(inst.rs2)) as i64), + RISCV_FP_FCMP_FLT => self.int_reg.set_reg(inst.rd, (self.fp_reg.get_reg(inst.rs1) < self.fp_reg.get_reg(inst.rs2)) as i64), + RISCV_FP_FCMP_FLE => self.int_reg.set_reg(inst.rd, (self.fp_reg.get_reg(inst.rs1) <= self.fp_reg.get_reg(inst.rs2)) as i64), _ => panic!("this instruction ({}) doesn't exists", inst.value) } }, @@ -582,12 +582,12 @@ impl Machine { /// print memory FOR DEBUG /// /// "@"adress [16 bytes] - pub fn _print_memory(machine : &mut Machine, from: usize, to: usize) { + pub fn print_memory(&self, from: usize, to: usize) { for i in from..to { if i%16 == 0 { print!("\n@{:04x} ", i); } - print!("{:02x}", machine.main_memory[i]); + print!("{:02x}", self.main_memory[i]); } println!(); }