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> ExecutableInstructionOperands for Rv64ZbkbInstruction<Reg> where
17 Reg: Register<Type = u64>
18{
19}
20
21#[instruction_execution]
22const impl<Reg, Env> ExecutableInstructionCsr<Env> for Rv64ZbkbInstruction<Reg> where
23 Reg: Register<Type = u64>
24{
25}
26
27#[instruction_execution]
28const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
29 for Rv64ZbkbInstruction<Reg>
30where
31 Reg: [const] Register<Type = u64>,
32 Regs: [const] RegisterFile<Reg>,
33{
34 #[inline(always)]
35 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
36 fn execute(
37 self,
38 Rs1Rs2OperandValues {
39 rs1_value,
40 rs2_value,
41 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
42 _regs: &mut Regs,
43 _env: &mut Env,
44 _memory: &mut Memory,
45 _program_counter: &mut PC,
46 ) -> ExecutionResult<Self::Reg> {
47 match self {
48 Self::Pack { rd, rs1: _, rs2: _ } => {
49 let lo = rs1_value & 0x0000_0000_FFFF_FFFFu64;
52 let hi = (rs2_value & 0x0000_0000_FFFF_FFFFu64) << 32;
53 ExecutionResult::Continue { rd, value: lo | hi }
54 }
55 Self::Packh { rd, rs1: _, rs2: _ } => {
56 let lo = rs1_value & 0xFF;
59 let hi = (rs2_value & 0xFF) << 8;
60 ExecutionResult::Continue { rd, value: lo | hi }
61 }
62 Self::Packw { rd, rs1: _, rs2: _ } => {
63 let lo = rs1_value & 0xFFFF;
66 let hi = (rs2_value & 0xFFFF) << 16;
67 let word = (lo | hi) as u32;
68 let value = i64::from(word.cast_signed()).cast_unsigned();
69 ExecutionResult::Continue { rd, value }
70 }
71 Self::Brev8 { rd, rs1: _ } => {
72 let bytes = rs1_value.to_le_bytes();
74 let value = u64::from_le_bytes([
75 bytes[0].reverse_bits(),
76 bytes[1].reverse_bits(),
77 bytes[2].reverse_bits(),
78 bytes[3].reverse_bits(),
79 bytes[4].reverse_bits(),
80 bytes[5].reverse_bits(),
81 bytes[6].reverse_bits(),
82 bytes[7].reverse_bits(),
83 ]);
84 ExecutionResult::Continue { rd, value }
85 }
86 }
87 }
88}