diff --git a/src/simulator/machine.rs b/src/simulator/machine.rs index 83be4a4..4965234 100644 --- a/src/simulator/machine.rs +++ b/src/simulator/machine.rs @@ -398,6 +398,114 @@ impl Machine { } } } + }, + //****************************************************************************************** + // Treatment for: Simple floating point extension + RISCV_FP => { + match inst.funct7 { + RISCV_FP_ADD => { + machine.fp_reg[inst.rd as usize] = machine.fp_reg[inst.rs1 as usize] + machine.fp_reg[inst.rs2 as usize]; + }, + RISCV_FP_SUB => { + machine.fp_reg[inst.rd as usize] = machine.fp_reg[inst.rs1 as usize] - machine.fp_reg[inst.rs2 as usize]; + }, + RISCV_FP_MUL => { + machine.fp_reg[inst.rd as usize] = machine.fp_reg[inst.rs1 as usize] * machine.fp_reg[inst.rs2 as usize]; + }, + RISCV_FP_DIV => { + machine.fp_reg[inst.rd as usize] = machine.fp_reg[inst.rs1 as usize] / machine.fp_reg[inst.rs2 as usize]; + }, + RISCV_FP_SQRT => { + machine.fp_reg[inst.rd as usize] = machine.fp_reg[inst.rs1 as usize].sqrt(); + }, + RISCV_FP_FSGN => { + let local_float = machine.fp_reg[inst.rs1 as usize]; + match inst.funct3 { + RISCV_FP_FSGN_J => { + if machine.fp_reg[inst.rs2 as usize] < 0 { + machine.fp_reg[inst.rd as usize] = -local_float; + } else { + machine.fp_reg[inst.rd as usize] = local_float; + } + } + RISCV_FP_FSGN_JN => { + if machine.fp_reg[inst.rs2 as usize] < 0 { + machine.fp_reg[inst.rd as usize] = local_float; + } else { + machine.fp_reg[inst.rd as usize] = -local_float; + } + } + RISCV_FP_FSGN_JX => { + if (machine.fp_reg[inst.rs2 as usize] < 0 && machine.fp_reg[inst.rs1 as usize] >= 0) || (machine.fp_reg[inst.rs2 as usize] >= 0 && machine.fp_reg[inst.rs1 as usize] < 0) { + machine.fp_reg[inst.rd as usize] = -local_float; + } else { + machine.fp_reg[inst.rd as usize] = local_float; + } + } + _ => { + panic!("this instruction ({}) doesn't exists", inst.value); + } + } + }, + RISCV_FP_MINMAX => { + let r1 = machine.fp_reg[inst.rs1 as usize]; + let r2 = machine.fp_reg[inst.rs2 as usize]; + match inst.funct3 { + RISCV_FP_MINMAX_MIN => { + machine.fp_reg[inst.rd as usize] = if r1 < r2 {r1} else {r2} + }, + RISCV_FP_MINMAX_MAX => { + machine.fp_reg[inst.rd as usize] = 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[inst.rd as usize] = machine.fp_reg[inst.rs1 as usize]; + } else { + machine.int_reg[inst.rd as usize] = machine.fp_reg[inst.rs1 as usize] as u64; + } + }, + RISCV_FP_FCVTS => { + if inst.rs2 == RISCV_FP_FCVTS_W { + machine.fp_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize]; + } else { + machine.fp_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize] as u32; + } + }, + RISCV_FP_FMVW => { + machine.fp_reg[inst.rd as usize] = machine.int_reg[inst.rs1 as usize]; + }, + RISCV_FP_FMVXFCLASS => { + if inst.funct3 == RISCV_FP_FMVXFCLASS_FMVX { + machine.int_reg[inst.rd as usize] = machine.fp_reg[inst.rs1 as usize]; + } else { + panic!("Fclass instruction is not handled in riscv simulator"); + } + }, + RISCV_FP_FCMP => { + match inst.funct3 { + RISCV_FP_FCMP_FEQ => { + machine.int_reg[inst.rd as usize] = if machine.fp_reg[inst.rs1 as usize] == machine.fp_reg[inst.rs2 as usize] {1} else {0}; + }, + RISCV_FP_FCMP_FLT => { + machine.int_reg[inst.rd as usize] = if machine.fp_reg[inst.rs1 as usize] < machine.fp_reg[inst.rs2 as usize] {1} else {0}; + }, + RISCV_FP_FCMP_FLE => { + machine.int_reg[inst.rd as usize] = if machine.fp_reg[inst.rs1 as usize] <= machine.fp_reg[inst.rs2 as usize] {1} else {0}; + }, + _ => { + panic!("this instruction ({}) doesn't exists", inst.value); + } + } + }, + _ => { + panic!("this instruction ({}) doesn't exists", inst.value); + } + } } _ => { panic!("{} opcode non géré", inst.opcode)}, }