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