ab_riscv_interpreter/rv64/a/
zaamo.rs1#[cfg(test)]
4mod tests;
5
6use crate::{
7 ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands,
8 ExecutableInstructionResult, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, VirtualMemory,
9};
10use ab_riscv_macros::instruction_execution;
11use ab_riscv_primitives::prelude::*;
12use core::ops::ControlFlow;
13
14#[instruction_execution]
15const impl<Reg> ExecutableInstructionOperands for Rv64ZaamoInstruction<Reg> where
16 Reg: Register<Type = u64>
17{
18}
19
20#[instruction_execution]
21const impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
22 for Rv64ZaamoInstruction<Reg>
23where
24 Reg: Register<Type = u64>,
25{
26}
27
28#[instruction_execution]
29const impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
30 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
31 for Rv64ZaamoInstruction<Reg>
32where
33 Reg: [const] Register<Type = u64>,
34 Regs: [const] RegisterFile<Reg>,
35 Memory: [const] VirtualMemory,
36{
37 #[inline(always)]
38 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
39 fn execute(
40 self,
41 Rs1Rs2OperandValues {
42 rs1_value,
43 rs2_value,
44 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
45 _regs: &mut Regs,
46 _ext_state: &mut ExtState,
47 memory: &mut Memory,
48 _program_counter: &mut PC,
49 _system_instruction_handler: &mut InstructionHandler,
50 ) -> ExecutableInstructionResult<(), Self, CustomError> {
51 match self {
52 Self::Amoswap {
53 rd,
54 rs1: _,
55 rs2: _,
56 aq: _,
57 rl: _,
58 } => {
59 let old = memory.read::<i32>(rs1_value)?;
60 memory.write(rs1_value, rs2_value as u32)?;
61 Ok(ControlFlow::Continue((rd, i64::from(old).cast_unsigned())))
62 }
63 Self::Amoadd {
64 rd,
65 rs1: _,
66 rs2: _,
67 aq: _,
68 rl: _,
69 } => {
70 let old = memory.read::<i32>(rs1_value)?;
71 let new = (old.cast_unsigned()).wrapping_add(rs2_value as u32);
72 memory.write(rs1_value, new)?;
73 Ok(ControlFlow::Continue((rd, i64::from(old).cast_unsigned())))
74 }
75 Self::Amoxor {
76 rd,
77 rs1: _,
78 rs2: _,
79 aq: _,
80 rl: _,
81 } => {
82 let old = memory.read::<i32>(rs1_value)?;
83 let new = old.cast_unsigned() ^ (rs2_value as u32);
84 memory.write(rs1_value, new)?;
85 Ok(ControlFlow::Continue((rd, i64::from(old).cast_unsigned())))
86 }
87 Self::Amoand {
88 rd,
89 rs1: _,
90 rs2: _,
91 aq: _,
92 rl: _,
93 } => {
94 let old = memory.read::<i32>(rs1_value)?;
95 let new = old.cast_unsigned() & (rs2_value as u32);
96 memory.write(rs1_value, new)?;
97 Ok(ControlFlow::Continue((rd, i64::from(old).cast_unsigned())))
98 }
99 Self::Amoor {
100 rd,
101 rs1: _,
102 rs2: _,
103 aq: _,
104 rl: _,
105 } => {
106 let old = memory.read::<i32>(rs1_value)?;
107 let new = old.cast_unsigned() | (rs2_value as u32);
108 memory.write(rs1_value, new)?;
109 Ok(ControlFlow::Continue((rd, i64::from(old).cast_unsigned())))
110 }
111 Self::Amomin {
112 rd,
113 rs1: _,
114 rs2: _,
115 aq: _,
116 rl: _,
117 } => {
118 let old = memory.read::<i32>(rs1_value)?;
119 let new = if old < (rs2_value as u32).cast_signed() {
120 old.cast_unsigned()
121 } else {
122 rs2_value as u32
123 };
124 memory.write(rs1_value, new)?;
125 Ok(ControlFlow::Continue((rd, i64::from(old).cast_unsigned())))
126 }
127 Self::Amomax {
128 rd,
129 rs1: _,
130 rs2: _,
131 aq: _,
132 rl: _,
133 } => {
134 let old = memory.read::<i32>(rs1_value)?;
135 let new = if old > (rs2_value as u32).cast_signed() {
136 old.cast_unsigned()
137 } else {
138 rs2_value as u32
139 };
140 memory.write(rs1_value, new)?;
141 Ok(ControlFlow::Continue((rd, i64::from(old).cast_unsigned())))
142 }
143 Self::Amominu {
144 rd,
145 rs1: _,
146 rs2: _,
147 aq: _,
148 rl: _,
149 } => {
150 let old = memory.read::<i32>(rs1_value)?;
151 let new = if old.cast_unsigned() < (rs2_value as u32) {
152 old.cast_unsigned()
153 } else {
154 rs2_value as u32
155 };
156 memory.write(rs1_value, new)?;
157 Ok(ControlFlow::Continue((rd, i64::from(old).cast_unsigned())))
158 }
159 Self::Amomaxu {
160 rd,
161 rs1: _,
162 rs2: _,
163 aq: _,
164 rl: _,
165 } => {
166 let old = memory.read::<i32>(rs1_value)?;
167 let new = if old.cast_unsigned() > (rs2_value as u32) {
168 old.cast_unsigned()
169 } else {
170 rs2_value as u32
171 };
172 memory.write(rs1_value, new)?;
173 Ok(ControlFlow::Continue((rd, i64::from(old).cast_unsigned())))
174 }
175
176 Self::AmoswapD {
177 rd,
178 rs1: _,
179 rs2: _,
180 aq: _,
181 rl: _,
182 } => {
183 let old = memory.read::<u64>(rs1_value)?;
184 memory.write(rs1_value, rs2_value)?;
185 Ok(ControlFlow::Continue((rd, old)))
186 }
187 Self::AmoaddD {
188 rd,
189 rs1: _,
190 rs2: _,
191 aq: _,
192 rl: _,
193 } => {
194 let old = memory.read::<u64>(rs1_value)?;
195 memory.write(rs1_value, old.wrapping_add(rs2_value))?;
196 Ok(ControlFlow::Continue((rd, old)))
197 }
198 Self::AmoxorD {
199 rd,
200 rs1: _,
201 rs2: _,
202 aq: _,
203 rl: _,
204 } => {
205 let old = memory.read::<u64>(rs1_value)?;
206 memory.write(rs1_value, old ^ rs2_value)?;
207 Ok(ControlFlow::Continue((rd, old)))
208 }
209 Self::AmoandD {
210 rd,
211 rs1: _,
212 rs2: _,
213 aq: _,
214 rl: _,
215 } => {
216 let old = memory.read::<u64>(rs1_value)?;
217 memory.write(rs1_value, old & rs2_value)?;
218 Ok(ControlFlow::Continue((rd, old)))
219 }
220 Self::AmoorD {
221 rd,
222 rs1: _,
223 rs2: _,
224 aq: _,
225 rl: _,
226 } => {
227 let old = memory.read::<u64>(rs1_value)?;
228 memory.write(rs1_value, old | rs2_value)?;
229 Ok(ControlFlow::Continue((rd, old)))
230 }
231 Self::AmominD {
232 rd,
233 rs1: _,
234 rs2: _,
235 aq: _,
236 rl: _,
237 } => {
238 let old = memory.read::<u64>(rs1_value)?;
239 let new = if old.cast_signed() < rs2_value.cast_signed() {
240 old
241 } else {
242 rs2_value
243 };
244 memory.write(rs1_value, new)?;
245 Ok(ControlFlow::Continue((rd, old)))
246 }
247 Self::AmomaxD {
248 rd,
249 rs1: _,
250 rs2: _,
251 aq: _,
252 rl: _,
253 } => {
254 let old = memory.read::<u64>(rs1_value)?;
255 let new = if old.cast_signed() > rs2_value.cast_signed() {
256 old
257 } else {
258 rs2_value
259 };
260 memory.write(rs1_value, new)?;
261 Ok(ControlFlow::Continue((rd, old)))
262 }
263 Self::AmominuD {
264 rd,
265 rs1: _,
266 rs2: _,
267 aq: _,
268 rl: _,
269 } => {
270 let old = memory.read::<u64>(rs1_value)?;
271 let new = if old < rs2_value { old } else { rs2_value };
272 memory.write(rs1_value, new)?;
273 Ok(ControlFlow::Continue((rd, old)))
274 }
275 Self::AmomaxuD {
276 rd,
277 rs1: _,
278 rs2: _,
279 aq: _,
280 rl: _,
281 } => {
282 let old = memory.read::<u64>(rs1_value)?;
283 let new = if old > rs2_value { old } else { rs2_value };
284 memory.write(rs1_value, new)?;
285 Ok(ControlFlow::Continue((rd, old)))
286 }
287 }
288 }
289}