ab_riscv_interpreter/rv64/zk/
zbkb.rs1#[cfg(test)]
4mod tests;
5
6use crate::{
7 ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
8 ExecutionResult, FetchInstructionResult, InstructionFetcher, OpaqueThreadedExecutionResult,
9 RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, ThreadedExecutableInstruction,
10 ThreadedExecutionResult,
11};
12use ab_riscv_macros::instruction_execution;
13use ab_riscv_primitives::prelude::*;
14
15#[instruction_execution]
16const impl<Reg, Hart> ExecutableInstructionOperands for Rv64ZbkbInstruction<Hart>
17where
18 Reg: Register<Type = u64>,
19 Hart: HartConfig<Reg = Reg>,
20{
21}
22
23#[instruction_execution]
24const impl<Reg, Hart, Env> ExecutableInstructionCsr<Env> for Rv64ZbkbInstruction<Hart>
25where
26 Reg: Register<Type = u64>,
27 Hart: HartConfig<Reg = Reg>,
28{
29}
30
31#[instruction_execution]
32const impl<Reg, Hart, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
33 for Rv64ZbkbInstruction<Hart>
34where
35 Reg: [const] Register<Type = u64>,
36 Hart: HartConfig<Reg = Reg>,
37 Regs: [const] RegisterFile<Reg>,
38{
39 #[inline(always)]
40 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
41 fn execute(
42 self,
43 Rs1Rs2OperandValues {
44 rs1_value,
45 rs2_value,
46 }: Rs1Rs2OperandValues<Reg::Type>,
47 _regs: &mut Regs,
48 _env: &mut Env,
49 _memory: &mut Memory,
50 _program_counter: &PC,
51 ) -> ExecutionResult<Reg> {
52 match self {
53 Self::Pack { rd, rs1: _, rs2: _ } => {
54 let lo = rs1_value & 0x0000_0000_FFFF_FFFFu64;
57 let hi = (rs2_value & 0x0000_0000_FFFF_FFFFu64) << 32;
58 ExecutionResult::Continue { rd, value: lo | hi }
59 }
60 Self::Packh { rd, rs1: _, rs2: _ } => {
61 let lo = rs1_value & 0xFF;
64 let hi = (rs2_value & 0xFF) << 8;
65 ExecutionResult::Continue { rd, value: lo | hi }
66 }
67 Self::Packw { rd, rs1: _, rs2: _ } => {
68 let lo = rs1_value & 0xFFFF;
71 let hi = (rs2_value & 0xFFFF) << 16;
72 let word = (lo | hi) as u32;
73 let value = i64::from(word.cast_signed()).cast_unsigned();
74 ExecutionResult::Continue { rd, value }
75 }
76 Self::Brev8 { rd, rs1: _ } => {
77 let bytes = rs1_value.to_le_bytes();
79 let value = u64::from_le_bytes([
80 bytes[0].reverse_bits(),
81 bytes[1].reverse_bits(),
82 bytes[2].reverse_bits(),
83 bytes[3].reverse_bits(),
84 bytes[4].reverse_bits(),
85 bytes[5].reverse_bits(),
86 bytes[6].reverse_bits(),
87 bytes[7].reverse_bits(),
88 ]);
89 ExecutionResult::Continue { rd, value }
90 }
91 }
92 }
93}