Author: | Wojciech Muła |
---|---|
Added on: | 2008-06-18 |
There is no such instruction — CVTDQ2PS converts signed 32-bit ints. Solution: first zero the MSB, such number is never negative in U2, so mentioned instruction could be used. Then add 232 if the MSB was set.
float CONST[4] SIMD_ALIGN = packed_float((float)((uint32_t)(1 << 31))); /* 2^31 */ uint32_t MASK_0_30[4] SIMD_ALIGN = packed_dword(0x7fffffff); uint32_t MASK_31[4] SIMD_ALIGN = packed_dword(0x80000000); void convert_uint32_float(uint32_t in[4], float out[4]) { __asm__ volatile ( "movdqu (%%eax), %%xmm0 \n" "movdqa %%xmm0, %%xmm1 \n" "pand MASK_0_30, %%xmm0 \n" // xmm0 - mask MSB bit - never less then zero in U2 "cvtdq2ps %%xmm0, %%xmm0 \n" // convert this value to float "psrad $32, %%xmm1 \n" // populate MSB in higher word (enough to mask CONST) "pand CONST, %%xmm1 \n" // xmm1 = MSB set ? float(2^31) : float(0) "addps %%xmm1, %%xmm0 \n" // add 2^31 if MSB set "movdqu %%xmm0, (%%ebx) \n" : /* no output */ : "a" (in), "b" (out) ); }