ab_riscv_interpreter/rv64/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::rv64::b::zbc::Rv64ZbcInstruction;
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 Rv64ZbcInstruction<Reg>
19where
20 Reg: Register<Type = u64>,
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 = "riscv64", target_feature = "zbkc") => {
38 core::arch::riscv64::clmul(a as usize, b as usize) as u64
39 }
40 _ => {{
41 let result = zbc_helpers::clmul_internal(a, b);
42 result as u64
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 = "riscv64", target_feature = "zbkc") => {
55 core::arch::riscv64::clmulh(a as usize, b as usize) as u64
56 }
57 _ => {{
58 let result = zbc_helpers::clmul_internal(a, b);
59 (result >> 64) as u64
60 }}
61 };
62
63 state.regs.write(rd, value);
64 }
65 Self::Clmulr { rd, rs1, rs2 } => {
66 let a = state.regs.read(rs1);
67 let b = state.regs.read(rs2);
68
69 let value = cfg_select! {
71 all(not(miri), target_arch = "riscv64", target_feature = "zbc") => {
72 core::arch::riscv64::clmulr(a as usize, b as usize) as u64
73 }
74 _ => {{
75 let result = zbc_helpers::clmul_internal(a, b);
76 (result >> 63) as u64
77 }}
78 };
79
80 state.regs.write(rd, value);
81 }
82 }
83
84 Ok(ControlFlow::Continue(()))
85 }
86}