简体   繁体   中英

SSE intrinsics: masking a float and using bitwise and?

Basically the problem is related to x86 assembler where you have a number that you want to set to either zero or the number itself using an and . If you and that number with negative one you get back the number itself but if you and it with zero you get zero.

Now the problem I'm having with SSE instrinsics is that floats aren't the same in binary as doubles (or maybe I'm mistaken). Anyways here's the code, I've tried using all kinds of floats to mask the second and third numbers (127.0f and 99.0f respectively) but no luck.

#include <xmmintrin.h>
#include <stdio.h>

void print_4_bit_num(const char * label, __m128 var)
{
    float *val = (float *) &var;
    printf("%s: %f %f %f %f\n",
       label, val[3], val[2], val[1], val[0]);
}
int main()
{
    __m128 v1 = _mm_set_ps(1.0f, 127.0f,  99.0f, 1.0f);
    __m128 v2 = _mm_set_ps(1.0f, 65535.0f, 127.0f, 0.0f);
    __m128 v = _mm_and_ps(v1, v2);

    print_4_bit_num("v1", v1);
    print_4_bit_num("v2", v2);
    print_4_bit_num("v ", v);

    return 0;
}

You need to use a bitwise (integer) mask when you AND , so to eg clear alternate values in a vector you might do something like this:

__m128 v1 = _mm_set_ps(1.0f, 127.0f,  99.0f, 1.0f);
__m128 v2 = _mm_castsi128_ps(_mm_set_epi32(0, -1, 0, -1));
__m128 v = _mm_and_ps(v1, v2); // => v = { 0.0f, 127.0f, 0.0f, 1.0f }

You can cast any SSE vector to any SSE vector type of the same size (128 bit, or 256 bit), and you will get the exact same bits as before; there won't be any actual code. Obviously if you cast 4 float to 2 double you get nonsense, but for your case you cast float to some integer type, do the and, cast the result back.

If you have SSE4.1 (which I bet you do), you should consider _mm_blendv_ps(a,b,mask) . This only uses the sign bit of its mask argument and essentially implements the vectorised mask<0?b:a .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM