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