Skip to main content

ab_riscv_interpreter/rv32/b/
zbb.rs

1//! RV32 Zbb extension
2
3pub mod rv32_zbb_helpers;
4#[cfg(test)]
5mod tests;
6
7use crate::{ExecutableInstruction, ExecutionError, RegisterFile};
8use ab_riscv_macros::instruction_execution;
9use ab_riscv_primitives::prelude::*;
10use core::ops::ControlFlow;
11
12#[instruction_execution]
13impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
14    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
15    for Rv32ZbbInstruction<Reg>
16where
17    Reg: Register<Type = u32>,
18    Regs: RegisterFile<Reg>,
19{
20    #[inline(always)]
21    fn execute(
22        self,
23        regs: &mut Regs,
24        _ext_state: &mut ExtState,
25        _memory: &mut Memory,
26        _program_counter: &mut PC,
27        _system_instruction_handler: &mut InstructionHandler,
28    ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
29        match self {
30            Self::Andn { rd, rs1, rs2 } => {
31                let value = regs.read(rs1) & !regs.read(rs2);
32                regs.write(rd, value);
33            }
34            Self::Orn { rd, rs1, rs2 } => {
35                let value = regs.read(rs1) | !regs.read(rs2);
36                regs.write(rd, value);
37            }
38            Self::Xnor { rd, rs1, rs2 } => {
39                let value = !(regs.read(rs1) ^ regs.read(rs2));
40                regs.write(rd, value);
41            }
42            Self::Clz { rd, rs1 } => {
43                let value = regs.read(rs1).leading_zeros();
44                regs.write(rd, value);
45            }
46            Self::Ctz { rd, rs1 } => {
47                let value = regs.read(rs1).trailing_zeros();
48                regs.write(rd, value);
49            }
50            Self::Cpop { rd, rs1 } => {
51                let value = regs.read(rs1).count_ones();
52                regs.write(rd, value);
53            }
54            Self::Max { rd, rs1, rs2 } => {
55                let a = regs.read(rs1).cast_signed();
56                let b = regs.read(rs2).cast_signed();
57                let value = a.max(b).cast_unsigned();
58                regs.write(rd, value);
59            }
60            Self::Maxu { rd, rs1, rs2 } => {
61                let value = regs.read(rs1).max(regs.read(rs2));
62                regs.write(rd, value);
63            }
64            Self::Min { rd, rs1, rs2 } => {
65                let a = regs.read(rs1).cast_signed();
66                let b = regs.read(rs2).cast_signed();
67                let value = a.min(b).cast_unsigned();
68                regs.write(rd, value);
69            }
70            Self::Minu { rd, rs1, rs2 } => {
71                let value = regs.read(rs1).min(regs.read(rs2));
72                regs.write(rd, value);
73            }
74            Self::Sextb { rd, rs1 } => {
75                let value = i32::from(regs.read(rs1) as i8).cast_unsigned();
76                regs.write(rd, value);
77            }
78            Self::Sexth { rd, rs1 } => {
79                let value = i32::from(regs.read(rs1) as i16).cast_unsigned();
80                regs.write(rd, value);
81            }
82            Self::Zexth { rd, rs1 } => {
83                let value = u32::from(regs.read(rs1) as u16);
84                regs.write(rd, value);
85            }
86            Self::Rol { rd, rs1, rs2 } => {
87                let shamt = regs.read(rs2) & 0x1f;
88                let value = regs.read(rs1).rotate_left(shamt);
89                regs.write(rd, value);
90            }
91            Self::Ror { rd, rs1, rs2 } => {
92                let shamt = regs.read(rs2) & 0x1f;
93                let value = regs.read(rs1).rotate_right(shamt);
94                regs.write(rd, value);
95            }
96            Self::Rori { rd, rs1, shamt } => {
97                let value = regs.read(rs1).rotate_right(u32::from(shamt & 0x1f));
98                regs.write(rd, value);
99            }
100            Self::Orcb { rd, rs1 } => {
101                let src = regs.read(rs1);
102
103                regs.write(rd, rv32_zbb_helpers::orc_b(src));
104            }
105            Self::Rev8 { rd, rs1 } => {
106                let value = regs.read(rs1).swap_bytes();
107                regs.write(rd, value);
108            }
109        }
110
111        Ok(ControlFlow::Continue(()))
112    }
113}