Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [SH] Fix mac.w insn simulation for SH2 and above
@ 2026-08-02 13:53 Oleg Endo
  2026-08-24 11:03 ` Ping^1 " Oleg Endo
  2026-08-24 12:09 ` Andrew Burgess
  0 siblings, 2 replies; 4+ messages in thread
From: Oleg Endo @ 2026-08-02 13:53 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 687 bytes --]

Hi,

The simulator currently implements only the SH1 version of the mac.w
instruction.  On SH1 the MACH:MACL accumulator register is only 42-bit.  It
was extended to 64-bit on SH2 and every variant that followed after.

The issue probably never showed up because GCC hasn't been able to emit the
SH integer mac instructions.  I ran into this because I was trying to do
exactly that and while running some tests on sh-sim.

The attached patch uses the bfd_mach field to distinguish between SH1 and
not-SH1 in the simulation of the mac.w instruction, in a similar way as it's
already been done for some SH2A instructions.


OK to commit & push?

Best regards,
Oleg Endo

[-- Attachment #2: 0001-simsh-fix-macw-insn-for-SH2.patch --]
[-- Type: text/x-patch, Size: 1195 bytes --]

From 6b07e3daa73acac1d1800c94cdfae0b83509f2d1 Mon Sep 17 00:00:00 2001
From: Oleg Endo <olegendo@gcc.gnu.org>
Date: Sun, 2 Aug 2026 19:37:21 +0900
Subject: [PATCH] sim/sh: fix mac.w insn for SH2+

On SH1 the MACH:MACL accumulator is only 42 bits wide.  On SH2 and above it's 64
bits wide.  Emulate the corresponding behavior based on the bfd_mach field.
---
 sim/sh/interp.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/sim/sh/interp.c b/sim/sh/interp.c
index c8c2a74..cc4ae2c 100644
--- a/sim/sh/interp.c
+++ b/sim/sh/interp.c
@@ -1197,8 +1197,11 @@ macw (int *regs, unsigned char *memory, int n, int m, int endianw)
       long mach;
       /* Add to MACH the sign extended product, and carry from low sum.  */
       mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
-      /* Sign extend at 10:th bit in MACH.  */
-      MACH = (mach & 0x1ff) | -(mach & 0x200);
+      /* SH1:  MACH:MACL is 42 bits wide, sign extend at the 10:th bit in MACH.
+         SH2+: MACH:MACL is 64 bits wide.  */
+      if (saved_state.asregs.bfd_mach == bfd_mach_sh)
+	mach = (mach & 0x1ff) | -(mach & 0x200);
+      MACH = mach;
     }
   MACL = sum;
 }
--
libgit2 1.9.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Ping^1  Re: [SH] Fix mac.w insn simulation for SH2 and above
  2026-08-02 13:53 [SH] Fix mac.w insn simulation for SH2 and above Oleg Endo
@ 2026-08-24 11:03 ` Oleg Endo
  2026-08-24 12:09 ` Andrew Burgess
  1 sibling, 0 replies; 4+ messages in thread
From: Oleg Endo @ 2026-08-24 11:03 UTC (permalink / raw)
  To: gdb-patches

Ping

