qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Zack Buhman" <zack@buhman.org>,
	"Yoshinori Sato" <ysato@users.sourceforge.jp>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: [PULL 13/35] target/sh4: Fix mac.w with saturation enabled
Date: Mon,  8 Apr 2024 07:49:07 -1000	[thread overview]
Message-ID: <20240408174929.862917-14-richard.henderson@linaro.org> (raw)
In-Reply-To: <20240408174929.862917-1-richard.henderson@linaro.org>

From: Zack Buhman <zack@buhman.org>

The saturation arithmetic logic in helper_macw is not correct.
I tested and verified this behavior on a SH7091.

Reviewd-by: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Zack Buhman <zack@buhman.org>
Message-Id: <20240405233802.29128-3-zack@buhman.org>
[rth: Reformat helper_macw, add a test case.]
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/sh4/helper.h           |  2 +-
 target/sh4/op_helper.c        | 28 +++++++++-------
 tests/tcg/sh4/test-macw.c     | 61 +++++++++++++++++++++++++++++++++++
 tests/tcg/sh4/Makefile.target |  3 ++
 4 files changed, 82 insertions(+), 12 deletions(-)
 create mode 100644 tests/tcg/sh4/test-macw.c

diff --git a/target/sh4/helper.h b/target/sh4/helper.h
index 64056e4a39..29011d3dbb 100644
--- a/target/sh4/helper.h
+++ b/target/sh4/helper.h
@@ -12,7 +12,7 @@ DEF_HELPER_1(discard_movcal_backup, void, env)
 DEF_HELPER_2(ocbi, void, env, i32)
 
 DEF_HELPER_3(macl, void, env, s32, s32)
-DEF_HELPER_3(macw, void, env, i32, i32)
+DEF_HELPER_3(macw, void, env, s32, s32)
 
 DEF_HELPER_2(ld_fpscr, void, env, i32)
 
diff --git a/target/sh4/op_helper.c b/target/sh4/op_helper.c
index d0bae0cc00..99394b714c 100644
--- a/target/sh4/op_helper.c
+++ b/target/sh4/op_helper.c
@@ -177,22 +177,28 @@ void helper_macl(CPUSH4State *env, int32_t arg0, int32_t arg1)
     env->mac = res;
 }
 
