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
This commit is contained in:
Quentin Legot 2023-02-04 18:16:52 +01:00
parent 83c212199e
commit 3762547402
4 changed files with 38 additions and 11 deletions

View File

@ -9,6 +9,6 @@ fn main() {
let a : u8 = 128; let a : u8 = 128;
let b : i8 = a as i8; let b : i8 = a as i8;
let c : u8 = b as u8; let c : u8 = b as u8;
println!("aaa {}", c); println!("aaa {c}");
println!("read_memory : {}", Machine::read_memory(&mut m, 2, 4)); println!("read_memory : {}", Machine::read_memory(&mut m, 2, 4));
} }

View File

@ -105,7 +105,7 @@ impl Machine {
/// - **address** in the memory to read /// - **address** in the memory to read
pub fn read_memory(machine : &mut Machine, size : i32, address : usize) -> u64 { pub fn read_memory(machine : &mut Machine, size : i32, address : usize) -> u64 {
if ![1, 2, 4, 8].contains(&size) { 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; let mut ret: u64 = 0;
@ -128,11 +128,11 @@ impl Machine {
/// - **value** data to be written /// - **value** data to be written
pub fn write_memory(machine: &mut Machine, size: i32, address: usize, value: u64) { pub fn write_memory(machine: &mut Machine, size: i32, address: usize, value: u64) {
if ![1, 2, 4, 8].contains(&size) { 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 { for i in 0..size as usize {
let inv_i = size as usize - i - 1; 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 // Treatment for: OPW INSTRUCTIONS
RISCV_OPW => { 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_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_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; 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); 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_dataa = machine.int_reg.get_reg(inst.rs1 as usize) & 0xffffffff;
let local_datab = machine.int_reg.get_reg(inst.rs2 as usize) & 0xffffffff; let local_datab = machine.int_reg.get_reg(inst.rs2 as usize) & 0xffffffff;

View File

@ -303,7 +303,7 @@ pub mod global {
/// ///
/// Shift right logical immediate word (RV64I only) /// 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; pub const RISCV_OPIW_SLLIW: u8 = 0x1;
/// Shift right immediate instructions (logical or arithmetic depend of func7) /// Shift right immediate instructions (logical or arithmetic depend of func7)
@ -312,7 +312,7 @@ pub mod global {
/// ///
/// Shift right logical immediate word (RV64I only) /// 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 /// Complete left bits by a zero, should be used with an unsigned value in most case
pub const RISCV_OPIW_SRW_SRLIW: u8 = 0x0; pub const RISCV_OPIW_SRW_SRLIW: u8 = 0x0;
@ -320,7 +320,7 @@ pub mod global {
/// ///
/// Shift right arithmetic immediate word (RV64I only) /// Shift right arithmetic immediate word (RV64I only)
/// ///
/// `SRAIW rd, rs1, imm12` => `rd <- rs1 >> imm12` /// `SRAIW rd, rs1, imm12` => `rd <- rs1 >> shamt`
/// ///
/// Keep sign bit /// Keep sign bit
pub const RISCV_OPIW_SRW_SRAIW: u8 = 0x20; pub const RISCV_OPIW_SRW_SRAIW: u8 = 0x20;

View File

@ -91,9 +91,9 @@ pub fn print(ins: Instruction, pc: i32) -> String { //TODO pc should be u64
RISCV_OPIW => { RISCV_OPIW => {
if ins.funct3 == RISCV_OPIW_SRW { if ins.funct3 == RISCV_OPIW_SRW {
if ins.funct7 == RISCV_OPIW_SRW_SRLIW { 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 { } 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 { } else if ins.funct3 == RISCV_OPIW_SLLIW {
format!("{}\t{}, {}, {}", NAMES_OPI[ins.funct3 as usize], REG_X[rd], REG_X[rs1], REG_X[rs2]) format!("{}\t{}, {}, {}", NAMES_OPI[ins.funct3 as usize], REG_X[rd], REG_X[rs1], REG_X[rs2])