On Sun, 2026-08-02 at 22:53 +0900, Oleg Endo wrote:
> Hi,
> 
> The simulator currently implements only the SH1 version of the mac.w
> instruction.  On SH1 the MACH:MACL accumulator register is only 42-bit.  It
> was extended to 64-bit on SH2 and every variant that followed after.
> 
> The issue probably never showed up because GCC hasn't been able to emit the
> SH integer mac instructions.  I ran into this because I was trying to do
> exactly that and while running some tests on sh-sim.
> 
> The attached patch uses the bfd_mach field to distinguish between SH1 and
> not-SH1 in the simulation of the mac.w instruction, in a similar way as it's
> already been done for some SH2A instructions.
> 
> 
> OK to commit & push?
> 
> Best regards,
> Oleg Endo

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [SH] Fix mac.w insn simulation for SH2 and above
  2026-08-02 13:53 [SH] Fix mac.w insn simulation for SH2 and above Oleg Endo
  2026-08-24 11:03 ` Ping^1 " Oleg Endo
@ 2026-08-24 12:09 ` Andrew Burgess
  2026-08-25  0:55   ` Oleg Endo
  1 sibling, 1 reply; 4+ messages in thread
From: Andrew Burgess @ 2026-08-24 12:09 UTC (permalink / raw)
  To: Oleg Endo, gdb-patches

Oleg Endo <olegendo1024@gmail.com> writes:

> Hi,
>
> The simulator currently implements only the SH1 version of the mac.w
> instruction.  On SH1 the MACH:MACL accumulator register is only 42-bit.  It
> was extended to 64-bit on SH2 and every variant that followed after.
>
> The issue probably never showed up because GCC hasn't been able to emit the
> SH integer mac instructions.  I ran into this because I was trying to do
> exactly that and while running some tests on sh-sim.
>
> The attached patch uses the bfd_mach field to distinguish between SH1 and
> not-SH1 in the simulation of the mac.w instruction, in a similar way as it's
> already been done for some SH2A instructions.
>
>
> OK to commit & push?
>
> Best regards,
> Oleg Endo
> From 6b07e3daa73acac1d1800c94cdfae0b83509f2d1 Mon Sep 17 00:00:00 2001
> From: Oleg Endo <olegendo@gcc.gnu.org>
> Date: Sun, 2 Aug 2026 19:37:21 +0900
> Subject: [PATCH] sim/sh: fix mac.w insn for SH2+
>
> On SH1 the MACH:MACL accumulator is only 42 bits wide.  On SH2 and above it's 64
> bits wide.  Emulate the corresponding behavior based on the bfd_mach field.
> ---
>  sim/sh/interp.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/sim/sh/interp.c b/sim/sh/interp.c
> index c8c2a74..cc4ae2c 100644
> --- a/sim/sh/interp.c
> +++ b/sim/sh/interp.c
> @@ -1197,8 +1197,11 @@ macw (int *regs, unsigned char *memory, int n, int m, int endianw)
>        long mach;
>        /* Add to MACH the sign extended product, and carry from low sum.  */
>        mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
> -      /* Sign extend at 10:th bit in MACH.  */
> -      MACH = (mach & 0x1ff) | -(mach & 0x200);
> +      /* SH1:  MACH:MACL is 42 bits wide, sign extend at the 10:th bit in MACH.

Could you fix '10:th' to '10th' please.

> +         SH2+: MACH:MACL is 64 bits wide.  */

This line should be indented with TAB.

> +      if (saved_state.asregs.bfd_mach == bfd_mach_sh)
> +	mach = (mach & 0x1ff) | -(mach & 0x200);
> +      MACH = mach;
>      }

Is it possible to write a test for this change?  I know simulator
testing is very patchy, but if we add tests for things that are fixed
we'll slowly start to build up some decent test coverage.

Thanks,
Andrew


>    MACL = sum;
>  }
> --
> libgit2 1.9.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [SH] Fix mac.w insn simulation for SH2 and above
  2026-08-24 12:09 ` Andrew Burgess
