ab_riscv_interpreter/rv32/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 Rv32ZaamoInstruction<Reg> where
16 Reg: Register<Type = u32>
17{
18}
19
20#[instruction_execution]
21const impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
22 for Rv32ZaamoInstruction<Reg>
23where
24 Reg: Register<Type = u32>,
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 Rv32ZaamoInstruction<Reg>
32where
33 Reg: [const] Register<Type = u32>,
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::<u32>(u64::from(rs1_value))?;
60 memory.write(u64::from(rs1_value), rs2_value)?;
61 Ok(ControlFlow::Continue((rd, old)))
62 }
63 Self::Amoadd {
64 rd,
65 rs1: _,
66 rs2: _,
67 aq: _,
68 rl: _,
69 } => {
70 let old = memory.read::<u32>(u64::from(rs1_value))?;
71 memory.write(u64::from(rs1_value), old.wrapping_add(rs2_value))?;
72 Ok(ControlFlow::Continue((rd, old)))
73 }
74 Self::Amoxor {
75 rd,
76 rs1: _,
77 rs2: _,
78 aq: _,
79 rl: _,
80 } => {
81 let old = memory.read::<u32>(u64::from(rs1_value))?;
82 memory.write(u64::from(rs1_value), old ^ rs2_value)?;
83 Ok(ControlFlow::Continue((rd, old)))
84 }
85 Self::Amoand {
86 rd,
87 rs1: _,
88 rs2: _,
89 aq: _,
90 rl: _,
91 } => {
92 let old = memory.read::<u32>(u64::from(rs1_value))?;
93 memory.write(u64::from(rs1_value), old & rs2_value)?;
94 Ok(ControlFlow::Continue((rd, old)))
95 }
96 Self::Amoor {
97 rd,
98 rs1: _,
99 rs2: _,
100 aq: _,
101 rl: _,
102 } => {
103 let old = memory.read::<u32>(u64::from(rs1_value))?;
104 memory.write(u64::from(rs1_value), old | rs2_value)?;
105 Ok(ControlFlow::Continue((rd, old)))
106 }
107 Self::Amomin {
108 rd,
109 rs1: _,
110 rs2: _,
111 aq: _,
112 rl: _,
113 } => {
114 let old = memory.read::<u32>(u64::from(rs1_value))?;
115 let new = if old.cast_signed() < rs2_value.cast_signed() {
116 old
117 } else {
118 rs2_value
119 };
120 memory.write(u64::from(rs1_value), new)?;
121 Ok(ControlFlow::Continue((rd, old)))
122 }
123 Self::Amomax {
124 rd,
125 rs1: _,
126 rs2: _,
127 aq: _,
128 rl: _,
129 } => {
130 let old = memory.read::<u32>(u64::from(rs1_value))?;
131 let new = if old.cast_signed() > rs2_value.cast_signed() {
132 old
133 } else {
134 rs2_value
135 };
136 memory.write(u64::from(rs1_value), new)?;
137 Ok(ControlFlow::Continue((rd, old)))
138 }
139 Self::Amominu {
140 rd,
141 rs1: _,
142 rs2: _,
143 aq: _,
144 rl: _,
145 } => {
146 let old = memory.read::<u32>(u64::from(rs1_value))?;
147 let new = if old < rs2_value { old } else { rs2_value };
148 memory.write(u64::from(rs1_value), new)?;
149 Ok(ControlFlow::Continue((rd, old)))
150 }
151 Self::Amomaxu {
152 rd,
153 rs1: _,
154 rs2: _,
155 aq: _,
156 rl: _,
157 } => {
158 let old = memory.read::<u32>(u64::from(rs1_value))?;
159 let new = if old > rs2_value { old } else { rs2_value };
160 memory.write(u64::from(rs1_value), new)?;
161 Ok(ControlFlow::Continue((rd, old)))
162 }
163 }
164 }
165}