title: Converting float vector to 16-bit int without saturating
body: <p>I want to convert a floating point value to a 16-bit unsigned integer without saturating (wraparound/overflow instead).</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;xmmintrin.h&gt;
  
  void satur_wrap()
  {
      const float bigVal = 99000.f;
      const __m128 bigValVec = _mm_set1_ps(bigVal);
  
      const __m64 outVec64 =_mm_cvtps_pi16(bigValVec);
  
  #if 0
      const __m128i outVec = _mm_movpi64_epi64(outVec64);
  #else
  
      #if 1
          const __m128i outVec  = _mm_packs_epi32(_mm_cvttps_epi32(bigValVec), _mm_cvttps_epi32(bigValVec));
      #else
          const __m128i outVec  = _mm_cvttps_epi32(bigValVec);
      #endif
  
  #endif
  
      uint16_t *outVals = NULL;
      posix_memalign((void **) &amp;outVals, sizeof(__m128i), sizeof(__m128i));
  
      _mm_store_si128(reinterpret_cast&lt;__m128i *&gt;(outVals), outVec);
  
      for (int i = 0; i &lt; sizeof(outVec) / sizeof(*outVals); i++)
      {
          std::cout &lt;&lt; "outVals[" &lt;&lt; i &lt;&lt; "]: " &lt;&lt; outVals[i] &lt;&lt; std::endl;
      }
  
      std::cout &lt;&lt; std::endl
          &lt;&lt; "\tbigVal: " &lt;&lt; bigVal &lt;&lt; std::endl
          &lt;&lt; "\t(unsigned short) bigVal: " &lt;&lt; ((unsigned short) bigVal)  &lt;&lt; std::endl
          &lt;&lt; "\t((unsigned short)((int) bigVal)): " &lt;&lt; ((unsigned short)((int) bigVal)) &lt;&lt; std::endl
          &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>Sample execution:</p>
  
  <pre><code>$ ./row
  outVals[0]: 32767
  outVals[1]: 32767
  outVals[2]: 32767
  outVals[3]: 32767
  outVals[4]: 32767
  outVals[5]: 32767
  outVals[6]: 32767
  outVals[7]: 32767
  
          bigVal: 99000
          (unsigned short) bigVal: 65535
          ((unsigned short)((int) bigVal)): 33464
  </code></pre>
  
  <p>The <code>((unsigned short)((int) bigVal))</code> expression works as desired (but it's probably UB, right?).  But I can't find something quite similar with SSE.  I must be missing something, but I couldn't find a primitive to convert four 32-bit <code>float</code>s to four 32-bit <code>int</code>s.</p>
  
  <hr>
  
  <p>EDIT: Oops, I figured it would be "normal" for 32-bit integer -> 16-bit unsigned integer conversion to use wraparound.  But I've since learned that <code>_mm_packs_epi32</code> uses signed-saturate (and there doesn't appear to be a <code>_mm_packus_epi32</code>).  Is there a way to set the mode, or another primitive besides <code>_mm_packus_epi32</code>?</p>