Strange behavior with movq

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 *)&in;

  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



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux