ab_riscv_interpreter/rv32/zce/
zcb.rs1#[cfg(test)]
6mod tests;
7
8use crate::{
9 ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
10 ExecutionResult, FetchInstructionResult, InstructionFetcher, OpaqueThreadedExecutionResult,
11 PackedAddress, ProgramCounter, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands,
12 SystemInstructionHandler, ThreadedExecutableInstruction, ThreadedExecutionResult,
13 VirtualMemory,
14};
15use ab_riscv_macros::instruction_execution;
16use ab_riscv_primitives::prelude::*;
17use core::ops::ControlFlow;
18
19#[instruction_execution]
20const impl<Reg> ExecutableInstructionOperands for Rv32ZcbInstruction<Reg> where
21 Reg: Register<Type = u32>
22{
23}
24
25#[instruction_execution]
26const impl<Reg, Env> ExecutableInstructionCsr<Env> for Rv32ZcbInstruction<Reg> where
27 Reg: Register<Type = u32>
28{
29}
30
31#[instruction_execution]
32const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
33 for Rv32ZcbInstruction<Reg>
34where
35 Reg: [const] Register<Type = u32>,
36{
37 #[inline(always)]
38 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
39 fn execute(
40 self,
41 Rs1Rs2OperandValues {
42 rs1_value,
43 rs2_value,
44 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
45 regs: &mut Regs,
46 _env: &mut Env,
47 memory: &mut Memory,
48 program_counter: &mut PC,
49 ) -> ExecutionResult<Self::Reg> {
50 ExecutionResult::ContinueNoWrite
51 }
52}
53
54#[instruction_execution]
55const impl<Reg> ExecutableInstructionOperands for Rv32ZcbOnlyInstruction<Reg> where
56 Reg: Register<Type = u32>
57{
58}
59
60#[instruction_execution]
61const impl<Reg, Env> ExecutableInstructionCsr<Env> for Rv32ZcbOnlyInstruction<Reg> where
62 Reg: Register<Type = u32>
63{
64}
65
66#[instruction_execution]
67const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
68 for Rv32ZcbOnlyInstruction<Reg>
69where
70 Reg: [const] Register<Type = u32>,
71 Regs: [const] RegisterFile<Reg>,
72 Memory: [const] VirtualMemory,
73 PC: [const] ProgramCounter<Reg::Type, Memory>,
74 Env: [const] SystemInstructionHandler<Reg, Regs, Memory, PC>,
75{
76 #[inline(always)]
77 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
78 fn execute(
79 self,
80 Rs1Rs2OperandValues {
81 rs1_value,
82 rs2_value,
83 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
84 regs: &mut Regs,
85 _env: &mut Env,
86 memory: &mut Memory,
87 _program_counter: &mut PC,
88 ) -> ExecutionResult<Self::Reg> {
89 match self {
90 Self::CLbu { rd, rs1: _, uimm } => {
91 let addr = u64::from(rs1_value.wrapping_add(u32::from(uimm)));
92 let value = memory.read::<u8>(addr)?;
93 ExecutionResult::Continue {
94 rd,
95 value: u32::from(value),
96 }
97 }
98 Self::CLh { rd, rs1: _, uimm } => {
99 let addr = u64::from(rs1_value.wrapping_add(u32::from(uimm)));
100 let value = i32::from(memory.read::<i16>(addr)?);
101 ExecutionResult::Continue {
102 rd,
103 value: value.cast_unsigned(),
104 }
105 }
106 Self::CLhu { rd, rs1: _, uimm } => {
107 let addr = u64::from(rs1_value.wrapping_add(u32::from(uimm)));
108 let value = memory.read::<u16>(addr)?;
109 ExecutionResult::Continue {
110 rd,
111 value: u32::from(value),
112 }
113 }
114 Self::CSb {
115 rs1: _,
116 rs2: _,
117 uimm,
118 } => {
119 let addr = u64::from(rs1_value.wrapping_add(u32::from(uimm)));
120 memory.write(addr, rs2_value as u8)?;
121 ExecutionResult::ContinueNoWrite
122 }
123 Self::CSh {
124 rs1: _,
125 rs2: _,
126 uimm,
127 } => {
128 let addr = u64::from(rs1_value.wrapping_add(u32::from(uimm)));
129 memory.write(addr, rs2_value as u16)?;
130 ExecutionResult::ContinueNoWrite
131 }
132 Self::CZextB { rd } => {
133 let value = regs.read(rd) & 0xff;
134 ExecutionResult::Continue { rd, value }
135 }
136 Self::CSextB { rd } => {
137 let value = i32::from(regs.read(rd) as i8);
138 ExecutionResult::Continue {
139 rd,
140 value: value.cast_unsigned(),
141 }
142 }
143 Self::CZextH { rd } => {
144 let value = regs.read(rd) & 0xffff;
145 ExecutionResult::Continue { rd, value }
146 }
147 Self::CSextH { rd } => {
148 let value = i32::from(regs.read(rd) as i16);
149 ExecutionResult::Continue {
150 rd,
151 value: value.cast_unsigned(),
152 }
153 }
154 Self::CNot { rd } => {
155 let value = !regs.read(rd);
156 ExecutionResult::Continue { rd, value }
157 }
158 Self::CMul { rd, rs2: _ } => {
159 let value = regs.read(rd).wrapping_mul(rs2_value);
160 ExecutionResult::Continue { rd, value }
161 }
162 }
163 }
164}