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    RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands,
9};
10use ab_riscv_macros::instruction_execution;
11use ab_riscv_primitives::prelude::*;
12use core::ops::ControlFlow;
13
14#[instruction_execution]
15impl<Reg> ExecutableInstructionOperands for Rv64ZbaInstruction<Reg> where Reg: Register<Type = u64> {}
16
17#[instruction_execution]
18impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
19    for Rv64ZbaInstruction<Reg>
20where
21    Reg: Register<Type = u64>,
22{
23}
24
25#[instruction_execution]
26impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
27    ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
28    for Rv64ZbaInstruction<Reg>
29where
30    Reg: Register<Type = u64>,
31    Regs: RegisterFile<Reg>,
32{
33    #[inline(always)]
34    fn execute(
35        self,
36        Rs1Rs2OperandValues {
37            rs1_value,
38            rs2_value,
39        }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
40        _regs: &mut Regs,
41        _ext_state: &mut ExtState,
42        _memory: &mut Memory,
43        _program_counter: &mut PC,
44        _system_instruction_handler: &mut InstructionHandler,
45    ) -> Result<
46        ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
47        ExecutionError<Reg::Type, CustomError>,
48    > {
49        match self {
50            Self::AddUw { rd, rs1: _, rs2: _ } => {
51                let rs1_val = (rs1_value as u32) as u64;
52                let value = rs1_val.wrapping_add(rs2_value);
53                Ok(ControlFlow::Continue((rd, value)))
54            }
55            Self::Sh1add { rd, rs1: _, rs2: _ } => {
56                let value = (rs1_value << 1).wrapping_add(rs2_value);
57                Ok(ControlFlow::Continue((rd, value)))
58            }
59            Self::Sh1addUw { rd, rs1: _, rs2: _ } => {
60                let rs1_val = (rs1_value as u32) as u64;
61                let value = (rs1_val << 1).wrapping_add(rs2_value);
62                Ok(ControlFlow::Continue((rd, value)))
63            }
64            Self::Sh2add { rd, rs1: _, rs2: _ } => {
65                let value = (rs1_value << 2).wrapping_add(rs2_value);
66                Ok(ControlFlow::Continue((rd, value)))
67            }
68            Self::Sh2addUw { rd, rs1: _, rs2: _ } => {
69                let rs1_val = (rs1_value as u32) as u64;
70                let value = (rs1_val << 2).wrapping_add(rs2_value);
71                Ok(ControlFlow::Continue((rd, value)))
72            }
73            Self::Sh3add { rd, rs1: _, rs2: _ } => {
74                let value = (rs1_value << 3).wrapping_add(rs2_value);
75                Ok(ControlFlow::Continue((rd, value)))
76            }
77            Self::Sh3addUw { rd, rs1: _, rs2: _ } => {
78                let rs1_val = (rs1_value as u32) as u64;
79                let value = (rs1_val << 3).wrapping_add(rs2_value);
80                Ok(ControlFlow::Continue((rd, value)))
81            }
82            Self::SlliUw { rd, rs1: _, shamt } => {
83                let rs1_val = (rs1_value as u32) as u64;
84                let value = rs1_val << (shamt & 0x3f);
85                Ok(ControlFlow::Continue((rd, value)))
86            }
87        }
88    }
89}