From 5560a0ed3961fd7d165b2eadac330d95fda99992 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 18 Oct 2022 11:47:36 -0400 Subject: [PATCH] Fix overflow test for ASL. --- .../M68k/Implementation/PerformImplementation.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/InstructionSets/M68k/Implementation/PerformImplementation.hpp b/InstructionSets/M68k/Implementation/PerformImplementation.hpp index d1d62eb68..47e6000d3 100644 --- a/InstructionSets/M68k/Implementation/PerformImplementation.hpp +++ b/InstructionSets/M68k/Implementation/PerformImplementation.hpp @@ -361,10 +361,16 @@ template void shif if(type == Type::LSL) { status.overflow_flag = 0; } else { + // Overflow records whether the top bit changed at any point during the operation. if(shift >= size) { - status.overflow_flag = destination & top_bit(); + // The result is going to be all bits evacuated through the top giving a net + // result of 0, so overflow is set if any bit was originally set. + status.overflow_flag = destination; } else { - status.overflow_flag = (destination ^ (destination << shift)) & top_bit(); + // For a shift of n places, overflow will be set if the top n bits were not + // all the same value. + const auto affected_bits = IntT(~0 << shift); + status.overflow_flag = (destination & affected_bits) && (destination & affected_bits) != affected_bits; } } @@ -382,7 +388,7 @@ template void shif } else { status.carry_flag = status.extend_flag = (destination >> (shift - 1)) & 1; } - status.overflow_flag = 0; + status.overflow_flag = 0; // The top bit can't change during an ASR, and LSR always clears overflow. const IntT sign_word = type == Type::LSR ?