*BSD News Article 8911


Return to BSD News archive

Path: sserve!manuel.anu.edu.au!munnari.oz.au!uunet!cs.utexas.edu!sun-barr!sh.wide!wnoc-kyo!astemgw!kocb!yab
From: yab@kocb.kocb.astem.or.jp (Kenji Yabuuchi)
Newsgroups: comp.unix.bsd
Subject: BUG: assigning float to int.
Message-ID: <YAB.92Dec8145855@kocb.kocb.astem.or.jp>
Date: 8 Dec 92 05:58:55 GMT
Sender: news@kocb.astem.or.jp
Organization: Kubota, Kyoto Office of Computer Business
Lines: 121
Nntp-Posting-Host: kocb


I'm using 386BSD and gcc-1.39. And I found that when assigning a
floating point number to an integer, it rounds the value rather than
truncate.

This is because there is a wrong assumption about rounding control
bits of control word of floating point unit in the following
libraries:

  ___fixdfsi	(/usr/src/lib/libc/i386/gen/fixdfsi.s)
  ___fixundfsi	(/usr/src/lib/libc/i386/gen/fixunsdfsi.s)

These libraries are also in /usr/src/usr.bin/gcc/gnulib/i386 directory.


I don't know which is better, to rewrite these libraries or rewrite
floating point unit intialization codes. However, in the source code
of function modf(/usr/src/lib/libc/i386/gen/modf.s), there is a
rounding control bits processing. So I fix the libraries. The diff
against the original codes are following.

*** fixdfsi.s.orig	Wed Dec  9 07:20:01 1992
--- fixdfsi.s	Wed Dec  9 07:22:57 1992
***************
*** 40,46 ****
  
  	.globl ___fixdfsi
  ___fixdfsi:
! 	fldl	4(%esp)
! 	fistpl	4(%esp)
! 	movl	4(%esp),%eax
  	ret
--- 40,60 ----
  
  	.globl ___fixdfsi
  ___fixdfsi:
! 	enter	$20, $0
! 
! 	fnstcw	-4(%ebp)	
! 	movw	-4(%ebp), %dx
! 	orw	$0xc00, %dx		/* set truncate bits 	*/
! 	movw	%dx, -8(%ebp)
! 	fldcw	-8(%ebp)		/* save it to control word */
! 
! 	movl	8(%ebp), %edx		/* copy arg to local 	*/
! 	movl	12(%ebp), %ecx
! 	movl	%edx, -20(%ebp)
! 	movl	%ecx, -16(%ebp)	
! 	fldl	-20(%ebp)	
! 	fistpl	-12(%ebp)		/* truncate it 		*/
! 	fldcw	-4(%ebp)		/* restore control word */
! 	movl	-12(%ebp), %eax	
! 	leave
  	ret
*** fixunsdfsi.s.orig	Wed Dec  9 07:19:51 1992
--- fixunsdfsi.s	Wed Dec  9 07:19:33 1992
***************
*** 40,60 ****
  
  	.globl ___fixunsdfsi
  ___fixunsdfsi:
! 	fldl	4(%esp)		/* argument double to accum stack */
! 	frndint			/* create integer */
! 	fcoml	fbiggestsigned	/* bigger than biggest signed? */
  	fstsw	%ax
  	sahf
  	jnb	1f
  	
! 	fistpl	4(%esp)
! 	movl	4(%esp),%eax
  	ret
  
! 1:	fsubl	fbiggestsigned	/* reduce for proper conversion */
! 	fistpl	4(%esp)		/* convert */
! 	movl	4(%esp),%eax
  	orl	$0x80000000,%eax	/* restore bias */
  	ret
  
  fbiggestsigned:	.double	0r2147483648.0
--- 40,76 ----
  
  	.globl ___fixunsdfsi
  ___fixunsdfsi:
! 	enter	$20, $0
! 	
! 	fnstcw	-4(%ebp)	
! 	movw	-4(%ebp), %dx
! 	orw	$0xc00, %dx		/* set truncate bits 	*/
! 	movw	%dx, -8(%ebp)
! 	fldcw	-8(%ebp)		/* save it to control word */
! 
! 	movl	8(%ebp), %edx		/* copy arg to local 	*/
! 	movl	12(%ebp), %ecx
! 	movl	%edx, -20(%ebp)
! 	movl	%ecx, -16(%ebp)	
! 	fldl	-20(%ebp)		/* argument double to accum stack */
! 	frndint				/* create integer */
! 	fcoml	fbiggestsigned		/* bigger than biggest signed? */
  	fstsw	%ax
  	sahf
  	jnb	1f
  	
! 	fistpl	-12(%ebp)
! 	fldcw	-4(%ebp)		/* restore control word */
! 	movl	-12(%ebp),%eax
! 	leave
  	ret
  
! 1:	fsubl	fbiggestsigned		/* reduce for proper conversion */
! 	fistpl	-12(%ebp)		/* convert */
! 	fldcw	-4(%ebp)		/* restore control word */
! 	movl	-12(%ebp),%eax
  	orl	$0x80000000,%eax	/* restore bias */
+ 	leave
  	ret
  
  fbiggestsigned:	.double	0r2147483648.0

---
Kenji Yabuuchi			KUBOTA corporation
yab@kocb.astem.or.jp		ASTEM RI