ab_riscv_interpreter/rv32/
m.rs1#[cfg(test)]
4mod tests;
5pub mod zmmul;
6
7use crate::{ExecutableInstruction, ExecutionError, InterpreterState};
8use ab_riscv_macros::instruction_execution;
9use ab_riscv_primitives::instructions::rv32::m::Rv32MInstruction;
10use ab_riscv_primitives::registers::general_purpose::Register;
11use core::ops::ControlFlow;
12
13#[instruction_execution]
14impl<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>
15 ExecutableInstruction<
16 InterpreterState<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>,
17 CustomError,
18 > for Rv32MInstruction<Reg>
19where
20 Reg: Register<Type = u32>,
21 [(); Reg::N]:,
22{
23 #[inline(always)]
24 fn execute(
25 self,
26 state: &mut InterpreterState<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>,
27 ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
28 match self {
29 Self::Mul { rd, rs1, rs2 } => {
30 let value = state.regs.read(rs1).wrapping_mul(state.regs.read(rs2));
31 state.regs.write(rd, value);
32 }
33 Self::Mulh { rd, rs1, rs2 } => {
34 let (_lo, prod) = state
36 .regs
37 .read(rs1)
38 .cast_signed()
39 .widening_mul(state.regs.read(rs2).cast_signed());
40 state.regs.write(rd, prod.cast_unsigned());
41 }
42 Self::Mulhsu { rd, rs1, rs2 } => {
43 let prod =
45 i64::from(state.regs.read(rs1).cast_signed()) * i64::from(state.regs.read(rs2));
46 let value = prod >> 32;
47 state.regs.write(rd, value.cast_unsigned() as u32);
48 }
49 Self::Mulhu { rd, rs1, rs2 } => {
50 let prod = u64::from(state.regs.read(rs1)) * u64::from(state.regs.read(rs2));
52 let value = prod >> 32;
53 state.regs.write(rd, value as u32);
54 }
55 Self::Div { rd, rs1, rs2 } => {
56 let dividend = state.regs.read(rs1).cast_signed();
57 let divisor = state.regs.read(rs2).cast_signed();
58 let value = if divisor == 0 {
59 -1i32
60 } else if dividend == i32::MIN && divisor == -1 {
61 i32::MIN
62 } else {
63 dividend / divisor
64 };
65 state.regs.write(rd, value.cast_unsigned());
66 }
67 Self::Divu { rd, rs1, rs2 } => {
68 let dividend = state.regs.read(rs1);
69 let divisor = state.regs.read(rs2);
70 let value = dividend.checked_div(divisor).unwrap_or(u32::MAX);
71 state.regs.write(rd, value);
72 }
73 Self::Rem { rd, rs1, rs2 } => {
74 let dividend = state.regs.read(rs1).cast_signed();
75 let divisor = state.regs.read(rs2).cast_signed();
76 let value = if divisor == 0 {
77 dividend
78 } else if dividend == i32::MIN && divisor == -1 {
79 0
80 } else {
81 dividend % divisor
82 };
83 state.regs.write(rd, value.cast_unsigned());
84 }
85 Self::Remu { rd, rs1, rs2 } => {
86 let dividend = state.regs.read(rs1);
87 let divisor = state.regs.read(rs2);
88 let value = if divisor == 0 {
89 dividend
90 } else {
91 dividend % divisor
92 };
93 state.regs.write(rd, value);
94 }
95 }
96
97 Ok(ControlFlow::Continue(()))
98 }
99}