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