SIMD

MMX Shift

The logical shift left, logical shift right and arithmetic shift right instructions shift each element by a specified number of bits. The logical left and right shifts also enable a 64-bit quantity (quadword) to be shifted as one block, assisting in data type conversions and alignment operations.

 

PSLLW mm, mm/m64
PSLLW mm, imm8
PSLLD mm, mm/m64
PSLLD mm, imm8
PSLLQ mm, mm/m64
PSLLQ mm, imm8

The PSLL (Packed Shift Left Logical) instructions shift the bits of the first operand to the left by the amount of bits specified in the source operand. The empty low-order bits are set to zero. If the value specified by the second operand is greater than 15 (for words), 31 (for doublewords), or 63 (for quadwords), then the destination is set to all zeros. The destination operand is an MMX register, while the source operand can be either an MMX register, a 64-bit memory operand or 
an immediate 8-bit operand. PSLL supports packed word (PSLLW), packed doubleword (PSLLD) and quadword (PSLLQ) data types.

PSLLW instruction with 64-bit operand:
IF (COUNT > 15)
THEN DEST[64..0] ? 0000000000000000H
ELSE DEST[15..0] ? ZeroExtend(DEST[15..0] << COUNT);
* repeat shift operation for 2nd and 3rd words *;
DEST[63..48] ? ZeroExtend(DEST[63..48] << COUNT);

PSLLD instruction with 64-bit operand:
IF (COUNT > 31)
THEN DEST[64..0] ? 0000000000000000H
ELSE DEST[31..0] ? ZeroExtend(DEST[31..0] << COUNT);
DEST[63..32] ? ZeroExtend(DEST[63..32] << COUNT);

PSLLQ instruction with 64-bit operand:
IF (COUNT > 63)
THEN DEST[64..0] ? 0000000000000000H
ELSE DEST ? ZeroExtend(DEST << COUNT);

PSLLW __m64 _mm_slli_pi16 (__m64 m, int count)
PSLLW __m64 _mm_sll_pi16(__m64 m, __m64 count)

PSLLD __m64 _mm_slli_pi32(__m64 m, int count)
PSLLD __m64 _mm_sll_pi32(__m64 m, __m64 count)

PSLLQ __m64 _mm_slli_si64(__m64 m, int count)
PSLLQ __m64 _mm_sll_si64(__m64 m, __m64 count)


 

PSRLW mm, mm/m64
PSRLW mm, imm8
PSRLD mm, mm/m64
PSRLD mm, imm8
PSRLQ mm, mm/m64
PSRLQ mm, imm8

The PSRL (Packed Shift Right Logical) instructions shift the bits of the first operand to the right by the amount of bits specified in the count operand. The result of the shift operation is written to the destination register. The empty high-order bits are set to zero. If the value specified by the second operand is greater than 15 (for words), or 31 (for doublewords), or 63 (for quadwords), then the destination is set to all zeros. The destination operand is an MMX register, while the count operand (source operand) can be either an MMX register, a 64-bit memory operand, or an immediate 8-bit operand. PSRL supports packed word (PSRLW), packed doubleword (PSRLD) and quadword (PSRLQ) data types.

PSRLW instruction with 64-bit operand:
IF (COUNT > 15)
THEN DEST[64..0] ? 0000000000000000H
ELSE DEST[15..0] ? ZeroExtend(DEST[15..0] >> COUNT);
* repeat shift operation for 2nd and 3rd words *;
DEST[63..48] ? ZeroExtend(DEST[63..48] >> COUNT);

PSRLD instruction with 64-bit operand:
IF (COUNT > 31)
THEN DEST[64..0] ? 0000000000000000H
ELSE DEST[31..0] ? ZeroExtend(DEST[31..0] >> COUNT);
DEST[63..32] ? ZeroExtend(DEST[63..32] >> COUNT);

PSRLQ instruction with 64-bit operand:
IF (COUNT > 63)
THEN DEST[64..0] ? 0000000000000000H
ELSE DEST ? ZeroExtend(DEST >> COUNT);

PSRLW __m64 _mm_srli_pi16(__m64 m, int count)
PSRLW __m64 _mm_srl_pi16 (__m64 m, __m64 count)

PSRLD __m64 _mm_srli_pi32 (__m64 m, int count)
PSRLD __m64 _mm_srl_pi32 (__m64 m, __m64 count)

PSRLQ __m64 _mm_srli_si64 (__m64 m, int count)
PSRLQ __m64 _mm_srl_si64 (__m64 m, __m64 count)


 

PSRAW mm, mm/m64
PSRAW mm, imm8
PSRAD mm, mm/m64
PSRAD mm, imm8

The PSRA (Packed Shift Right Arithmetic) instructions shift the bits of the first operand to the right by the amount of bits specified in the source operand. The empty high-order bits of each element are filled with the initial value of the sign bit of the data element. If the value specified by the second operand is greater than 15 (for words), or 31 (for doublewords), each destination element is filled with the initial value of the sign bit of the element. The destination operand is an MMX register, while the source operand can be either an MMX register, a 64-bit memory operand, or an immediate 8-bit operand. This instruction supports packed word (PSRAW) and packed doubleword (PSRAD) data types. 

PSRAW instruction with 64-bit operand:
IF (COUNT > 15)
THEN COUNT ? 16;
DEST[15..0] ? SignExtend(DEST[15..0] >> COUNT);
* repeat shift operation for 2nd and 3rd words *;
DEST[63..48] ? SignExtend(DEST[63..48] >> COUNT);

PSRAD instruction with 64-bit operand:
IF (COUNT > 31)
THEN COUNT ? 32;
DEST[31..0] ? SignExtend(DEST[31..0] >> COUNT);
DEST[63..32] ? SignExtend(DEST[63..32] >> COUNT);

PSRAW __m64 _mm_srai_pi16 (__m64 m, int count)

PSRAW __m64 _mm_sraw_pi16 (__m64 m, __m64 count)

PSRAD __m64 _mm_srai_pi32 (__m64 m, int count)

PSRAD __m64 _mm_sra_pi32 (__m64 m, __m64 count)

An example of arithmetic shift usage is the absolute value of a vector of signed words. The following code fragment assumes that the MMX register MM0 holds the signed source operand, while MM1 returns the absolute value of each component of MM0.

MOVQ MM1, MM0 make a copy of source data
PSRAW MM0,15 replicate sign bit
PXOR MM0, MM1 take 1’s complement of just the negative fields
PSUBS MM1,MM0 add 1 to just the negative fields
 

Leave a Reply

Your email address will not be published. Required fields are marked *