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