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