diff --git a/crates/xenia-cpu/src/interpreter.rs b/crates/xenia-cpu/src/interpreter.rs index 9795ac8..c22cd0b 100644 --- a/crates/xenia-cpu/src/interpreter.rs +++ b/crates/xenia-cpu/src/interpreter.rs @@ -1464,7 +1464,12 @@ fn execute(ctx: &mut PpcContext, mem: &dyn MemoryAccess, instr: &DecodedInstr) - let mut rs = instr.rs(); let mut bytes_left = nb; if let Some(t) = ctx.reservation_table.as_ref().filter(|t| t.is_enabled()) { - if t.has_active_reservers() { t.invalidate_for_write(ea); } + if t.has_active_reservers() { + let first_line = ea & !RESERVATION_MASK; + let last_line = ea.wrapping_add(nb - 1) & !RESERVATION_MASK; + t.invalidate_for_write(first_line); + if last_line != first_line { t.invalidate_for_write(last_line); } + } } while bytes_left > 0 { let val = ctx.gpr[rs] as u32; @@ -1600,6 +1605,9 @@ fn execute(ctx: &mut PpcContext, mem: &dyn MemoryAccess, instr: &DecodedInstr) - // Zero 32 bytes at effective address let ea = if instr.ra() == 0 { 0u64 } else { ctx.gpr[instr.ra()] }; let ea = (ea.wrapping_add(ctx.gpr[instr.rb()]) as u32) & !31; + if let Some(t) = ctx.reservation_table.as_ref().filter(|t| t.is_enabled()) { + if t.has_active_reservers() { t.invalidate_for_write(ea); } + } for i in 0..8 { mem.write_u32(ea + i * 4, 0); } @@ -1609,6 +1617,9 @@ fn execute(ctx: &mut PpcContext, mem: &dyn MemoryAccess, instr: &DecodedInstr) - // Zero 128 bytes let ea = if instr.ra() == 0 { 0u64 } else { ctx.gpr[instr.ra()] }; let ea = (ea.wrapping_add(ctx.gpr[instr.rb()]) as u32) & !127; + if let Some(t) = ctx.reservation_table.as_ref().filter(|t| t.is_enabled()) { + if t.has_active_reservers() { t.invalidate_for_write(ea); } + } for i in 0..32 { mem.write_u32(ea + i * 4, 0); } @@ -4418,8 +4429,15 @@ fn execute(ctx: &mut PpcContext, mem: &dyn MemoryAccess, instr: &DecodedInstr) - let nb = ctx.xer() & 0x7F; let mut rs = instr.rs(); let mut bytes_left = nb; - if let Some(t) = ctx.reservation_table.as_ref().filter(|t| t.is_enabled()) { - if t.has_active_reservers() { t.invalidate_for_write(ea); } + if nb > 0 { + if let Some(t) = ctx.reservation_table.as_ref().filter(|t| t.is_enabled()) { + if t.has_active_reservers() { + let first_line = ea & !RESERVATION_MASK; + let last_line = ea.wrapping_add(nb - 1) & !RESERVATION_MASK; + t.invalidate_for_write(first_line); + if last_line != first_line { t.invalidate_for_write(last_line); } + } + } } while bytes_left > 0 { let val = ctx.gpr[rs] as u32;