diff options
| author | taitep <taitep@taitep.se> | 2025-12-30 20:53:57 +0100 |
|---|---|---|
| committer | taitep <taitep@taitep.se> | 2025-12-30 20:53:57 +0100 |
| commit | 0f0e844223a17452835aed88adb3af976d2e1eae (patch) | |
| tree | 2d993912a48ef5277c70035bb02c160e53a0f733 /src/instructions | |
| parent | 5a383956c9ee27d50452aa237a9f34b7f75e8f7c (diff) | |
Finish RV64M
Diffstat (limited to 'src/instructions')
| -rw-r--r-- | src/instructions/rvm.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/instructions/rvm.rs b/src/instructions/rvm.rs index bd0c100..b87b9f9 100644 --- a/src/instructions/rvm.rs +++ b/src/instructions/rvm.rs @@ -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); |
