From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1H6Oun-0002L0-T7 for qemu-devel@nongnu.org; Mon, 15 Jan 2007 05:18:09 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1H6Ouk-0002Ep-DB for qemu-devel@nongnu.org; Mon, 15 Jan 2007 05:18:09 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1H6Ouk-0002EM-5f for qemu-devel@nongnu.org; Mon, 15 Jan 2007 05:18:06 -0500 Received: from [81.56.128.63] (helo=fbxmetz.linbox.com) by monty-python.gnu.org with esmtp (Exim 4.52) id 1H6Ouj-0003FW-C8 for qemu-devel@nongnu.org; Mon, 15 Jan 2007 05:18:06 -0500 Received: from [192.168.0.14] (helo=[192.168.0.14]) by fbxmetz.linbox.com with esmtp (Exim 3.36 #1 (Debian)) id 1H6Oug-0001uJ-00 for ; Mon, 15 Jan 2007 11:18:02 +0100 Message-ID: <45AB54D9.9020207@linbox.com> Date: Mon, 15 Jan 2007 11:18:01 +0100 From: Ludovic Drolez MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [BUG] QEMU x86_64 SSE bug in modf() Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Hi ! I've found a bug in Qemu: conversion of floats to strings fails in some cases. For example, Ganglia (cluster monitoring software), shows random values and as well as PHP5 programs. Float to string conversion uses modf() but this function fails under QEMU and SLES 64, as you can see in this small test program below: =========== #include #include int main() { double x = 1.1; double y; double z; printf("Calling modf() for %f\n", x); z = modf(x,&y); printf("fractional part = %f\ninteger part = %f\n", z, y); return 0; } =========== Under QEMU/Sles 10 64 you get: Calling modf() for 1.100000 fractional part = 1.100000 <---??? integer part = 1.000000 But with a real x64 system or under QEMU/Debian 64 you get the right result: Calling modf() for 1.100000 fractional part = 0.100000 integer part = 1.000000 The SLES's glibc uses lots of SSE instructions as you can see in the dump below (gcc 4.1.0): ===========SLES 64 modf()========== 000000000002ed00 : 2ed00: f2 0f 11 44 24 f8 movsd %xmm0,0xfffffffffffffff8(%rsp) 2ed06: 48 8b 44 24 f8 mov 0xfffffffffffffff8(%rsp),%rax 2ed0b: 66 0f 28 c8 movapd %xmm0,%xmm1 2ed0f: 48 89 c6 mov %rax,%rsi 2ed12: 48 b8 ff ff ff ff ff mov $0x7fffffffffffffff,%rax 2ed19: ff ff 7f 2ed1c: 48 89 f2 mov %rsi,%rdx 2ed1f: 48 21 c2 and %rax,%rdx 2ed22: 48 b8 ff ff ff ff ff mov $0x433fffffffffffff,%rax 2ed29: ff 3f 43 2ed2c: 48 39 c2 cmp %rax,%rdx 2ed2f: 76 3f jbe 2ed70 2ed31: 48 b8 00 00 00 00 00 mov $0x7ff0000000000000,%rax 2ed38: 00 f0 7f 2ed3b: 48 39 c2 cmp %rax,%rdx 2ed3e: 0f 87 82 00 00 00 ja 2edc6 2ed44: 48 b8 00 00 00 00 00 mov $0x8000000000000000,%rax 2ed4b: 00 00 80 2ed4e: f2 0f 11 07 movsd %xmm0,(%rdi) 2ed52: 48 21 c6 and %rax,%rsi 2ed55: 48 89 74 24 f8 mov %rsi,0xfffffffffffffff8(%rsp) 2ed5a: f2 0f 10 44 24 f8 movsd 0xfffffffffffffff8(%rsp),%xmm0 2ed60: 66 0f 28 c8 movapd %xmm0,%xmm1 2ed64: 66 0f 28 c1 movapd %xmm1,%xmm0 2ed68: c3 retq 2ed69: 66 data16 2ed6a: 66 data16 2ed6b: 66 data16 2ed6c: 90 nop 2ed6d: 66 data16 2ed6e: 66 data16 2ed6f: 90 nop 2ed70: 48 b8 ff ff ff ff ff mov $0x3fefffffffffffff,%rax 2ed77: ff ef 3f 2ed7a: 48 39 c2 cmp %rax,%rdx 2ed7d: 77 15 ja 2ed94 2ed7f: 48 b8 00 00 00 00 00 mov $0x8000000000000000,%rax 2ed86: 00 00 80 2ed89: 66 0f 28 c1 movapd %xmm1,%xmm0 2ed8d: 48 21 c6 and %rax,%rsi 2ed90: 48 89 37 mov %rsi,(%rdi) 2ed93: c3 retq 2ed94: 48 8d 04 36 lea (%rsi,%rsi,1),%rax 2ed98: b9 33 04 00 00 mov $0x433,%ecx 2ed9d: 48 c1 e8 35 shr $0x35,%rax 2eda1: 29 c1 sub %eax,%ecx 2eda3: 48 c7 c0 ff ff ff ff mov $0xffffffffffffffff,%rax 2edaa: 48 d3 e0 shl %cl,%rax 2edad: 48 21 c6 and %rax,%rsi 2edb0: 66 48 0f 6e c6 movd %rsi,%xmm0 2edb5: 48 89 74 24 f0 mov %rsi,0xfffffffffffffff0(%rsp) 2edba: 48 89 37 mov %rsi,(%rdi) 2edbd: f2 0f 5c c8 subsd %xmm0,%xmm1 2edc1: 66 0f 28 c1 movapd %xmm1,%xmm0 2edc5: c3 retq 2edc6: f2 0f 58 c8 addsd %xmm0,%xmm1 2edca: f2 0f 11 07 movsd %xmm0,(%rdi) 2edce: 66 0f 28 c1 movapd %xmm1,%xmm0 2edd2: c3 retq ==================================== And the Debian one, a little less (gcc 4.1.3): =========== Debian 64 modf() =============== 000000000002e360 : 2e360: f2 0f 11 44 24 f8 movsd %xmm0,0xfffffffffffffff8(%rsp) 2e366: 48 8b 54 24 f8 mov 0xfffffffffffffff8(%rsp),%rdx 2e36b: 48 89 d6 mov %rdx,%rsi 2e36e: 41 89 d0 mov %edx,%r8d 2e371: 48 c1 ee 20 shr $0x20,%rsi 2e375: 89 f0 mov %esi,%eax 2e377: c1 f8 14 sar $0x14,%eax 2e37a: 25 ff 07 00 00 and $0x7ff,%eax 2e37f: 8d 88 01 fc ff ff lea 0xfffffffffffffc01(%rax),%ecx 2e385: 83 f9 13 cmp $0x13,%ecx 2e388: 7f 38 jg 2e3c2 2e38a: 85 c9 test %ecx,%ecx 2e38c: 0f 88 ae 00 00 00 js 2e440 2e392: ba ff ff 0f 00 mov $0xfffff,%edx 2e397: d3 fa sar %cl,%edx 2e399: 89 d0 mov %edx,%eax 2e39b: 21 f0 and %esi,%eax 2e39d: 44 09 c0 or %r8d,%eax 2e3a0: 75 7e jne 2e420 2e3a2: f2 0f 11 07 movsd %xmm0,(%rdi) 2e3a6: 81 e6 00 00 00 80 and $0x80000000,%esi 2e3ac: 89 f0 mov %esi,%eax 2e3ae: 48 c1 e0 20 shl $0x20,%rax 2e3b2: 48 89 44 24 f8 mov %rax,0xfffffffffffffff8(%rsp) 2e3b7: 66 0f 12 4c 24 f8 movlpd 0xfffffffffffffff8(%rsp),%xmm1 2e3bd: f2 0f 10 c1 movsd %xmm1,%xmm0 2e3c1: c3 retq 2e3c2: 83 f9 33 cmp $0x33,%ecx 2e3c5: 7f 39 jg 2e400 2e3c7: 8d 88 ed fb ff ff lea 0xfffffffffffffbed(%rax),%ecx 2e3cd: b8 ff ff ff ff mov $0xffffffff,%eax 2e3d2: d3 e8 shr %cl,%eax 2e3d4: 85 c2 test %eax,%edx 2e3d6: 74 ca je 2e3a2 2e3d8: f7 d0 not %eax 2e3da: 21 c2 and %eax,%edx 2e3dc: 48 89 f0 mov %rsi,%rax 2e3df: 48 c1 e0 20 shl $0x20,%rax 2e3e3: 48 09 d0 or %rdx,%rax 2e3e6: 48 89 44 24 f8 mov %rax,0xfffffffffffffff8(%rsp) 2e3eb: 48 89 07 mov %rax,(%rdi) 2e3ee: 66 0f 12 4c 24 f8 movlpd 0xfffffffffffffff8(%rsp),%xmm1 2e3f4: f2 0f 5c c1 subsd %xmm1,%xmm0 2e3f8: f3 c3 repz retq 2e3fa: 66 data16 2e3fb: 66 data16 2e3fc: 90 nop 2e3fd: 66 data16 2e3fe: 66 data16 2e3ff: 90 nop 2e400: 81 f9 00 04 00 00 cmp $0x400,%ecx 2e406: f2 0f 11 07 movsd %xmm0,(%rdi) 2e40a: 75 9a jne 2e3a6 2e40c: 89 f0 mov %esi,%eax 2e40e: 25 ff ff 0f 00 and $0xfffff,%eax 2e413: 41 09 c0 or %eax,%r8d 2e416: 74 8e je 2e3a6 2e418: eb de jmp 2e3f8 2e41a: 66 data16 2e41b: 66 data16 2e41c: 90 nop 2e41d: 66 data16 2e41e: 66 data16 2e41f: 90 nop 2e420: 89 d0 mov %edx,%eax 2e422: f7 d0 not %eax 2e424: 21 f0 and %esi,%eax 2e426: 48 c1 e0 20 shl $0x20,%rax 2e42a: 48 89 44 24 f8 mov %rax,0xfffffffffffffff8(%rsp) 2e42f: 48 89 07 mov %rax,(%rdi) 2e432: 66 0f 12 4c 24 f8 movlpd 0xfffffffffffffff8(%rsp),%xmm1 2e438: f2 0f 5c c1 subsd %xmm1,%xmm0 2e43c: c3 retq 2e43d: 66 data16 2e43e: 66 data16 2e43f: 90 nop 2e440: 81 e6 00 00 00 80 and $0x80000000,%esi 2e446: 89 f0 mov %esi,%eax 2e448: 48 c1 e0 20 shl $0x20,%rax 2e44c: 48 89 07 mov %rax,(%rdi) 2e44f: c3 retq ======================= Would someone be able to track down this SSE QEMU bug seen only in SLES's modf() function ? Cheers, -- Ludovic DROLEZ Linbox / Free&ALter Soft http://lrs.linbox.org