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
next prev 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).