1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
POWER8: Wrong behaviour with float-to-int punning
Building a reduced test program with 'gcc -O2 -fno-inline -mcpu=power8' produces wrong results at runtime. I don't think gcc is at fault here.
---
#include <stdio.h>
int getWord(const float x)
{
return *(int*)&x;
}
void main()
{
int foo = getWord(+123.456f);
int bar = getWord(-123.456f);
printf("%d\n", foo);
printf("%d\n", bar);
return;
}
---
This prints:
---
0
0
---
Compiling with 'gcc -O2 -fno-inline -mcpu=power7' and you instead get the expected result:
---
1123477881
-1024005767
---
The different between the two programs is:
--- power7.s
+++ power8.s
@@ -6,9 +6,9 @@
.globl getWord
.type getWord, @function
getWord:
- stfs 1,-16(1)
- ori 2,2,0
- lwa 3,-16(1)
+ xscvdpspn 0,1
+ mfvsrwz 3,0
+ extsw 3,3
blr
.long 0
.byte 0,0,0,0,0,0,0,0
.size getWord,.-getWord
Seems like qemu doesn't handle xscvdpspn/mfvsrwz correctly.
https://github.com/qemu/qemu/commit/7ee19fb9d682689d36c849576c808cf92e3bae40
https://github.com/qemu/qemu/commit/f5c0f7f981333da59cc35c3210d05ec1775c97c1
|