ab_riscv_interpreter/rv32/b/
zbb.rs1pub mod rv32_zbb_helpers;
4#[cfg(test)]
5mod tests;
6
7use crate::{
8 ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
9 ExecutionResult, FetchInstructionResult, InstructionFetcher, OpaqueThreadedExecutionResult,
10 RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, ThreadedExecutableInstruction,
11 ThreadedExecutionResult,
12};
13use ab_riscv_macros::instruction_execution;
14use ab_riscv_primitives::prelude::*;
15
16#[instruction_execution]
17const impl<Reg> ExecutableInstructionOperands for Rv32ZbbInstruction<Reg> where
18 Reg: Register<Type = u32>
19{
20}
21
22#[instruction_execution]
23const impl<Reg, Env> ExecutableInstructionCsr<Env> for Rv32ZbbInstruction<Reg> where
24 Reg: Register<Type = u32>
25{
26}
27
28#[instruction_execution]
29const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
30 for Rv32ZbbInstruction<Reg>
31where
32 Reg: [const] Register<Type = u32>,
33 Regs: [const] RegisterFile<Reg>,
34{
35 #[inline(always)]
36 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
37 fn execute(
38 self,
39 Rs1Rs2OperandValues {
40 rs1_value,
41 rs2_value,
42 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
43 _regs: &mut Regs,
44 _env: &mut Env,
45 _memory: &mut Memory,
46 _program_counter: &mut PC,
47 ) -> ExecutionResult<Self::Reg> {
48 match self {
49 Self::Andn { rd, rs1: _, rs2: _ } => {
50 let value = rs1_value & !rs2_value;
51 ExecutionResult::Continue { rd, value }
52 }
53 Self::Orn { rd, rs1: _, rs2: _ } => {
54 let value = rs1_value | !rs2_value;
55 ExecutionResult::Continue { rd, value }
56 }
57 Self::Xnor { rd, rs1: _, rs2: _ } => {
58 let value = !(rs1_value ^ rs2_value);
59 ExecutionResult::Continue { rd, value }
60 }
61 Self::Clz { rd, rs1: _ } => {
62 let value = rs1_value.leading_zeros();
63 ExecutionResult::Continue { rd, value }
64 }
65 Self::Ctz { rd, rs1: _ } => {
66 let value = rs1_value.trailing_zeros();
67 ExecutionResult::Continue { rd, value }
68 }
69 Self::Cpop { rd, rs1: _ } => {
70 let value = rs1_value.count_ones();
71 ExecutionResult::Continue { rd, value }
72 }
73 Self::Max { rd, rs1: _, rs2: _ } => {
74 let a = rs1_value.cast_signed();
75 let b = rs2_value.cast_signed();
76 let value = a.max(b).cast_unsigned();
77 ExecutionResult::Continue { rd, value }
78 }
79 Self::Maxu { rd, rs1: _, rs2: _ } => {
80 let value = rs1_value.max(rs2_value);
81 ExecutionResult::Continue { rd, value }
82 }
83 Self::Min { rd, rs1: _, rs2: _ } => {
84 let a = rs1_value.cast_signed();
85 let b = rs2_value.cast_signed();
86 let value = a.min(b).cast_unsigned();
87 ExecutionResult::Continue { rd, value }
88 }
89 Self::Minu { rd, rs1: _, rs2: _ } => {
90 let value = rs1_value.min(rs2_value);
91 ExecutionResult::Continue { rd, value }
92 }
93 Self::Sextb { rd, rs1: _ } => {
94 let value = i32::from(rs1_value as i8).cast_unsigned();
95 ExecutionResult::Continue { rd, value }
96 }
97 Self::Sexth { rd, rs1: _ } => {
98 let value = i32::from(rs1_value as i16).cast_unsigned();
99 ExecutionResult::Continue { rd, value }
100 }
101 Self::Zexth { rd, rs1: _ } => {
102 let value = u32::from(rs1_value as u16);
103 ExecutionResult::Continue { rd, value }
104 }
105 Self::Rol { rd, rs1: _, rs2: _ } => {
106 let shamt = rs2_value & 0x1f;
107 let value = rs1_value.rotate_left(shamt);
108 ExecutionResult::Continue { rd, value }
109 }
110 Self::Ror { rd, rs1: _, rs2: _ } => {
111 let shamt = rs2_value & 0x1f;
112 let value = rs1_value.rotate_right(shamt);
113 ExecutionResult::Continue { rd, value }
114 }
115 Self::Rori { rd, rs1: _, shamt } => {
116 let value = rs1_value.rotate_right(u32::from(shamt & 0x1f));
117 ExecutionResult::Continue { rd, value }
118 }
119 Self::Orcb { rd, rs1: _ } => {
120 let src = rs1_value;
121
122 ExecutionResult::Continue {
123 rd,
124 value: rv32_zbb_helpers::orc_b(src),
125 }
126 }
127 Self::Rev8 { rd, rs1: _ } => {
128 let value = rs1_value.swap_bytes();
129 ExecutionResult::Continue { rd, value }
130 }
131 }
132 }
133}