use crate::isa::op::{AtomicOp, MemWidth};
pub fn atomic_alu(op: AtomicOp, mem_val: u64, reg_val: u64, width: MemWidth) -> u64 {
if matches!(width, MemWidth::Word) {
let a = mem_val as i32;
let b = reg_val as i32;
let res = match op {
AtomicOp::Swap => b,
AtomicOp::Add => a.wrapping_add(b),
AtomicOp::Xor => a ^ b,
AtomicOp::And => a & b,
AtomicOp::Or => a | b,
AtomicOp::Min => a.min(b),
AtomicOp::Max => a.max(b),
AtomicOp::MinU => (mem_val as u32).min(reg_val as u32) as i32,
AtomicOp::MaxU => (mem_val as u32).max(reg_val as u32) as i32,
_ => 0,
};
res as i64 as u64
} else {
let a = mem_val as i64;
let b = reg_val as i64;
let res = match op {
AtomicOp::Swap => b,
AtomicOp::Add => a.wrapping_add(b),
AtomicOp::Xor => a ^ b,
AtomicOp::And => a & b,
AtomicOp::Or => a | b,
AtomicOp::Min => a.min(b),
AtomicOp::Max => a.max(b),
AtomicOp::MinU => (mem_val).min(reg_val) as i64,
AtomicOp::MaxU => (mem_val).max(reg_val) as i64,
_ => 0,
};
res as u64
}
}