@ 2026-08-25  0:55   ` Oleg Endo
  0 siblings, 0 replies; 4+ messages in thread
From: Oleg Endo @ 2026-08-25  0:55 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 2754 bytes --]


On Mon, 2026-08-24 at 13:09 +0100, Andrew Burgess wrote:
> Oleg Endo <olegendo1024@gmail.com> writes:
> 
> > Hi,
> > 
> > The simulator currently implements only the SH1 version of the mac.w
> > instruction.  On SH1 the MACH:MACL accumulator register is only 42-bit.  It
> > was extended to 64-bit on SH2 and every variant that followed after.
> > 
> > The issue probably never showed up because GCC hasn't been able to emit the
> > SH integer mac instructions.  I ran into this because I was trying to do
> > exactly that and while running some tests on sh-sim.
> > 
> > The attached patch uses the bfd_mach field to distinguish between SH1 and
> > not-SH1 in the simulation of the mac.w instruction, in a similar way as it's
> > already been done for some SH2A instructions.
> > 
> > 
> > OK to commit & push?
> > 
> > Best regards,
> > Oleg Endo
> > From 6b07e3daa73acac1d1800c94cdfae0b83509f2d1 Mon Sep 17 00:00:00 2001
> > From: Oleg Endo <olegendo@gcc.gnu.org>
> > Date: Sun, 2 Aug 2026 19:37:21 +0900
> > Subject: [PATCH] sim/sh: fix mac.w insn for SH2+
> > 
> > On SH1 the MACH:MACL accumulator is only 42 bits wide.  On SH2 and above it's 64
> > bits wide.  Emulate the corresponding behavior based on the bfd_mach field.
> > ---
> >  sim/sh/interp.c | 7 +++++--
> >  1 file changed, 5 insertions(+), 2 deletions(-)
> > 
> > diff --git a/sim/sh/interp.c b/sim/sh/interp.c
> > index c8c2a74..cc4ae2c 100644
> > --- a/sim/sh/interp.c
> > +++ b/sim/sh/interp.c
> > @@ -1197,8 +1197,11 @@ macw (int *regs, unsigned char *memory, int n, int m, int endianw)
> >        long mach;
> >        /* Add to MACH the sign extended product, and carry from low sum.  */
> >        mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
> > -      /* Sign extend at 10:th bit in MACH.  */
> > -      MACH = (mach & 0x1ff) | -(mach & 0x200);
> > +      /* SH1:  MACH:MACL is 42 bits wide, sign extend at the 10:th bit in MACH.
> 
> Could you fix '10:th' to '10th' please.
> 
> > +         SH2+: MACH:MACL is 64 bits wide.  */
> 
> This line should be indented with TAB.
> 
> > +      if (saved_state.asregs.bfd_mach == bfd_mach_sh)
> > +	mach = (mach & 0x1ff) | -(mach & 0x200);
> > +      MACH = mach;
> >      }
> 
> Is it possible to write a test for this change?  I know simulator
> testing is very patchy, but if we add tests for things that are fixed
> we'll slowly start to build up some decent test coverage.
> 

Added test case and adjusted the other hunks.
Updated patch attached.

One of my previous sh-sim changes caused a fallout.  I've posted a separate
patch for that, awaiting feedback.
https://marc.info/?l=gdb-patches&m=178567807485933&w=2

Best regards,
Oleg Endo


[-- Attachment #2: 0001-simsh-fix-macw-insn-for-SH2_1.patch --]
[-- Type: text/x-patch, Size: 3407 bytes --]

From af1b5bf366406270696dddd399f32ae7e48f15a6 Mon Sep 17 00:00:00 2001
From: Oleg Endo <olegendo@gcc.gnu.org>
Date: Sun, 2 Aug 2026 19:37:21 +0900
Subject: [PATCH] sim/sh: fix mac.w insn for SH2+

On SH1 the MACH:MACL accumulator is only 42 bits wide.  On SH2 and above it's 64
bits wide.  Emulate the corresponding behavior based on the bfd_mach field.
---
 sim/sh/interp.c             |  7 +++++--
 sim/testsuite/sh/macw-sh1.s | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 sim/testsuite/sh/macw.s     | 21 +++++++++++++++++++++
 3 files changed, 72 insertions(+), 2 deletions(-)
 create mode 100644 sim/testsuite/sh/macw-sh1.s

diff --git a/sim/sh/interp.c b/sim/sh/interp.c
index c8c2a74..33f825b 100644
--- a/sim/sh/interp.c
+++ b/sim/sh/interp.c
@@ -1197,8 +1197,11 @@ macw (int *regs, unsigned char *memory, int n, int m, int endianw)
       long mach;
       /* Add to MACH the sign extended product, and carry from low sum.  */
       mach = MACH + (-(prod < 0)) + ((unsigned long) sum < prod);
-      /* Sign extend at 10:th bit in MACH.  */
-      MACH = (mach & 0x1ff) | -(mach & 0x200);
+      /* SH1:  MACH:MACL is 42 bits wide, sign extend at the 10th bit in MACH.
+	 SH2+: MACH:MACL is 64 bits wide.  */
+      if (saved_state.asregs.bfd_mach == bfd_mach_sh)
+	mach = (mach & 0x1ff) | -(mach & 0x200);
+      MACH = mach;
     }
   MACL = sum;
 }
diff --git a/sim/testsuite/sh/macw-sh1.s b/sim/testsuite/sh/macw-sh1.s
new file mode 100644
index 0000000..bb073d5
--- /dev/null
+++ b/sim/testsuite/sh/macw-sh1.s
@@ -0,0 +1,46 @@
+# sh testcase SH1 mac.w
+# mach: sh
+# as(sh):	--isa=sh -defsym sim_cpu=1
+
+# --isa=sh marks the resulting object as bfd_mach_sh, i.e. SH1.
+# When executing an SH1 object the simulator should implement the SH1 behavior
+# of the narrow 42-bit accumulator.
+# sim_cpu=1 prevents testutils.inc from emitting the floating point helpers,
+# which SH1 does not have.
+
+	.include "testutils.inc"
+
+	start
+	set_grs_a5a5
+
+	# On SH1 MACH:MACL is only 42 bits wide.  MACH keeps its low 10 bits
+	# and bit 9 is the sign bit of the accumulator.
+
+	# Bits above bit 9 are dropped.
+	set_sreg	0, macl
+	set_sreg	0x456, mach
+	mova		coeff0,r0
+	mac.w		@r0+, @r0+
+	assert_sreg	0x56, mach
+	assert_sreg	6, macl
+
+	# Bit 9 is sign extended into the upper bits.
+	set_sreg	0, macl
+	set_sreg	0x200, mach
+	mova		coeff0,r0
+	mac.w		@r0+, @r0+
+	assert_sreg	0xfffffe00, mach
+	assert_sreg	6, macl
+
+	set_greg	0xa5a5a5a5, r0
+	set_greg	0xa5a5a5a5, r1
+
+	test_grs_a5a5
+
+	pass
+	exit 0
+
+	.align 2
+coeff0:
+	.word	2
+	.word	3
diff --git a/sim/testsuite/sh/macw.s b/sim/testsuite/sh/macw.s
index 7e3ebc0..b2424d8 100644
--- a/sim/testsuite/sh/macw.s
+++ b/sim/testsuite/sh/macw.s
@@ -33,6 +33,24 @@ doubleinc:
 	mac.w	@r0+, @r0+
 	assertreg0 four00+4
 
+acc64:
+	# On SH2+ MACH:MACL is 64 bits wide.  Check that MACH bits > 9
+	# are kept.  For SH1 case see macw-sh1.s.
+	set_sreg	0, macl
+	set_sreg	0x456, mach
+	mova		coeff0,r0
+	mac.w		@r0+, @r0+
+	assert_sreg	0x456, mach
+	assert_sreg	6, macl
+
+	# Bit 9 of MACH is an ordinary data bit here, not a sign bit.
+	set_sreg	0, macl
+	set_sreg	0x200, mach
+	mova		coeff0,r0
+	mac.w		@r0+, @r0+
+	assert_sreg	0x200, mach
+	assert_sreg	6, macl
+
 	set_greg	0xa5a5a5a5, r0
 	set_greg	0xa5a5a5a5, r1
 
@@ -48,6 +66,9 @@ four00:
 four12:
 	.word	17
 	.word	3
+coeff0:
+	.word	2
+	.word	3
 
 
 pfour00:
--
libgit2 1.9.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-08-25  0:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-02 13:53 [SH] Fix mac.w insn simulation for SH2 and above Oleg Endo
2026-08-24 11:03 ` Ping^1 " Oleg Endo
2026-08-24 12:09 ` Andrew Burgess
2026-08-25  0:55   ` Oleg Endo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox