diff mbox

[for-2.5,13/30] m68k: set Z and N on divu/muls overflow as a real 68040

Message ID 1439151229-27747-14-git-send-email-laurent@vivier.eu
State New
Headers show

Commit Message

Laurent Vivier Aug. 9, 2015, 8:13 p.m. UTC
This allows to compare simulation results with a real 68040.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 target-m68k/op_helper.c | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

Comments

Richard Henderson Aug. 12, 2015, 6:29 a.m. UTC | #1
On 08/09/2015 01:13 PM, Laurent Vivier wrote:
> This allows to compare simulation results with a real 68040.
>
> Signed-off-by: Laurent Vivier<laurent@vivier.eu>
> ---
>   target-m68k/op_helper.c | 38 ++++++++++++++++++++++++++------------
>   1 file changed, 26 insertions(+), 12 deletions(-)

A good incentive, yes, but...  hmm.  Certainly another incentive to split 
helpers, rather than pass in "word".

I don't have a way to review this though, so the best I can do is

Acked-by: Richard Henderson <rth@twiddle.net>


r~
diff mbox

Patch

diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index 1af0ca6..71641bf 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -193,12 +193,19 @@  void HELPER(divu)(CPUM68KState *env, uint32_t word)
     quot = num / den;
     rem = num % den;
     flags = 0;
-    if (word && quot > 0xffff)
-        flags |= CCF_V;
-    if (quot == 0)
-        flags |= CCF_Z;
-    else if ((int32_t)quot < 0)
-        flags |= CCF_N;
+    if (word && quot > 0xffff) {
+        /* real 68040 keep Z and N on overflow,
+         * whereas documentation says "undefined"
+         */
+        flags |= CCF_V | (env->cc_dest & (CCF_Z|CCF_N));
+    } else {
+        if (quot == 0) {
+            flags |= CCF_Z;
+        } else if ((int16_t)quot < 0) {
+            flags |= CCF_N;
+        }
+    }
+
     env->div1 = quot;
     env->div2 = rem;
     env->cc_dest = flags;
@@ -220,12 +227,19 @@  void HELPER(divs)(CPUM68KState *env, uint32_t word)
     quot = num / den;
     rem = num % den;
     flags = 0;
-    if (word && quot != (int16_t)quot)
-        flags |= CCF_V;
-    if (quot == 0)
-        flags |= CCF_Z;
-    else if (quot < 0)
-        flags |= CCF_N;
+    if (word && quot != (int16_t)quot) {
+        /* real 68040 keep Z and N on overflow,
+         * whereas documentation says "undefined"
+         */
+        flags |= CCF_V | (env->cc_dest & (CCF_Z|CCF_N));
+    } else {
+        if (quot == 0) {
+            flags |= CCF_Z;
+        } else if ((int16_t)quot < 0) {
+            flags |= CCF_N;
+        }
+    }
+
     env->div1 = quot;
     env->div2 = rem;
     env->cc_dest = flags;