ab_riscv_primitives/instructions/rv32/zk/zkn/
zknd.rs1#[cfg(test)]
4mod tests;
5
6use crate::instructions::Instruction;
7use crate::registers::general_purpose::Register;
8use ab_riscv_macros::instruction;
9use core::fmt;
10
11#[derive(Debug, Clone, Copy)]
15#[derive_const(PartialEq, Eq)]
16#[repr(u8)]
17pub enum Rv32AesBs {
18 B0 = 0,
19 B1 = 1,
20 B2 = 2,
21 B3 = 3,
22}
23
24impl From<Rv32AesBs> for u8 {
25 #[inline(always)]
26 fn from(bs: Rv32AesBs) -> Self {
27 bs as u8
28 }
29}
30
31impl From<Rv32AesBs> for usize {
32 #[inline(always)]
33 fn from(bs: Rv32AesBs) -> Self {
34 usize::from(bs as u8)
35 }
36}
37
38impl fmt::Display for Rv32AesBs {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 fmt::Display::fmt(&(*self as u8), f)
41 }
42}
43
44impl Rv32AesBs {
45 #[inline(always)]
47 pub const fn from_bits(bits: u8) -> Option<Self> {
48 match bits {
49 0 => Some(Self::B0),
50 1 => Some(Self::B1),
51 2 => Some(Self::B2),
52 3 => Some(Self::B3),
53 _ => None,
54 }
55 }
56}
57
58#[instruction]
60#[derive(Debug, Clone, Copy)]
61#[derive_const(PartialEq, Eq)]
62pub enum Rv32ZkndInstruction<Reg> {
63 Aes32Dsi {
68 rd: Reg,
69 rs1: Reg,
70 rs2: Reg,
71 bs: Rv32AesBs,
72 },
73 Aes32Dsmi {
78 rd: Reg,
79 rs1: Reg,
80 rs2: Reg,
81 bs: Rv32AesBs,
82 },
83}
84
85#[instruction]
105const impl<Reg> Instruction for Rv32ZkndInstruction<Reg>
106where
107 Reg: [const] Register<Type = u32>,
108{
109 type Reg = Reg;
110
111 #[inline(always)]
112 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
113 fn try_decode(instruction: u32) -> Option<Self> {
114 let opcode = (instruction & 0b111_1111) as u8;
115 let rd_bits = ((instruction >> 7) & 0x1f) as u8;
116 let funct3 = ((instruction >> 12) & 0b111) as u8;
117 let rs1_bits = ((instruction >> 15) & 0x1f) as u8;
118 let rs2_bits = ((instruction >> 20) & 0x1f) as u8;
119 let funct5 = ((instruction >> 25) & 0b1_1111) as u8;
120 let bs_bits = ((instruction >> 30) & 0b11) as u8;
121
122 if opcode != 0b011_0011 {
124 None?;
125 }
126 if funct3 != 0b000 {
127 None?;
128 }
129
130 let rd = Reg::from_bits(rd_bits)?;
131 let rs1 = Reg::from_bits(rs1_bits)?;
132 let rs2 = Reg::from_bits(rs2_bits)?;
133 let bs = Rv32AesBs::from_bits(bs_bits)?;
134
135 match funct5 {
136 0b1_0101 => Some(Self::Aes32Dsi { rd, rs1, rs2, bs }),
138 0b1_0111 => Some(Self::Aes32Dsmi { rd, rs1, rs2, bs }),
140 _ => None,
141 }
142 }
143
144 #[inline(always)]
145 fn alignment() -> u8 {
146 align_of::<u32>() as u8
147 }
148
149 #[inline(always)]
150 fn size(&self) -> u8 {
151 size_of::<u32>() as u8
152 }
153}
154
155#[instruction]
156impl<Reg> fmt::Display for Rv32ZkndInstruction<Reg>
157where
158 Reg: fmt::Display,
159{
160 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161 match self {
162 Self::Aes32Dsi { rd, rs1, rs2, bs } => {
163 write!(f, "aes32dsi {rd}, {rs1}, {rs2}, {bs}")
164 }
165 Self::Aes32Dsmi { rd, rs1, rs2, bs } => {
166 write!(f, "aes32dsmi {rd}, {rs1}, {rs2}, {bs}")
167 }
168 }
169 }
170}