summaryrefslogtreecommitdiff
path: root/src/instructions
diff options
context:
space:
mode:
Diffstat (limited to 'src/instructions')
-rw-r--r--src/instructions/rvm.rs36
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);