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