Skip to main content

ab_riscv_interpreter/rv64/b/
zbb.rs

1//! RV64 Zbb extension
2
3#[cfg(test)]
4mod tests;
5
6use crate::rv64::Rv64InterpreterState;
7use crate::{ExecutableInstruction, ExecutionError};
8use ab_riscv_macros::instruction_execution;
9use ab_riscv_primitives::instruction::rv64::b::zbb::Rv64ZbbInstruction;
10use ab_riscv_primitives::registers::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 Rv64ZbbInstruction<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::Andn { rd, rs1, rs2 } => {
30                let value = state.regs.read(rs1) & !state.regs.read(rs2);
31                state.regs.write(rd, value);
32            }
33            Self::Orn { rd, rs1, rs2 } => {
34                let value = state.regs.read(rs1) | !state.regs.read(rs2);
35                state.regs.write(rd, value);
36            }
37            Self::Xnor { rd, rs1, rs2 } => {
38                let value = !(state.regs.read(rs1) ^ state.regs.read(rs2));
39                state.regs.write(rd, value);
40            }
41            Self::Clz { rd, rs1 } => {
42                let value = state.regs.read(rs1).leading_zeros() as u64;
43                state.regs.write(rd, value);
44            }
45            Self::Clzw { rd, rs1 } => {
46                let value = (state.regs.read(rs1) as u32).leading_zeros() as u64;
47                state.regs.write(rd, value);
48            }
49            Self::Ctz { rd, rs1 } => {
50                let value = state.regs.read(rs1).trailing_zeros() as u64;
51                state.regs.write(rd, value);
52            }
53            Self::Ctzw { rd, rs1 } => {
54                let value = (state.regs.read(rs1) as u32).trailing_zeros() as u64;
55                state.regs.write(rd, value);
56            }
57            Self::Cpop { rd, rs1 } => {
58                let value = state.regs.read(rs1).count_ones() as u64;
59                state.regs.write(rd, value);
60            }
61            Self::Cpopw { rd, rs1 } => {
62                let value = (state.regs.read(rs1) as u32).count_ones() as u64;
63                state.regs.write(rd, value);
64            }
65            Self::Max { rd, rs1, rs2 } => {
66                let a = state.regs.read(rs1).cast_signed();
67                let b = state.regs.read(rs2).cast_signed();
68                let value = a.max(b).cast_unsigned();
69                state.regs.write(rd, value);
70            }
71            Self::Maxu { rd, rs1, rs2 } => {
72                let value = state.regs.read(rs1).max(state.regs.read(rs2));
73                state.regs.write(rd, value);
74            }
75            Self::Min { rd, rs1, rs2 } => {
76                let a = state.regs.read(rs1).cast_signed();
77                let b = state.regs.read(rs2).cast_signed();
78                let value = a.min(b).cast_unsigned();
79                state.regs.write(rd, value);
80            }
81            Self::Minu { rd, rs1, rs2 } => {
82                let value = state.regs.read(rs1).min(state.regs.read(rs2));
83                state.regs.write(rd, value);
84            }
85            Self::Sextb { rd, rs1 } => {
86                let value = ((state.regs.read(rs1) as i8) as i64).cast_unsigned();
87                state.regs.write(rd, value);
88            }
89            Self::Sexth { rd, rs1 } => {
90                let value = ((state.regs.read(rs1) as i16) as i64).cast_unsigned();
91                state.regs.write(rd, value);
92            }
93            Self::Zexth { rd, rs1 } => {
94                let value = (state.regs.read(rs1) as u16) as u64;
95                state.regs.write(rd, value);
96            }
97            Self::Rol { rd, rs1, rs2 } => {
98                let shamt = (state.regs.read(rs2) & 0x3f) as u32;
99                let value = state.regs.read(rs1).rotate_left(shamt);
100                state.regs.write(rd, value);
101            }
102            Self::Rolw { rd, rs1, rs2 } => {
103                let shamt = (state.regs.read(rs2) & 0x1f) as u32;
104                let value = ((state.regs.read(rs1) as u32)
105                    .rotate_left(shamt)
106                    .cast_signed() as i64)
107                    .cast_unsigned();
108                state.regs.write(rd, value);
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((shamt & 0x3f) as u32);
117                state.regs.write(rd, value);
118            }
119            Self::Roriw { rd, rs1, shamt } => {
120                let value = ((state.regs.read(rs1) as u32)
121                    .rotate_right((shamt & 0x1f) as u32)
122                    .cast_signed() as i64)
123                    .cast_unsigned();
124                state.regs.write(rd, value);
125            }
126            Self::Rorw { rd, rs1, rs2 } => {
127                let shamt = (state.regs.read(rs2) & 0x1f) as u32;
128                let value = ((state.regs.read(rs1) as u32)
129                    .rotate_right(shamt)
130                    .cast_signed() as i64)
131                    .cast_unsigned();
132                state.regs.write(rd, value);
133            }
134            Self::Orcb { rd, rs1 } => {
135                let src = state.regs.read(rs1);
136                let mut result = 0u64;
137                for i in 0..8 {
138                    let byte = (src >> (i * 8)) & 0xFF;
139                    if byte != 0 {
140                        result |= 0xFFu64 << (i * 8);
141                    }
142                }
143                state.regs.write(rd, result);
144            }
145            Self::Rev8 { rd, rs1 } => {
146                let value = state.regs.read(rs1).swap_bytes();
147                state.regs.write(rd, value);
148            }
149        }
150
151        Ok(ControlFlow::Continue(()))
152    }
153}