add floating point instructions

This commit is contained in:
Baptiste 2023-02-01 16:41:49 +01:00
parent 40374bf26f
commit ff0d10edb5

View File

@ -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)},
}