ab_riscv_interpreter/rv64/zk/zkn/
zknh.rs1#[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 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 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 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 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 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 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 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 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}