Finish RV64M

This commit is contained in:
2025-12-30 20:53:57 +01:00
parent 5a383956c9
commit 0f0e844223
3 changed files with 52 additions and 3 deletions

View File

@@ -32,7 +32,6 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
// OP
(0b000, 0b0000000) => rvi::add(core, instr),
(0b000, 0b0100000) => rvi::sub(core, instr),
(0b000, 0b0000001) => rvm::mul(core, instr),
(0b010, 0b0000000) => rvi::slt(core, instr),
(0b011, 0b0000000) => rvi::sltu(core, instr),
(0b001, 0b0000000) => rvi::sll(core, instr),
@@ -40,8 +39,16 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
(0b101, 0b0100000) => rvi::sra(core, instr),
(0b111, 0b0000000) => rvi::and(core, instr),
(0b100, 0b0000000) => rvi::xor(core, instr),
(0b100, 0b0000001) => rvm::div(core, instr),
(0b110, 0b0000000) => rvi::or(core, instr),
// rvm
(0b000, 0b0000001) => rvm::mul(core, instr),
(0b001, 0b0000001) => rvm::mulh(core, instr),
(0b010, 0b0000001) => rvm::mulhsu(core, instr),
(0b011, 0b0000001) => rvm::mulhu(core, instr),
(0b100, 0b0000001) => rvm::div(core, instr),
(0b101, 0b0000001) => rvm::divu(core, instr),
(0b110, 0b0000001) => rvm::rem(core, instr),
(0b111, 0b0000001) => rvm::remu(core, instr),
_ => illegal(instr),
},
0b01110 => match (instr.funct3(), instr.funct7()) {
@@ -51,6 +58,12 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
(0b001, 0b0000000) => rvi::sllw(core, instr),
(0b101, 0b0000000) => rvi::srlw(core, instr),
(0b101, 0b0100000) => rvi::sraw(core, instr),
// rvm
(0b000, 0b0000001) => rvm::mulw(core, instr),
(0b100, 0b0000001) => rvm::divw(core, instr),
(0b101, 0b0000001) => rvm::divuw(core, instr),
(0b110, 0b0000001) => rvm::remw(core, instr),
(0b111, 0b0000001) => rvm::remuw(core, instr),
_ => illegal(instr),
},
0b00100 => match instr.funct3() {

View File

@@ -8,9 +8,45 @@ use crate::{core::Core, decode::Instruction, exceptions::Exception};
// multiplication
instr_op_r!(mul, u64::wrapping_mul);
instr_op_r!(mulw, |a, b| u32::wrapping_mul(a as u32, b as u32) as u64);
instr_op_r!(mulh, |a, b| ((a as i64 as i128 * b as i64 as i128) >> 64)
as u64);
instr_op_r!(mulhsu, |a, b| ((a as i64 as i128 * b as i128) >> 64) as u64);
instr_op_r!(mulhu, |a, b| ((a as u128 * b as u128) >> 64) as u64);
// division
instr_op_r!(div, |a, b| match b {
0 => -1,
_ => i64::wrapping_div(a as i64, b as i64),
} as u64);
instr_op_r!(divu, |a, b| match b {
0 => u64::MAX,
_ => a / b,
});
instr_op_r!(divw, |a, b| match b {
0 => -1,
_ => i32::wrapping_div(a as i32, b as i32),
} as i64 as u64);
instr_op_r!(divuw, |a, b| match b {
0 => u32::MAX,
_ => a as u32 / b as u32,
} as i32 as i64 as u64);
// remainder
instr_op_r!(rem, |a, b| match b {
0 => a,
_ => i64::wrapping_rem(a as i64, b as i64) as u64,
});
instr_op_r!(remu, |a, b| match b {
0 => a,
_ => a % b,
});
instr_op_r!(remw, |a, b| match b {
0 => a as i32,
_ => i32::wrapping_rem(a as i32, b as i32),
} as i64 as u64);
instr_op_r!(remuw, |a, b| match b {
0 => a as u32,
_ => a as u32 % b as u32,
} as i32 as i64 as u64);