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