vpermd

Permute Doublewords

VPERMD ymm1, ymm2, ymm3/m256

Full permutation of 8 integers using indices from a register.

Details

Performs a full permutation of 8 doublewords (32-bit integers) within a 256-bit YMM register using per-element indices from another YMM register or memory. The low 3 bits of each index select which of the 8 source doublewords to place at that position; if bit 31 is set in the index, the result element is zeroed. No arithmetic flags are affected.

Pseudocode Operation

for i = 0 to 7:
  idx = src1[i*32 + 31 : i*32]
  if idx[31] == 1:
    dest[i*32 + 31 : i*32] ← 0
  else:
    src_idx = idx[2:0]
    dest[i*32 + 31 : i*32] ← src2[src_idx*32 + 31 : src_idx*32]

Example

VPERMD ymm1, ymm2, ymm3/m256

Encoding

Binary Layout
VEX
+0
opcode
+3
ModRM
+4
 
Format VEX
Opcode VEX.256.66.0F38.W0 36 /r
Extension AVX2

Operands

  • dest
    256-bit YMM AVX register
  • src1
    256-bit YMM AVX register
  • src2
    256-bit YMM AVX register or Memory operand

Reference (Intel® SDM)

Instruction Forms

Opcode Instruction Op/En 64/32-bit Mode CPUID Description
VEX.256.66.0F38.W0 36 /r VPERMD ymm1, ymm2, ymm3/m256 A V/V AVX2 Permute doublewords in ymm3/m256 using indices in ymm2 and store the result in ymm1.
EVEX.256.66.0F38.W0 36 /r VPERMD ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst B V/V (AVX512VL AND AVX512F) OR AVX10.1 Permute doublewords in ymm3/m256/m32bcst using indexes in ymm2 and store the result in ymm1 using writemask k1.
EVEX.512.66.0F38.W0 36 /r VPERMD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst B V/V AVX512F OR AVX10.1 Permute doublewords in zmm3/m512/m32bcst using indices in zmm2 and store the result in zmm1 using writemask k1.
EVEX.128.66.0F38.W1 8D /r VPERMW xmm1 {k1}{z}, xmm2, xmm3/m128 C V/V (AVX512VL AND AVX512BW) OR AVX10.1 Permute word integers in xmm3/m128 using indexes in xmm2 and store the result in xmm1 using writemask k1.
EVEX.256.66.0F38.W1 8D /r VPERMW ymm1 {k1}{z}, ymm2, ymm3/m256 C V/V (AVX512VL AND AVX512BW) OR AVX10.1 Permute word integers in ymm3/m256 using indexes in ymm2 and store the result in ymm1 using writemask k1.
EVEX.512.66.0F38.W1 8D /r VPERMW zmm1 {k1}{z}, zmm2, zmm3/m512 C V/V AVX512BW OR AVX10.1 Permute word integers in zmm3/m512 using indexes in zmm2 and store the result in zmm1 using writemask k1.

Instruction Operand Encoding

Op/En Tuple Type Operand 1 Operand 2 Operand 3 Operand 4
A N/A ModRM:reg (w) VEX.vvvv (r) ModRM:r/m (r) N/A
B Full ModRM:reg (w) EVEX.vvvv (r) ModRM:r/m (r) N/A
C Full Mem ModRM:reg (w) EVEX.vvvv (r) ModRM:r/m (r) N/A

Description

Copies doublewords (or words) from the second source operand (the third operand) to the destination operand (the first operand) according to the indices in the first source operand (the second operand). Note that this instruction permits a doubleword (word) in the source operand to be copied to more than one location in the destination operand. VEX.256 encoded VPERMD: The first and second operands are YMM registers, the third operand can be a YMM register or memory location. Bits (MAXVL-1:256) of the corresponding destination register are zeroed. EVEX encoded VPERMD: The first and second operands are ZMM/YMM registers, the third operand can be a ZMM/YMM register, a 512/256-bit memory location or a 512/256-bit vector broadcasted from a 32-bit memory location. The elements in the destination are updated using the writemask k1. VPERMW: first and second operands are ZMM/YMM/XMM registers, the third operand can be a ZMM/YMM/XMM register, or a 512/256/128-bit memory location. The destination is updated using the writemask k1. EVEX.128 encoded versions: Bits (MAXVL-1:128) of the corresponding ZMM register are zeroed. VPERMD/VPERMW—Permute Packed Doubleword/Word Elements Vol. 2C 5-500

Operation

