VPERMT2W, VPERMT2D, VPERMT2Q, VPERMT2PS, VPERMT2PD

Full Permute From Two Tables Overwriting One Table

stableVMJITAOTinstruction

Encodings

OpcodeInstructionOp/En64-bitCompat/LegacyDescription
EVEX.128.66.0F38.W1 7D /rVPERMT2W xmm1 {k1}{z}, xmm2, xmm3/m128AValidValidPermute word integers from two tables in AVX512BW) OR xmm3/m128 and xmm1 using indexes in xmm2 and AVX10.1 store the result in xmm1 using writemask k1.
EVEX.256.66.0F38.W1 7D /rVPERMT2W ymm1 {k1}{z}, ymm2, ymm3/m256AValidValidPermute word integers from two tables in AVX512BW) OR ymm3/m256 and ymm1 using indexes in ymm2 and AVX10.1 store the result in ymm1 using writemask k1.
EVEX.512.66.0F38.W1 7D /rVPERMT2W zmm1 {k1}{z}, zmm2, zmm3/m512AValidValidPermute word integers from two tables in OR AVX10.1 zmm3/m512 and zmm1 using indexes in zmm2 and store the result in zmm1 using writemask k1.
EVEX.128.66.0F38.W0 7E /rVPERMT2D xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcstBValidValidPermute double-words from two tables in AVX512F) OR xmm3/m128/m32bcst and xmm1 using indexes in AVX10.1 xmm2 and store the result in xmm1 using writemask k1.
EVEX.256.66.0F38.W0 7E /rVPERMT2D ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcstBValidValidPermute double-words from two tables in AVX512F) OR ymm3/m256/m32bcst and ymm1 using indexes in AVX10.1 ymm2 and store the result in ymm1 using writemask k1.
EVEX.512.66.0F38.W0 7E /rVPERMT2D zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcstBValidValidPermute double-words from two tables in OR AVX10.1 zmm3/m512/m32bcst and zmm1 using indices in zmm2 and store the result in zmm1 using writemask k1.
EVEX.128.66.0F38.W1 7E /rVPERMT2Q xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcstBValidValidPermute quad-words from two tables in AVX512F) OR xmm3/m128/m64bcst and xmm1 using indexes in AVX10.1 xmm2 and store the result in xmm1 using writemask k1.
EVEX.256.66.0F38.W1 7E /rVPERMT2Q ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcstBValidValidPermute quad-words from two tables in AVX512F) OR ymm3/m256/m64bcst and ymm1 using indexes in AVX10.1 ymm2 and store the result in ymm1 using writemask k1.
EVEX.512.66.0F38.W1 7E /rVPERMT2Q zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcstBValidValidPermute quad-words from two tables in OR AVX10.1 zmm3/m512/m64bcst and zmm1 using indices in zmm2 and store the result in zmm1 using writemask k1.
EVEX.128.66.0F38.W0 7F /rVPERMT2PS xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcstBValidValidPermute single-precision floating-point values from AVX512F) OR two tables in xmm3/m128/m32bcst and xmm1 AVX10.1 using indexes in xmm2 and store the result in xmm1 using writemask k1.
EVEX.256.66.0F38.W0 7F /rVPERMT2PS ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcstBValidValidPermute single-precision floating-point values from AVX512F) OR two tables in ymm3/m256/m32bcst and ymm1 AVX10.1 using indexes in ymm2 and store the result in ymm1 using writemask k1.
EVEX.512.66.0F38.W0 7F /rVPERMT2PS zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst Opcode/ Op Instruction EnBValidValidPermute single-precision floating-point values from OR AVX10.1 two tables in zmm3/m512/m32bcst and zmm1 using indices in zmm2 and store the result in zmm1 using writemask k1. / 6 4/32 CPUID Feature Description b S it Mode Flag upport
EVEX.128.66.0F38.W1 7F /rVPERMT2PD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcstBValidPermute double precision floating-point values from AVX512F) OR two tables in xmm3/m128/m64bcst and xmm1 AVX10.1 using indexes in xmm2 and store the result in xmm1 using writemask k1.
EVEX.256.66.0F38.W1 7F /rVPERMT2PD ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcstBValidPermute double precision floating-point values from AVX512F) OR two tables in ymm3/m256/m64bcst and ymm1 AVX10.1 using indexes in ymm2 and store the result in ymm1 using writemask k1.
EVEX.512.66.0F38.W1 7F /rVPERMT2PD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcstBValidPermute double precision floating-point values from OR AVX10.1 two tables in zmm3/m512/m64bcst and zmm1 using indices in zmm2 and store the result in zmm1 using writemask k1.

