Skip to main content

ab_riscv_interpreter/rv64/b/
zbb.rs

1//! RV64 Zbb extension
2
3#[cfg(test)]
4mod tests;
5
6use crate::{ExecutableInstruction, ExecutionError, InterpreterState};
7use ab_riscv_macros::instruction_execution;
8use ab_riscv_primitives::instructions::rv64::b::zbb::Rv64ZbbInstruction;
9use ab_riscv_primitives::registers::general_purpose::Register;
10use core::ops::ControlFlow;
11
12#[instruction_execution]
13impl<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>
14    ExecutableInstruction<
15        InterpreterState<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>,
16        CustomError,
17    > for Rv64ZbbInstruction<Reg>
18where
19    Reg: Register<Type = u64>,
20    [(); Reg::N]:,
21{
22    #[inline(always)]
23    fn execute(
24        self,
25        state: &mut InterpreterState<Reg, ExtState, Memory, PC, InstructionHandler, CustomError>,
26    ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
27        match self {
28            Self::Andn { rd, rs1, rs2 } => {
29                let value = state.regs.read(rs1) & !state.regs.read(rs2);
30                state.regs.write(rd, value);
31            }
32            Self::Orn { rd, rs1, rs2 } => {
33                let value = state.regs.read(rs1) | !state.regs.read(rs2);
34                state.regs.write(rd, value);
35            }
36            Self::Xnor { rd, rs1, rs2 } => {
37                let value = !(state.regs.read(rs1) ^ state.regs.read(rs2));
38                state.regs.write(rd, value);
39            }
40            Self::Clz { rd, rs1 } => {
41                let value = u64::from(state.regs.read(rs1).leading_zeros());
42                state.regs.write(rd, value);
43            }
44            Self::Clzw { rd, rs1 } => {
45                let value = u64::from((state.regs.read(rs1) as u32).leading_zeros());
46                state.regs.write(rd, value);
47            }
48            Self::Ctz { rd, rs1 } => {
49                let value = u64::from(state.regs.read(rs1).trailing_zeros());
50                state.regs.write(rd, value);
51            }
52            Self::Ctzw { rd, rs1 } => {
53                let value = u64::from((state.regs.read(rs1) as u32).trailing_zeros());
54                state.regs.write(rd, value);
55            }
56            Self::Cpop { rd, rs1 } => {
57                let value = u64::from(state.regs.read(rs1).count_ones());
58                state.regs.write(rd, value);
59            }
60            Self::Cpopw { rd, rs1 } => {
61                let value = u64::from((state.regs.read(rs1) as u32).count_ones());
62                state.regs.write(rd, value);
63            }
64            Self::Max { rd, rs1, rs2 } => {
65                let a = state.regs.read(rs1).cast_signed();
66                let b = state.regs.read(rs2).cast_signed();
67                let value = a.max(b).cast_unsigned();
68                state.regs.write(rd, value);
69            }
70            Self::Maxu { rd, rs1, rs2 } => {
71                let value = state.regs.read(rs1).max(state.regs.read(rs2));
72                state.regs.write(rd, value);
73            }
74            Self::Min { rd, rs1, rs2 } => {
75                let a = state.regs.read(rs1).cast_signed();
76                let b = state.regs.read(rs2).cast_signed();
77                let value = a.min(b).cast_unsigned();
78                state.regs.write(rd, value);
79            }
80            Self::Minu { rd, rs1, rs2 } => {
81                let value = state.regs.read(rs1).min(state.regs.read(rs2));
82                state.regs.write(rd, value);
83            }
84            Self::Sextb { rd, rs1 } => {
85                let value = i64::from(state.regs.read(rs1) as i8).cast_unsigned();
86                state.regs.write(rd, value);
87            }
88            Self::Sexth { rd, rs1 } => {
89                let value = i64::from(state.regs.read(rs1) as i16).cast_unsigned();
90                state.regs.write(rd, value);
91            }
92            Self::Zexth { rd, rs1 } => {
93                let value = u64::from(state.regs.read(rs1) as u16);
94                state.regs.write(rd, value);
95            }
96            Self::Rol { rd, rs1, rs2 } => {
97                let shamt = (state.regs.read(rs2) & 0x3f) as u32;
98                let value = state.regs.read(rs1).rotate_left(shamt);
99                state.regs.write(rd, value);
100            }
101            Self::Rolw { rd, rs1, rs2 } => {
102                let shamt = (state.regs.read(rs2) & 0x1f) as u32;
103                let value = i64::from(
104                    (state.regs.read(rs1) as u32)
105                        .rotate_left(shamt)
106                        .cast_signed(),
107                );
108                state.regs.write(rd, value.cast_unsigned());
109            }
110            Self::Ror { rd, rs1, rs2 } => {
111                let shamt = (state.regs.read(rs2) & 0x3f) as u32;
112                let value = state.regs.read(rs1).rotate_right(shamt);
113                state.regs.write(rd, value);
114            }
115            Self::Rori { rd, rs1, shamt } => {
116                let value = state.regs.read(rs1).rotate_right(u32::from(shamt & 0x3f));
117                state.regs.write(rd, value);
118            }
119            Self::Roriw { rd, rs1, shamt } => {
120                let value = i64::from(
121                    (state.regs.read(rs1) as u32)
122                        .rotate_right((shamt & 0x1f) as u32)
123                        .cast_signed(),
124                );
125                state.regs.write(rd, value.cast_unsigned());
126            }
127            Self::Rorw { rd, rs1, rs2 } => {
128                let shamt = (state.regs.read(rs2) & 0x1f) as u32;
129                let value = i64::from(
130                    (state.regs.read(rs1) as u32)
131                        .rotate_right(shamt)
132                        .cast_signed(),
133                );
134                state.regs.write(rd, value.cast_unsigned());
135            }
136            Self::Orcb { rd, rs1 } => {
137                let src = state.regs.read(rs1);
138                let mut result = 0u64;
139                for i in 0..8 {
140                    let byte = (src >> (i * 8)) & 0xFF;
141                    if byte != 0 {
142                        result |= 0xFF << (i * 8);
143                    }
144                }
145                state.regs.write(rd, result);
146            }
147            Self::Rev8 { rd, rs1 } => {
148                let value = state.regs.read(rs1).swap_bytes();
149                state.regs.write(rd, value);
150            }
151        }
152
153        Ok(ControlFlow::Continue(()))
154    }
155}