Hi,
I've a problem with the movq instruction on a 32 bits OS : when that
instruction is executed it has a bad effect on the floating stack.
The gcc version I tried : 4.5.1 and 4.1.2.
The OS : Red Hat Enterprise Linux Client release 5.5 (Tikanga)
kernel : 2.6.18-194.el5PAE
Please note that the following code works fine if I use an older but 64
bits version of RHEL:
Red Hat Enterprise Linux WS release 4 (Nahant Update 5)
kernel : 2.6.9-55.ELsmp
I wrote a very simple example to test some movntq builtin function:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
double *out;
double in = 2.0;
long long unsigned int *vin = (long long unsigned int *)∈
out = (double*)malloc(sizeof(double));
out[0] = 0.0;
printf("%E\n", out[0]);
printf("%E\n", *((double*)vin));
__builtin_ia32_movntq((long long unsigned int*)(out), *vin);
printf("%E\n", *out);
}
Since I'm compiling on a 32 bits OS I use the following compilation
command: gcc movntq.c -mfpmath=sse -msse3
If I have a look at the assembly code I have the following code between
the two last printf :
call printf
movl -12(%ebp), %eax
movl (%eax), %edx
movl 4(%eax), %ecx
movl -16(%ebp), %eax
movl %edx, -32(%ebp)
movl %ecx, -28(%ebp)
movq -32(%ebp), %mm0
movntq %mm0, (%eax)
movl -16(%ebp), %eax
movsd (%eax), %xmm0
movsd %xmm0, 4(%esp)
movl $.LC2, (%esp)
call printf
The problem is around the movq instruction... When I go over that
instruction using the stepi of gdb, the floating stack gets very strange:
(gdb) info float
R7: Valid 0x403d8000000000000000 +4611686018427387904
R6: Zero 0x00000000000000000000 +0
R5: Zero 0x00000000000000000000 +0
R4: Zero 0x00000000000000000000 +0
R3: Zero 0x00000000000000000000 +0
R2: Zero 0x00000000000000000000 +0
R1: Zero 0x00000000000000000000 +0
=>R0: Special 0xffff4000000000000000 Unsupported
Status Word: 0x0000
TOP: 0
Control Word: 0x037f IM DM ZM OM UM PM
PC: Extended Precision (64-bits)
RC: Round to nearest
Tag Word: 0x1556
Instruction Pointer: 0x73:0x007f6c4e
Operand Pointer: 0x7b:0xbfffda64
Opcode: 0xdd5c
If the value stored in out[0] is ok after the movntq instruction (p
out[0] returns 2 in gdb) the last printf returns a NAN...
Does anyone have an idea about what's going on here ? Is it a bug ?
Best Regards
Olivier