Subject: port-sparc/958: int remainder op (.rem) broken for negative divisors; fix included
To: None <gnats-admin@NetBSD.ORG>
From: Lon Willett <willett@math.utah.edu>
List: netbsd-bugs
Date: 04/11/1995 09:05:04
>Number:         958
>Category:       port-sparc
>Synopsis:       int remainder op (.rem) broken for negative divisors; fix included
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Apr 11 09:05:01 1995
>Originator:     Lon Willett
>Organization:
none
>Release:        7 Apr 95
>Environment:

System: NetBSD holly 1.0A NetBSD 1.0A (HOLLY) #6: Sun Apr 9 16:20:31 MDT 1995 lon@holly:/usr/src/sys/arch/sparc/compile/HOLLY sparc

>Description:

The (signed) integer remainder function, ".rem", returns the negative of
the result that it should when the divisor is negative.  e.g. it computes

	 2 % -3	--> -2	(should be 2)
	 1 % -3	--> -1	(should be 1)
	-1 % -3	-->  1	(should be -1)
	-2 % -3	-->  2	(should be -2)

>How-To-Repeat:

	Try any code that uses integer remainder with a negative divisor,
	e.g.

		printf ("%d\n", atoi("1") % atoi("-3"));

	will print "-1", not "1".

>Fix:

Here's my patch ("diff -u" format):

--- src/lib/libc/arch/sparc/gen/divrem.m4.orig	Mon Mar 20 00:20:54 1995
+++ src/lib/libc/arch/sparc/gen/divrem.m4	Mon Apr 10 21:11:09 1995
@@ -110,7 +110,9 @@
 `	! compute sign of result; if neither is negative, no problem
 	orcc	divisor, dividend, %g0	! either negative?
 	bge	2f			! no, go do the divide
-	xor	divisor, dividend, SIGN	! compute sign in any case
+	ifelse(OP, `div',
+		`xor	divisor, dividend, SIGN',
+		`mov	dividend, SIGN')	! compute sign in any case
 	tst	divisor
 	bge	1f
 	tst	dividend
--- src/sys/lib/libkern/arch/sparc/divrem.m4.orig	Mon Nov 21 15:46:48 1994
+++ src/sys/lib/libkern/arch/sparc/divrem.m4	Mon Apr 10 22:37:11 1995
@@ -114,7 +114,9 @@
 `	! compute sign of result; if neither is negative, no problem
 	orcc	divisor, dividend, %g0	! either negative?
 	bge	2f			! no, go do the divide
-	xor	divisor, dividend, SIGN	! compute sign in any case
+	ifelse(OP, `div',
+		`xor	divisor, dividend, SIGN',
+		`mov	dividend, SIGN')	! compute sign in any case
 	tst	divisor
 	bge	1f
 	tst	dividend
------------------------------------------------------------------------
>Audit-Trail:
>Unformatted: