ab_riscv_primitives/instructions/
zicsr.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#[instruction]
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum ZicsrInstruction<Reg> {
15 Csrrw { rd: Reg, rs1: Reg, csr_index: u16 },
16 Csrrs { rd: Reg, rs1: Reg, csr_index: u16 },
17 Csrrc { rd: Reg, rs1: Reg, csr_index: u16 },
18 Csrrwi { rd: Reg, zimm: u8, csr_index: u16 },
19 Csrrsi { rd: Reg, zimm: u8, csr_index: u16 },
20 Csrrci { rd: Reg, zimm: u8, csr_index: u16 },
21}
22
23#[instruction]
24const impl<Reg> Instruction for ZicsrInstruction<Reg>
25where
26 Reg: [const] Register,
27{
28 type Reg = Reg;
29
30 #[inline(always)]
31 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
32 fn try_decode(instruction: u32) -> Option<Self> {
33 let opcode = (instruction & 0b111_1111) as u8;
34 let rd_bits = ((instruction >> 7) & 0x1f) as u8;
35 let funct3 = ((instruction >> 12) & 0b111) as u8;
36 let rs1_bits = ((instruction >> 15) & 0x1f) as u8;
37 let csr_bits = ((instruction >> 20) & 0x0fff) as u16;
38
39 match opcode {
40 0b111_0011 => {
41 let rd = Reg::from_bits(rd_bits)?;
42 match funct3 {
43 0b001 => {
44 let rs1 = Reg::from_bits(rs1_bits)?;
45 Some(Self::Csrrw {
46 rd,
47 rs1,
48 csr_index: csr_bits,
49 })
50 }
51 0b010 => {
52 let rs1 = Reg::from_bits(rs1_bits)?;
53 Some(Self::Csrrs {
54 rd,
55 rs1,
56 csr_index: csr_bits,
57 })
58 }
59 0b011 => {
60 let rs1 = Reg::from_bits(rs1_bits)?;
61 Some(Self::Csrrc {
62 rd,
63 rs1,
64 csr_index: csr_bits,
65 })
66 }
67 0b101 => Some(Self::Csrrwi {
68 rd,
69 zimm: rs1_bits,
70 csr_index: csr_bits,
71 }),
72 0b110 => Some(Self::Csrrsi {
73 rd,
74 zimm: rs1_bits,
75 csr_index: csr_bits,
76 }),
77 0b111 => Some(Self::Csrrci {
78 rd,
79 zimm: rs1_bits,
80 csr_index: csr_bits,
81 }),
82 _ => None,
83 }
84 }
85 _ => None,
86 }
87 }
88
89 #[inline(always)]
90 fn alignment() -> u8 {
91 align_of::<u32>() as u8
92 }
93
94 #[inline(always)]
95 fn size(&self) -> u8 {
96 size_of::<u32>() as u8
97 }
98}
99
100#[instruction]
101impl<Reg> fmt::Display for ZicsrInstruction<Reg>
102where
103 Reg: fmt::Display,
104{
105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 match self {
107 Self::Csrrw { rd, rs1, csr_index } => write!(f, "csrrw {rd}, {csr_index}, {rs1}"),
108 Self::Csrrs { rd, rs1, csr_index } => write!(f, "csrrs {rd}, {csr_index}, {rs1}"),
109 Self::Csrrc { rd, rs1, csr_index } => write!(f, "csrrc {rd}, {csr_index}, {rs1}"),
110 Self::Csrrwi {
111 rd,
112 zimm,
113 csr_index,
114 } => write!(f, "csrrwi {rd}, {csr_index}, {zimm}"),
115 Self::Csrrsi {
116 rd,
117 zimm,
118 csr_index,
119 } => write!(f, "csrrsi {rd}, {csr_index}, {zimm}"),
120 Self::Csrrci {
121 rd,
122 zimm,
123 csr_index,
124 } => write!(f, "csrrci {rd}, {csr_index}, {zimm}"),
125 }
126 }
127}