Subject: port-sun3/2811: [dM] code-generation bug
To: None <port-m68k@NetBSD.ORG>
From: Gordon W. Ross <gwr@mc.com>
List: port-m68k
Date: 10/07/1996 10:58:41
[  This would appear to affect all m68k ports.  Ideas? -gwr ]

>Number:         2811
>Category:       port-sun3
>Synopsis:       [dM] code-generation bug
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Oct  6 17:05:00 1996
>Last-Modified:
>Originator:     der Mouse
>Organization:
	Dis-
>Release:        1.2_BETA, sup of Jul 3
>Environment:
	Seen on Sun-3/260, likely exists on any sun3, possibly other
	68k ports suffer from it.
System: NetBSD Twig.Rodents.Montreal.QC.CA 1.2_BETA NetBSD 1.2_BETA (TWIG) #0: Tue Sep 3 00:45:26 EDT 1996 mouse@Twig.Rodents.Montreal.QC.CA:/mouse/sources/working-usr-src/sys/arch/sun3/compile/TWIG sun3
>Description:
	There's a bug somewhere in the compiler's code generation.

	I do not (yet) know whether this appears in the underlying gcc
	distribution or was introduced by the NetBSD adaptation.  (The
	former seems likelier to me.)

	A loop reading
		for (; i >= 0; i--)
		  {
		    n0 = num_ptr[i];
		    __asm__ ("divu%.l %4,%1:%0"
			: "=d" ((unsigned long int)( quot_ptr[i] )),
			  "=d" ((unsigned long int)(  n1 ))
			: "0" ((unsigned long int)(  n0 )),
			  "1" ((unsigned long int)(  n1 )),
			  "dmi" ((unsigned long int)(  d ))	);
		  }
	gets miscompiled; in particular, in the resulting assembly (no
	optimization), in the fragment
			movel a6@(-12),d3
		#APP
			divul a6@(-20),d3:d2
		#NO_APP
			movel d3,d0		<<< line A
			movel d2,a0@(d0:l)	<<< line B
			movel d0,d1
			movel d1,a6@(-12)
	the lines marked "line A" and "line B" should be interchanged.
	Before the __asm__-generated instruction, d0 is correctly
	loaded with the addressing offset for the subscript store, but
	the compiler spazz causes it to try to use the remainder from
	the division as the subscript offset.  This usually segfaults;
	if the remainder is small, it may simply store into a randomly
	wrong memory location.

	Full input (and output, in case this is in some
	incomprehensible way the fault of something on this particular
	system) files are given below.  This is a stripped-down version
	of something seen while trying to install ssh 1.2.14 on
	NetBSD/sun3; it was crashing in mpn_div.  The .i file given
	here is a test case obtained by gutting cc -E output from
	mpn_div.c.

[ remainder deleted - see the PR ]