From 37625474020b6c343e5ba858b629ed7e73f4c947 Mon Sep 17 00:00:00 2001 From: Quentin Legot Date: Sat, 4 Feb 2023 18:16:52 +0100 Subject: [PATCH] Added OPIW OPs and made some fix (see description) Fix some warning which appear on clippy Fix print with 2 OPIW operations Fix doc in mod.rs --- src/main.rs | 2 +- src/simulator/machine.rs | 37 ++++++++++++++++++++++++++++++++----- src/simulator/mod.rs | 6 +++--- src/simulator/print.rs | 4 ++-- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index 953914e..4acaaf7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,6 @@ fn main() { let a : u8 = 128; let b : i8 = a as i8; let c : u8 = b as u8; - println!("aaa {}", c); + println!("aaa {c}"); println!("read_memory : {}", Machine::read_memory(&mut m, 2, 4)); } diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index c8a6fd6..44888f4 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -105,7 +105,7 @@ impl Machine { /// - **address** in the memory to read pub fn read_memory(machine : &mut Machine, size : i32, address : usize) -> u64 { if ![1, 2, 4, 8].contains(&size) { - panic!("ERROR read_memory : wrong size parameter {}, must be (1, 2, 4 or 8)", size); + panic!("ERROR read_memory : wrong size parameter {size}, must be (1, 2, 4 or 8)"); } let mut ret: u64 = 0; @@ -128,11 +128,11 @@ impl Machine { /// - **value** data to be written pub fn write_memory(machine: &mut Machine, size: i32, address: usize, value: u64) { if ![1, 2, 4, 8].contains(&size) { - panic!("ERROR write_memory: WRONG `size` PARAMETER ({}), must be 1, 2, 4 or 8", size) + panic!("ERROR write_memory: WRONG `size` PARAMETER ({size}), must be 1, 2, 4 or 8") } for i in 0..size as usize { let inv_i = size as usize - i - 1; - machine.main_memory[address + i as usize] = ((value & 0xff << (8 * inv_i)) >> (inv_i * 8)) as u8; + machine.main_memory[address + i] = ((value & 0xff << (8 * inv_i)) >> (inv_i * 8)) as u8; } } @@ -392,9 +392,36 @@ impl Machine { } }, //****************************************************************************************** + // Treatment for OPIW INSTRUCTIONS + RISCV_OPIW => { + let local_data = machine.int_reg.get_reg(inst.rs1 as usize); + match inst.funct3 { + RISCV_OPIW_ADDIW => { + let result = local_data + inst.imm12_I_signed as i64; + machine.int_reg.set_reg(inst.rd as usize, result); + }, + RISCV_OPIW_SLLIW => { + let result = local_data << inst.shamt; + machine.int_reg.set_reg(inst.rd as usize, result); + }, + RISCV_OPIW_SRW => { + let result; + if inst.funct7 == RISCV_OPIW_SRW_SRLIW { + result = (local_data >> inst.shamt) & machine.shiftmask[32 + inst.shamt as usize] as i64; + } else { // SRAIW + result = local_data >> inst.shamt; + } + machine.int_reg.set_reg(inst.rd as usize, result); + }, + _ => { + panic!("In OPI switch case, this should never happen... Instr was {}\n", inst.value); + } + } + }, + //****************************************************************************************** // Treatment for: OPW INSTRUCTIONS RISCV_OPW => { - if inst.funct7 == 1 { + if inst.funct7 == 1 { // rv64m let local_data_a = machine.int_reg.get_reg(inst.rs1 as usize) & 0xffffffff; let local_data_b = machine.int_reg.get_reg(inst.rs2 as usize) & 0xffffffff; let local_data_a_unsigned = machine.int_reg.get_reg(inst.rs1 as usize) & 0xffffffff; @@ -421,7 +448,7 @@ impl Machine { panic!("this instruction ({}) doesn't exists", inst.value); } } - } else { + } else { // others rv64 OPW operations let local_dataa = machine.int_reg.get_reg(inst.rs1 as usize) & 0xffffffff; let local_datab = machine.int_reg.get_reg(inst.rs2 as usize) & 0xffffffff; diff --git a/src/simulator/mod.rs b/src/simulator/mod.rs index 266e97a..16e19a5 100644 --- a/src/simulator/mod.rs +++ b/src/simulator/mod.rs @@ -303,7 +303,7 @@ pub mod global { /// /// Shift right logical immediate word (RV64I only) /// - /// `SLLIW rd, rs1, imm12` => `rd <- rs1 >> imm12` + /// `SLLIW rd, rs1, imm12` => `rd <- rs1 >> shamt` pub const RISCV_OPIW_SLLIW: u8 = 0x1; /// Shift right immediate instructions (logical or arithmetic depend of func7) @@ -312,7 +312,7 @@ pub mod global { /// /// Shift right logical immediate word (RV64I only) /// - /// `SRLIW rd, rs1, imm12` => `rd <- rs1 >> imm12` + /// `SRLIW rd, rs1, imm12` => `rd <- rs1 >> shamt` /// /// Complete left bits by a zero, should be used with an unsigned value in most case pub const RISCV_OPIW_SRW_SRLIW: u8 = 0x0; @@ -320,7 +320,7 @@ pub mod global { /// /// Shift right arithmetic immediate word (RV64I only) /// - /// `SRAIW rd, rs1, imm12` => `rd <- rs1 >> imm12` + /// `SRAIW rd, rs1, imm12` => `rd <- rs1 >> shamt` /// /// Keep sign bit pub const RISCV_OPIW_SRW_SRAIW: u8 = 0x20; diff --git a/src/simulator/print.rs b/src/simulator/print.rs index 68a8b89..4bad5ad 100644 --- a/src/simulator/print.rs +++ b/src/simulator/print.rs @@ -91,9 +91,9 @@ pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64 RISCV_OPIW => { if ins.funct3 == RISCV_OPIW_SRW { if ins.funct7 == RISCV_OPIW_SRW_SRLIW { - format!("srlwi\t{}, {}, {}", REG_X[rd], REG_X[rs1], REG_X[rs2]) + format!("srliw\t{}, {}, {}", REG_X[rd], REG_X[rs1], REG_X[rs2]) } else { - format!("srawi\t{}, {}, {}", REG_X[rd], REG_X[rs1], REG_X[rs2]) + format!("sraiw\t{}, {}, {}", REG_X[rd], REG_X[rs1], REG_X[rs2]) } } else if ins.funct3 == RISCV_OPIW_SLLIW { format!("{}\t{}, {}, {}", NAMES_OPI[ins.funct3 as usize], REG_X[rd], REG_X[rs1], REG_X[rs2])