title: %q in inline assembly with -arch i386
body: <p>I'm working with a library (pulseaudio, src/pulsecore/svolume_mmx.c) that has code similar to the following dummy code:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stdint.h&gt;
  #include &lt;inttypes.h&gt;
  
  int main(int argc, char *argv[]) {
    int32_t x = 5;
    int32_t *p_x = &amp;x;
  #if defined(__i386__)
    int32_t tmp;
  #elif defined(__amd64__)
    int64_t tmp;
  #endif
  
    __asm__ __volatile__ (
      " xor %1, %1                    \n\t"
      " movd (%q0, %1, 4), %%mm0      \n\t"
      " emms                          \n\t"
      : "+r" (p_x), "+r" (tmp)
    );
    printf("%"PRId32"\n", x);
    return 0;
  }
  </code></pre>
  
  <p>I'm trying to compile this as a 32-bit library on 64-bit mac osx. When I compile this normally, everything works fine, but when I compile it as the desired 32-bit library with the -arch flag, this happens:</p>
  
  <pre><code>$ gcc -std=c99 -arch i386 -o main main.c
  /var/folders/random_stuff_here.s:22:bad register name `%rcx, %edx,4)'
  </code></pre>
  
  <p>After reading the assembly output of gcc, the problem is in the movd line. The %q0 register is being filled in as %rcx, which is a 64-bit register. The assembler is attempting to create a 32-bit output from this, and is failing.</p>
  
  <p>I couldn't find much about what the 'q' in %q0 means, but I eventually found documentation for a <a href="http://www.pgroup.com/doc/pgiug.pdf" rel="nofollow">different compiler</a> (on page 194) which describes the q as meaning "Produces the quad word register name for an operand if the target supports quad word. Otherwise, it produces a word register name. (For example, if operand 0 is in register 'a', then %q0 produces %rax on x86_64 or %eax on x86.)" It appears that the code generation for the asm block outputs 64-bit registers if you ask for it with the 'q' flag, even if the -arch flag is specifying a 32-bit output.</p>
  
  <p>Using the -m32 flag in addition to the -arch i386 flag doesn't help at all. How can I tell the asm code generator to only use 32-bit registers for %qx symbols? I'd prefer to give extra flags to gcc over modifying the source of this library.</p>