*BSD News Article 14734


Return to BSD News archive

Newsgroups: comp.os.386bsd.bugs
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!pacbell.com!amdahl!netcomsv!netcom.com!abe
From: abe@netcom.com (David Abercrombie)
Subject: Casts to int rounding bug fix
Message-ID: <abeC5rIqp.2Bn@netcom.com>
Keywords: int, cast, gcc, fix
Organization: NETCOM On-line Communication Services (408 241-9760 guest)
Date: Tue, 20 Apr 1993 03:23:13 GMT
Lines: 212

I have included the following:
	1) Description of the bug,
        2) A fix by steve@robobar.co.uk (Steve Bleazard), 
        3) Brief installation instructions
        4) Description of my system configuration, and
        5) A test program.

1) Bug description =============================================

Programs compiled on 386bsd using the stock gcc 1.39 do not cast
doubles to ints correctly.  K&R says: "When the value of a
floating type is converted to integral type, the fractional part
is discarded...".  However, under 386bsd, doubles get ROUNDED to
the nearest int during a cast (instead of getting truncated).
This did not seem to occur under gcc 2.3.3 (on ref.tfs.com).

2) Fix by steve@robobar.co.uk (Steve Bleazard) ==================

"...the bug appears to be in the __fix{uns}dfsi routines that
convert from double to long.  The 386 versions of these routines
do not appear to set the rounding mode.  [...] gcc 2.3.3 appears to
have it's own C version of these routines...."

------------------------------ Cut Here -------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line, and after the 
#    "Cut Here" line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	fixdfsi.S
#	fixunsdfsi.S
# This archive created: Sat Jan  9 10:34:31 1993
export PATH; PATH=/bin:$PATH
if test -f 'fixdfsi.S'
then
	echo shar: will not over-write existing file "'fixdfsi.S'"
else
sed 's/^X//' << \SHAR_EOF > 'fixdfsi.S'
X	.file	"__fixdfsi.s"
X.text
X	.align 2
X.globl ___fixdfsi
X___fixdfsi:
X	pushl %ebp
X	movl %esp,%ebp
X	subl	$12,%esp
X	fstcw	-4(%ebp)  
X	movw	-4(%ebp),%ax
X	orw	$0x0c00,%ax  
X	movw	%ax,-2(%ebp) 
X	fldcw	-2(%ebp)     
X	fldl	8(%ebp)
X	fistpl	-12(%ebp)    
X	fldcw	-4(%ebp)     
X	movl	-12(%ebp),%eax
X	leave
X	ret
SHAR_EOF
fi # end of overwriting check
if test -f 'fixunsdfsi.S'
then
	echo shar: will not over-write existing file "'fixunsdfsi.S'"
else
sed 's/^X//' << \SHAR_EOF > 'fixunsdfsi.S'
X	.file	"__fixdfsi.s"
X.text
X	.align 2
X.globl ___fixunsdfsi
X___fixunsdfsi:
X	pushl	%ebp
X	movl	%esp,%ebp
X	subl	$12,%esp
X	fstcw	-4(%ebp)  
X	movw	-4(%ebp),%ax
X	orw	$0x0c00,%ax  
X	movw	%ax,-2(%ebp) 
X	fldcw	-2(%ebp)     
X	fldl	8(%ebp)
X
X	fcoml	fbiggestsigned	/* bigger than biggest signed? */
X	fstsw	%ax
X	sahf
X	jnb	1f
X	
X	fistpl	-12(%ebp)    
X	movl	-12(%ebp),%eax
X	jmp	2f
X
X1:	fsubl	fbiggestsigned	/* reduce for proper conversion */
X	fistpl	-12(%ebp)		/* convert */
X	movl	-12(%ebp),%eax
X	orl	$0x80000000,%eax	/* restore bias */
X
X2:	fldcw	-4(%ebp)     
X	leave
X	ret
X
X	fcoml	fbiggestsigned	/* bigger than biggest signed? */
X	fstsw	%ax
X	sahf
X	jnb	1f
X	
X	fistpl	4(%esp)
X	movl	4(%esp),%eax
X	ret
X
X1:	fsubl	fbiggestsigned	/* reduce for proper conversion */
X	fistpl	4(%esp)		/* convert */
X	movl	4(%esp),%eax
X	orl	$0x80000000,%eax	/* restore bias */
X	ret
X
X	.data
Xfbiggestsigned:	.double	0r2147483648.0
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0
------------------------------ Cut Here -------------------------

3) Installation =================================================

The files provided above replace the following files:

     /usr/src/usr.bin/gcc/gnulib/i386/fixunsdfsi.s
     /usr/src/usr.bin/gcc/gnulib/i386/fixdfsi.s
     /usr/src/lib/libc/i386/gen/fixunsdfsi.s
     /usr/src/lib/libc/i386/gen/fixdfsi.s

Note that the replacement files end with upper-case "S" and the
original files end with lower-case "s".  The original files
should be saved, and the replacemet files should be renamed to
end in lower-case "s".  Note also that the original files in
gnulib are identical to the original files in libc (with the
exception of the version control date in fixdfsi.s).  I created
hard links between the replacement files, since it is not clear
to me why they should be different.

Recompile /usr/src/lib, /usr/src/usr.bin/gcc, etc...

     cd /usr/src/lib;		make; make install; make clean;
     cd /usr/src/usr.bin/gcc;	make; make install; make clean;

4) System configuration =========================================

     386/486/387:               Micronics 386/33, Intel 387
     ISA/EISA/SCSI:             Adaptec 1542B
     RAM size:                  16
     drive(s) type and size:    Maxtor 340
     tape(s) type and size:     Archive 2150S
     ethernet type:             none
     graphics type:             Prodesigner II
     serial type:               16550
     parallel type:             n/a
     other:                     patches 1-?

5) Test program =================================================

This program prompts for a numeric string, then asks for a
storage type.  As soon as a storage type is chosen, the program
prints the number as cast to a variety of data types.  The most
recent number entered at the prompt is saved to facilitate
testing a variety of storage types with a single numeric value.
Ctrl-D exits the program.


begin 644 cast.c.Z
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
D$,D$UO%#>M?;WO>^@2CQC=!TJSL$^VH7PMV\*,H&:S5ZP4<!
 
end

-- 
Dave Abercrombie          abe@netcom.com
(415) 442-0102           lyra!abe@wet.com