Skip to main content

ab_riscv_interpreter/rv64/b/
zba.rs

1//! RV64 Zba extension
2
3#[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 Rv64ZbaInstruction<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 Rv64ZbaInstruction<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 Rv64ZbaInstruction<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::AddUw { rd, rs1: _, rs2: _ } => {
54                let rs1_val = u64::from(rs1_value as u32);
55                let value = rs1_val.wrapping_add(rs2_value);
56                ExecutionResult::Continue { rd, value }
57            }
58            Self::Sh1add { rd, rs1: _, rs2: _ } => {
59                let value = (rs1_value << 1).wrapping_add(rs2_value);
60                ExecutionResult::Continue { rd, value }
61            }
62            Self::Sh1addUw { rd, rs1: _, rs2: _ } => {
63                let rs1_val = u64::from(rs1_value as u32);
64                let value = (rs1_val << 1).wrapping_add(rs2_value);
65                ExecutionResult::Continue { rd, value }
66            }
67            Self::Sh2add { rd, rs1: _, rs2: _ } => {
68                let value = (rs1_value << 2).wrapping_add(rs2_value);
69                ExecutionResult::Continue { rd, value }
70            }
71            Self::Sh2addUw { rd, rs1: _, rs2: _ } => {
72                let rs1_val = u64::from(rs1_value as u32);
73                let value = (rs1_val << 2).wrapping_add(rs2_value);
74                ExecutionResult::Continue { rd, value }
75            }
76            Self::Sh3add { rd, rs1: _, rs2: _ } => {
77                let value = (rs1_value << 3).wrapping_add(rs2_value);
78                ExecutionResult::Continue { rd, value }
79            }
80            Self::Sh3addUw { rd, rs1: _, rs2: _ } => {
81                let rs1_val = u64::from(rs1_value as u32);
82                let value = (rs1_val << 3).wrapping_add(rs2_value);
83                ExecutionResult::Continue { rd, value }
84            }
85            Self::SlliUw { rd, rs1: _, shamt } => {
86                let rs1_val = u64::from(rs1_value as u32);
87                let value = rs1_val << shamt.get();
88                ExecutionResult::Continue { rd, value }
89            }
90        }
91    }
92}