ab_riscv_interpreter/rv32/b/
zbc.rs1#[cfg(test)]
4mod tests;
5pub mod zbc_helpers;
6
7use crate::{ExecutableInstruction, ExecutionError, InterpreterState};
8use ab_riscv_macros::instruction_execution;
9use ab_riscv_primitives::instructions::rv32::b::zbc::Rv32ZbcInstruction;
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 Rv32ZbcInstruction<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::Clmul { rd, rs1, rs2 } => {
30 let () = zbc_helpers::PLACEHOLDER;
32 let a = state.regs.read(rs1);
33 let b = state.regs.read(rs2);
34
35 let value = cfg_select! {
37 all(not(miri), target_arch = "riscv32", target_feature = "zbkc") => {
38 core::arch::riscv32::clmul(a as usize, b as usize) as u32
39 }
40 _ => {{
41 let result = zbc_helpers::clmul_internal(a, b);
42 result as u32
43 }}
44 };
45
46 state.regs.write(rd, value);
47 }
48 Self::Clmulh { rd, rs1, rs2 } => {
49 let a = state.regs.read(rs1);
50 let b = state.regs.read(rs2);
51
52 let value = cfg_select! {
54 all(not(miri), target_arch = "riscv32", target_feature = "zbkc") => {
55 core::arch::riscv32::clmulh(a as usize, b as usize) as u32
56 }
57 _ => {{
58 let result = zbc_helpers::clmul_internal(a, b);
59 (result >> 32) as u32
60 }}
61 };
62 state.regs.write(rd, value);
63 }
64 Self::Clmulr { rd, rs1, rs2 } => {
65 let a = state.regs.read(rs1);
66 let b = state.regs.read(rs2);
67
68 let value = cfg_select! {
70 all(not(miri), target_arch = "riscv32", target_feature = "zbc") => {
71 core::arch::riscv32::clmulr(a as usize, b as usize) as u32
72 }
73 _ => {{
74 let result = zbc_helpers::clmul_internal(a, b);
75 (result >> 31) as u32
76 }}
77 };
78
79 state.regs.write(rd, value);
80 }
81 }
82
83 Ok(ControlFlow::Continue(()))
84 }
85}