ab_riscv_interpreter/rv32/m/
zmmul.rs1use crate::{
4 ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
5 ExecutionResult, FetchInstructionResult, InstructionFetcher, OpaqueThreadedExecutionResult,
6 RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, ThreadedExecutableInstruction,
7 ThreadedExecutionResult,
8};
9use ab_riscv_macros::instruction_execution;
10use ab_riscv_primitives::prelude::*;
11
12#[instruction_execution]
13const impl<Reg, Hart> ExecutableInstructionOperands for Rv32ZmmulInstruction<Hart>
14where
15 Reg: Register<Type = u32>,
16 Hart: HartConfig<Reg = Reg>,
17{
18}
19
20#[instruction_execution]
21const impl<Reg, Hart, Env> ExecutableInstructionCsr<Env> for Rv32ZmmulInstruction<Hart>
22where
23 Reg: Register<Type = u32>,
24 Hart: HartConfig<Reg = Reg>,
25{
26}
27
28#[instruction_execution]
29const impl<Reg, Hart, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
30 for Rv32ZmmulInstruction<Hart>
31where
32 Reg: [const] Register<Type = u32>,
33 Hart: HartConfig<Reg = Reg>,
34{
35 #[inline(always)]
36 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
37 fn execute(
38 self,
39 Rs1Rs2OperandValues {
40 rs1_value,
41 rs2_value,
42 }: Rs1Rs2OperandValues<Reg::Type>,
43 _regs: &mut Regs,
44 _env: &mut Env,
45 _memory: &mut Memory,
46 _program_counter: &PC,
47 ) -> ExecutionResult<Reg> {
48 match self {
49 Self::Mul { rd, rs1: _, rs2: _ } => {
50 let value = rs1_value.wrapping_mul(rs2_value);
51 ExecutionResult::Continue { rd, value }
52 }
53 Self::Mulh { rd, rs1: _, rs2: _ } => {
54 let (_lo, prod) = rs1_value
56 .cast_signed()
57 .carrying_mul(rs2_value.cast_signed(), 0);
58 ExecutionResult::Continue {
59 rd,
60 value: prod.cast_unsigned(),
61 }
62 }
63 Self::Mulhsu { rd, rs1: _, rs2: _ } => {
64 let prod = i64::from(rs1_value.cast_signed()) * i64::from(rs2_value);
66 let value = prod >> 32;
67 ExecutionResult::Continue {
68 rd,
69 value: value.cast_unsigned() as u32,
70 }
71 }
72 Self::Mulhu { rd, rs1: _, rs2: _ } => {
73 let prod = u64::from(rs1_value) * u64::from(rs2_value);
75 let value = prod >> 32;
76 ExecutionResult::Continue {
77 rd,
78 value: value as u32,
79 }
80 }
81 }
82 }
83}