title: GCC inline assembly - Move float to XMM0 before call
body: <p>I'm currently trying to call a generic C function from GCC inline assembly (bad idea, I know, but I'm bored today...).</p>
  
  <p>My operating system is Mac OS X, 64bits, so the calling convention is System V, meaning arguments 0-6 are passed through the <code>rdi</code>, <code>rsi</code>, <code>rdx</code>, <code>rcx</code>, <code>r8</code> and <code>r9</code> registers. Other arguments are pushed to the stack.</p>
  
  <p>I know the function signature, so I can guess the return type, and the type of the arguments.
  With that information, I can place the arguments in the correct registers.</p>
  
  <p>Everything is working great with integer types, but I got a problem with floating point values.</p>
  
  <p>Floating point values need to be passed through the <code>xmm0</code>-<code>xmm7</code> registers.</p>
  
  <p>So the problem is basically the following. I've got a C variable of type <code>float</code>. I need to move that variable in, let's say, the <code>xmm0</code> register, using GCC's inline assembly.</p>
  
  <p>Imagine the following code:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  void foo( int x )
  {
      printf( "X: %i\n", x );
  }
  
  int main( void )
  {
      int x = 42;
  
      __asm__
      (
          "mov %[x], %%rdi;"
          "call _foo;"
          :
          : [ x ] "m" ( x )
      );
  
      return 0;
  }
  </code></pre>
  
  <p>The function <code>foo</code> is called, with 42 as parameter. It works...</p>
  
  <p>Now I try the same with a float argument. I only have to use <code>movss</code> instead of <code>mov</code>, and it works.</p>
  
  <p>The problem comes when I try to call both functions:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  void foo( int a )
  {
      printf( "A: %i\n", a );
  }
  
  void bar( float b )
  {
      printf( "B: %f\n", b );
  }
  
  int main( void )
  {
      int   a = 42;
      float b = 42;
  
      __asm__
      (
          "mov %[a], %%rdi;"
          "call _foo;"
          "movss %[b], %%xmm0;"
          "call _bar;"
          :
          : [ a ] "m" ( a ),
            [ b ] "m" ( b )
      );
  
      return 0;
  }
  </code></pre>
  
  <p>The function taking the float argument receive 0. I don't understand why.
  I don't touch the stack, so there's no cleanup to do...</p>
  
  <p>If I call the functions directly from C, GCC produces the following:</p>
  
  <pre><code>movl    $42, -4(%rbp)
  movl    $0x42280000, %eax
  movl    %eax, -8(%rbp)
  movl    -4(%rbp), %edi
  call    _foo
  movss   -8(%rbp), %xmm0
  call    _bar
  </code></pre>
  
  <p>I don't get the difference... Any help will be greatly appreciated : )</p>
  
  <p>Have a nice day, all</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>As requested, here's the ASM output when using inline assembly:</p>
  
  <pre><code> movl    $42, -4(%rbp)
   movl    $0x42280000, %eax
   movl    %eax, -8(%rbp)
   mov    -4(%rbp), %rdi;
   call    _foo;
   movl    -8(%rbp), %eax;
   movl    %eax, -4(%rbp);
   movss    -4(%rbp), %xmm0;
   call    _bar;
  </code></pre>
  
  <p><strong>EDIT2</strong></p>
  
  <p>As requested, here's the GDB output:</p>
  
  <pre><code>0x100000e9e &lt;main+4&gt;:   movl   $0x2a,-0x4(%rbp)
  0x100000ea5 &lt;main+11&gt;:  mov    $0x42280000,%eax
  0x100000eaa &lt;main+16&gt;:  mov    %eax,-0x8(%rbp)
  0x100000ead &lt;main+19&gt;:  mov    -0x4(%rbp),%rdi
  0x100000eb1 &lt;main+23&gt;:  callq  0x100000e54 &lt;foo&gt;
  0x100000eb6 &lt;main+28&gt;:  movss  -0x8(%rbp),%xmm0
  0x100000ebb &lt;main+33&gt;:  callq  0x100000e75 &lt;bar&gt;
  </code></pre>