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 <stdio.h>
#include <math.h>
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 <modf>:
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 <modf+0x70>
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 <modf+0xc6>
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 <modf+0x94>
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 <modf>:
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 <modf+0x62>
2e38a: 85 c9 test %ecx,%ecx
2e38c: 0f 88 ae 00 00 00 js 2e440 <modf+0xe0>
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 <modf+0xc0>
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 <modf+0xa0>
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 <modf+0x42>
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 <modf+0x46>
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 <modf+0x46>
2e418: eb de jmp 2e3f8 <modf+0x98>
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
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel