ab_riscv_interpreter/rv64/b/
zbb.rs1pub mod rv64_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 Rv64ZbbInstruction<Reg>
16where
17 Reg: Register<Type = u64>,
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 = u64::from(regs.read(rs1).leading_zeros());
44 regs.write(rd, value);
45 }
46 Self::Clzw { rd, rs1 } => {
47 let value = u64::from((regs.read(rs1) as u32).leading_zeros());
48 regs.write(rd, value);
49 }
50 Self::Ctz { rd, rs1 } => {
51 let value = u64::from(regs.read(rs1).trailing_zeros());
52 regs.write(rd, value);
53 }
54 Self::Ctzw { rd, rs1 } => {
55 let value = u64::from((regs.read(rs1) as u32).trailing_zeros());
56 regs.write(rd, value);
57 }
58 Self::Cpop { rd, rs1 } => {
59 let value = u64::from(regs.read(rs1).count_ones());
60 regs.write(rd, value);
61 }
62 Self::Cpopw { rd, rs1 } => {
63 let value = u64::from((regs.read(rs1) as u32).count_ones());
64 regs.write(rd, value);
65 }
66 Self::Max { rd, rs1, rs2 } => {
67 let a = regs.read(rs1).cast_signed();
68 let b = regs.read(rs2).cast_signed();
69 let value = a.max(b).cast_unsigned();
70 regs.write(rd, value);
71 }
72 Self::Maxu { rd, rs1, rs2 } => {
73 let value = regs.read(rs1).max(regs.read(rs2));
74 regs.write(rd, value);
75 }
76 Self::Min { rd, rs1, rs2 } => {
77 let a = regs.read(rs1).cast_signed();
78 let b = regs.read(rs2).cast_signed();
79 let value = a.min(b).cast_unsigned();
80 regs.write(rd, value);
81 }
82 Self::Minu { rd, rs1, rs2 } => {
83 let value = regs.read(rs1).min(regs.read(rs2));
84 regs.write(rd, value);
85 }
86 Self::Sextb { rd, rs1 } => {
87 let value = i64::from(regs.read(rs1) as i8).cast_unsigned();
88 regs.write(rd, value);
89 }
90 Self::Sexth { rd, rs1 } => {
91 let value = i64::from(regs.read(rs1) as i16).cast_unsigned();
92 regs.write(rd, value);
93 }
94 Self::Zexth { rd, rs1 } => {
95 let value = u64::from(regs.read(rs1) as u16);
96 regs.write(rd, value);
97 }
98 Self::Rol { rd, rs1, rs2 } => {
99 let shamt = (regs.read(rs2) & 0x3f) as u32;
100 let value = regs.read(rs1).rotate_left(shamt);
101 regs.write(rd, value);
102 }
103 Self::Rolw { rd, rs1, rs2 } => {
104 let shamt = (regs.read(rs2) & 0x1f) as u32;
105 let value = i64::from((regs.read(rs1) as u32).rotate_left(shamt).cast_signed());
106 regs.write(rd, value.cast_unsigned());
107 }
108 Self::Ror { rd, rs1, rs2 } => {
109 let shamt = (regs.read(rs2) & 0x3f) as u32;
110 let value = regs.read(rs1).rotate_right(shamt);
111 regs.write(rd, value);
112 }
113 Self::Rori { rd, rs1, shamt } => {
114 let value = regs.read(rs1).rotate_right(u32::from(shamt & 0x3f));
115 regs.write(rd, value);
116 }
117 Self::Roriw { rd, rs1, shamt } => {
118 let value = i64::from(
119 (regs.read(rs1) as u32)
120 .rotate_right((shamt & 0x1f) as u32)
121 .cast_signed(),
122 );
123 regs.write(rd, value.cast_unsigned());
124 }
125 Self::Rorw { rd, rs1, rs2 } => {
126 let shamt = (regs.read(rs2) & 0x1f) as u32;
127 let value = i64::from((regs.read(rs1) as u32).rotate_right(shamt).cast_signed());
128 regs.write(rd, value.cast_unsigned());
129 }
130 Self::Orcb { rd, rs1 } => {
131 let src = regs.read(rs1);
132
133 regs.write(rd, rv64_zbb_helpers::orc_b(src));
134 }
135 Self::Rev8 { rd, rs1 } => {
136 let value = regs.read(rs1).swap_bytes();
137 regs.write(rd, value);
138 }
139 }
140
141 Ok(ControlFlow::Continue(()))
142 }
143}