qemu-ppc (user) incorrectly translates float32 arithmetics
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
QEMU |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
I'm using qemu-3.1.0 (Gentoo).
When I was running regression test suite via qemu-ppc for GHC I noticed a few uint32_t<->float32 failures I did not expect to encounter.
Here is an example
$ cat a.c
#include <stdio.h>
#include <stdint.h>
int main() {
volatile uint32_t i = 1;
printf("0x1 = %e\n", *(volatile float*)&i);
}
$ powerpc-
0x1 = 2.802597e-45
$ scp a timberdoodle.
a 100% 826KB 102.0KB/s 00:08
$ ssh timberdoodle.
0x1 = 1.401298e-45
$ qemu-ppc ./a
0x1 = 2.802597e-45
Looks like off-by-one bit somewhere. I'm not sure if it's FPU instruction or some internals of printf() that are emulated incorrectly.
My native system is x86_64-pc-linux-gnu with a few binfmt_misc handlers wired.
Checking other targets I have locally I get the following:
affected targets:
- powerpc
- powerpc64
- powerpc64le
unaffected targets:
- arm
- arm64
- hppa
- sparc
probably unaffected:
- alpha (maybe it's ok as alpha is not quite an IEEE754 platform)
Raw log:
$ for gcc in /usr/bin/*-gcc; do rm -f a; $gcc -O2 a.c -Wall -o a -fno-strict- aliasing -fno-stack- protector 2>/dev/null && ./a 2>/dev/null && echo -n "$gcc: " && file a; done | sort
0x1 = 1.401298e-45 : /usr/bin/ aarch64- unknown- linux-gnu- gcc: a: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld- linux-aarch64. so.1, for GNU/Linux 3.7.0, not stripped aarch64_ be-unknown- linux-gnu- gcc: a: ELF 64-bit MSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld- linux-aarch64_ be.so.1, for GNU/Linux 3.7.0, not stripped ld-linux- x86-64. so.2, for GNU/Linux 3.2.0, with debug_info, not stripped armv6j- unknown- linux-gnueabihf -gcc: a: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld- linux-armhf. so.3, for GNU/Linux 3.2.0, not stripped armv7a- unknown- linux-gnueabihf -gcc: a: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld- linux-armhf. so.3, for GNU/Linux 3.2.0, not stripped hppa-unknown- linux-gnu- gcc: a: ELF 32-bit MSB pie executable, PA-RISC, 1.1 version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 3.2.0, with debug_info, not stripped hppa2.0- unknown- linux-gnu- gcc: a: ELF 32-bit MSB pie executable, PA-RISC, 1.1 version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 3.2.0, with debug_info, not stripped m68k-unknown- linux-gnu- gcc: a: ELF 32-bit MSB pie executable, Motorola m68k, 68020, version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 3.2.0, not stripped mips64- unknown- linux-gnuabin64 -gcc: a: ELF 64-bit MSB pie executable, MIPS, MIPS-III version 1 (SYSV), dynamically linked, interpreter /lib64/ld.so.1, for GNU/Linux 3.2.0, not stripped riscv64- unknown- linux-gnu- gcc: a: ELF 64-bit LSB pie executable, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld- linux-riscv64- lp64d.so. 1, for GNU/Linux 4.15.0, not stripped s390x-unknown- linux-gnu- gcc: a: ELF 64-bit MSB pie executable, IBM S/390, version 1 (SYSV), dynamically linked, interpreter /lib/ld64.so.1, for GNU/Linux 3.2.0, not stripped sparc-unknown- linux-gnu- gcc: a: ELF 32-bit MSB pie executable, SPARC32PLUS, V8+ Required, total store ordering, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, not stripped
0x1 = 1.401298e-45 : /usr/bin/
0x1 = 1.401298e-45 : /usr/bin/afl-gcc: a: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/
0x1 = 1.401298e-45 : /usr/bin/
0x1 = 1.401298e-45 : /usr/bin/
0x1 = 1.401298e-45 : /usr/bin/
0x1 = 1.401298e-45 : /usr/bin/
0x1 = 1.401298e-45 : /usr/bin/
0x1 = 1.401298e-45 : /usr/bin/
0x1 = 1.401298e-45 : /usr/bin/
0x1 = 1.401298e-45 : /usr/bin/
0x1 = 1.401298e-45 : /usr/bin/
0x1 = 1.401298e-45 : /u...