Skip to main content

ab_riscv_interpreter/rv64/b/
zbb.rs

1//! RV64 Zbb extension
2
3pub 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}