title: C/C++ convert int to short and inline asm (ARM specific)
body: <p>This isn't a trivial question. <br/><b>NOTE: I don't need opinions or advises to use pure asm. I actually need to get done what I'm talking about: to get inline asm without this sign/zero extend optcode when assigning result to a short int.</b><br/><br/>
  I'm dealing with a library that abuses 16-bit shorts for many functions and I'm optimizing it. I need to add a few optimized functions with inline asm. The problem is that in many places result of the function is assigned to a short int. That is, compiler generates uxth or sxth arm opcode.<br/><br/>
  My goal is to avoid that problem and to make sure that this useless opcode isn't generated.
  First of all, I need to define my optimized function to return short int. This way if it's assigned to an int or to a short int there is no extra opcode to convert the result.<br/><br/>
  The problem is that I have no clue how to skip that int->short conversion that compiler generates inside my own function.<br/>
  Dumb cast like: <code>*(short*)(void*)&amp;value</code> doesn't work. Compiler either starts messing with the stack making problem even more, or it still uses that same sxth to sign-extend the result.<br/><br/>
  I compile for multiple compilers, and I was able to resolve it for arm's armcc compiler, but I can't get it done with GCC (I compile with 4.4.3 or 4.6.3). With armcc I use short type inside inline asm statement. In gcc even if I use short compiler still for some reason believes that sign extension is required.<br/><br/></p>
  
  <p>Here's a simple code snippet that I can't get to work with GCC, any advice on how to get it to work? For this simple example I'll use clz instruction:</p>
  
  <p>sample file <b>test.c</b> file:<br/><br/></p>
  
  <pre><code>static __inline short CLZ(int n)
  {
      short ret;
  #ifdef __GNUC__
      __asm__("clz %0, %1" : "=r"(ret) : "r"(n));
  #else
      __asm { clz ret, n; }
  #endif
      return ret;
  }
  
  //test function
  short test_clz(int n)
  {
      return CLZ(n);
  }
  </code></pre>
  
  <p><br/><br/>
  here's expected result that I get with armcc -c -O3:</p>
  
  <pre><code>test_clz:
      CLZ      r0,r0
      BX       lr
  </code></pre>
  
  <p>Here's unacceptable result that GCC -c -O3 gives me:</p>
  
  <pre><code>test_clz:
      clz r0, r0
      sxth    r0, r0
      bx  lr
  </code></pre>
  
  <p>Note also, that if rewrite CLZ with internal variable <code>int ret;</code> instead of <code>short ret;</code> then armcc generates the same result as GCC.</p>
  
  <p>Quick line to get the asm output with gcc or armcc:<br/>
  <code>gcc -O3 -c test.c -o test.o &amp;&amp; objdump -d test.o &gt; test.s</code><br/>
  <code>armcc -O3 --arm --asm -c test.c</code></p>