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