Operand encoding

Each mode is a value of the Op/En column above. It says which field of the encoded instruction carries each operand, in the order they are written, and whether the instruction reads it, writes it or both.

A

  1. modrm.reg lectura y escrituraModRM byte, reg field (bits 5-3)
  2. evex.vvvv lecturaEVEX prefix, vvvv field (inverted)
  3. modrm.rm lecturaModRM byte, r/m field (bits 2-0); with the SIB byte and the displacement when the mod field asks for them

Tupla: Full Mem

B

  1. modrm.reg lectura y escrituraModRM byte, reg field (bits 5-3)
  2. evex.vvvv lecturaEVEX prefix, vvvv field (inverted)
  3. modrm.rm lecturaModRM byte, r/m field (bits 2-0); with the SIB byte and the displacement when the mod field asks for them

Tupla: Full

Measured cost

Loading measurements from arch-data...

Description

Permutes 16-bit/32-bit/64-bit values in the first operand and the third operand (the second source operand) using indices in the second operand (the first source operand) to select elements from the first and third operands. The selected elements are written to the destination operand (the first operand) according to the writemask k1.

The first and second operands are ZMM/YMM/XMM registers. The second operand contains input indices to select elements from the two input tables in the 1st and 3rd operands. The first operand is also the destination of the result.

D/Q/PS/PD element versions: The second source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a 32/64-bit memory location. Broadcast from the low 32/64-bit memory location is performed if EVEX.b and the id bit for table selection are set (selecting table_2).

Dword/PS versions: The id bit for table selection is bit 4/3/2, depending on VL=512, 256, 128. Bits [3:0]/[2:0]/[1:0] of each element in the input index vector select an element within the two source operands, If the id bit is 0, table_1 (the first source) is selected; otherwise the second source operand is selected.

Qword/PD versions: The id bit for table selection is bit 3/2/1, and bits [2:0]/[1:0] /bit 0 selects element within each input table.

Word element versions: The second source operand can be a ZMM/YMM/XMM register, or a 512/256/128-bit memory location. The id bit for table selection is bit 5/4/3, and bits [4:0]/[3:0]/[2:0] selects element within each input table.

Note that these instructions permit a 16-bit/32-bit/64-bit value in the source operands to be copied to more than one location in the destination operand. Note also that in this case, the same index can be reused for example for a second iteration, while the table elements being permuted are overwritten.

Bits (MAXVL-1:256/128) of the destination are zeroed for VL=256,128.

Operation

VPERMT2W (EVEX encoded versions)

(KL, VL) = (8, 128), (16, 256), (32, 512)

IF VL = 128

     id := 2

FI;

IF VL = 256

     id := 3

FI;

IF VL = 512

     id := 4

FI;

TMP_DEST := DEST

FOR j := 0 TO KL-1

     i := j * 16

     off := 16*SRC1[i+id:i]

     IF k1[j] OR *no writemask*

          THEN

                  DEST[i+15:i]=SRC1[i+id+1] ? SRC2[off+15:off]

                      : TMP_DEST[off+15:off]

          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

VPERMT2D/VPERMT2PS (EVEX encoded versions)
(KL, VL) = (4, 128), (8, 256), (16, 512)
IF VL = 128

    id := 1
FI;
IF VL = 256

    id := 2
FI;
IF VL = 512

    id := 3
FI;
TMP_DEST := DEST
FOR j := 0 TO KL-1

    i := j * 32
    off := 32*SRC1[i+id:i]
    IF k1[j] OR *no writemask*

          THEN
                IF (EVEX.b = 1) AND (SRC2 *is memory*)
                      THEN
                            DEST[i+31:i] := SRC1[i+id+1] ? SRC2[31:0]
                           : TMP_DEST[off+31:off]
                ELSE
                      DEST[i+31:i] := SRC1[i+id+1] ? SRC2[off+31:off]
                           : TMP_DEST[off+31:off]


                  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

VPERMT2Q/VPERMT2PD (EVEX encoded versions)

(KL, VL) = (2, 128), (4, 256), (8 512)

IF VL = 128

     id := 0

FI;

IF VL = 256

     id := 1

FI;

IF VL = 512

     id := 2

FI;

TMP_DEST:= DEST

