Search code examples
assemblynasmintelsimdmmx

Why xmm logical shift is not working?


I loaded some content at xmm1 register, let's say it can be viewed as

xmm1 = | bgra | bgra | bgra | bgra | (each one a dw)

Now, i want to shift 1 byte logically to the right every double word so it ends up like this:

xmm1 = | 0bgr | 0bgr | 0bgr | 0bgr | (each one a dw)

I found at the intel doc that i was probably looking for the function "psrld": enter image description here

Yet, it isn't working as i expect since at the beginning the value of xmm1 is

xmm1           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x37, 0x51, 0x9e, 0x0, 0x3e, 0x58, 0xa5, 0x0, 0x3e, 0x5a, 0xa7, 0x0, 0x4a, 0x66, 0xb3, 0x0}, v8_int16 = {0x5137, 0x9e, 0x583e, 0xa5, 0x5a3e, 0xa7, 0x664a, 0xb3}, v4_int32 = {0x9e5137, 0xa5583e, 0xa75a3e, 0xb3664a}, v2_int64 = {0xa5583e009e5137, 0xb3664a00a75a3e}, uint128 = 0x00b3664a00a75a3e00a5583e009e5137}

and then, after applying psrld xmm1, 1, the value of xmm1 is

xmm1           {v4_float = {0x0, 0x0, 0x0, 0x0}, v2_double = {0x0, 0x0}, v16_int8 = {0x9b, 0x28, 0x4f, 0x0, 0x1f, 0xac, 0x52, 0x0, 0x1f, 0xad, 0x53, 0x0, 0x25, 0xb3, 0x59, 0x0}, v8_int16 = {0x289b, 0x4f, 0xac1f, 0x52, 0xad1f, 0x53, 0xb325, 0x59}, v4_int32 = {0x4f289b, 0x52ac1f, 0x53ad1f, 0x59b325}, v2_int64 = {0x52ac1f004f289b, 0x59b3250053ad1f}, uint128 = 0x0059b3250053ad1f0052ac1f004f289b}

Which is not what i want to do. Where am i wrong? What is the correct way to accomplish this?


Solution

  • The output of your examples was correct, so, for example, the first v4_int32 was 0x9e5137 =

    100111100101000100110111
    

    and after psrld xmm1, 1 it was 0x4f289b =

    010011110010100010011011
    

    so every uint32 was shifted right by one bit.


    What you were trying was right - except for one point:
    You were shifting right by one bit and not by one byte as you wanted. So using

    psrld xmm1, 8   ; shift right by one byte
    

    instead of

    psrld xmm1, 1   ; shift right by one bit
    

    should fix your problems.