VPERMD (EVEX encoded versions)
(KL, VL) = (8, 256), (16, 512)
IF VL = 256 THEN n := 2; FI;
IF VL = 512 THEN n := 3; FI;
FOR j := 0 TO KL-1
i := j * 32
id := 32*SRC1[i+n:i]
IF k1[j] OR *no writemask*
THEN
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN DEST[i+31:i] := SRC2[31:0];
ELSE DEST[i+31:i] := SRC2[id+31:id];
FI;
ELSE
IF *merging-masking*                                 ; merging-masking
THEN *DEST[i+31:i] remains unchanged*
ELSE                                                         ; zeroing-masking
DEST[i+31:i] := 0
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0

VPERMD (VEX.256 encoded version)
DEST[31:0] := (SRC2[255:0] >> (SRC1[2:0] * 32))[31:0];
DEST[63:32] := (SRC2[255:0] >> (SRC1[34:32] * 32))[31:0];
DEST[95:64] := (SRC2[255:0] >> (SRC1[66:64] * 32))[31:0];
DEST[127:96] := (SRC2[255:0] >> (SRC1[98:96] * 32))[31:0];
DEST[159:128] := (SRC2[255:0] >> (SRC1[130:128] * 32))[31:0];
DEST[191:160] := (SRC2[255:0] >> (SRC1[162:160] * 32))[31:0];
DEST[223:192] := (SRC2[255:0] >> (SRC1[194:192] * 32))[31:0];
DEST[255:224] := (SRC2[255:0] >> (SRC1[226:224] * 32))[31:0];
DEST[MAXVL-1:256] := 0

VPERMW (EVEX encoded versions)
(KL, VL) = (8, 128), (16, 256), (32, 512)
IF VL = 128 THEN n := 2; FI;
IF VL = 256 THEN n := 3; FI;
IF VL = 512 THEN n := 4; FI;
FOR j := 0 TO KL-1
i := j * 16
id := 16*SRC1[i+n:i]
IF k1[j] OR *no writemask*
THEN DEST[i+15:i] := SRC2[id+15:id]
ELSE
IF *merging-masking*                                 ; merging-masking
THEN *DEST[i+15:i] remains unchanged*
ELSE                                                         ; zeroing-masking
DEST[i+15:i] := 0
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0


VPERMD/VPERMW—Permute Packed Doubleword/Word Elements                                                                              Vol. 2C 5-501

Intel C/C++ Compiler Intrinsic Equivalent

VPERMD __m512i _mm512_permutexvar_epi32( __m512i idx, __m512i a);
VPERMD __m512i _mm512_mask_permutexvar_epi32(__m512i s, __mmask16 k, __m512i idx, __m512i a);
VPERMD __m512i _mm512_maskz_permutexvar_epi32( __mmask16 k, __m512i idx, __m512i a);
VPERMD __m256i _mm256_permutexvar_epi32( __m256i idx, __m256i a);
VPERMD __m256i _mm256_mask_permutexvar_epi32(__m256i s, __mmask8 k, __m256i idx, __m256i a);
VPERMD __m256i _mm256_maskz_permutexvar_epi32( __mmask8 k, __m256i idx, __m256i a);
VPERMW __m512i _mm512_permutexvar_epi16( __m512i idx, __m512i a);
VPERMW __m512i _mm512_mask_permutexvar_epi16(__m512i s, __mmask32 k, __m512i idx, __m512i a);
VPERMW __m512i _mm512_maskz_permutexvar_epi16( __mmask32 k, __m512i idx, __m512i a);
VPERMW __m256i _mm256_permutexvar_epi16( __m256i idx, __m256i a);
VPERMW __m256i _mm256_mask_permutexvar_epi16(__m256i s, __mmask16 k, __m256i idx, __m256i a);
VPERMW __m256i _mm256_maskz_permutexvar_epi16( __mmask16 k, __m256i idx, __m256i a);
VPERMW __m128i _mm_permutexvar_epi16( __m128i idx, __m128i a);
VPERMW __m128i _mm_mask_permutexvar_epi16(__m128i s, __mmask8 k, __m128i idx, __m128i a);
VPERMW __m128i _mm_maskz_permutexvar_epi16( __mmask8 k, __m128i idx, __m128i a);

Exceptions

SIMD Floating-Point Exceptions

None

Other Exceptions

Non-EVEX-encoded instruction, see Table 2-21, “Type 4 Class Exception Conditions.” EVEX-encoded VPERMD, see Table 2-52, “Type E4NF Class Exception Conditions.” EVEX-encoded VPERMW, see Exceptions Type E4NF.nb in Table 2-52, “Type E4NF Class Exception Conditions.” Additionally: #UD If VEX.L = 0. If EVEX.L’L = 0 for VPERMD. VPERMD/VPERMW—Permute Packed Doubleword/Word Elements Vol. 2C 5-502