FOR j := 0 TO KL-1

     i := j * 64

     off := 64*SRC1[i+id:i]

     IF k1[j] OR *no writemask*

          THEN

                  IF (EVEX.b = 1) AND (SRC2 *is memory*)

                      THEN

                        DEST[i+63:i] := SRC1[i+id+1] ? SRC2[63:0]

                        : TMP_DEST[off+63:off]

                  ELSE

                      DEST[i+63:i] := SRC1[i+id+1] ? SRC2[off+63:off]

                        : TMP_DEST[off+63:off]

                  FI

          ELSE

                  IF *merging-masking*          ; merging-masking

                      THEN *DEST[i+63:i] remains unchanged*

                      ELSE                      ; zeroing-masking

                        DEST[i+63:i] := 0

                  FI

     FI;

ENDFOR

DEST[MAXVL-1:VL] := 0

Intel C/C++ compiler intrinsics

VPERMT2D __m512i _mm512_permutex2var_epi32(__m512i a, __m512i idx, __m512i b);
VPERMT2D __m512i _mm512_mask_permutex2var_epi32(__m512i a, __mmask16 k, __m512i idx, __m512i b);
VPERMT2D __m512i _mm512_mask2_permutex2var_epi32(__m512i a, __m512i idx, __mmask16 k, __m512i b);
VPERMT2D __m512i _mm512_maskz_permutex2var_epi32(__mmask16 k, __m512i a, __m512i idx, __m512i b);
VPERMT2D __m256i _mm256_permutex2var_epi32(__m256i a, __m256i idx, __m256i b);
VPERMT2D __m256i _mm256_mask_permutex2var_epi32(__m256i a, __mmask8 k, __m256i idx, __m256i b);
VPERMT2D __m256i _mm256_mask2_permutex2var_epi32(__m256i a, __m256i idx, __mmask8 k, __m256i b);
VPERMT2D __m256i _mm256_maskz_permutex2var_epi32(__mmask8 k, __m256i a, __m256i idx, __m256i b);
VPERMT2D __m128i _mm_permutex2var_epi32(__m128i a, __m128i idx, __m128i b);
VPERMT2D __m128i _mm_mask_permutex2var_epi32(__m128i a, __mmask8 k, __m128i idx, __m128i b);
VPERMT2D __m128i _mm_mask2_permutex2var_epi32(__m128i a, __m128i idx, __mmask8 k, __m128i b);
VPERMT2D __m128i _mm_maskz_permutex2var_epi32(__mmask8 k, __m128i a, __m128i idx, __m128i b);
VPERMT2PD __m512d _mm512_permutex2var_pd(__m512d a, __m512i idx, __m512d b);
VPERMT2PD __m512d _mm512_mask_permutex2var_pd(__m512d a, __mmask8 k, __m512i idx, __m512d b);
VPERMT2PD __m512d _mm512_mask2_permutex2var_pd(__m512d a, __m512i idx, __mmask8 k, __m512d b);
VPERMT2PD __m512d _mm512_maskz_permutex2var_pd(__mmask8 k, __m512d a, __m512i idx, __m512d b);
VPERMT2PD __m256d _mm256_permutex2var_pd(__m256d a, __m256i idx, __m256d b);
VPERMT2PD __m256d _mm256_mask_permutex2var_pd(__m256d a, __mmask8 k, __m256i idx, __m256d b);
VPERMT2PD __m256d _mm256_mask2_permutex2var_pd(__m256d a, __m256i idx, __mmask8 k, __m256d b);
VPERMT2PD __m256d _mm256_maskz_permutex2var_pd(__mmask8 k, __m256d a, __m256i idx, __m256d b);
VPERMT2PD __m128d _mm_permutex2var_pd(__m128d a, __m128i idx, __m128d b);
VPERMT2PD __m128d _mm_mask_permutex2var_pd(__m128d a, __mmask8 k, __m128i idx, __m128d b);
VPERMT2PD __m128d _mm_mask2_permutex2var_pd(__m128d a, __m128i idx, __mmask8 k, __m128d b);
VPERMT2PD __m128d _mm_maskz_permutex2var_pd(__mmask8 k, __m128d a, __m128i idx, __m128d b);
VPERMT2PS __m512 _mm512_permutex2var_ps(__m512 a, __m512i idx, __m512 b);
VPERMT2PS __m512 _mm512_mask_permutex2var_ps(__m512 a, __mmask16 k, __m512i idx, __m512 b);
VPERMT2PS __m512 _mm512_mask2_permutex2var_ps(__m512 a, __m512i idx, __mmask16 k, __m512 b);
VPERMT2PS __m512 _mm512_maskz_permutex2var_ps(__mmask16 k, __m512 a, __m512i idx, __m512 b);
VPERMT2PS __m256 _mm256_permutex2var_ps(__m256 a, __m256i idx, __m256 b);
VPERMT2PS __m256 _mm256_mask_permutex2var_ps(__m256 a, __mmask8 k, __m256i idx, __m256 b);
VPERMT2PS __m256 _mm256_mask2_permutex2var_ps(__m256 a, __m256i idx, __mmask8 k, __m256 b);
VPERMT2PS __m256 _mm256_maskz_permutex2var_ps(__mmask8 k, __m256 a, __m256i idx, __m256 b);
VPERMT2PS __m128 _mm_permutex2var_ps(__m128 a, __m128i idx, __m128 b);
VPERMT2PS __m128 _mm_mask_permutex2var_ps(__m128 a, __mmask8 k, __m128i idx, __m128 b);
VPERMT2PS __m128 _mm_mask2_permutex2var_ps(__m128 a, __m128i idx, __mmask8 k, __m128 b);
VPERMT2PS __m128 _mm_maskz_permutex2var_ps(__mmask8 k, __m128 a, __m128i idx, __m128 b);
VPERMT2Q __m512i _mm512_permutex2var_epi64(__m512i a, __m512i idx, __m512i b);
VPERMT2Q __m512i _mm512_mask_permutex2var_epi64(__m512i a, __mmask8 k, __m512i idx, __m512i b);
VPERMT2Q __m512i _mm512_mask2_permutex2var_epi64(__m512i a, __m512i idx, __mmask8 k, __m512i b);
VPERMT2Q __m512i _mm512_maskz_permutex2var_epi64(__mmask8 k, __m512i a, __m512i idx, __m512i b);
VPERMT2Q __m256i _mm256_permutex2var_epi64(__m256i a, __m256i idx, __m256i b);
VPERMT2Q __m256i _mm256_mask_permutex2var_epi64(__m256i a, __mmask8 k, __m256i idx, __m256i b);
VPERMT2Q __m256i _mm256_mask2_permutex2var_epi64(__m256i a, __m256i idx, __mmask8 k, __m256i b);
VPERMT2Q __m256i _mm256_maskz_permutex2var_epi64(__mmask8 k, __m256i a, __m256i idx, __m256i b);
VPERMT2Q __m128i _mm_permutex2var_epi64(__m128i a, __m128i idx, __m128i b);
VPERMT2Q __m128i _mm_mask_permutex2var_epi64(__m128i a, __mmask8 k, __m128i idx, __m128i b);
VPERMT2Q __m128i _mm_mask2_permutex2var_epi64(__m128i a, __m128i idx, __mmask8 k, __m128i b);
VPERMT2Q __m128i _mm_maskz_permutex2var_epi64(__mmask8 k, __m128i a, __m128i idx, __m128i b);
VPERMT2W __m512i _mm512_permutex2var_epi16(__m512i a, __m512i idx, __m512i b);
VPERMT2W __m512i _mm512_mask_permutex2var_epi16(__m512i a, __mmask32 k, __m512i idx, __m512i b);
VPERMT2W __m512i _mm512_mask2_permutex2var_epi16(__m512i a, __m512i idx, __mmask32 k, __m512i b);
VPERMT2W __m512i _mm512_maskz_permutex2var_epi16(__mmask32 k, __m512i a, __m512i idx, __m512i b);
VPERMT2W __m256i _mm256_permutex2var_epi16(__m256i a, __m256i idx, __m256i b);
VPERMT2W __m256i _mm256_mask_permutex2var_epi16(__m256i a, __mmask16 k, __m256i idx, __m256i b);
VPERMT2W __m256i _mm256_mask2_permutex2var_epi16(__m256i a, __m256i idx, __mmask16 k, __m256i b);
VPERMT2W __m256i _mm256_maskz_permutex2var_epi16(__mmask16 k, __m256i a, __m256i idx, __m256i b);
VPERMT2W __m128i _mm_permutex2var_epi16(__m128i a, __m128i idx, __m128i b);
VPERMT2W __m128i _mm_mask_permutex2var_epi16(__m128i a, __mmask8 k, __m128i idx, __m128i b);
VPERMT2W __m128i _mm_mask2_permutex2var_epi16(__m128i a, __m128i idx, __mmask8 k, __m128i b);
VPERMT2W __m128i _mm_maskz_permutex2var_epi16(__mmask8 k, __m128i a, __m128i idx, __m128i b);

SIMD Floating-Point Exceptions

None.

Other Exceptions

VPERMT2D/Q/PS/PD: See Table 2-52, "Type E4NF Class Exception Conditions." VPERMT2W: See Exceptions Type E4NF.nb in Table 2-52, "Type E4NF Class Exception Conditions."

Sources