ab_riscv_interpreter/rv32/b/
zbb.rs1pub 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}