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