-void helper_macw(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
+void helper_macw(CPUSH4State *env, int32_t arg0, int32_t arg1)
 {
-    int64_t res;
+    /* Inputs are already sign-extended from 16 bits. */
+    int32_t mul = arg0 * arg1;
 
-    res = ((uint64_t) env->mach << 32) | env->macl;
-    res += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1;
-    env->mach = (res >> 32) & 0xffffffff;
-    env->macl = res & 0xffffffff;
     if (env->sr & (1u << SR_S)) {
-        if (res < -0x80000000) {
+        /*
+         * In saturation arithmetic mode, the accumulator is 32-bit
+         * with carry. MACH is not considered during the addition
+         * operation nor the 32-bit saturation logic.
+         */
+        int32_t res, macl = env->macl;
+
+        if (sadd32_overflow(macl, mul, &res)) {
+            res = macl < 0 ? INT32_MIN : INT32_MAX;
+            /* If overflow occurs, the MACH register is set to 1. */
             env->mach = 1;
-            env->macl = 0x80000000;
-        } else if (res > 0x000000007fffffff) {
-            env->mach = 1;
-            env->macl = 0x7fffffff;
         }
+        env->macl = res;
+    } else {
+        /* In non-saturation arithmetic mode, the accumulator is 64-bit */
+        env->mac += mul;
     }
 }
 
diff --git a/tests/tcg/sh4/test-macw.c b/tests/tcg/sh4/test-macw.c
new file mode 100644
index 0000000000..4eceec8634
--- /dev/null
+++ b/tests/tcg/sh4/test-macw.c
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int64_t mac_w(int64_t mac, const int16_t *a, const int16_t *b)
+{
+    register uint32_t macl __asm__("macl") = mac;
+    register uint32_t mach __asm__("mach") = mac >> 32;
+
+    asm volatile("mac.w @%0+,@%1+"
+                 : "+r"(a), "+r"(b), "+x"(macl), "+x"(mach));
+
+    return ((uint64_t)mach << 32) | macl;
+}
+
+typedef struct {
+    int64_t mac;
+    int16_t a, b;
+    int64_t res[2];
+} Test;
+
+__attribute__((noinline))
+void test(const Test *t, int sat)
+{
+    int64_t res;
+
+    if (sat) {
+        asm volatile("sets");
+    } else {
+        asm volatile("clrs");
+    }
+    res = mac_w(t->mac, &t->a, &t->b);
+
+    if (res != t->res[sat]) {
+        fprintf(stderr, "%#llx + (%#x * %#x) = %#llx -- got %#llx\n",
+                t->mac, t->a, t->b, t->res[sat], res);
+        abort();
+    }
+}
+
+int main()
+{
+    static const Test tests[] = {
+        { 0, 2, 3, { 6, 6 } },
+        { 0x123456787ffffffell, 2, -3,
+          { 0x123456787ffffff8ll, 0x123456787ffffff8ll } },
+        { 0xabcdef127ffffffall, 2, 3,
+          { 0xabcdef1280000000ll, 0x000000017fffffffll } },
+        { 0xfffffffffll, INT16_MAX, INT16_MAX,
+          { 0x103fff0000ll, 0xf3fff0000ll } },
+    };
+
+    for (int i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) {
+        for (int j = 0; j < 2; ++j) {
+            test(&tests[i], j);
+        }
+    }
+    return 0;
+}
diff --git a/tests/tcg/sh4/Makefile.target b/tests/tcg/sh4/Makefile.target
index 9a11c10924..4d09291c0c 100644
--- a/tests/tcg/sh4/Makefile.target
+++ b/tests/tcg/sh4/Makefile.target
@@ -14,3 +14,6 @@ VPATH += $(SRC_PATH)/tests/tcg/sh4
 
 test-macl: CFLAGS += -O -g
 TESTS += test-macl
+
+test-macw: CFLAGS += -O -g
+TESTS += test-macw
-- 
2.34.1



  parent reply	other threads:[~2024-04-08 17:56 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-08 17:48 [PULL 00/35] misc patch queue Richard Henderson
2024-04-08 17:48 ` [PULL 01/35] tcg/optimize: Do not attempt to constant fold neg_vec Richard Henderson
2024-04-08 17:48 ` [PULL 02/35] linux-user: Fix waitid return of siginfo_t and rusage Richard Henderson
2024-04-08 17:48 ` [PULL 03/35] linux-user: do_setsockopt: fix SOL_ALG.ALG_SET_KEY Richard Henderson
2024-04-08 17:48 ` [PULL 04/35] linux-user: do_setsockopt: make ip_mreq local to the place it is used and inline target_to_host_ip_mreq() Richard Henderson
2024-04-08 17:48 ` [PULL 05/35] linux-user: do_setsockopt: make ip_mreq_source local to the place where it is used Richard Henderson
2024-04-08 17:49 ` [PULL 06/35] linux-user: do_setsockopt: eliminate goto in switch for SO_SNDTIMEO Richard Henderson
2024-04-08 17:49 ` [PULL 07/35] linux-user: Add FITRIM ioctl Richard Henderson
2024-04-08 17:49 ` [PULL 08/35] linux-user: replace calloc() with g_new0() Richard Henderson
2024-04-08 17:49 ` [PULL 09/35] target/hppa: Fix IIAOQ, IIASQ for pa2.0 Richard Henderson
2024-04-08 17:49 ` [PULL 10/35] target/sh4: mac.w: memory accesses are 16-bit words Richard Henderson
2024-04-08 17:49 ` [PULL 11/35] target/sh4: Merge mach and macl into a union Richard Henderson
2024-04-08 17:49 ` [PULL 12/35] target/sh4: Fix mac.l with saturation enabled Richard Henderson
2024-04-08 17:49 ` Richard Henderson [this message]
2024-04-08 17:49 ` [PULL 14/35] target/sh4: add missing CHECK_NOT_DELAY_SLOT Richard Henderson
2024-04-08 17:49 ` [PULL 15/35] target/m68k: Map FPU exceptions to FPSR register Richard Henderson
2024-04-08 17:49 ` [PULL 16/35] target/m68k: Pass semihosting arg to exit Richard Henderson
2024-04-08 17:49 ` [PULL 17/35] target/m68k: Perform the semihosting test during translate Richard Henderson
2024-04-08 17:49 ` [PULL 18/35] target/m68k: Support semihosting on non-ColdFire targets Richard Henderson
2024-04-08 17:49 ` [PULL 19/35] tcg: Add TCGContext.emit_before_op Richard Henderson
2024-04-08 17:49 ` [PULL 20/35] accel/tcg: Add insn_start to DisasContextBase Richard Henderson
2024-04-08 17:49 ` [PULL 21/35] target/arm: Use insn_start from DisasContextBase Richard Henderson
2024-04-08 17:49 ` [PULL 22/35] target/hppa: " Richard Henderson
2024-04-08 17:49 ` [PULL 23/35] target/i386: Preserve DisasContextBase.insn_start across rewind Richard Henderson
2024-04-08 17:49 ` [PULL 24/35] target/microblaze: Use insn_start from DisasContextBase Richard Henderson
2024-04-08 17:49 ` [PULL 25/35] target/riscv: " Richard Henderson
2024-04-08 17:49 ` [PULL 26/35] target/s390x: " Richard Henderson
2024-04-08 17:49 ` [PULL 27/35] accel/tcg: Improve can_do_io management Richard Henderson
2024-04-08 17:49 ` [PULL 28/35] util/bufferiszero: Remove SSE4.1 variant Richard Henderson
2024-04-08 17:49 ` [PULL 29/35] util/bufferiszero: Remove AVX512 variant Richard Henderson
2024-04-08 17:49 ` [PULL 30/35] util/bufferiszero: Reorganize for early test for acceleration Richard Henderson
2024-04-08 17:49 ` [PULL 31/35] util/bufferiszero: Remove useless prefetches Richard Henderson
2024-04-08 17:49 ` [PULL 32/35] util/bufferiszero: Optimize SSE2 and AVX2 variants Richard Henderson
2024-04-08 17:49 ` [PULL 33/35] util/bufferiszero: Improve scalar variant Richard Henderson
2024-04-08 17:49 ` [PULL 34/35] util/bufferiszero: Introduce biz_accel_fn typedef Richard Henderson
2024-04-08 17:49 ` [PULL 35/35] util/bufferiszero: Simplify test_buffer_is_zero_next_accel Richard Henderson
2024-04-09  8:50 ` [PULL 00/35] misc patch queue Peter Maydell
2024-04-09  9:53   ` Philippe Mathieu-Daudé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240408174929.862917-14-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=ysato@users.sourceforge.jp \
    --cc=zack@buhman.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).