Subject: port-i386/11914: div(3) and ldiv(3) are broken on i386
To: None <gnats-bugs@gnats.netbsd.org>
From: None <lukem@wasabisystems.com>
List: netbsd-bugs
Date: 01/07/2001 19:49:20
>Number: 11914
>Category: port-i386
>Synopsis: div(3) and ldiv(3) return incorrect results on i386
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: port-i386-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jan 07 19:49:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator: Luke Mewburn
>Release: 1.5 (and -current)
>Organization:
Luke Mewburn <lukem@wasabisystems.com> http://www.wasabisystems.com
Luke Mewburn <lukem@netbsd.org> http://www.netbsd.org
Wasabi Systems - providing NetBSD sales, support and service.
>Environment:
System: NetBSD argo.akimbo.com.au 1.5_BETA2 NetBSD 1.5_BETA2 (ARGO) #0: Thu Nov 16 19:55:34 EST 2000 lukem@argo.akimbo.com.au:/z/src/netbsd-1-5/src/sys/arch/i386/compile/ARGO i386
>Description:
ldiv(3) doesn't return the correct results. from observation, i'd
say it's just returning garbage back on the stack. a quick test
shows div(3) is borken too.
it's just the assembly versions in libc/arch/i386/stdlibc/*div.S
which seem to be at fault.
i noticed this whilst debugging why the `adnshost' program in
the `adns-1.0' asynchronous dns package wasn't working.
>How-To-Repeat:
try and use ldiv or div. notice they're knackered.
i've attached a small test program.
======
#include <stdio.h>
#include <stdlib.h>
#ifdef USE_LDIV
#define FUNC ldiv
#define IN_T long
#define RET_T ldiv_t
#define FMT_T "%ld"
#else
#define FUNC div
#define IN_T int
#define RET_T div_t
#define FMT_T "%d"
#endif
int
main(int argc, char *argv[])
{
IN_T val;
RET_T dr;
val = 1999236;
dr = FUNC(val, 1000000);
printf("in " FMT_T ", result: quotient " FMT_T " remainder " FMT_T "\n",
val, dr.quot, dr.rem);
return (0);
}
=====
the following will product wrong results for div & ldiv:
% gcc test.c
% ./a.out
in 1999236, result: quotient 134514686 remainder 134519216
% gcc -DUSE_LDIV test.c
% ./a.out
in 1999236, result: quotient 134514686 remainder 134519216
compare against using the C versions:
% gcc test.c /usr/src/lib/libc/stdlib/div.c
% ./a.out
in 1999236, result: quotient 1 remainder 999236
% gcc -DUSE_LDIV test.c /usr/src/lib/libc/stdlib/ldiv.c
% ./a.out
in 1999236, result: quotient 1 remainder 999236
>Fix:
don't use the assembly versions; div & ldiv aren't that
commonly used that the effort of fixing and maintaining the
assembly versions is worth the effort (IMHO).
if we decide that not supporting the assembly versions is TRT,
then we could probably remove support from
libc/arch/*/stdlib/Makefile.inc for building div.o and ldiv.o
and move it back to libc/stdlib/Makefile.inc, since the i386
is the only port that provides assembly versions of these
anyway.
i'm happy to commit a fix to ditch the assembly stuff in
favour of the C versions.
>Release-Note:
>Audit-Trail:
>Unformatted: