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