Skip to main content

ab_riscv_interpreter/rv64/zk/zkn/
zknh.rs

1//! RV64 Zknh extension
2
3#[cfg(test)]
4mod tests;
5
6use crate::rv64::Rv64InterpreterState;
7use crate::{ExecutableInstruction, ExecutionError};
8use ab_riscv_macros::instruction_execution;
9use ab_riscv_primitives::instruction::rv64::zk::zkn::zknh::Rv64ZknhInstruction;
10use ab_riscv_primitives::registers::Register;
11use core::ops::ControlFlow;
12
13#[instruction_execution]
14impl<Reg, Memory, PC, InstructionHandler, CustomError>
15    ExecutableInstruction<
16        Rv64InterpreterState<Reg, Memory, PC, InstructionHandler, CustomError>,
17        CustomError,
18    > for Rv64ZknhInstruction<Reg>
19where
20    Reg: Register<Type = u64>,
21    [(); Reg::N]:,
22{
23    #[inline(always)]
24    fn execute(
25        self,
26        state: &mut Rv64InterpreterState<Reg, Memory, PC, InstructionHandler, CustomError>,
27    ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, Self, CustomError>> {
28        match self {
29            Self::Sha256Sig0 { rd, rs1 } => {
30                let x = state.regs.read(rs1) as u32;
31
32                let res32 = {
33                    // SAFETY: Just an intrinsic, no undefined behavior
34                    #[cfg(all(not(miri), target_arch = "riscv64", target_feature = "zknh"))]
35                    unsafe {
36                        core::arch::riscv64::sha256sig0(x)
37                    }
38
39                    #[cfg(not(all(not(miri), target_arch = "riscv64", target_feature = "zknh")))]
40                    {
41                        x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3)
42                    }
43                };
44
45                state
46                    .regs
47                    .write(rd, i64::from(res32.cast_signed()).cast_unsigned());
48            }
49            Self::Sha256Sig1 { rd, rs1 } => {
50                let x = state.regs.read(rs1) as u32;
51
52                let res32 = {
53                    // SAFETY: Just an intrinsic, no undefined behavior
54                    #[cfg(all(not(miri), target_arch = "riscv64", target_feature = "zknh"))]
55                    unsafe {
56                        core::arch::riscv64::sha256sig1(x)
57                    }
58
59                    #[cfg(not(all(not(miri), target_arch = "riscv64", target_feature = "zknh")))]
60                    {
61                        x.rotate_right(17) ^ x.rotate_right(19) ^ (x >> 10)
62                    }
63                };
64
65                state
66                    .regs
67                    .write(rd, i64::from(res32.cast_signed()).cast_unsigned());
68            }
69            Self::Sha256Sum0 { rd, rs1 } => {
70                let x = state.regs.read(rs1) as u32;
71
72                let res32 = {
73                    // SAFETY: Just an intrinsic, no undefined behavior
74                    #[cfg(all(not(miri), target_arch = "riscv64", target_feature = "zknh"))]
75                    unsafe {
76                        core::arch::riscv64::sha256sum0(x)
77                    }
78
79                    #[cfg(not(all(not(miri), target_arch = "riscv64", target_feature = "zknh")))]
80                    {
81                        x.rotate_right(2) ^ x.rotate_right(13) ^ x.rotate_right(22)
82                    }
83                };
84
85                state
86                    .regs
87                    .write(rd, i64::from(res32.cast_signed()).cast_unsigned());
88            }
89            Self::Sha256Sum1 { rd, rs1 } => {
90                let x = state.regs.read(rs1) as u32;
91
92                let res32 = {
93                    // SAFETY: Just an intrinsic, no undefined behavior
94                    #[cfg(all(not(miri), target_arch = "riscv64", target_feature = "zknh"))]
95                    unsafe {
96                        core::arch::riscv64::sha256sum1(x)
97                    }
98
99                    #[cfg(not(all(not(miri), target_arch = "riscv64", target_feature = "zknh")))]
100                    {
101                        x.rotate_right(6) ^ x.rotate_right(11) ^ x.rotate_right(25)
102                    }
103                };
104
105                state
106                    .regs
107                    .write(rd, i64::from(res32.cast_signed()).cast_unsigned());
108            }
109            Self::Sha512Sig0 { rd, rs1 } => {
110                let x = state.regs.read(rs1);
111
112                let res = {
113                    // SAFETY: Just an intrinsic, no undefined behavior
114                    #[cfg(all(not(miri), target_arch = "riscv64", target_feature = "zknh"))]
115                    unsafe {
116                        core::arch::riscv64::sha512sig0(x)
117                    }
118
119                    #[cfg(not(all(not(miri), target_arch = "riscv64", target_feature = "zknh")))]
120                    {
121                        x.rotate_right(1) ^ x.rotate_right(8) ^ (x >> 7)
122                    }
123                };
124
125                state.regs.write(rd, res);
126            }
127            Self::Sha512Sig1 { rd, rs1 } => {
128                let x = state.regs.read(rs1);
129
130                let res = {
131                    // SAFETY: Just an intrinsic, no undefined behavior
132                    #[cfg(all(not(miri), target_arch = "riscv64", target_feature = "zknh"))]
133                    unsafe {
134                        core::arch::riscv64::sha512sig1(x)
135                    }
136
137                    #[cfg(not(all(not(miri), target_arch = "riscv64", target_feature = "zknh")))]
138                    {
139                        x.rotate_right(19) ^ x.rotate_right(61) ^ (x >> 6)
140                    }
141                };
142
143                state.regs.write(rd, res);
144            }
145            Self::Sha512Sum0 { rd, rs1 } => {
146                let x = state.regs.read(rs1);
147
148                let res = {
149                    // SAFETY: Just an intrinsic, no undefined behavior
150                    #[cfg(all(not(miri), target_arch = "riscv64", target_feature = "zknh"))]
151                    unsafe {
152                        core::arch::riscv64::sha512sum0(x)
153                    }
154
155                    #[cfg(not(all(not(miri), target_arch = "riscv64", target_feature = "zknh")))]
156                    {
157                        x.rotate_right(28) ^ x.rotate_right(34) ^ x.rotate_right(39)
158                    }
159                };
160
161                state.regs.write(rd, res);
162            }
163            Self::Sha512Sum1 { rd, rs1 } => {
164                let x = state.regs.read(rs1);
165
166                let res = {
167                    // SAFETY: Just an intrinsic, no undefined behavior
168                    #[cfg(all(not(miri), target_arch = "riscv64", target_feature = "zknh"))]
169                    unsafe {
170                        core::arch::riscv64::sha512sum1(x)
171                    }
172
173                    #[cfg(not(all(not(miri), target_arch = "riscv64", target_feature = "zknh")))]
174                    {
175                        x.rotate_right(14) ^ x.rotate_right(18) ^ x.rotate_right(41)
176                    }
177                };
178
179                state.regs.write(rd, res);
180            }
181        }
182
183        Ok(ControlFlow::Continue(()))
184    }
185}