|
|
ELSE DEST[23:16] := DEST[23:16];
IF (MASK[31] = 1) THEN DEST[31:24] := SRC[31:24]
ELSE DEST[31:24] := DEST[31:24];
IF (MASK[39] = 1) THEN DEST[39:32] := SRC[39:32]
ELSE DEST[39:32] := DEST[39:32];
IF (MASK[47] = 1) THEN DEST[47:40] := SRC[47:40]
ELSE DEST[47:40] := DEST[47:40];
IF (MASK[55] = 1) THEN DEST[55:48] := SRC[55:48]
ELSE DEST[55:48] := DEST[55:48];
IF (MASK[63] = 1) THEN DEST[63:56] := SRC[63:56]
ELSE DEST[63:56] := DEST[63:56];
IF (MASK[71] = 1) THEN DEST[71:64] := SRC[71:64]
ELSE DEST[71:64] := DEST[71:64];
IF (MASK[79] = 1) THEN DEST[79:72] := SRC[79:72]
ELSE DEST[79:72] := DEST[79:72];
IF (MASK[87] = 1) THEN DEST[87:80] := SRC[87:80]
ELSE DEST[87:80] := DEST[87:80];
IF (MASK[95] = 1) THEN DEST[95:88] := SRC[95:88]
ELSE DEST[95:88] := DEST[95:88];
IF (MASK[103] = 1) THEN DEST[103:96] := SRC[103:96]
ELSE DEST[103:96] := DEST[103:96];
IF (MASK[111] = 1) THEN DEST[111:104] := SRC[111:104]
ELSE DEST[111:104] := DEST[111:104];
IF (MASK[119] = 1) THEN DEST[119:112] := SRC[119:112]
ELSE DEST[119:112] := DEST[119:112];
IF (MASK[127] = 1) THEN DEST[127:120] := SRC[127:120]
ELSE DEST[127:120] := DEST[127:120])
DEST[MAXVL-1:128] (Unmodified)
VPBLENDVB (VEX.128 Encoded Version)
MASK := SRC3
IF (MASK[7] = 1) THEN DEST[7:0] := SRC2[7:0];
ELSE DEST[7:0] := SRC1[7:0];
IF (MASK[15] = 1) THEN DEST[15:8] := SRC2[15:8];
ELSE DEST[15:8] := SRC1[15:8];
IF (MASK[23] = 1) THEN DEST[23:16] := SRC2[23:16]
ELSE DEST[23:16] := SRC1[23:16];
IF (MASK[31] = 1) THEN DEST[31:24] := SRC2[31:24]
ELSE DEST[31:24] := SRC1[31:24];
IF (MASK[39] = 1) THEN DEST[39:32] := SRC2[39:32]
ELSE DEST[39:32] := SRC1[39:32];
IF (MASK[47] = 1) THEN DEST[47:40] := SRC2[47:40]
ELSE DEST[47:40] := SRC1[47:40];
IF (MASK[55] = 1) THEN DEST[55:48] := SRC2[55:48]
ELSE DEST[55:48] := SRC1[55:48];
IF (MASK[63] = 1) THEN DEST[63:56] := SRC2[63:56]
ELSE DEST[63:56] := SRC1[63:56];
IF (MASK[71] = 1) THEN DEST[71:64] := SRC2[71:64]
ELSE DEST[71:64] := SRC1[71:64];
IF (MASK[79] = 1) THEN DEST[79:72] := SRC2[79:72]
ELSE DEST[79:72] := SRC1[79:72];
IF (MASK[87] = 1) THEN DEST[87:80] := SRC2[87:80]
ELSE DEST[87:80] := SRC1[87:80];
IF (MASK[95] = 1) THEN DEST[95:88] := SRC2[95:88]
PBLENDVB-Variable Blend Packed Bytes
Vol. 2B
4-232
ELSE DEST[95:88] := SRC1[95:88];
IF (MASK[103] = 1) THEN DEST[103:96] := SRC2[103:96]
ELSE DEST[103:96] := SRC1[103:96];
IF (MASK[111] = 1) THEN DEST[111:104] := SRC2[111:104]
ELSE DEST[111:104] := SRC1[111:104];
IF (MASK[119] = 1) THEN DEST[119:112] := SRC2[119:112]
ELSE DEST[119:112] := SRC1[119:112];
IF (MASK[127] = 1) THEN DEST[127:120] := SRC2[127:120]
ELSE DEST[127:120] := SRC1[127:120])
DEST[MAXVL-1:128] := 0
VPBLENDVB (VEX.256 Encoded Version)
MASK := SRC3
IF (MASK[7] == 1) THEN DEST[7:0] := SRC2[7:0];
ELSE DEST[7:0] := SRC1[7:0];
IF (MASK[15] == 1) THEN DEST[15:8] := SRC2[15:8];
ELSE DEST[15:8] := SRC1[15:8];
IF (MASK[23] == 1) THEN DEST[23:16] := SRC2[23:16]
ELSE DEST[23:16] := SRC1[23:16];
IF (MASK[31] == 1) THEN DEST[31:24] := SRC2[31:24]
ELSE DEST[31:24] := SRC1[31:24];
IF (MASK[39] == 1) THEN DEST[39:32] := SRC2[39:32]
ELSE DEST[39:32] := SRC1[39:32];
IF (MASK[47] == 1) THEN DEST[47:40] := SRC2[47:40]
ELSE DEST[47:40] := SRC1[47:40];
IF (MASK[55] == 1) THEN DEST[55:48] := SRC2[55:48]
ELSE DEST[55:48] := SRC1[55:48];
IF (MASK[63] == 1) THEN DEST[63:56] := SRC2[63:56]
ELSE DEST[63:56] := SRC1[63:56];
IF (MASK[71] == 1) THEN DEST[71:64] := SRC2[71:64]
ELSE DEST[71:64] := SRC1[71:64];
IF (MASK[79] == 1) THEN DEST[79:72] := SRC2[79:72]
ELSE DEST[79:72] := SRC1[79:72];
IF (MASK[87] == 1) THEN DEST[87:80] := SRC2[87:80]
ELSE DEST[87:80] := SRC1[87:80];
IF (MASK[95] == 1) THEN DEST[95:88] := SRC2[95:88]
ELSE DEST[95:88] := SRC1[95:88];
IF (MASK[103] == 1) THEN DEST[103:96] := SRC2[103:96]
ELSE DEST[103:96] := SRC1[103:96];
IF (MASK[111] == 1) THEN DEST[111:104] := SRC2[111:104]
ELSE DEST[111:104] := SRC1[111:104];
IF (MASK[119] == 1) THEN DEST[119:112] := SRC2[119:112]
ELSE DEST[119:112] := SRC1[119:112];
IF (MASK[127] == 1) THEN DEST[127:120] := SRC2[127:120]
ELSE DEST[127:120] := SRC1[127:120])
IF (MASK[135] == 1) THEN DEST[135:128] := SRC2[135:128];
ELSE DEST[135:128] := SRC1[135:128];
IF (MASK[143] == 1) THEN DEST[143:136] := SRC2[143:136];
ELSE DEST[[143:136] := SRC1[143:136];
IF (MASK[151] == 1) THEN DEST[151:144] := SRC2[151:144]
ELSE DEST[151:144] := SRC1[151:144];
IF (MASK[159] == 1) THEN DEST[159:152] := SRC2[159:152]
ELSE DEST[159:152] := SRC1[159:152];
IF (MASK[167] == 1) THEN DEST[167:160] := SRC2[167:160]
PBLENDVB-Variable Blend Packed Bytes
Vol. 2B
4-233
ELSE DEST[167:160] := SRC1[167:160];
IF (MASK[175] == 1) THEN DEST[175:168] := SRC2[175:168]
ELSE DEST[175:168] := SRC1[175:168];
IF (MASK[183] == 1) THEN DEST[183:176] := SRC2[183:176]
ELSE DEST[183:176] := SRC1[183:176];
IF (MASK[191] == 1) THEN DEST[191:184] := SRC2[191:184]
ELSE DEST[191:184] := SRC1[191:184];
IF (MASK[199] == 1) THEN DEST[199:192] := SRC2[199:192]
ELSE DEST[199:192] := SRC1[199:192];
IF (MASK[207] == 1) THEN DEST[207:200] := SRC2[207:200]
ELSE DEST[207:200] := SRC1[207:200]
IF (MASK[215] == 1) THEN DEST[215:208] := SRC2[215:208]
ELSE DEST[215:208] := SRC1[215:208];
IF (MASK[223] == 1) THEN DEST[223:216] := SRC2[223:216]
ELSE DEST[223:216] := SRC1[223:216];
IF (MASK[231] == 1) THEN DEST[231:224] := SRC2[231:224]
ELSE DEST[231:224] := SRC1[231:224];
IF (MASK[239] == 1) THEN DEST[239:232] := SRC2[239:232]
ELSE DEST[239:232] := SRC1[239:232];
IF (MASK[247] == 1) THEN DEST[247:240] := SRC2[247:240]
ELSE DEST[247:240] := SRC1[247:240];
IF (MASK[255] == 1) THEN DEST[255:248] := SRC2[255:248]
ELSE DEST[255:248] := SRC1[255:248]
Intel C/C++ Compiler Intrinsic Equivalent
(V)PBLENDVB __m128i _mm_blendv_epi8 (__m128i v1, __m128i v2, __m128i mask);
VPBLENDVB __m256i _mm256_blendv_epi8 (__m256i v1, __m256i v2, __m256i mask);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally:
#UD
If VEX.W = 1.
PBLENDVB-Variable Blend Packed Bytes
Vol. 2B
4-234
PBLENDW-Blend Packed Words
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
66 0F 3A 0E /r ib
RMI
V/V
SSE4_1
Select words from xmm1 and xmm2/m128 from
PBLENDW xmm1, xmm2/m128, imm8
mask specified in imm8 and store the values into
xmm1.
VEX.128.66.0F3A.WIG 0E /r ib
RVMI
V/V
AVX
Select words from xmm2 and xmm3/m128 from
VPBLENDW xmm1, xmm2, xmm3/m128, imm8
mask specified in imm8 and store the values into
xmm1.
VEX.256.66.0F3A.WIG 0E /r ib
RVMI
V/V
AVX2
Select words from ymm2 and ymm3/m256 from
VPBLENDW ymm1, ymm2, ymm3/m256, imm8
mask specified in imm8 and store the values into
ymm1.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMI
ModRM:reg (r, w)
ModRM:r/m (r)
imm8
N/A
RVMI
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Words from the source operand (second operand) are conditionally written to the destination operand (first
operand) depending on bits in the immediate operand (third operand). The immediate bits (bits 7:0) form a mask
that determines whether the corresponding word in the destination is copied from the source. If a bit in the mask,
corresponding to a word, is “1”, then the word is copied, else the word element in the destination operand is
unchanged.
128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The
first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination
register remain unchanged.
VEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The
first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register
are zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register
or a 256-bit memory location. The destination operand is a YMM register.
Operation
PBLENDW (128-bit Legacy SSE Version)
IF (imm8[0] = 1) THEN DEST[15:0] := SRC[15:0]
ELSE DEST[15:0] := DEST[15:0]
IF (imm8[1] = 1) THEN DEST[31:16] := SRC[31:16]
ELSE DEST[31:16] := DEST[31:16]
IF (imm8[2] = 1) THEN DEST[47:32] := SRC[47:32]
ELSE DEST[47:32] := DEST[47:32]
IF (imm8[3] = 1) THEN DEST[63:48] := SRC[63:48]
ELSE DEST[63:48] := DEST[63:48]
IF (imm8[4] = 1) THEN DEST[79:64] := SRC[79:64]
ELSE DEST[79:64] := DEST[79:64]
IF (imm8[5] = 1) THEN DEST[95:80] := SRC[95:80]
ELSE DEST[95:80] := DEST[95:80]
IF (imm8[6] = 1) THEN DEST[111:96] := SRC[111:96]
ELSE DEST[111:96] := DEST[111:96]
IF (imm8[7] = 1) THEN DEST[127:112] := SRC[127:112]
PBLENDW-Blend Packed Words
Vol. 2B
4-235
ELSE DEST[127:112] := DEST[127:112]
VPBLENDW (VEX.128 Encoded Version)
IF (imm8[0] = 1) THEN DEST[15:0] := SRC2[15:0]
ELSE DEST[15:0] := SRC1[15:0]
IF (imm8[1] = 1) THEN DEST[31:16] := SRC2[31:16]
ELSE DEST[31:16] := SRC1[31:16]
IF (imm8[2] = 1) THEN DEST[47:32] := SRC2[47:32]
ELSE DEST[47:32] := SRC1[47:32]
IF (imm8[3] = 1) THEN DEST[63:48] := SRC2[63:48]
ELSE DEST[63:48] := SRC1[63:48]
IF (imm8[4] = 1) THEN DEST[79:64] := SRC2[79:64]
ELSE DEST[79:64] := SRC1[79:64]
IF (imm8[5] = 1) THEN DEST[95:80] := SRC2[95:80]
ELSE DEST[95:80] := SRC1[95:80]
IF (imm8[6] = 1) THEN DEST[111:96] := SRC2[111:96]
ELSE DEST[111:96] := SRC1[111:96]
IF (imm8[7] = 1) THEN DEST[127:112] := SRC2[127:112]
ELSE DEST[127:112] := SRC1[127:112]
DEST[MAXVL-1:128] := 0
VPBLENDW (VEX.256 Encoded Version)
IF (imm8[0] == 1) THEN DEST[15:0] := SRC2[15:0]
ELSE DEST[15:0] := SRC1[15:0]
IF (imm8[1] == 1) THEN DEST[31:16] := SRC2[31:16]
ELSE DEST[31:16] := SRC1[31:16]
IF (imm8[2] == 1) THEN DEST[47:32] := SRC2[47:32]
ELSE DEST[47:32] := SRC1[47:32]
IF (imm8[3] == 1) THEN DEST[63:48] := SRC2[63:48]
ELSE DEST[63:48] := SRC1[63:48]
IF (imm8[4] == 1) THEN DEST[79:64] := SRC2[79:64]
ELSE DEST[79:64] := SRC1[79:64]
IF (imm8[5] == 1) THEN DEST[95:80] := SRC2[95:80]
ELSE DEST[95:80] := SRC1[95:80]
IF (imm8[6] == 1) THEN DEST[111:96] := SRC2[111:96]
ELSE DEST[111:96] := SRC1[111:96]
IF (imm8[7] == 1) THEN DEST[127:112] := SRC2[127:112]
ELSE DEST[127:112] := SRC1[127:112]
IF (imm8[0] == 1) THEN DEST[143:128] := SRC2[143:128]
ELSE DEST[143:128] := SRC1[143:128]
IF (imm8[1] == 1) THEN DEST[159:144] := SRC2[159:144]
ELSE DEST[159:144] := SRC1[159:144]
IF (imm8[2] == 1) THEN DEST[175:160] := SRC2[175:160]
ELSE DEST[175:160] := SRC1[175:160]
IF (imm8[3] == 1) THEN DEST[191:176] := SRC2[191:176]
ELSE DEST[191:176] := SRC1[191:176]
IF (imm8[4] == 1) THEN DEST[207:192] := SRC2[207:192]
ELSE DEST[207:192] := SRC1[207:192]
IF (imm8[5] == 1) THEN DEST[223:208] := SRC2[223:208]
ELSE DEST[223:208] := SRC1[223:208]
IF (imm8[6] == 1) THEN DEST[239:224] := SRC2[239:224]
ELSE DEST[239:224] := SRC1[239:224]
IF (imm8[7] == 1) THEN DEST[255:240] := SRC2[255:240]
ELSE DEST[255:240] := SRC1[255:240]
PBLENDW-Blend Packed Words
Vol. 2B
4-236
Intel C/C++ Compiler Intrinsic Equivalent
(V)PBLENDW __m128i _mm_blend_epi16 (__m128i v1, __m128i v2, const int mask);
VPBLENDW __m256i _mm256_blend_epi16 (__m256i v1, __m256i v2, const int mask)
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally:
#UD
If VEX.L = 1 and AVX2 = 0.
PBLENDW-Blend Packed Words
Vol. 2B
4-237
PBNDKB-Platform Bind Key to Binary Large Object
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
bit Mode
Flag
Support
NP 0F 01 C7
ZO
V/I
PBNDKB
This instruction is used to bind information to a
platform by encrypting it with a platform-specific
PBNDKB
wrapping key.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
The PBNDKB instruction allows software to bind information to a platform by encrypting it with a platform-specific
wrapping key. The encrypted data may later be used by the PCONFIG instruction to configure the total storage
encryption (TSE) engine.
The instruction can be executed only in 64-bit mode. The registers RBX and RCX provide input information to the
instruction. Executions of PBNDKB may fail for platform-specific reasons. An execution reports failure by setting
the ZF flag and loading EAX with a non-zero failure reason; a successful execution clears ZF and EAX.
The instruction operates on 256-byte data structures called bind structures. It reads a bind structure at the linear
address in RBX and writes a modified bind structure to the linear address in RCX. The addresses in RBX and RCX
must be different from each other and must be 256-byte aligned.
The instruction encrypts a portion of the input bind structure and generates a MAC of parts of that structure. The
encrypted data and MAC are written out as part of the output bind structure.
The format of a bind structure is given in Table 4-13.
Table 4-13. Bind Structure Format
Field
Offset (bytes)
Size (bytes)
Comments
MAC
0
16
Output by PBNDKB as a MAC based on the input bind structure
Reserved
16
8
Reserved; must be zero on input, output as zero
IV
24
12
Initialization vector generated and output by PBNDKB
Reserved
36
28
Reserved; must be zero on input, output as zero
BTENCDATA
64
64
Encryption data (plaintext on input; ciphertext on output)
BTDATA
128
128
Additional control and data (modified but not encrypted)
A description of each of the fields in a bind structure is provided below:
• MAC: A MAC produced by PBNDKB of parts of its input bind structure. This field in the input bind structure is
not used.
• IV: PBNDKB randomly generates a 96-bit initialization vector and uses it as input to an authenticated
encryption function. The generated IV is written to the output bind structure. If there is insufficient entropy for
the random-number generator, PBNDKB will fail and report the failure by loading EAX with value 1 (ENTRO-
PY_ERROR). This field in the input bind structure is not used.
• BTENCDATA: In the input bind structure, the field contains the data to be encrypted. The data consist of two
256-bit keys, a data key and a tweak key. If the value of the KEY_GENERATION_CTRL field of the BTDATA (see
below) is 1, PBNDKB randomizes the values of these keys before encrypting them. (If there is insufficient
entropy for the random-number generator, PBNDKB will fail and report the failure by loading EAX with value 1
(ENTROPY_ERROR).) PBNDKB writes the encrypted data to this field in the output bind structure.
• BTDATA: This field contains additional control and data that are not encrypted. It has the following format:
PBNDKB-Platform Bind Key to Binary Large Object
Vol. 2B
4-238
— USER_SUPP_CHALLENGE (bytes 31:0): PBNDKB uses this value in the input bind structure to determine
the wrapping key (see below). It writes zero to this field in the output bind structure.
- KEY_GENERATION_CTRL (byte 32): PBNDKB uses this value in the input bind structure to determine
whether to randomize the keys being encrypted. The value must be 0 or 1 (otherwise, a #GP occurs).
- The remaining 95 bytes are reserved and must be zero.
PBNDKB determines a 256-bit wrapping key by computing an HMAC based on SHA-256 using 256-bit platform-
specific key and the USER_SUPP_CHALLENGE in the BTDATA field in the input bind structure.
PBNDKB then uses the wrapping key and an AES GCM authenticated encryption function to encrypt BTENCDATA
and produce a MAC. The encryption function uses the following inputs:
• The 64-byte BTENCDATA to be encrypted (which may have been randomized; see above).
• The 256-bit wrapping key.
• The 96-bit IV randomly generated by PBNDKB.
•
176 bytes of additional authenticated data that are the concatenation of 8 bytes of zeroes, the IV, 28 bytes of
zeroes, and the BTDATA in the input bind structure.
• The length of the additional authenticated data (176).
The encryption function produces a structure with 64 bytes of encrypted data and a 16-byte MAC. PBNDKB saves
these values to the corresponding fields in its output bind structure. Other fields are copied from the input bind
structure or written as zero, except the IV (which receives the randomly generated value) and the
USER_SUPP_CHALLENGE in the BTDATA, which is written as zero.
Operation
(* #UD if PBNDKB is not enumerated, CPL > 0, or not in 64-bit mode*)
IF CPUID.07H.01H:EBX.PBNDKB[bit 1] = 0 OR CPL > 0 OR not in 64-bit mode
THEN #UD; FI;
(* #GP if pointers are not aligned or overlapping *)
IF RBX = RCX OR RBX is not 256-byte aligned OR RCX is not 256-byte aligned
THEN #GP(0); FI;
Load TMP_BIND_STRUCT from 256 bytes at linear address in RBX;
(* MAC and IV fields might not be read. *)
(* Check TMP_BIND_STRUCT for illegal values *)
IF bytes 23:16 and bytes 63:36 of TMP_BIND_STRUCT are not all zero
THEN #GP(0); FI;
IF TMP_BIND_STRUCT.BTDATA.KEY_GENERATION_CTRL > 1
THEN #GP(0); FI;
IF bytes 127:33 of TMP_BIND_STRUCT.BTDATA are not all zero
THEN #GP(0); FI;
(* Randomize input keys if requested *)
IF TMP_BIND_STRUCT.BTDATA.KEY_GENERATION_CONTROL= 1
THEN
Load RNG_DATA_KEY with a random 256-bit value using hardware RNG;
Load RNG_TWEAK_KEY with a random 256-bit value using hardware RNG;
IF there was insufficient entropy
THEN (* PBNDKB failure *)
RFLAGS.ZF := 1;
RAX := ENTROPY_ERROR;
(* failure reason 1 *)
GOTO EXIT;
FI;
PBNDKB-Platform Bind Key to Binary Large Object
Vol. 2B
4-239
(* XOR the input keys with the random keys; this does not modify input bind structure in memory *)
TMP_BIND_STRUCT.BTENCDATA.DATA_KEY := RNG_DATA_KEY XOR TMP_BIND_STRUCT.BTENCDATA.DATA_KEY;
TMP_BIND_STRUCT.BTENCDATA.TWEAK_KEY := RNG_TWEAK_KEY XOR TMP_BIND_STRUCT.BTENCDATA.TWEAK_KEY;
FI;
(* Compute wrapping key from platform key and user challenge *)
PLATFORM_KEY := 256-bit platform-specific key;
WRAPPING_KEY := HMAC_SHA256(PLATFORM_KEY, TMP_BIND_STRUCT.BTDATA.USER_SUPP_CHALLENGE);
(* Generate random data for initialization vector *)
Load TMP_IV with a random 96-bit value using hardware RNG;
IF there was insufficient entropy
THEN (* PBNDKB failure *)
RFLAGS.ZF := 1;
RAX := ENTROPY_ERROR;
(* failure reason 1 *)
GOTO EXIT;
FI;
(* Compose 176 bytes of additional authenticated data for use by authenticated decryption *)
AAD := Concatenation of 8 bytes of zeroes, TMP_IV, 28 bytes of zeroes, and TMP_BIND_STRUCT.BTDATA;
ENCRYPT_STRUCT := AES256_GCM_ENC(TMP_BIND_STRUCT.BTENCDATA, WRAPPING_KEY, TMP_IV, AAD, 176);
OUT_BIND_STRUCT.MAC := ENCRYPT_STRUCT.MAC;
OUT_BIND_STRUCT[bytes 23:16] := 0;
OUT_BIND_STRUCT.IV := TMP_IV;
OUT_BIND_STRUCT[bytes 63:36] := 0;
OUT_BIND_STRUCT.BTENCDATA := ENCRYPT_STRUCT.ENC_DATA;
OUT_BIND_STRUCT.BTDATA.USER_SUPP_CHALLENGE := 0;
OUT_BIND_STRUCT.BTDATA.KEY_GENERATION_CTRL := IN_BIND_STRUCT.BTDATA.KEY_GENERATION_CTRL;
OUT_BIND_STRUCT.BTDATA[bytes 127:33] := 0;
(* Save OUT_BIND_STRUCT to memory *)
Store OUT_BIND_STRUCT to 256 bytes at linear address in RCX;
(* Indicate successful completion *)
RAX := 0;
RFLAGS.ZF := 0;
EXIT:
RFLAGS.CF := 0;
RFLAGS.PF := 0;
RFLAGS.AF := 0;
RFLAGS.OF := 0;
RFLAGS.SF := 0;
Protected Mode Exceptions
#UD
PBNDKB is not supported in protected mode.
Real-Address Mode Exceptions
#UD
PBNDKB is not supported in real-address mode.
PBNDKB-Platform Bind Key to Binary Large Object
Vol. 2B
4-240
Virtual-8086 Mode Exceptions
#UD
PBNDKB is not supported in virtual-8086 mode.
Compatibility Mode Exceptions
#UD
PBNDKB is not supported in compatibility mode.
64-Bit Mode Exceptions
#GP(0)
If the values of RBX and RCX are not both canonical.
If RBX or RCX is not 256B aligned.
If RBX = RCX.
If any of the reserved bytes in the input bind structure are set (including bytes in BTDATA).
If the value of the key-generation control in the BTDATA field of the input bind structure is not
0 or 1.
#PF(fault-code)
If a page fault occurs in accessing memory operands.
#UD
If the LOCK prefix are used.
If the current privilege level is not 0.
If CPUID.07H.01H:EBX.PBNDKB[1] = 0.
PBNDKB-Platform Bind Key to Binary Large Object
Vol. 2B
4-241
PCLMULQDQ-Carry-Less Multiplication Quadword
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature Flag
Support
66 0F 3A 44 /r ib
A
V/V
PCLMULQDQ
Performs carry-less multiplication of one
PCLMULQDQ xmm1, xmm2/m128, imm8
quadword of xmm1 by one quadword of
xmm2/m128, stores the 128-bit result in
xmm1. The immediate is used to determine
which quadwords of xmm1 and xmm2/m128
should be used.
VEX.128.66.0F3A.WIG 44 /r ib
B
V/V
PCLMULQDQ
Performs carry-less multiplication of one
VPCLMULQDQ xmm1, xmm2, xmm3/m128, imm8
AVX
quadword of xmm2 by one quadword of
xmm3/m128, stores the 128-bit result in
xmm1. The immediate is used to determine
which quadwords of xmm2 and xmm3/m128
should be used.
VEX.256.66.0F3A.WIG 44 /r /ib
B
V/V
VPCLMULQDQ
For each 128-bit lane, performs two carry-less
VPCLMULQDQ ymm1, ymm2, ymm3/m256, imm8
AVX
multiplications of one quadword of ymm2 by
one quadword of ymm3/m256, stores the two
128-bit results in ymm1. The immediate is
used to determine which quadword in each
128-bit lane of ymm2 and ymm3/m256
should be used.
EVEX.128.66.0F3A.WIG 44 /r /ib
C
V/V
VPCLMULQDQ
Performs carry-less multiplication of one
VPCLMULQDQ xmm1, xmm2, xmm3/m128, imm8
(AVX512VL
quadword of xmm2 by one quadword of
OR AVX10.1)
xmm3/m128, stores the 128-bit result in
xmm1. The immediate is used to determine
which quadwords of xmm2 and xmm3/m128
should be used.
EVEX.256.66.0F3A.WIG 44 /r /ib
C
V/V
VPCLMULQDQ
For each 128-bit lane, performs two carry-less
VPCLMULQDQ ymm1, ymm2, ymm3/m256, imm8
(AVX512VL
multiplications of one quadword of ymm2 by
OR AVX10.1)
one quadword of ymm3/m256, stores the two
128-bit results in ymm1. The immediate is
used to determine which quadword in each
128-bit lane of ymm2 and ymm3/m256
should be used.
EVEX.512.66.0F3A.WIG 44 /r /ib
C
V/V
VPCLMULQDQ
For each 128-bit lane, performs two carry-less
VPCLMULQDQ zmm1, zmm2, zmm3/m512, imm8
(AVX512F
multiplications of one quadword of zmm2 by
OR AVX10.1)
one quadword of zmm3/m512, stores the four
128-bit results in zmm1. The immediate is
used to determine which quadword in each
128-bit lane of zmm2 and zmm3/m512
should be used.
Instruction Operand Encoding
Op/En
Tuple
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
imm8
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
imm8
C
Full Mem
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
imm8 (r)
Description
Performs packed carry-less multiplication of quadword pairs. XMM versions perform a single multiply of a pair of
PCLMULQDQ-Carry-Less Multiplication Quadword
Vol. 2B
4-242
quadwords. YMM versions perform two packed multiplies of pairs of quadwords. ZMM versions perform four packed
multiplies of pairs of quadwords. Bits 4 and 0 are used to select which 64-bit half of each operand to use according
to Table 4-14, other bits of the immediate byte are ignored.
The EVEX encoded form of this instruction does not support memory fault suppression.
Table 4-14. PCLMULQDQ Quadword Selection of Immediate Byte
Imm[4]
Imm[0]
PCLMULQDQ Operation
0
0
CL_MUL( SRC21[63:0], SRC1[63:0] )
0
1
CL_MUL( SRC2[63:0], SRC1[127:64] )
1
0
CL_MUL( SRC2[127:64], SRC1[63:0] )
1
1
CL_MUL( SRC2[127:64], SRC1[127:64] )
NOTES:
1. SRC2 denotes the second source operand, which can be a register or memory; SRC1 denotes the first source and destination oper-
and.
The first source operand and the destination operand are the same and must be a ZMM/YMM/XMM register. The
second source operand can be a ZMM/YMM/XMM register or a 512/256/128-bit memory location. Bits (VL_MAX-
1:128) of the corresponding YMM destination register remain unchanged.
Compilers and assemblers may implement the following pseudo-op syntax to simplify programming and emit the
required encoding for imm8.
Table 4-15. Pseudo-Op and PCLMULQDQ Implementation
Pseudo-Op
Imm8 Encoding
PCLMULLQLQDQ xmm1, xmm2
0000_0000B
PCLMULHQLQDQ xmm1, xmm2
0000_0001B
PCLMULLQHQDQ xmm1, xmm2
0001_0000B
PCLMULHQHQDQ xmm1, xmm2
0001_0001B
Operation
define PCLMUL128(X,Y):
// helper function
FOR i := 0 to 63:
TMP [ i ] := X[ 0 ] and Y[ i ]
FOR j := 1 to i:
TMP [ i ] := TMP [ i ] xor (X[ j ] and Y[ i - j ])
DEST[ i ] := TMP[ i ]
FOR i := 64 to 126:
TMP [ i ] := 0
FOR j := i - 63 to 63:
TMP [ i ] := TMP [ i ] xor (X[ j ] and Y[ i - j ])
DEST[ i ] := TMP[ i ]
DEST[127] := 0;
RETURN DEST
// 128b vector
PCLMULQDQ-Carry-Less Multiplication Quadword
Vol. 2B
4-243
PCLMULQDQ (SSE Version)
IF imm8[0] = 0:
TEMP1 := SRC1.qword[0]
ELSE:
TEMP1 := SRC1.qword[1]
IF imm8[4] = 0:
TEMP2 := SRC2.qword[0]
ELSE:
TEMP2 := SRC2.qword[1]
DEST[127:0] := PCLMUL128(TEMP1, TEMP2)
DEST[MAXVL-1:128] (Unmodified)
VPCLMULQDQ (128b and 256b VEX Encoded Versions)
(KL,VL) = (1,128), (2,256)
FOR i= 0 to KL-1:
IF imm8[0] = 0:
TEMP1 := SRC1.xmm[i].qword[0]
ELSE:
TEMP1 := SRC1.xmm[i].qword[1]
IF imm8[4] = 0:
TEMP2 := SRC2.xmm[i].qword[0]
ELSE:
TEMP2 := SRC2.xmm[i].qword[1]
DEST.xmm[i] := PCLMUL128(TEMP1, TEMP2)
DEST[MAXVL-1:VL] := 0
VPCLMULQDQ (EVEX Encoded Version)
(KL,VL) = (1,128), (2,256), (4,512)
FOR i = 0 to KL-1:
IF imm8[0] = 0:
TEMP1 := SRC1.xmm[i].qword[0]
ELSE:
TEMP1 := SRC1.xmm[i].qword[1]
IF imm8[4] = 0:
TEMP2 := SRC2.xmm[i].qword[0]
ELSE:
TEMP2 := SRC2.xmm[i].qword[1]
DEST.xmm[i] := PCLMUL128(TEMP1, TEMP2)
DEST[MAXVL-1:VL] := 0
Intel C/C++ Compiler Intrinsic Equivalent
(V)PCLMULQDQ __m128i _mm_clmulepi64_si128 (__m128i, __m128i, const int)
VPCLMULQDQ __m256i _mm256_clmulepi64_epi128(__m256i, __m256i, const int);
VPCLMULQDQ __m512i _mm512_clmulepi64_epi128(__m512i, __m512i, const int);
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally:
#UD
If VEX.L = 1.
EVEX-encoded: See Table 2-52, “Type E4NF Class Exception Conditions.”
PCLMULQDQ-Carry-Less Multiplication Quadword
Vol. 2B
4-244
PCMPEQB/PCMPEQW/PCMPEQD- Compare Packed Data for Equal
Opcode/
Op/ En
64/32 bit
CPUID Feature
Description
Instruction
Mode
Flag
Support
NP 0F 74 /r1
A
V/V
MMX
Compare packed bytes in mm/m64 and mm for
equality.
PCMPEQB mm, mm/m64
66 0F 74 /r
A
V/V
SSE2
Compare packed bytes in xmm2/m128 and
xmm1 for equality.
PCMPEQB xmm1, xmm2/m128
NP 0F 75 /r1
A
V/V
MMX
Compare packed words in mm/m64 and mm
for equality.
PCMPEQW mm, mm/m64
66 0F 75 /r
A
V/V
SSE2
Compare packed words in xmm2/m128 and
xmm1 for equality.
PCMPEQW xmm1, xmm2/m128
NP 0F 76 /r1
A
V/V
MMX
Compare packed doublewords in mm/m64 and
mm for equality.
PCMPEQD mm, mm/m64
66 0F 76 /r
A
V/V
SSE2
Compare packed doublewords in xmm2/m128
and xmm1 for equality.
PCMPEQD xmm1, xmm2/m128
VEX.128.66.0F.WIG 74 /r
B
V/V
AVX
Compare packed bytes in xmm3/m128 and
xmm2 for equality.
VPCMPEQB xmm1, xmm2, xmm3/m128
VEX.128.66.0F.WIG 75 /r
B
V/V
AVX
Compare packed words in xmm3/m128 and
xmm2 for equality.
VPCMPEQW xmm1, xmm2, xmm3/m128
VEX.128.66.0F.WIG 76 /r
B
V/V
AVX
Compare packed doublewords in xmm3/m128
and xmm2 for equality.
VPCMPEQD xmm1, xmm2, xmm3/m128
VEX.256.66.0F.WIG 74 /r
B
V/V
AVX2
Compare packed bytes in ymm3/m256 and
VPCMPEQB ymm1, ymm2, ymm3 /m256
ymm2 for equality.
VEX.256.66.0F.WIG 75 /r
B
V/V
AVX2
Compare packed words in ymm3/m256 and
ymm2 for equality.
VPCMPEQW ymm1, ymm2, ymm3 /m256
VEX.256.66.0F.WIG 76 /r
B
V/V
AVX2
Compare packed doublewords in ymm3/m256
and ymm2 for equality.
VPCMPEQD ymm1, ymm2, ymm3 /m256
EVEX.128.66.0F.W0 76 /r
C
V/V
(AVX512VL AND
Compare Equal between int32 vector xmm2
VPCMPEQD k1 {k2}, xmm2,
AVX512F) OR
and int32 vector xmm3/m128/m32bcst, and
xmm3/m128/m32bcst
AVX10.1
set vector mask k1 to reflect the
zero/nonzero status of each element of the
result, under writemask.
EVEX.256.66.0F.W0 76 /r
C
V/V
(AVX512VL AND
Compare Equal between int32 vector ymm2
VPCMPEQD k1 {k2}, ymm2,
AVX512F) OR
and int32 vector ymm3/m256/m32bcst, and
ymm3/m256/m32bcst
AVX10.1
set vector mask k1 to reflect the
zero/nonzero status of each element of the
result, under writemask.
EVEX.512.66.0F.W0 76 /r
C
V/V
AVX512F
Compare Equal between int32 vectors in
VPCMPEQD k1 {k2}, zmm2,
OR AVX10.1
zmm2 and zmm3/m512/m32bcst, and set
zmm3/m512/m32bcst
destination k1 according to the comparison
results under writemask k2.
EVEX.128.66.0F.WIG 74 /r
D
V/V
(AVX512VL AND
Compare packed bytes in xmm3/m128 and
VPCMPEQB k1 {k2}, xmm2, xmm3 /m128
AVX512BW) OR
xmm2 for equality and set vector mask k1 to
AVX10.1
reflect the zero/nonzero status of each
element of the result, under writemask.
PCMPEQB/PCMPEQW/PCMPEQD- Compare Packed Data for Equal
Vol. 2B
4-245
Opcode/
Op/ En
64/32 bit
CPUID Feature
Description
Instruction
Mode
Flag
Support
EVEX.256.66.0F.WIG 74 /r
D
V/V
(AVX512VL AND
Compare packed bytes in ymm3/m256 and
VPCMPEQB k1 {k2}, ymm2, ymm3 /m256
AVX512BW) OR
ymm2 for equality and set vector mask k1 to
AVX10.1
reflect the zero/nonzero status of each
element of the result, under writemask.
EVEX.512.66.0F.WIG 74 /r
D
V/V
AVX512BW
Compare packed bytes in zmm3/m512 and
VPCMPEQB k1 {k2}, zmm2, zmm3 /m512
OR AVX10.1
zmm2 for equality and set vector mask k1 to
reflect the zero/nonzero status of each
element of the result, under writemask.
EVEX.128.66.0F.WIG 75 /r
D
V/V
(AVX512VL AND
Compare packed words in xmm3/m128 and
VPCMPEQW k1 {k2}, xmm2, xmm3 /m128
AVX512BW) OR
xmm2 for equality and set vector mask k1 to
AVX10.1
reflect the zero/nonzero status of each
element of the result, under writemask.
EVEX.256.66.0F.WIG 75 /r
D
V/V
(AVX512VL AND
Compare packed words in ymm3/m256 and
VPCMPEQW k1 {k2}, ymm2, ymm3 /m256
AVX512BW) OR
ymm2 for equality and set vector mask k1 to
AVX10.1
reflect the zero/nonzero status of each
element of the result, under writemask.
EVEX.512.66.0F.WIG 75 /r
D
V/V
AVX512BW
Compare packed words in zmm3/m512 and
VPCMPEQW k1 {k2}, zmm2, zmm3 /m512
OR AVX10.1
zmm2 for equality and set vector mask k1 to
reflect the zero/nonzero status of each
element of the result, under writemask.
NOTES:
1. See note in Section 2.5, “Intel® AVX and Intel® SSE Instruction Exception Classification,” in the Intel® 64 and IA-32 Architectures Soft-
ware Developer’s Manual, Volume 2A, and Section 25.25.3, “Exception Conditions of Legacy SIMD Instructions Operating on MMX Reg-
isters,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
C
Full
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
D
Full Mem
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs a SIMD compare for equality of the packed bytes, words, or doublewords in the destination operand (first
operand) and the source operand (second operand). If a pair of data elements is equal, the corresponding data
element in the destination operand is set to all 1s; otherwise, it is set to all 0s.
The (V)PCMPEQB instruction compares the corresponding bytes in the destination and source operands; the
(V)PCMPEQW instruction compares the corresponding words in the destination and source operands; and the
(V)PCMPEQD instruction compares the corresponding doublewords in the destination and source operands.
In 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to
access additional registers (XMM8-XMM15).
Legacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The
destination operand can be an MMX technology register.
128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The
first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination
register remain unchanged.
PCMPEQB/PCMPEQW/PCMPEQD- Compare Packed Data for Equal
Vol. 2B
4-246
VEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The
first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register
are zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register
or a 256-bit memory location. The destination operand is a YMM register.
EVEX encoded VPCMPEQD: The first source operand (second operand) is a ZMM/YMM/XMM register. 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-bit memory location. The destination operand (first operand) is a mask register updated
according to the writemask k2.
EVEX encoded VPCMPEQB/W: The first source operand (second operand) is a ZMM/YMM/XMM register. The second
source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand
(first operand) is a mask register updated according to the writemask k2.
Operation
PCMPEQB (With 64-bit Operands)
IF DEST[7:0] = SRC[7:0]
THEN DEST[7:0) := FFH;
ELSE DEST[7:0] := 0; FI;
(* Continue comparison of 2nd through 7th bytes in DEST and SRC *)
IF DEST[63:56] = SRC[63:56]
THEN DEST[63:56] := FFH;
ELSE DEST[63:56] := 0; FI;
COMPARE_BYTES_EQUAL (SRC1, SRC2)
IF SRC1[7:0] = SRC2[7:0]
THEN DEST[7:0] := FFH;
ELSE DEST[7:0] := 0; FI;
(* Continue comparison of 2nd through 15th bytes in SRC1 and SRC2 *)
IF SRC1[127:120] = SRC2[127:120]
THEN DEST[127:120] := FFH;
ELSE DEST[127:120] := 0; FI;
COMPARE_WORDS_EQUAL (SRC1, SRC2)
IF SRC1[15:0] = SRC2[15:0]
THEN DEST[15:0] := FFFFH;
ELSE DEST[15:0] := 0; FI;
(* Continue comparison of 2nd through 7th 16-bit words in SRC1 and SRC2 *)
IF SRC1[127:112] = SRC2[127:112]
THEN DEST[127:112] := FFFFH;
ELSE DEST[127:112] := 0; FI;
COMPARE_DWORDS_EQUAL (SRC1, SRC2)
IF SRC1[31:0] = SRC2[31:0]
THEN DEST[31:0] := FFFFFFFFH;
ELSE DEST[31:0] := 0; FI;
(* Continue comparison of 2nd through 3rd 32-bit dwords in SRC1 and SRC2 *)
IF SRC1[127:96] = SRC2[127:96]
THEN DEST[127:96] := FFFFFFFFH;
ELSE DEST[127:96] := 0; FI;
PCMPEQB (With 128-bit Operands)
DEST[127:0] := COMPARE_BYTES_EQUAL(DEST[127:0],SRC[127:0])
DEST[MAXVL-1:128] (Unmodified)
PCMPEQB/PCMPEQW/PCMPEQD- Compare Packed Data for Equal
Vol. 2B
4-247
VPCMPEQB (VEX.128 Encoded Version)
DEST[127:0] := COMPARE_BYTES_EQUAL(SRC1[127:0],SRC2[127:0])
DEST[MAXVL-1:128] := 0
VPCMPEQB (VEX.256 Encoded Version)
DEST[127:0] := COMPARE_BYTES_EQUAL(SRC1[127:0],SRC2[127:0])
DEST[255:128] := COMPARE_BYTES_EQUAL(SRC1[255:128],SRC2[255:128])
DEST[MAXVL-1:256] := 0
VPCMPEQB (EVEX Encoded Versions)
(KL, VL) = (16, 128), (32, 256), (64, 512)
FOR j := 0 TO KL-1
i := j * 8
IF k2[j] OR *no writemask*
THEN
/* signed comparison */
CMP := SRC1[i+7:i] == SRC2[i+7:i];
IF CMP = TRUE
THEN DEST[j] := 1;
ELSE DEST[j] := 0; FI;
ELSE
DEST[j] := 0
; zeroing-masking onlyFI;
FI;
ENDFOR
DEST[MAX_KL-1:KL] := 0
PCMPEQW (With 64-bit Operands)
IF DEST[15:0] = SRC[15:0]
THEN DEST[15:0] := FFFFH;
ELSE DEST[15:0] := 0; FI;
(* Continue comparison of 2nd and 3rd words in DEST and SRC *)
IF DEST[63:48] = SRC[63:48]
THEN DEST[63:48] := FFFFH;
ELSE DEST[63:48] := 0; FI;
PCMPEQW (With 128-bit Operands)
DEST[127:0] := COMPARE_WORDS_EQUAL(DEST[127:0],SRC[127:0])
DEST[MAXVL-1:128] (Unmodified)
VPCMPEQW (VEX.128 Encoded Version)
DEST[127:0] := COMPARE_WORDS_EQUAL(SRC1[127:0],SRC2[127:0])
DEST[MAXVL-1:128] := 0
VPCMPEQW (VEX.256 Encoded Version)
DEST[127:0] := COMPARE_WORDS_EQUAL(SRC1[127:0],SRC2[127:0])
DEST[255:128] := COMPARE_WORDS_EQUAL(SRC1[255:128],SRC2[255:128])
DEST[MAXVL-1:256] := 0
PCMPEQB/PCMPEQW/PCMPEQD- Compare Packed Data for Equal
Vol. 2B
4-248
VPCMPEQW (EVEX Encoded Versions)
(KL, VL) = (8, 128), (16, 256), (32, 512)
FOR j := 0 TO KL-1
i := j * 16
IF k2[j] OR *no writemask*
THEN
/* signed comparison */
CMP := SRC1[i+15:i] == SRC2[i+15:i];
IF CMP = TRUE
THEN DEST[j] := 1;
ELSE DEST[j] := 0; FI;
ELSE
DEST[j] := 0
; zeroing-masking onlyFI;
FI;
ENDFOR
DEST[MAX_KL-1:KL] := 0
PCMPEQD (With 64-bit Operands)
IF DEST[31:0] = SRC[31:0]
THEN DEST[31:0] := FFFFFFFFH;
ELSE DEST[31:0] := 0; FI;
IF DEST[63:32] = SRC[63:32]
THEN DEST[63:32] := FFFFFFFFH;
ELSE DEST[63:32] := 0; FI;
PCMPEQD (With 128-bit Operands)
DEST[127:0] := COMPARE_DWORDS_EQUAL(DEST[127:0],SRC[127:0])
DEST[MAXVL-1:128] (Unmodified)
VPCMPEQD (VEX.128 Encoded Version)
DEST[127:0] := COMPARE_DWORDS_EQUAL(SRC1[127:0],SRC2[127:0])
DEST[MAXVL-1:128] := 0
VPCMPEQD (VEX.256 Encoded Version)
DEST[127:0] := COMPARE_DWORDS_EQUAL(SRC1[127:0],SRC2[127:0])
DEST[255:128] := COMPARE_DWORDS_EQUAL(SRC1[255:128],SRC2[255:128])
DEST[MAXVL-1:256] := 0
VPCMPEQD (EVEX Encoded Versions)
(KL, VL) = (4, 128), (8, 256), (16, 512)
FOR j := 0 TO KL-1
i := j * 32
IF k2[j] OR *no writemask*
THEN
/* signed comparison */
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN CMP := SRC1[i+31:i] = SRC2[31:0];
ELSE CMP := SRC1[i+31:i] = SRC2[i+31:i];
FI;
IF CMP = TRUE
THEN DEST[j] := 1;
ELSE DEST[j] := 0; FI;
ELSE
DEST[j] := 0
; zeroing-masking only
FI;
ENDFOR
PCMPEQB/PCMPEQW/PCMPEQD- Compare Packed Data for Equal
Vol. 2B
4-249
DEST[MAX_KL-1:KL] := 0
Intel C/C++ Compiler Intrinsic Equivalents
VPCMPEQB __mmask64 _mm512_cmpeq_epi8_mask(__m512i a, __m512i b);
VPCMPEQB __mmask64 _mm512_mask_cmpeq_epi8_mask(__mmask64 k, __m512i a, __m512i b);
VPCMPEQB __mmask32 _mm256_cmpeq_epi8_mask(__m256i a, __m256i b);
VPCMPEQB __mmask32 _mm256_mask_cmpeq_epi8_mask(__mmask32 k, __m256i a, __m256i b);
VPCMPEQB __mmask16 _mm_cmpeq_epi8_mask(__m128i a, __m128i b);
VPCMPEQB __mmask16 _mm_mask_cmpeq_epi8_mask(__mmask16 k, __m128i a, __m128i b);
VPCMPEQW __mmask32 _mm512_cmpeq_epi16_mask(__m512i a, __m512i b);
VPCMPEQW __mmask32 _mm512_mask_cmpeq_epi16_mask(__mmask32 k, __m512i a, __m512i b);
VPCMPEQW __mmask16 _mm256_cmpeq_epi16_mask(__m256i a, __m256i b);
VPCMPEQW __mmask16 _mm256_mask_cmpeq_epi16_mask(__mmask16 k, __m256i a, __m256i b);
VPCMPEQW __mmask8 _mm_cmpeq_epi16_mask(__m128i a, __m128i b);
VPCMPEQW __mmask8 _mm_mask_cmpeq_epi16_mask(__mmask8 k, __m128i a, __m128i b);
VPCMPEQD __mmask16 _mm512_cmpeq_epi32_mask( __m512i a, __m512i b);
VPCMPEQD __mmask16 _mm512_mask_cmpeq_epi32_mask(__mmask16 k, __m512i a, __m512i b);
VPCMPEQD __mmask8 _mm256_cmpeq_epi32_mask(__m256i a, __m256i b);
VPCMPEQD __mmask8 _mm256_mask_cmpeq_epi32_mask(__mmask8 k, __m256i a, __m256i b);
VPCMPEQD __mmask8 _mm_cmpeq_epi32_mask(__m128i a, __m128i b);
VPCMPEQD __mmask8 _mm_mask_cmpeq_epi32_mask(__mmask8 k, __m128i a, __m128i b);
PCMPEQB __m64 _mm_cmpeq_pi8 (__m64 m1, __m64 m2)
PCMPEQW __m64 _mm_cmpeq_pi16 (__m64 m1, __m64 m2)
PCMPEQD __m64 _mm_cmpeq_pi32 (__m64 m1, __m64 m2)
(V)PCMPEQB __m128i _mm_cmpeq_epi8 ( __m128i a, __m128i b)
(V)PCMPEQW __m128i _mm_cmpeq_epi16 ( __m128i a, __m128i b)
(V)PCMPEQD __m128i _mm_cmpeq_epi32 ( __m128i a, __m128i b)
VPCMPEQB __m256i _mm256_cmpeq_epi8 ( __m256i a, __m256i b)
VPCMPEQW __m256i _mm256_cmpeq_epi16 ( __m256i a, __m256i b)
VPCMPEQD __m256i _mm256_cmpeq_epi32 ( __m256i a, __m256i b)
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
Non-EVEX-encoded instruction, see Table 2-21, “Type 4 Class Exception Conditions.”
EVEX-encoded VPCMPEQD, see Table 2-51, “Type E4 Class Exception Conditions.”
EVEX-encoded VPCMPEQB/W, see Exceptions Type E4.nb in Table 2-51, “Type E4 Class Exception Conditions.”
PCMPEQB/PCMPEQW/PCMPEQD- Compare Packed Data for Equal
Vol. 2B
4-250
PCMPEQQ-Compare Packed Qword Data for Equal
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
66 0F 38 29 /r
A
V/V
SSE4_1
Compare packed qwords in xmm2/m128 and
PCMPEQQ xmm1, xmm2/m128
xmm1 for equality.
VEX.128.66.0F38.WIG 29 /r
B
V/V
AVX
Compare packed quadwords in xmm3/m128 and
VPCMPEQQ xmm1, xmm2, xmm3/m128
xmm2 for equality.
VEX.256.66.0F38.WIG 29 /r
B
V/V
AVX2
Compare packed quadwords in ymm3/m256 and
VPCMPEQQ ymm1, ymm2, ymm3 /m256
ymm2 for equality.
EVEX.128.66.0F38.W1 29 /r
C
V/V
(AVX512VL AND
Compare Equal between int64 vector xmm2 and
VPCMPEQQ k1 {k2}, xmm2,
AVX512F) OR
int64 vector xmm3/m128/m64bcst, and set
xmm3/m128/m64bcst
AVX10.1
vector mask k1 to reflect the zero/nonzero status
of each element of the result, under writemask.
EVEX.256.66.0F38.W1 29 /r
C
V/V
(AVX512VL AND
Compare Equal between int64 vector ymm2 and
VPCMPEQQ k1 {k2}, ymm2,
AVX512F) OR
int64 vector ymm3/m256/m64bcst, and set
ymm3/m256/m64bcst
AVX10.1
vector mask k1 to reflect the zero/nonzero status
of each element of the result, under writemask.
EVEX.512.66.0F38.W1 29 /r
C
V/V
AVX512F
Compare Equal between int64 vector zmm2 and
VPCMPEQQ k1 {k2}, zmm2,
OR AVX10.1
int64 vector zmm3/m512/m64bcst, and set
zmm3/m512/m64bcst
vector mask k1 to reflect the zero/nonzero status
of each element of the result, under writemask.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
C
Full
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs an SIMD compare for equality of the packed quadwords in the destination operand (first operand) and the
source operand (second operand). If a pair of data elements is equal, the corresponding data element in the desti-
nation is set to all 1s; otherwise, it is set to 0s.
128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The
first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM destination
register remain unchanged.
VEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The
first source and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM register
are zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register
or a 256-bit memory location. The destination operand is a YMM register.
EVEX encoded VPCMPEQQ: The first source operand (second operand) is a ZMM/YMM/XMM register. 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 64-bit memory location. The destination operand (first operand) is a mask register updated
according to the writemask k2.
Operation
PCMPEQQ (With 128-bit Operands)
IF (DEST[63:0] = SRC[63:0])
THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;
PCMPEQQ-Compare Packed Qword Data for Equal
Vol. 2B
4-251
ELSE DEST[63:0] := 0; FI;
IF (DEST[127:64] = SRC[127:64])
THEN DEST[127:64] := FFFFFFFFFFFFFFFFH;
ELSE DEST[127:64] := 0; FI;
DEST[MAXVL-1:128] (Unmodified)
COMPARE_QWORDS_EQUAL (SRC1, SRC2)
IF SRC1[63:0] = SRC2[63:0]
THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;
ELSE DEST[63:0] := 0; FI;
IF SRC1[127:64] = SRC2[127:64]
THEN DEST[127:64] := FFFFFFFFFFFFFFFFH;
ELSE DEST[127:64] := 0; FI;
VPCMPEQQ (VEX.128 Encoded Version)
DEST[127:0] := COMPARE_QWORDS_EQUAL(SRC1,SRC2)
DEST[MAXVL-1:128] := 0
VPCMPEQQ (VEX.256 Encoded Version)
DEST[127:0] := COMPARE_QWORDS_EQUAL(SRC1[127:0],SRC2[127:0])
DEST[255:128] := COMPARE_QWORDS_EQUAL(SRC1[255:128],SRC2[255:128])
DEST[MAXVL-1:256] := 0
VPCMPEQQ (EVEX Encoded Versions)
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k2[j] OR *no writemask*
THEN
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN CMP := SRC1[i+63:i] = SRC2[63:0];
ELSE CMP := SRC1[i+63:i] = SRC2[i+63:i];
FI;
IF CMP = TRUE
THEN DEST[j] := 1;
ELSE DEST[j] := 0; FI;
ELSE
DEST[j] := 0
; zeroing-masking only
FI;
ENDFOR
DEST[MAX_KL-1:KL] := 0
PCMPEQQ-Compare Packed Qword Data for Equal
Vol. 2B
4-252
Intel C/C++ Compiler Intrinsic Equivalent
VPCMPEQQ __mmask8 _mm512_cmpeq_epi64_mask( __m512i a, __m512i b);
VPCMPEQQ __mmask8 _mm512_mask_cmpeq_epi64_mask(__mmask8 k, __m512i a, __m512i b);
VPCMPEQQ __mmask8 _mm256_cmpeq_epi64_mask( __m256i a, __m256i b);
VPCMPEQQ __mmask8 _mm256_mask_cmpeq_epi64_mask(__mmask8 k, __m256i a, __m256i b);
VPCMPEQQ __mmask8 _mm_cmpeq_epi64_mask( __m128i a, __m128i b);
VPCMPEQQ __mmask8 _mm_mask_cmpeq_epi64_mask(__mmask8 k, __m128i a, __m128i b);
(V)PCMPEQQ __m128i _mm_cmpeq_epi64(__m128i a, __m128i b);
VPCMPEQQ __m256i _mm256_cmpeq_epi64( __m256i a, __m256i b);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
Non-EVEX-encoded instruction, see Table 2-21, “Type 4 Class Exception Conditions.”
EVEX-encoded VPCMPEQQ, see Table 2-51, “Type E4 Class Exception Conditions.”
PCMPEQQ-Compare Packed Qword Data for Equal
Vol. 2B
4-253
PCMPESTRI-Packed Compare Explicit Length Strings, Return Index
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
66 0F 3A 61 /r imm8
RMI
V/V
SSE4_2
Perform a packed comparison of string data with
PCMPESTRI xmm1, xmm2/m128, imm8
explicit lengths, generating an index, and storing the
result in ECX.
VEX.128.66.0F3A 61 /r ib
RMI
V/V
AVX
Perform a packed comparison of string data with
VPCMPESTRI xmm1, xmm2/m128, imm8
explicit lengths, generating an index, and storing the
result in ECX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMI
ModRM:reg (r)
ModRM:r/m (r)
imm8
N/A
Description
The instruction compares and processes data from two string fragments based on the encoded value in the imm8
control byte (see Section 4.1, “Imm8 Control Byte Operation for PCMPESTRI / PCMPESTRM / PCMPISTRI / PCMP-
ISTRM”), and generates an index stored to the count register (ECX).
Each string fragment is represented by two values. The first value is an xmm (or possibly m128 for the second
operand) which contains the data elements of the string (byte or word data). The second value is stored in an input
length register. The input length register is EAX/RAX (for xmm1) or EDX/RDX (for xmm2/m128). The length
represents the number of bytes/words which are valid for the respective xmm/m128 data.
The length of each input is interpreted as being the absolute-value of the value in the length register. The absolute-
value computation saturates to 16 (for bytes) and 8 (for words), based on the value of imm8[bit3] when the value
in the length register is greater than 16 (8) or less than -16 (-8).
The comparison and aggregation operations are performed according to the encoded value of imm8 bit fields (see
Section 4.1). The index of the first (or last, according to imm8[6]) set bit of IntRes2 (see Section 4.1.4) is returned
in ECX. If no bits are set in IntRes2, ECX is set to 16 (8).
Note that the Arithmetic Flags are written in a non-standard manner in order to supply the most relevant informa-
tion:
CFlag - Reset if IntRes2 is equal to zero, set otherwise
ZFlag - Set if absolute-value of EDX is < 16 (8), reset otherwise
SFlag - Set if absolute-value of EAX is < 16 (8), reset otherwise
OFlag - IntRes2[0]
AFlag - Reset
PFlag - Reset
Effective Operand Size
Operating mode/size
Operand 1
Operand 2
Length 1
Length 2
Result
16 bit
xmm
xmm/m128
EAX
EDX
ECX
32 bit
xmm
xmm/m128
EAX
EDX
ECX
64 bit
xmm
xmm/m128
EAX
EDX
ECX
64 bit + REX.W
xmm
xmm/m128
RAX
RDX
ECX
PCMPESTRI-Packed Compare Explicit Length Strings, Return Index
Vol. 2B
4-254
Intel C/C++ Compiler Intrinsic Equivalent For Returning Index
int _mm_cmpestri (__m128i a, int la, __m128i b, int lb, const int mode);
Intel C/C++ Compiler Intrinsics For Reading EFlag Results
int _mm_cmpestra (__m128i a, int la, __m128i b, int lb, const int mode);
int _mm_cmpestrc (__m128i a, int la, __m128i b, int lb, const int mode);
int _mm_cmpestro (__m128i a, int la, __m128i b, int lb, const int mode);
int _mm_cmpestrs (__m128i a, int la, __m128i b, int lb, const int mode);
int _mm_cmpestrz (__m128i a, int la, __m128i b, int lb, const int mode);
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally, this instruction does not cause #GP if the
memory operand is not aligned to 16 Byte boundary, and:
#UD
If VEX.L = 1.
If VEX.vvvv ≠ 1111B.
PCMPESTRI-Packed Compare Explicit Length Strings, Return Index
Vol. 2B
4-255
PCMPESTRM-Packed Compare Explicit Length Strings, Return Mask
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
66 0F 3A 60 /r imm8
RMI
V/V
SSE4_2
Perform a packed comparison of string data
PCMPESTRM xmm1, xmm2/m128, imm8
with explicit lengths, generating a mask, and
storing the result in XMM0.
VEX.128.66.0F3A 60 /r ib
RMI
V/V
AVX
Perform a packed comparison of string data
VPCMPESTRM xmm1, xmm2/m128, imm8
with explicit lengths, generating a mask, and
storing the result in XMM0.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMI
ModRM:reg (r)
ModRM:r/m (r)
imm8
N/A
Description
The instruction compares data from two string fragments based on the encoded value in the imm8 contol byte (see
Section 4.1, “Imm8 Control Byte Operation for PCMPESTRI / PCMPESTRM / PCMPISTRI / PCMPISTRM”), and gener-
ates a mask stored to XMM0.
Each string fragment is represented by two values. The first value is an xmm (or possibly m128 for the second
operand) which contains the data elements of the string (byte or word data). The second value is stored in an input
length register. The input length register is EAX/RAX (for xmm1) or EDX/RDX (for xmm2/m128). The length
represents the number of bytes/words which are valid for the respective xmm/m128 data.
The length of each input is interpreted as being the absolute-value of the value in the length register. The absolute-
value computation saturates to 16 (for bytes) and 8 (for words), based on the value of imm8[bit3] when the value
in the length register is greater than 16 (8) or less than -16 (-8).
The comparison and aggregation operations are performed according to the encoded value of imm8 bit fields (see
Section 4.1). As defined by imm8[6], IntRes2 is then either stored to the least significant bits of XMM0 (zero
extended to 128 bits) or expanded into a byte/word-mask and then stored to XMM0.
Note that the Arithmetic Flags are written in a non-standard manner in order to supply the most relevant informa-
tion:
CFlag - Reset if IntRes2 is equal to zero, set otherwise
ZFlag - Set if absolute-value of EDX is < 16 (8), reset otherwise
SFlag - Set if absolute-value of EAX is < 16 (8), reset otherwise
OFlag -IntRes2[0]
AFlag - Reset
PFlag - Reset
Note: In VEX.128 encoded versions, bits (MAXVL-1:128) of XMM0 are zeroed. VEX.vvvv is reserved and must be
1111b, VEX.L must be 0, otherwise the instruction will #UD.
PCMPESTRM-Packed Compare Explicit Length Strings, Return Mask
Vol. 2B
4-256
Effective Operand Size
Operating mode/size
Operand 1
Operand 2
Length 1
Length 2
Result
16 bit
xmm
xmm/m128
EAX
EDX
XMM0
32 bit
xmm
xmm/m128
EAX
EDX
XMM0
64 bit
xmm
xmm/m128
EAX
EDX
XMM0
64 bit + REX.W
xmm
xmm/m128
RAX
RDX
XMM0
Intel C/C++ Compiler Intrinsic Equivalent For Returning Mask
__m128i _mm_cmpestrm (__m128i a, int la, __m128i b, int lb, const int mode);
Intel C/C++ Compiler Intrinsics For Reading EFlag Results
int _mm_cmpestra (__m128i a, int la, __m128i b, int lb, const int mode);
int _mm_cmpestrc (__m128i a, int la, __m128i b, int lb, const int mode);
int _mm_cmpestro (__m128i a, int la, __m128i b, int lb, const int mode);
int _mm_cmpestrs (__m128i a, int la, __m128i b, int lb, const int mode);
int _mm_cmpestrz (__m128i a, int la, __m128i b, int lb, const int mode);
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally, this instruction does not cause #GP if the
memory operand is not aligned to 16 Byte boundary, and:
#UD
If VEX.L = 1.
If VEX.vvvv ≠ 1111B.
PCMPESTRM-Packed Compare Explicit Length Strings, Return Mask
Vol. 2B
4-257
PCMPGTB/PCMPGTW/PCMPGTD-Compare Packed Signed Integers for Greater Than
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
NP 0F 64 /r1
A
V/V
MMX
Compare packed signed byte integers in mm and
mm/m64 for greater than.
PCMPGTB mm, mm/m64
66 0F 64 /r
A
V/V
SSE2
Compare packed signed byte integers in xmm1
and xmm2/m128 for greater than.
PCMPGTB xmm1, xmm2/m128
NP 0F 65 /r1
A
V/V
MMX
Compare packed signed word integers in mm and
mm/m64 for greater than.
PCMPGTW mm, mm/m64
66 0F 65 /r
A
V/V
SSE2
Compare packed signed word integers in xmm1
and xmm2/m128 for greater than.
PCMPGTW xmm1, xmm2/m128
NP 0F 66 /r1
A
V/V
MMX
Compare packed signed doubleword integers in
mm and mm/m64 for greater than.
PCMPGTD mm, mm/m64
66 0F 66 /r
A
V/V
SSE2
Compare packed signed doubleword integers in
xmm1 and xmm2/m128 for greater than.
PCMPGTD xmm1, xmm2/m128
VEX.128.66.0F.WIG 64 /r
B
V/V
AVX
Compare packed signed byte integers in xmm2
and xmm3/m128 for greater than.
VPCMPGTB xmm1, xmm2, xmm3/m128
VEX.128.66.0F.WIG 65 /r
B
V/V
AVX
Compare packed signed word integers in xmm2
and xmm3/m128 for greater than.
VPCMPGTW xmm1, xmm2, xmm3/m128
VEX.128.66.0F.WIG 66 /r
B
V/V
AVX
Compare packed signed doubleword integers in
xmm2 and xmm3/m128 for greater than.
VPCMPGTD xmm1, xmm2, xmm3/m128
VEX.256.66.0F.WIG 64 /r
B
V/V
AVX2
Compare packed signed byte integers in ymm2
and ymm3/m256 for greater than.
VPCMPGTB ymm1, ymm2, ymm3/m256
VEX.256.66.0F.WIG 65 /r
B
V/V
AVX2
Compare packed signed word integers in ymm2
and ymm3/m256 for greater than.
VPCMPGTW ymm1, ymm2, ymm3/m256
VEX.256.66.0F.WIG 66 /r
B
V/V
AVX2
Compare packed signed doubleword integers in
ymm2 and ymm3/m256 for greater than.
VPCMPGTD ymm1, ymm2, ymm3/m256
EVEX.128.66.0F.W0 66 /r
C
V/V
(AVX512VL AND
Compare Greater between int32 vector xmm2 and
VPCMPGTD k1 {k2}, xmm2,
AVX512F) OR
int32 vector xmm3/m128/m32bcst, and set
xmm3/m128/m32bcst
AVX10.1
vector mask k1 to reflect the zero/nonzero status
of each element of the result, under writemask.
EVEX.256.66.0F.W0 66 /r
C
V/V
(AVX512VL AND
Compare Greater between int32 vector ymm2 and
VPCMPGTD k1 {k2}, ymm2,
AVX512F) OR
int32 vector ymm3/m256/m32bcst, and set
ymm3/m256/m32bcst
AVX10.1
vector mask k1 to reflect the zero/nonzero status
of each element of the result, under writemask.
EVEX.512.66.0F.W0 66 /r
C
V/V
AVX512F
Compare Greater between int32 elements in
VPCMPGTD k1 {k2}, zmm2,
OR AVX10.1
zmm2 and zmm3/m512/m32bcst, and set
zmm3/m512/m32bcst
destination k1 according to the comparison results
under writemask. k2.
EVEX.128.66.0F.WIG 64 /r
D
V/V
(AVX512VL AND
Compare packed signed byte integers in xmm2
VPCMPGTB k1 {k2}, xmm2, xmm3/m128
AVX512BW) OR
and xmm3/m128 for greater than, and set vector
AVX10.1
mask k1 to reflect the zero/nonzero status of each
element of the result, under writemask.
EVEX.256.66.0F.WIG 64 /r
D
V/V
(AVX512VL AND
Compare packed signed byte integers in ymm2
VPCMPGTB k1 {k2}, ymm2, ymm3/m256
AVX512BW) OR
and ymm3/m256 for greater than, and set vector
AVX10.1
mask k1 to reflect the zero/nonzero status of each
element of the result, under writemask.
PCMPGTB/PCMPGTW/PCMPGTD-Compare Packed Signed Integers for Greater Than
Vol. 2B
4-258
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
EVEX.512.66.0F.WIG 64 /r
D
V/V
AVX512BW
Compare packed signed byte integers in zmm2 and
VPCMPGTB k1 {k2}, zmm2, zmm3/m512
OR AVX10.1
zmm3/m512 for greater than, and set vector
mask k1 to reflect the zero/nonzero status of each
element of the result, under writemask.
EVEX.128.66.0F.WIG 65 /r
D
V/V
(AVX512VL AND
Compare packed signed word integers in xmm2
VPCMPGTW k1 {k2}, xmm2, xmm3/m128
AVX512BW) OR
and xmm3/m128 for greater than, and set vector
AVX10.1
mask k1 to reflect the zero/nonzero status of each
element of the result, under writemask.
EVEX.256.66.0F.WIG 65 /r
D
V/V
(AVX512VL AND
Compare packed signed word integers in ymm2
VPCMPGTW k1 {k2}, ymm2, ymm3/m256
AVX512BW) OR
and ymm3/m256 for greater than, and set vector
AVX10.1
mask k1 to reflect the zero/nonzero status of each
element of the result, under writemask.
EVEX.512.66.0F.WIG 65 /r
D
V/V
AVX512BW
Compare packed signed word integers in zmm2
VPCMPGTW k1 {k2}, zmm2, zmm3/m512
OR AVX10.1
and zmm3/m512 for greater than, and set vector
mask k1 to reflect the zero/nonzero status of each
element of the result, under writemask.
NOTES:
1. See note in Section 2.5, “Intel® AVX and Intel® SSE Instruction Exception Classification,” in the Intel® 64 and IA-32 Architectures Soft-
ware Developer’s Manual, Volume 2A, and Section 25.25.3, “Exception Conditions of Legacy SIMD Instructions Operating on MMX Reg-
isters,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
C
Full
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
D
Full Mem
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs an SIMD signed compare for the greater value of the packed byte, word, or doubleword integers in the
destination operand (first operand) and the source operand (second operand). If a data element in the destination
operand is greater than the corresponding date element in the source operand, the corresponding data element in
the destination operand is set to all 1s; otherwise, it is set to all 0s.
The PCMPGTB instruction compares the corresponding signed byte integers in the destination and source oper-
ands; the PCMPGTW instruction compares the corresponding signed word integers in the destination and source
operands; and the PCMPGTD instruction compares the corresponding signed doubleword integers in the destina-
tion and source operands.
In 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to
access additional registers (XMM8-XMM15).
Legacy SSE instructions: The source operand can be an MMX technology register or a 64-bit memory location. The
destination operand can be an MMX technology register.
128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The
first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM
destination register remain unchanged.
VEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The
first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM
register are zeroed.
PCMPGTB/PCMPGTW/PCMPGTD-Compare Packed Signed Integers for Greater Than
Vol. 2B
4-259
VEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register
or a 256-bit memory location. The destination operand is a YMM register.
EVEX encoded VPCMPGTD: The first source operand (second operand) is a ZMM/YMM/XMM register. 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-bit memory location. The destination operand (first operand) is a mask register updated
according to the writemask k2.
EVEX encoded VPCMPGTB/W: The first source operand (second operand) is a ZMM/YMM/XMM register. The second
source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location. The destination operand
(first operand) is a mask register updated according to the writemask k2.
Operation
PCMPGTB (With 64-bit Operands)
IF DEST[7:0] > SRC[7:0]
THEN DEST[7:0) := FFH;
ELSE DEST[7:0] := 0; FI;
(* Continue comparison of 2nd through 7th bytes in DEST and SRC *)
IF DEST[63:56] > SRC[63:56]
THEN DEST[63:56] := FFH;
ELSE DEST[63:56] := 0; FI;
COMPARE_BYTES_GREATER (SRC1, SRC2)
IF SRC1[7:0] > SRC2[7:0]
THEN DEST[7:0] := FFH;
ELSE DEST[7:0] := 0; FI;
(* Continue comparison of 2nd through 15th bytes in SRC1 and SRC2 *)
IF SRC1[127:120] > SRC2[127:120]
THEN DEST[127:120] := FFH;
ELSE DEST[127:120] := 0; FI;
COMPARE_WORDS_GREATER (SRC1, SRC2)
IF SRC1[15:0] > SRC2[15:0]
THEN DEST[15:0] := FFFFH;
ELSE DEST[15:0] := 0; FI;
(* Continue comparison of 2nd through 7th 16-bit words in SRC1 and SRC2 *)
IF SRC1[127:112] > SRC2[127:112]
THEN DEST[127:112] := FFFFH;
ELSE DEST[127:112] := 0; FI;
COMPARE_DWORDS_GREATER (SRC1, SRC2)
IF SRC1[31:0] > SRC2[31:0]
THEN DEST[31:0] := FFFFFFFFH;
ELSE DEST[31:0] := 0; FI;
(* Continue comparison of 2nd through 3rd 32-bit dwords in SRC1 and SRC2 *)
IF SRC1[127:96] > SRC2[127:96]
THEN DEST[127:96] := FFFFFFFFH;
ELSE DEST[127:96] := 0; FI;
PCMPGTB (With 128-bit Operands)
DEST[127:0] := COMPARE_BYTES_GREATER(DEST[127:0],SRC[127:0])
DEST[MAXVL-1:128] (Unmodified)
PCMPGTB/PCMPGTW/PCMPGTD-Compare Packed Signed Integers for Greater Than
Vol. 2B
4-260
VPCMPGTB (VEX.128 Encoded Version)
DEST[127:0] := COMPARE_BYTES_GREATER(SRC1,SRC2)
DEST[MAXVL-1:128] := 0
VPCMPGTB (VEX.256 Encoded Version)
DEST[127:0] := COMPARE_BYTES_GREATER(SRC1[127:0],SRC2[127:0])
DEST[255:128] := COMPARE_BYTES_GREATER(SRC1[255:128],SRC2[255:128])
DEST[MAXVL-1:256] := 0
VPCMPGTB (EVEX Encoded Versions)
(KL, VL) = (16, 128), (32, 256), (64, 512)
FOR j := 0 TO KL-1
i := j * 8
IF k2[j] OR *no writemask*
THEN
/* signed comparison */
CMP := SRC1[i+7:i] > SRC2[i+7:i];
IF CMP = TRUE
THEN DEST[j] := 1;
ELSE DEST[j] := 0; FI;
ELSE
DEST[j] := 0
; zeroing-masking onlyFI;
FI;
ENDFOR
DEST[MAX_KL-1:KL] := 0
PCMPGTW (With 64-bit Operands)
IF DEST[15:0] > SRC[15:0]
THEN DEST[15:0] := FFFFH;
ELSE DEST[15:0] := 0; FI;
(* Continue comparison of 2nd and 3rd words in DEST and SRC *)
IF DEST[63:48] > SRC[63:48]
THEN DEST[63:48] := FFFFH;
ELSE DEST[63:48] := 0; FI;
PCMPGTW (With 128-bit Operands)
DEST[127:0] := COMPARE_WORDS_GREATER(DEST[127:0],SRC[127:0])
DEST[MAXVL-1:128] (Unmodified)
VPCMPGTW (VEX.128 Encoded Version)
DEST[127:0] := COMPARE_WORDS_GREATER(SRC1,SRC2)
DEST[MAXVL-1:128] := 0
VPCMPGTW (VEX.256 Encoded Version)
DEST[127:0] := COMPARE_WORDS_GREATER(SRC1[127:0],SRC2[127:0])
DEST[255:128] := COMPARE_WORDS_GREATER(SRC1[255:128],SRC2[255:128])
DEST[MAXVL-1:256] := 0
PCMPGTB/PCMPGTW/PCMPGTD-Compare Packed Signed Integers for Greater Than
Vol. 2B
4-261
VPCMPGTW (EVEX Encoded Versions)
(KL, VL) = (8, 128), (16, 256), (32, 512)
FOR j := 0 TO KL-1
i := j * 16
IF k2[j] OR *no writemask*
THEN
/* signed comparison */
CMP := SRC1[i+15:i] > SRC2[i+15:i];
IF CMP = TRUE
THEN DEST[j] := 1;
ELSE DEST[j] := 0; FI;
ELSE
DEST[j] := 0
; zeroing-masking onlyFI;
FI;
ENDFOR
DEST[MAX_KL-1:KL] := 0
PCMPGTD (With 64-bit Operands)
IF DEST[31:0] > SRC[31:0]
THEN DEST[31:0] := FFFFFFFFH;
ELSE DEST[31:0] := 0; FI;
IF DEST[63:32] > SRC[63:32]
THEN DEST[63:32] := FFFFFFFFH;
ELSE DEST[63:32] := 0; FI;
PCMPGTD (With 128-bit Operands)
DEST[127:0] := COMPARE_DWORDS_GREATER(DEST[127:0],SRC[127:0])
DEST[MAXVL-1:128] (Unmodified)
VPCMPGTD (VEX.128 Encoded Version)
DEST[127:0] := COMPARE_DWORDS_GREATER(SRC1,SRC2)
DEST[MAXVL-1:128] := 0
VPCMPGTD (VEX.256 Encoded Version)
DEST[127:0] := COMPARE_DWORDS_GREATER(SRC1[127:0],SRC2[127:0])
DEST[255:128] := COMPARE_DWORDS_GREATER(SRC1[255:128],SRC2[255:128])
DEST[MAXVL-1:256] := 0
VPCMPGTD (EVEX Encoded Versions)
(KL, VL) = (4, 128), (8, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 32
IF k2[j] OR *no writemask*
THEN
/* signed comparison */
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN CMP := SRC1[i+31:i] > SRC2[31:0];
ELSE CMP := SRC1[i+31:i] > SRC2[i+31:i];
FI;
IF CMP = TRUE
THEN DEST[j] := 1;
ELSE DEST[j] := 0; FI;
ELSE
DEST[j] := 0
; zeroing-masking only
FI;
ENDFOR
PCMPGTB/PCMPGTW/PCMPGTD-Compare Packed Signed Integers for Greater Than
Vol. 2B
4-262
DEST[MAX_KL-1:KL] := 0
Intel C/C++ Compiler Intrinsic Equivalents
VPCMPGTB __mmask64 _mm512_cmpgt_epi8_mask(__m512i a, __m512i b);
VPCMPGTB __mmask64 _mm512_mask_cmpgt_epi8_mask(__mmask64 k, __m512i a, __m512i b);
VPCMPGTB __mmask32 _mm256_cmpgt_epi8_mask(__m256i a, __m256i b);
VPCMPGTB __mmask32 _mm256_mask_cmpgt_epi8_mask(__mmask32 k, __m256i a, __m256i b);
VPCMPGTB __mmask16 _mm_cmpgt_epi8_mask(__m128i a, __m128i b);
VPCMPGTB __mmask16 _mm_mask_cmpgt_epi8_mask(__mmask16 k, __m128i a, __m128i b);
VPCMPGTD __mmask16 _mm512_cmpgt_epi32_mask(__m512i a, __m512i b);
VPCMPGTD __mmask16 _mm512_mask_cmpgt_epi32_mask(__mmask16 k, __m512i a, __m512i b);
VPCMPGTD __mmask8 _mm256_cmpgt_epi32_mask(__m256i a, __m256i b);
VPCMPGTD __mmask8 _mm256_mask_cmpgt_epi32_mask(__mmask8 k, __m256i a, __m256i b);
VPCMPGTD __mmask8 _mm_cmpgt_epi32_mask(__m128i a, __m128i b);
VPCMPGTD __mmask8 _mm_mask_cmpgt_epi32_mask(__mmask8 k, __m128i a, __m128i b);
VPCMPGTW __mmask32 _mm512_cmpgt_epi16_mask(__m512i a, __m512i b);
VPCMPGTW __mmask32 _mm512_mask_cmpgt_epi16_mask(__mmask32 k, __m512i a, __m512i b);
VPCMPGTW __mmask16 _mm256_cmpgt_epi16_mask(__m256i a, __m256i b);
VPCMPGTW __mmask16 _mm256_mask_cmpgt_epi16_mask(__mmask16 k, __m256i a, __m256i b);
VPCMPGTW __mmask8 _mm_cmpgt_epi16_mask(__m128i a, __m128i b);
VPCMPGTW __mmask8 _mm_mask_cmpgt_epi16_mask(__mmask8 k, __m128i a, __m128i b);
PCMPGTB __m64 _mm_cmpgt_pi8 (__m64 m1, __m64 m2)
PCMPGTW __m64 _mm_cmpgt_pi16 (__m64 m1, __m64 m2)
PCMPGTD __m64 _mm_cmpgt_pi32 (__m64 m1, __m64 m2)
(V)PCMPGTB __m128i _mm_cmpgt_epi8 ( __m128i a, __m128i b)
(V)PCMPGTW __m128i _mm_cmpgt_epi16 ( __m128i a, __m128i b)
(V)DCMPGTD __m128i _mm_cmpgt_epi32 ( __m128i a, __m128i b)
VPCMPGTB __m256i _mm256_cmpgt_epi8 ( __m256i a, __m256i b)
VPCMPGTW __m256i _mm256_cmpgt_epi16 ( __m256i a, __m256i b)
VPCMPGTD __m256i _mm256_cmpgt_epi32 ( __m256i a, __m256i b)
Flags Affected
None.
Numeric Exceptions
None.
Other Exceptions
Non-EVEX-encoded instruction, see Table 2-21, “Type 4 Class Exception Conditions.”
EVEX-encoded VPCMPGTD, see Table 2-51, “Type E4 Class Exception Conditions.”
EVEX-encoded VPCMPGTB/W, see Exceptions Type E4.nb in Table 2-51, “Type E4 Class Exception Conditions.”
PCMPGTB/PCMPGTW/PCMPGTD-Compare Packed Signed Integers for Greater Than
Vol. 2B
4-263
PCMPGTQ-Compare Packed Data for Greater Than
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
66 0F 38 37 /r
A
V/V
SSE4_2
Compare packed signed qwords in xmm2/m128
PCMPGTQ xmm1,xmm2/m128
and xmm1 for greater than.
VEX.128.66.0F38.WIG 37 /r
B
V/V
AVX
Compare packed signed qwords in xmm2 and
VPCMPGTQ xmm1, xmm2, xmm3/m128
xmm3/m128 for greater than.
VEX.256.66.0F38.WIG 37 /r
B
V/V
AVX2
Compare packed signed qwords in ymm2 and
VPCMPGTQ ymm1, ymm2, ymm3/m256
ymm3/m256 for greater than.
EVEX.128.66.0F38.W1 37 /r
C
V/V
(AVX512VL AND
Compare Greater between int64 vector xmm2 and
VPCMPGTQ k1 {k2}, xmm2,
AVX512F) OR
int64 vector xmm3/m128/m64bcst, and set
xmm3/m128/m64bcst
AVX10.1
vector mask k1 to reflect the zero/nonzero status
of each element of the result, under writemask.
EVEX.256.66.0F38.W1 37 /r
C
V/V
(AVX512VL AND
Compare Greater between int64 vector ymm2 and
VPCMPGTQ k1 {k2}, ymm2,
AVX512F) OR
int64 vector ymm3/m256/m64bcst, and set
ymm3/m256/m64bcst
AVX10.1
vector mask k1 to reflect the zero/nonzero status
of each element of the result, under writemask.
EVEX.512.66.0F38.W1 37 /r
C
V/V
AVX512F
Compare Greater between int64 vector zmm2 and
VPCMPGTQ k1 {k2}, zmm2,
OR AVX10.1
int64 vector zmm3/m512/m64bcst, and set
zmm3/m512/m64bcst
vector mask k1 to reflect the zero/nonzero status
of each element of the result, under writemask.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
C
Full
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs an SIMD signed compare for the packed quadwords in the destination operand (first operand) and the
source operand (second operand). If the data element in the first (destination) operand is greater than the
corresponding element in the second (source) operand, the corresponding data element in the destination is set
to all 1s; otherwise, it is set to 0s.
128-bit Legacy SSE version: The second source operand can be an XMM register or a 128-bit memory location. The
first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM
destination register remain unchanged.
VEX.128 encoded version: The second source operand can be an XMM register or a 128-bit memory location. The
first source operand and destination operand are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM
register are zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register
or a 256-bit memory location. The destination operand is a YMM register.
EVEX encoded VPCMPGTD/Q: The first source operand (second operand) is a ZMM/YMM/XMM register. 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 64-bit memory location. The destination operand (first operand) is a mask register updated
according to the writemask k2.
PCMPGTQ-Compare Packed Data for Greater Than
Vol. 2B
4-264
Operation
COMPARE_QWORDS_GREATER (SRC1, SRC2)
IF SRC1[63:0] > SRC2[63:0]
THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;
ELSE DEST[63:0] := 0; FI;
IF SRC1[127:64] > SRC2[127:64]
THEN DEST[127:64] := FFFFFFFFFFFFFFFFH;
ELSE DEST[127:64] := 0; FI;
VPCMPGTQ (VEX.128 Encoded Version)
DEST[127:0] := COMPARE_QWORDS_GREATER(SRC1,SRC2)
DEST[MAXVL-1:128] := 0
VPCMPGTQ (VEX.256 Encoded Version)
DEST[127:0] := COMPARE_QWORDS_GREATER(SRC1[127:0],SRC2[127:0])
DEST[255:128] := COMPARE_QWORDS_GREATER(SRC1[255:128],SRC2[255:128])
DEST[MAXVL-1:256] := 0
VPCMPGTQ (EVEX Encoded Versions)
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k2[j] OR *no writemask*
THEN
/* signed comparison */
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN CMP := SRC1[i+63:i] > SRC2[63:0];
ELSE CMP := SRC1[i+63:i] > SRC2[i+63:i];
FI;
IF CMP = TRUE
THEN DEST[j] := 1;
ELSE DEST[j] := 0; FI;
ELSE
DEST[j] := 0
; zeroing-masking only
FI;
ENDFOR
DEST[MAX_KL-1:KL] := 0
Intel C/C++ Compiler Intrinsic Equivalent
VPCMPGTQ __mmask8 _mm512_cmpgt_epi64_mask( __m512i a, __m512i b);
VPCMPGTQ __mmask8 _mm512_mask_cmpgt_epi64_mask(__mmask8 k, __m512i a, __m512i b);
VPCMPGTQ __mmask8 _mm256_cmpgt_epi64_mask( __m256i a, __m256i b);
VPCMPGTQ __mmask8 _mm256_mask_cmpgt_epi64_mask(__mmask8 k, __m256i a, __m256i b);
VPCMPGTQ __mmask8 _mm_cmpgt_epi64_mask( __m128i a, __m128i b);
VPCMPGTQ __mmask8 _mm_mask_cmpgt_epi64_mask(__mmask8 k, __m128i a, __m128i b);
(V)PCMPGTQ __m128i _mm_cmpgt_epi64(__m128i a, __m128i b)
VPCMPGTQ __m256i _mm256_cmpgt_epi64( __m256i a, __m256i b);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
PCMPGTQ-Compare Packed Data for Greater Than
Vol. 2B
4-265
Other Exceptions
Non-EVEX-encoded instruction, see Table 2-21, “Type 4 Class Exception Conditions.”
EVEX-encoded VPCMPGTQ, see Table 2-51, “Type E4 Class Exception Conditions.”
PCMPGTQ-Compare Packed Data for Greater Than
Vol. 2B
4-266
PCMPISTRI-Packed Compare Implicit Length Strings, Return Index
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
66 0F 3A 63 /r imm8
RM
V/V
SSE4_2
Perform a packed comparison of string data
PCMPISTRI xmm1, xmm2/m128, imm8
with implicit lengths, generating an index, and
storing the result in ECX.
VEX.128.66.0F3A.WIG 63 /r ib
RM
V/V
AVX
Perform a packed comparison of string data
VPCMPISTRI xmm1, xmm2/m128, imm8
with implicit lengths, generating an index, and
storing the result in ECX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (r)
ModRM:r/m (r)
imm8
N/A
Description
The instruction compares data from two strings based on the encoded value in the imm8 control byte (see Section
4.1, “Imm8 Control Byte Operation for PCMPESTRI / PCMPESTRM / PCMPISTRI / PCMPISTRM”), and generates an
index stored to ECX.
Each string is represented by a single value. The value is an xmm (or possibly m128 for the second operand) which
contains the data elements of the string (byte or word data). Each input byte/word is augmented with a
valid/invalid tag. A byte/word is considered valid only if it has a lower index than the least significant null
byte/word. (The least significant null byte/word is also considered invalid.)
The comparison and aggregation operations are performed according to the encoded value of imm8 bit fields (see
Section 4.1). The index of the first (or last, according to imm8[6]) set bit of IntRes2 is returned in ECX. If no bits
are set in IntRes2, ECX is set to 16 (8).
Note that the Arithmetic Flags are written in a non-standard manner in order to supply the most relevant informa-
tion:
CFlag - Reset if IntRes2 is equal to zero, set otherwise
ZFlag - Set if any byte/word of xmm2/mem128 is null, reset otherwise
SFlag - Set if any byte/word of xmm1 is null, reset otherwise
OFlag -IntRes2[0]
AFlag - Reset
PFlag - Reset
Note: In VEX.128 encoded version, VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the
instruction will #UD.
Effective Operand Size
Operating mode/size
Operand 1
Operand 2
Result
16 bit
xmm
xmm/m128
ECX
32 bit
xmm
xmm/m128
ECX
64 bit
xmm
xmm/m128
ECX
Intel C/C++ Compiler Intrinsic Equivalent For Returning Index
int _mm_cmpistri (__m128i a, __m128i b, const int mode);
PCMPISTRI-Packed Compare Implicit Length Strings, Return Index
Vol. 2B
4-267
Intel C/C++ Compiler Intrinsics For Reading EFlag Results
int _mm_cmpistra (__m128i a, __m128i b, const int mode);
int _mm_cmpistrc (__m128i a, __m128i b, const int mode);
int _mm_cmpistro (__m128i a, __m128i b, const int mode);
int _mm_cmpistrs (__m128i a, __m128i b, const int mode);
int _mm_cmpistrz (__m128i a, __m128i b, const int mode);
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally, this instruction does not cause #GP if the
memory operand is not aligned to 16 Byte boundary, and:
#UD
If VEX.L = 1.
If VEX.vvvv ≠ 1111B.
PCMPISTRI-Packed Compare Implicit Length Strings, Return Index
Vol. 2B
4-268
PCMPISTRM-Packed Compare Implicit Length Strings, Return Mask
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
66 0F 3A 62 /r imm8
RM
V/V
SSE4_2
Perform a packed comparison of string data
PCMPISTRM xmm1, xmm2/m128, imm8
with implicit lengths, generating a mask, and
storing the result in XMM0.
VEX.128.66.0F3A.WIG 62 /r ib
RM
V/V
AVX
Perform a packed comparison of string data
VPCMPISTRM xmm1, xmm2/m128, imm8
with implicit lengths, generating a Mask, and
storing the result in XMM0.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (r)
ModRM:r/m (r)
imm8
N/A
Description
The instruction compares data from two strings based on the encoded value in the imm8 byte (see Section 4.1,
“Imm8 Control Byte Operation for PCMPESTRI / PCMPESTRM / PCMPISTRI / PCMPISTRM”) generating a mask
stored to XMM0.
Each string is represented by a single value. The value is an xmm (or possibly m128 for the second operand) which
contains the data elements of the string (byte or word data). Each input byte/word is augmented with a
valid/invalid tag. A byte/word is considered valid only if it has a lower index than the least significant null
byte/word. (The least significant null byte/word is also considered invalid.)
The comparison and aggregation operation are performed according to the encoded value of imm8 bit fields (see
Section 4.1). As defined by imm8[6], IntRes2 is then either stored to the least significant bits of XMM0 (zero
extended to 128 bits) or expanded into a byte/word-mask and then stored to XMM0.
Note that the Arithmetic Flags are written in a non-standard manner in order to supply the most relevant informa-
tion:
CFlag - Reset if IntRes2 is equal to zero, set otherwise
ZFlag - Set if any byte/word of xmm2/mem128 is null, reset otherwise
SFlag - Set if any byte/word of xmm1 is null, reset otherwise
OFlag - IntRes2[0]
AFlag - Reset
PFlag - Reset
Note: In VEX.128 encoded versions, bits (MAXVL-1:128) of XMM0 are zeroed. VEX.vvvv is reserved and must be
1111b, VEX.L must be 0, otherwise the instruction will #UD.
Effective Operand Size
Operating mode/size
Operand 1
Operand 2
Result
16 bit
xmm
xmm/m128
XMM0
32 bit
xmm
xmm/m128
XMM0
64 bit
xmm
xmm/m128
XMM0
Intel C/C++ Compiler Intrinsic Equivalent For Returning Mask
__m128i _mm_cmpistrm (__m128i a, __m128i b, const int mode);
PCMPISTRM-Packed Compare Implicit Length Strings, Return Mask
Vol. 2B
4-269
Intel C/C++ Compiler Intrinsics For Reading EFlag Results
int _mm_cmpistra (__m128i a, __m128i b, const int mode);
int _mm_cmpistrc (__m128i a, __m128i b, const int mode);
int _mm_cmpistro (__m128i a, __m128i b, const int mode);
int _mm_cmpistrs (__m128i a, __m128i b, const int mode);
int _mm_cmpistrz (__m128i a, __m128i b, const int mode);
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally, this instruction does not cause #GP if the
memory operand is not aligned to 16 Byte boundary, and:
#UD
If VEX.L = 1.
If VEX.vvvv ≠ 1111B.
PCMPISTRM-Packed Compare Implicit Length Strings, Return Mask
Vol. 2B
4-270
PCONFIG-Platform Configuration
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
NP 0F 01 C5
A
V/V
PCONFIG
This instruction is used to execute functions for
PCONFIG
configuring platform features.
Instruction Operand Encoding
Op/En
Tuple
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
N/A
N/A
N/A
N/A
Description
The PCONFIG instruction allows software to configure certain platform features. It supports these features with
multiple leaf functions, selecting a leaf function using the value in EAX.
Depending on the leaf function, the registers RBX, RCX, and RDX may be used to provide input information or for
the instruction to report output information. Addresses and operands are 32 bits outside 64-bit mode and are 64
bits in 64-bit mode. The value of CS.D does not affect operand size or address size.
Executions of PCONFIG may fail for platform-specific reasons. An execution reports failure by setting the ZF flag
and loading EAX with a non-zero failure reason; a successful execution clears ZF and EAX.
Each PCONFIG leaf function applies to a specific hardware block called a PCONFIG target. The leaf function is
supported only if the processor supports that target. Each target is associated with a numerical target identifier,
and CPUID leaf 1BH (PCONFIG information) enumerates the identifiers of the supported targets. An attempt to
execute an undefined leaf function, or a leaf function that applies to an unsupported target identifier, results in a
general-protection exception (#GP).
Leaf Function MKTME_KEY_PROGRAM
PCONFIG leaf function 0 (selected by loading EAX with value 0) is used for key programming for total memory
encryption-multi-key (TME-MK).1 This leaf function is called MKTME_KEY_PROGRAM and it pertains to the TME-MK
target, which has target identifier 1. The leaf function uses the EBX (or RBX) register for additional input informa-
tion.
Software uses this leaf function to manage the encryption key associated with a particular key identifier (KeyID).
The leaf function uses a data structure called the TME-MK key programming structure (MKTME_KEY_PRO-
GRAM_STRUCT). Software provides the address of the structure (as an offset in the DS segment) in EBX (or RBX).
The format of the structure is given in Table 4-16.
Table 4-16. MKTME_KEY_PROGRAM_STRUCT Format
Field
Offset (bytes)
Size (bytes)
Comments
KEYID
0
2
Key Identifier.
KEYID_CTRL
2
4
KeyID control:
• Bits 7:0: key-programming command (COMMAND)
• Bits 23:8: encryption algorithm (ENC_ALG)
• Bits 31:24: Reserved, must be zero (RSVD)
Ignored
6
58
Not used.
KEY_FIELD_1
64
64
Software supplied data key or entropy for data key.
KEY_FIELD_2
128
64
Software supplied tweak key or entropy for tweak key.
1. Further details on TME-MK can be found here:
PCONFIG-Platform Configuration
Vol. 2B
4-271
A description of each of the fields in MKTME_KEY_PROGRAM_STRUCT is provided below:
•
KEYID: The key identifier (KeyID) being programmed to the TME-MK engine. This leaf function causes a
general-protection exception (#GP) if the KeyID is zero. KeyID zero always uses the current behavior
configured for TME (total memory encryption), either to encrypt with platform TME key or to bypass TME
encryption. This leaf function also causes a #GP if the KeyID exceeds the maximum enumerated
IA32_TME_CAPABILITY.MK_TME_MAX_KEYS[50:36] or configured by the setting of
IA32_TME_ACTIVATE.MK_TME_KEYID_BITS[39:32].
- If IA32_TME_ACTIVATE.MK_TME_KEYID_BITS[35:32] = k, KEYID[15:k] must be zero.
- If the logical processor is outside secure arbitration mode (SEAM; see Chapter 35) and
IA32_TME_ACTIVATE.TDX_RESERVED_KEYID_BITS[39:36] = p > 0, KEYID[k-1:k-p] must also be zero.
(Note that p will never exceed k.)
If either is not true, the leaf function causes #GP.
•
KEYID_CTRL: The KEYID_CTRL field comprises two sub-fields used by software to control the encryption
performed for the selected KeyID:
- Key-programming command (COMMAND; bits 7:0). This 8-bit field should contain one of the following
values:
• KEYID_SET_KEY_DIRECT (value 0). With this command, software programs directly the encryption key
to be used for the selected KeyID.
• KEYID_SET_KEY_RANDOM (value 1). With this command, software has the CPU generate and assign an
encryption key to be used for the selected KeyID using a hardware random-number generator.
If this command is used and there is insufficient entropy for the random-number generator, the leaf
function will fail and report the failure by loading EAX with value 2 (ENTROPY_ERROR).
Because the keys programed by this leaf function are discarded on reset and software cannot read the
programmed keys, the keys programmed with this command are ephemeral.
• KEYID_CLEAR_KEY (value 2). With this command, software indicates that the selected KeyID should
use the current behavior configured for TME (see above).
• KEYID_NO_ENCRYPT (value 3). With this command, software indicates that no encryption should be
used for the selected KeyID.
If any other value is used, the leaf function causes a #GP.
- Encryption algorithm (ENC_ALG, bits 23:8). Bits 63:48 of the IA32_TME_ACTIVATE MSR (MSR index 982H)
indicate which encryption algorithms are supported by the platform. The 16-bit ENC_ALG field should
specify one of the algorithms indicated in IA32_TME_ACTIVATE. This leaf function causes a #GP if ENC_ALG
does not set exactly one bit or if it sets a bit whose corresponding bit is not set in IA32_TME_AC-
TIVATE[63:48].
•
KEY_FIELD_1: Use of this field depends upon selected key-programming command:
- If the direct key-programming command is used (KEYID_SET_KEY_DIRECT), this field carries the software
supplied data key to be used for the KeyID.
- If the random key-programming command is used (KEYID_SET_KEY_RANDOM), this field carries the
software supplied entropy to be mixed in the CPU generated random data key.
- This field is ignored when one of the other key-programming commands is used.
It is software’s responsibility to ensure that the key supplied for the direct key-programming option or the
entropy supplied for the random key-programming option does not result in weak keys. There are no explicit
checks in the instruction to detect or prevent weak keys.
•
KEY_FIELD_2: Use of this field depends upon selected key-programming command:
- If the direct key-programming command is used (KEYID_SET_KEY_DIRECT), this field carries the software
supplied tweak key to be used for the KeyID.
- If the random key-programming command is used (KEYID_SET_KEY_RANDOM), this field carries the
software supplied entropy to be mixed in the CPU generated random tweak key.
- This field is ignored when one of the other key-programming commands is used.
PCONFIG-Platform Configuration
Vol. 2B
4-272
It is software’s responsibility to ensure that the key supplied for the direct key-programming option or the
entropy supplied for the random key-programming option does not result in weak keys. There are no explicit
checks in the instruction to detect or prevent weak keys.
All KeyIDs default to TME behavior (encrypt with TME key or bypass encryption) on activation of TME-MK. Software
can at any point decide to change the key for a KeyID using this leaf function. Changing the key for a KeyID does
not change the state of the TLB caches or memory pipeline. Software is responsible for taking appropriate actions
to ensure correct behavior.
The key table used by TME-MK is shared by all logical processors in a platform. For this reason, execution of the
MKTME_KEY_PROGRAM leaf function must gain exclusive access to the key table before updating it. The leaf func-
tion does this by acquiring lock (implemented in the platform) and retaining that lock until the execution
completes. An execution of the leaf function may fail to acquire the lock if it is already in use. In this situation, the
leaf function will load EAX with failure reason 5 (DEVICE_BUSY) indicating that software must retry. When this
happens, the key table is not updated, and software should retry execution of PCONFIG.
Leaf Function TSE_KEY_PROGRAM
PCONFIG leaf function 1(selected by loading EAX with value 1) is used for direct key programming for total storage
encryption (TSE). This leaf function is called TSE_KEY_PROGRAM and it pertains to the TSE target, which has
target identifier 2. The leaf function can be used only in 64-bit mode. It uses the RBX register for additional input
information.
Software uses this leaf function to manage the encryption key associated with a particular key identifier (KeyID).
The leaf function uses a data structure called the TSE key programming structure (TSE_KEY_PROGRAM_-
STRUCT). Software provides the linear address of the structure in RBX. The format of the structure is given in Table
4-17.
Table 4-17. TSE_KEY_PROGRAM_STRUCT Format
Field
Offset (bytes)
Size (bytes)
Comments
KEYID
0
2
Key Identifier.
KEYID_CTRL
2
4
KeyID control:
• Bits 7:0: key-programming command (COMMAND)
• Bits 23:8: encryption algorithm (ENC_ALG)
• Bits 31:24: Reserved, must be zero (RSVD)
Ignored
6
58
Not used.
KEY_FIELD_1
64
64
Software supplied data key.
KEY_FIELD_2
128
64
Software supplied tweak key.
A description of each of the fields in MKTME_KEY_PROGRAM_STRUCT is provided below:
• KEYID: The key identifier (KeyID) being programmed to the TSE engine. The leaf function causes a general-
protection exception (#GP) if the KeyID exceeds the maximum enumerated in the TSE_MAX_KEYS field
(bits 50:36) of the IA32_TSE_CAPABILITY MSR (MSR index 9F1H).
• KEYID_CTRL: The KEYID_CTRL field comprises two sub-fields used by software to control the encryption
performed for the selected KeyID:
- Key-programming command (COMMAND; bits 7:0). This 8-bit field should contain one of the following
values:
• TSE_SET_KEY_DIRECT (value 0). With this command, software programs directly the encryption key to
be used for the selected KeyID.
• TSE_NO_ENCRYPT (value 1). With this command, software indicates that no encryption should be used
for the selected KeyID.
If any other value is used, the leaf function causes a #GP.
- Encryption algorithm (ENC_ALG, bits 23:8). IA32_TSE_CAPABILITY[15:0] indicates which encryption
algorithms are supported by the platform. The 16-bit ENC_ALG field should specify one of the algorithms
PCONFIG-Platform Configuration
Vol. 2B
4-273
indicated in IA32_TSE_CAPABILITY. The leaf function causes a #GP if ENC_ALG does not set exactly one bit
or if it sets a bit whose corresponding bit is not set in IA32_TSE_CAPABILITY.
• KEY_FIELD_1: If the direct key-programming command is used (TSE_SET_KEY_DIRECT), this field carries
the software supplied data key to be used for the KeyID. Otherwise, the field is ignored.
• KEY_FIELD_2: If the direct key-programming command is used (TSE_SET_KEY_DIRECT), this field carries
the software supplied tweak key to be used for the KeyID. Otherwise, the field is ignored.
The TSE key table is shared by all logical processors in a platform. For this reason, execution of this leaf function
must gain exclusive access to the key table before updating it. The leaf function does this by acquiring a lock
(implemented in the platform) and retaining that lock until the execution completes. An execution of the leaf func-
tion may fail to acquire the lock if it is already in use. In this situation, the leaf function will load EAX with failure
reason 5 (DEVICE_BUSY). When this happens, the key table is not updated, and software should retry execution of
PCONFIG.
NOTES
Earlier versions of this manual specified that bytes 63:6 of MKTME_KEY_PROGRAM_STRUCT were
reserved and that leaf function MKTME_PROGRAM would cause a #GP if they were not all zero. This
is not the case. As indicated in Table 4-16, PCONFIG ignores those bytes.
They also specified that leaf function would cause a #GP if the upper 48 bytes of each of the 64-
byte key fields were not all 0. This is not the case. From each of these fields, the leaf function uses
the number of bytes required by the selected encryption algorithm (e.g., 32 bytes for AES-XTS
256) and ignores the upper bytes.
They also specified that the leaf function would complete and report a failure reason in EAX if the
structure specified an incorrect KeyID, and unsupported key-programming command, or an
incorrect selection of an encryption algorithm. This is not the case. As indicated above (and in the
Operation section), those conditions cause #GP.
Leaf Function TSE_KEY_PROGRAM_WRAPPED
PCONFIG leaf function 2 (selected by loading EAX with value 2) is used for wrapped key programming for total
storage encryption (TSE). This leaf function is called TSE_KEY_PROGRAM_WRAPPED and it pertains to the TSE
target, which has target identifier 2. The leaf function can be used only in 64-bit mode. It uses the RBX and RCX
registers for additional input information.
Software uses this leaf function to manage the encryption key associated with a particular key identifier (KeyID).
The leaf function uses control input provided in RBX. The format of that input is given in Table 4-18.
Table 4-18. TSE_KEY_PROGRAM_WRAPPED Control Input
Field
Bit Positions
Comments
KEYID
15:0
Key identifier.
Reserved
23:16
Reserved, must be zero.
ENC_ALG
39:24
Encryption algorithm.
Ignored
63:40
Not used.
A description of each of the fields in the control input is provided below:
• KEYID: The key identifier (KeyID) being programmed to the TSE engine. The leaf function causes a general-
protection exception (#GP) if the KeyID exceeds the maximum enumerated in the TSE_MAX_KEYs field
(bits 50:36) of the IA32_TSE_CAPABILITY MSR (MSR index 9F1H).
• ENC_ALG: The encryption algorithm selected for the KeyID. IA32_TSE_CAPABILITY[15:0] indicates which
encryption algorithms are supported by the platform. The 16-bit ENC_ALG field should specify one of the
algorithms indicated in IA32_TSE_CAPABILITY. The leaf function causes a #GP if ENC_ALG does not set exactly
one bit or if it sets a bit whose corresponding bit is not set in IA32_TSE_CAPABILITY.
The leaf function also uses a 256-byte data structure called the bind structure. This structure should be the
output of the PBNDKB instruction, subsequently modified by software (see below). Software provides the linear
address of the structure in RCX. The format of the structure is given in Table 4-19.
PCONFIG-Platform Configuration
Vol. 2B
4-274
Table 4-19. Bind Structure Format
Field
Offset (bytes)
Size (bytes)
Comments
MAC
0
16
MAC produced by PBNDKB of its input bind structure
Reserved
16
8
Reserved, must be zero.
IV
24
12
Initialization vector.
Reserved
36
28
Reserved, must be zero.
BTENCDATA
64
64
Encrypted data (data key and tweak key)
BTDATA
128
128
Additional control and data (not encrypted)
A description of each of the fields in TSE_BIND_STRUCT is provided below:
• MAC: A MAC produced by PBNDKB of its input bind structure. The PCONFIG leaf function will recompute the
MAC and confirm that it matches this value.
• IV: The initialization vector that PBNDKB used for encryption. The PCONFIG leaf function will use this in its
decryption of encrypted data and computation of the MAC.
• BTENCDATA: Data which had been encrypted by PBNDKB, containing the data and tweak keys to be used by
TSE.
• BTDATA: Data that was input to PBNDKB that was output without encryption. It has the following format:
- USER_SUPP_CHALLENGE (bytes 31:0): PBNDKB uses a value provided by software in its input bind
structure but writes zero to this field in the output bind structure to be used by PCONFIG. Software should
configure this field with the proper value before executing this PCONFIG leaf function.
- KEY_GENERATION_CTRL (byte 32): PBNDKB uses this value to determine whether to generate random
keys. The PCONFIG leaf function does not use this field.
- The remaining 95 bytes are reserved and must be zero.
The leaf function uses the entire BTDATA field when it computes the MAC.
The leaf function determines a 256-bit wrapping key by computing an HMAC based on SHA-256 using 256-bit
platform-specific key and the USER_SUPP_CHALLENGE in the BTDATA field of the TSE_BIND_STRUCT.
Using the wrapping key, the leaf function uses an AES GCM authenticated decryption function to decrypt BTENC-
DATA and compute a MAC. The decryption function uses the following inputs:
• The 64-byte BTENCDATA from TSE_BIND_STRUCT to be decrypted.
• The 256-bit wrapping key.
• The 96-bit IV from TSE_BIND_STRUCT.
• Additional authenticated data that is the concatenation of bytes 63:16 and bytes 255:128 of the TSE_BIND_-
STRUCT. These 176 bytes will comprise 8 bytes of zeroes, the 12-byte IV, 28 bytes of zeroes, and 128 bytes of
BTDATA of which the upper 95 bytes are zero).
• The length of the additional authenticated data (176).
The decryption function produces a structure with a 64 bytes of decrypted data and a 16-byte MAC. The decrypted
data comprises a 256-bit data key and a 256-bit tweak key.
If the MAC produced by the decryption function differs from that provided in the TSE_BIND_STRUCT, the leaf func-
tion will load EAX with failure reason 7 (UNWRAP_FAILURE). Otherwise, the leaf function will attempt to program
the TSE key table for the selected KeyID with the keys contained in the decrypted data.
The TSE key table is shared by all logical processors in a platform. For this reason, execution of this leaf function
must gain exclusive access to the key table before updating it. The leaf function does this by acquiring a lock
(implemented in the platform) and retaining that lock until the execution completes. An execution of the leaf func-
tion may fail to acquire the lock if it is already in use. In this situation, the leaf function will load EAX with failure
reason 5 (DEVICE_BUSY). When this happens, the key table is not updated, and software should retry execution of
PCONFIG.
PCONFIG-Platform Configuration
Vol. 2B
4-275
Operation
(* #UD if PCONFIG is not enumerated or CPL > 0 *)
IF CPUID.07H.00H:EDX.PCONFIG[18]= 0 OR CPL > 0
THEN #UD; FI;
(* #GP(0) for an unsupported leaf function *)
IF EAX > 2
THEN #GP(0); FI;
CASE (EAX)
(* operation based on selected leaf function *)
0 (MKTME_KEY_PROGRAM):
IF CPUID function 1BH does not enumerate support for the TME-MK target (value 1)
THEN #GP(0); FI;
(* Confirm that TME-MK is properly enabled by the IA32_TME_ACTIVATE MSR *)
(* The MSR must be locked, encryption enabled, and a non-zero number of KeyID bits specified *)
IF IA32_TME_ACTIVATE[0] = 0 OR IA32_TME_ACTIVATE[1] = 0 OR IA32_TME_ACTIVATE[35:32] = 0
THEN #GP(0); FI;
IF DS:RBX is not 256-byte aligned
THEN #GP(0); FI;
Load TMP_KEY_PROGRAM_STRUCT from 192 bytes at linear address DS:RBX;
IF TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL sets any reserved bits
THEN #GP(0); FI;
(* Check for a valid command *)
IF TMP_KEY_PROGRAM_STRUCT. KEYID_CTRL.COMMAND > 3
THEN #GP(0); FI;
(* Check that the KEYID being operated upon is a valid KEYID *)
IF TMP_KEY_PROGRAM_STRUCT.KEYID = 0 OR
TMP_KEY_PROGRAM_STRUCT.KEYID > IA32_TME_CAPABILITY.MK_TME_MAX_KEYS
THEN #GP(0); FI;
k := IA32_TME_ACTIVATE.MK_TME_KEYID_BITS;
IF TMP_KEY_PROGRAM_STRUCT.KEYID[15:k] != 0
THEN #GP(0); FI;
IF not in SEAM AND IA32_TME_ACTIVATE.TDX_RESERVED_KEYID_BITS > 0
THEN
p := IA32_TME_ACTIVATE.TDX_RESERVED_KEYID_BITS;
IF TMP_KEY_PROGRAM_STRUCT.KEYID[k-1:k-p] != 0
THEN #GP(0); FI;
FI;
(* Check that only one encryption algorithm is requested for the KeyID and it is one of the activated algorithms *)
IF TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG does not set exactly one bit OR
(TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG & IA32_TME_ACTIVATE[63:48]) = 0
THEN #GP(0); FI:
Attempt to acquire lock to gain exclusive access to platform key table for TME-MK;
IF attempt is unsuccessful
THEN (* PCONFIG failure *)
RFLAGS.ZF := 1;
RAX := DEVICE_BUSY;
(* failure reason 5 *)
PCONFIG-Platform Configuration
Vol. 2B
4-276
GOTO EXIT;
FI;
CASE (TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.COMMAND) OF
0 (KEYID_SET_KEY_DIRECT):
Update TME-MK table for TMP_KEY_PROGRAM_STRUCT.KEYID as follows:
Encrypt with the selected key
Use the encryption algorithm selected by TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG
(* The number of bytes used by the next two lines depends on selected encryption algorithm *)
DATA_KEY is TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_1
TWEAK_KEY is TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_2
BREAK;
1 (KEYID_SET_KEY_RANDOM):
Load TMP_RND_DATA_KEY with a random key using hardware RNG; (* key size depends on selected encryption algorithm *)
IF there was insufficient entropy
THEN (* PCONFIG failure *)
RFLAGS.ZF := 1;
RAX := ENTROPY_ERROR;
(* failure reason 2 *)
Release lock on platform key table;
GOTO EXIT;
FI;
Load TMP_RND_TWEAK_KEY with a random key using hardware RNG; (* key size depends on selected encryption algorithm *)
IF there was insufficient entropy
THEN (* PCONFIG failure *)
RFLAGS.ZF := 1;
RAX := ENTROPY_ERROR;
(* failure reason 2 *)
Release lock on platform key table;
GOTO EXIT;
FI;
(* Combine software-supplied entropy to the data key and tweak key *)
(* The number of bytes used by the next two lines depends on selected encryption algorithm *)
TMP_RND_DATA_KEY := TMP_RND_KEY XOR TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_1;
TMP_RND_TWEAK_KEY := TMP_RND_TWEAK_KEY XOR TMP_KEY_PROGRAM_STRUCT.KEY_FIELD_2;
Update TME-MK table for TMP_KEY_PROGRAM_STRUCT.KEYID as follows:
Encrypt with the selected key
Use the encryption algorithm selected by TMP_KEY_PROGRAM_STRUCT.KEYID_CTRL.ENC_ALG
(* The number of bytes used by the next two lines depends on selected encryption algorithm *)
DATA_KEY is TMP_RND_DATA_KEY
TWEAK_KEY is TMP_RND_TWEAK_KEY
BREAK;
2 (KEYID_CLEAR_KEY):
Update TME-MK table for TMP_KEY_PROGRAM_STRUCT.KEYID as follows:
Encrypt (or not) using the current configuration for TME
The specified encryption algorithm and key values are not used.
BREAK;
3 (KEYID_NO_ENCRYPT):
Update TME-MK table for TMP_KEY_PROGRAM_STRUCT.KEYID as follows:
Do not encrypt
The specified encryption algorithm and key values are not used.
BREAK;
PCONFIG-Platform Configuration
Vol. 2B
4-277
ESAC;
Release lock on platform key table for TME-MK;
1 (TSE_KEY_PROGRAM):
IF CPUID function 1BH does not enumerate support for the TSE target (value 2)
THEN #GP(0); FI;
IF not in 64-bit mode
THEN #GP(0); FI;
IF RBX is not 256-byte aligned
THEN #GP(0); FI;
Load TMP_KEY_STRUCT from 192 bytes at linear address in RBX;
IF TMP_KEY_STRUCT.KEYID_CTRL sets any reserved bits
THEN #GP(0); FI;
(* Check for a valid command *)
IF TMP_KEY_STRUCT. KEYID_CTRL.COMMAND > 1
THEN #GP(0); FI;
(* Check that the KEYID being operated upon is a valid KEYID *)
IF TMP_KEY_STRUCT.KEYID > IA32_TSE_CAPABILITY.TSE_MAX_KEYS
THEN #GP(0); FI;
(* Check that only one encryption algorithm is requested for the KeyID and it is one of the activated algorithms *)
IF TMP_KEY_STRUCT.KEYID_CTRL.ENC_ALG does not set exactly one bit OR
(TMP_KEY_STRUCT.KEYID_CTRL.ENC_ALG & IA32_TSE_CAPABILITY[15:0]) = 0
THEN #GP(0); FI;
Attempt to acquire lock to gain exclusive access to platform key table for TSE;
IF attempt is unsuccessful
THEN (* PCONFIG failure *)
RFLAGS.ZF := 1;
RAX := DEVICE_BUSY;
(* failure reason 5 *)
GOTO EXIT;
FI;
CASE (TMP_KEY_STRUCT.KEYID_CTRL.COMMAND) OF
0 (TSE_SET_KEY_DIRECT):
Update TSE table for TMP_KEY_STRUCT.KEYID as follows:
Encrypt with the selected key
Use the encryption algorithm selected by TMP_KEY_STRUCT.KEYID_CTRL.ENC_ALG
(* The number of bytes used by the next two lines depends on selected encryption algorithm *)
DATA_KEY is TMP_KEY_STRUCT.KEY_FIELD_1
TWEAK_KEY is TMP_KEY_STRUCT.KEY_FIELD_2
BREAK;
1 (TSE_NO_ENCRYPT):
Update TSE table for TMP_KEY_STRUCT.KEYID as follows:
Do not encrypt
The specified encryption algorithm and key values are not used.
BREAK;
PCONFIG-Platform Configuration
Vol. 2B
4-278
ESAC;
Release lock on platform key table for TSE;
2 (TSE_KEY_PROGRAM_WRAPPED):
IF CPUID function 1BH does not enumerate support for the TSE target (value 2)
THEN #GP(0); FI;
IF not in 64-bit mode OR RBX[23:16] != 0 OR RCX is not 256-byte aligned
THEN #GP(0); FI;
(* Check that the KEYID being operated upon is a valid KEYID *)
IF RBX[15:0] > IA32_TSE_CAPABILITY.TSE_MAX_KEYS
THEN #GP(0); FI;
(* Check that only one encryption algorithm is requested for the KeyID and it is one of the activated algorithms *)
IF RBX[39:24] does not set exactly one bit OR (RBX[39:24] & IA32_TSE_CAPABILITY[15:0]) = 0
THEN #GP(0); FI;
Load TMP_BIND_STRUCT from 256 bytes at linear address in RCX;
(* Check TMP_BIND_STRUCT for illegal values *)
IF bytes 23:16 and bytes 63:36 of TMP_BIND_STRUCT are not all zero
THEN #GP(0); FI;
IF TMP_BIND_STRUCT.BTDATA.KEY_GENERATION_CTRL > 1
THEN #GP(0); FI;
IF bytes 128:33 of TMP_BIND_STRUCT.BTDATA are not all zero
THEN #GP(0); FI;
(* Compute wrapping key *)
PLATFORM_KEY := 256-bit platform-specific key;
WRAPPING_KEY := HMAC_SHA256(PLATFORM_KEY, TMP_BIND_STRUCT.BTDATA.USER_SUPP_CHALLENGE);
(* Compose 176 bytes of additional authenticated data for use by authenticated decryption *)
AAD := Concatenation of bytes 63:16 and bytes 255:128 of TMP_BIND_STRUCT;
DECRYPT_STRUCT := AES256_GCM_DEC(TMP_BIND_STRUCT.BTENCDATA, WRAPPING_KEY, TMP_BIND_STRUCT.IV, AAD, 176);
(* Fail if MAC mismatch *)
IF TMP_BIND_STRUCT.MAC != DECRYPT_STRUCT.MAC
THEN
RFLAGS.ZF := 1;
RAX := UNWRAP_FAILURE; (* failure reason 7 *)
GOTO EXIT;
FI;
Attempt to acquire lock to gain exclusive access to platform key table for TSE;
IF attempt is unsuccessful
THEN (* PCONFIG failure *)
RFLAGS.ZF := 1;
RAX := DEVICE_BUSY;
(* failure reason 5 *)
GOTO EXIT;
FI;
Update TSE table for RBX[15:0] as follows:
PCONFIG-Platform Configuration
Vol. 2B
4-279
Encrypt with the selected key
Use the encryption algorithm selected by RBX[39:24]
(* The number of bytes used by the next two lines depends on selected encryption algorithm *)
DATA_KEY is DECRYPT_STRUCT.DEC_DATA.KEY_FIELD_1
TWEAK_KEY is DECRYPT_STRUCT.DEC_DATA.KEY_FIELD_2
Release lock on platform key table for TSE;
ESAC;
RAX := 0;
RFLAGS.ZF := 0;
EXIT:
RFLAGS.CF := 0;
RFLAGS.PF := 0;
RFLAGS.AF := 0;
RFLAGS.OF := 0;
RFLAGS.SF := 0;
Protected Mode Exceptions
#GP(0)
If input value in EAX encodes an unsupported leaf function.
If a memory operand effective address is outside the relevant segment limit.
MKTME_KEY_PROGRAM leaf function:
If CPUID function 1BH does not enumerate support for the TME-MK target (value 1).
If IA32_TME_ACTIVATE MSR is not locked.
If hardware encryption and TME-MK capability are not enabled in IA32_TME_ACTIVATE MSR.
If the memory operand is not 256B aligned.
If any of the reserved bits in the KEYID_CTRL field of the MKTME_KEY_PROGRAM_STRUCT are
set or that field indicates an unsupported KeyID, key-programming command, or encryption
algorithm.
TSE_KEY_PROGRAM leaf function:
The TSE_KEY_PROGRAM leaf function is not supported in protected mode.
TSE_KEY_PROGRAM_WRAPPED leaf function:
The TSE_KEY_PROGRAM_WRAPPED leaf function is not supported in protected mode.
#PF(fault-code)
If a page fault occurs in accessing memory operands.
#UD
If the LOCK prefix are used.
If current privilege level is not 0.
If CPUID.07H.00H:EDX.PCONFIG[18] = 0
Real-Address Mode Exceptions
#GP
If input value in EAX encodes an unsupported leaf function.
MKTME_KEY_PROGRAM leaf function:
If CPUID function 1BH does not enumerate support for the TME-MK target (value 1).
If IA32_TME_ACTIVATE MSR is not locked.
If hardware encryption and TME-MK capability are not enabled in IA32_TME_ACTIVATE MSR.
If a memory operand is not 256B aligned.
If any of the reserved bits in the KEYID_CTRL field of the MKTME_KEY_PROGRAM_STRUCT are
set or that field indicates an unsupported KeyID, key-programming command, or encryption
algorithm.
PCONFIG-Platform Configuration
Vol. 2B
4-280
TSE_KEY_PROGRAM leaf function:
The TSE_KEY_PROGRAM leaf function is not supported in real-address mode.
TSE_KEY_PROGRAM_WRAPPED leaf function:
The TSE_KEY_PROGRAM_WRAPPED leaf function is not supported in real-address mode.
#UD
If the LOCK prefix are used.
If CPUID.07H.00H:EDX.PCONFIG[18] = 0
Virtual-8086 Mode Exceptions
#UD
PCONFIG instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#GP(0)
If input value in EAX encodes an unsupported leaf function.
If a memory operand is non-canonical form.
MKTME_KEY_PROGRAM leaf function:
If CPUID function 1BH does not enumerate support for the TME-MK target (value 1).
If IA32_TME_ACTIVATE MSR is not locked.
If hardware encryption and TME-MK capability are not enabled in IA32_TME_ACTIVATE MSR.
If a memory operand is not 256B aligned.
If any of the reserved bits in the KEYID_CTRL field of the MKTME_KEY_PROGRAM_STRUCT are
set or that field indicates an unsupported KeyID, key-programming command, or encryption
algorithm.
TSE_KEY_PROGRAM leaf function:
IF CPUID function 1BH does not enumerate support for the TSE target (value 2).
If RBX is not 256-byte aligned.
If any of the reserved bits in the KEYID_CTRL field of the TMP_KEY_STRUCT are set or that
field indicates an unsupported KeyID, key-programming command, or encryption algorithm.
TSE_KEY_PROGRAM_WRAPPED leaf function:
IF CPUID function 1BH does not enumerate support for the TSE target (value 2).
If RCX is not 256-byte aligned.
If any of the reserved bits in RBX are set or that register indicates an unsupported KeyID or
encryption algorithm.
If any of the reserved bytes in the TSE_BIND_STRUCT are set (including bytes in BTDATA).
#PF(fault-code)
If a page fault occurs in accessing memory operands.
#UD
If the LOCK prefix are used.
If the current privilege level is not 0.
If CPUID.07H.00H:EDX.PCONFIG[18] = 0.
PCONFIG-Platform Configuration
Vol. 2B
4-281
PDEP-Parallel Bits Deposit
Opcode/
Op/
64/32-
CPUID
Description
Instruction
En
bit
Feature
Mode
Flag
VEX.LZ.F2.0F38.W0 F5 /r
RVM
V/V
BMI2
Parallel deposit of bits from r32b using mask in r/m32, result is written
PDEP r32a, r32b, r/m32
to r32a.
VEX.LZ.F2.0F38.W1 F5 /r
RVM
V/N.E.
BMI2
Parallel deposit of bits from r64b using mask in r/m64, result is written
PDEP r64a, r64b, r/m64
to r64a.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RVM
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
PDEP uses a mask in the second source operand (the third operand) to transfer/scatter contiguous low order bits
in the first source operand (the second operand) into the destination (the first operand). PDEP takes the low bits
from the first source operand and deposit them in the destination operand at the corresponding bit locations that
are set in the second source operand (mask). All other bits (bits not set in mask) in destination are set to zero.
SRC1
S31
S30
S29
S28
S27
S7
S6
S5
S4
S3
S2
S1
S
0
SRC2
0
0
0
1
0
1
0
1
0
0
1
0
0
(mask)
DEST
0
0
0
S3
0
S2
0
S1
0
0
S0
0
0
bit 0
bit 31
Figure 4-8. PDEP Example
This instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in
64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An
attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.
Operation
TEMP := SRC1;
MASK := SRC2;
DEST := 0 ;
m := 0, k := 0;
DO WHILE m < OperandSize
IF MASK[ m] = 1 THEN
DEST[ m] := TEMP[ k];
k := k+ 1;
FI
m := m+ 1;
OD
PDEP-Parallel Bits Deposit
Vol. 2B
4-282
Flags Affected
None.
Intel C/C++ Compiler Intrinsic Equivalent
PDEP unsigned __int32 _pdep_u32(unsigned __int32 src, unsigned __int32 mask);
PDEP unsigned __int64 _pdep_u64(unsigned __int64 src, unsigned __int32 mask);
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-29, “Type 13 Class Exception Conditions.”
PDEP-Parallel Bits Deposit
Vol. 2B
4-283
PEXT-Parallel Bits Extract
Opcode/
Op/
64/32-
CPUID
Description
Instruction
En
bit
Feature
Mode
Flag
VEX.LZ.F3.0F38.W0 F5 /r
RVM
V/V
BMI2
Parallel extract of bits from r32b using mask in r/m32, result is written
PEXT r32a, r32b, r/m32
to r32a.
VEX.LZ.F3.0F38.W1 F5 /r
RVM
V/N.E.
BMI2
Parallel extract of bits from r64b using mask in r/m64, result is written
PEXT r64a, r64b, r/m64
to r64a.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RVM
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
PEXT uses a mask in the second source operand (the third operand) to transfer either contiguous or non-contig-
uous bits in the first source operand (the second operand) to contiguous low order bit positions in the destination
(the first operand). For each bit set in the MASK, PEXT extracts the corresponding bits from the first source
operand and writes them into contiguous lower bits of destination operand. The remaining upper bits of destination
are zeroed.
SRC1
S31
S30
S29
S28
S27
S7
S6
S5
S4
S3
S2
S1
S0
SRC2
0
0
0
1
0
1
0
1
0
0
1
0
0
(mask)
DEST
0
0
0
0
0
0
0
0
0
S28
S7
S5
S2
bit 0
bit 31
Figure 4-9. PEXT Example
This instruction is not supported in real mode and virtual-8086 mode. The operand size is always 32 bits if not in
64-bit mode. In 64-bit mode operand size 64 requires VEX.W1. VEX.W1 is ignored in non-64-bit modes. An
attempt to execute this instruction with VEX.L not equal to 0 will cause #UD.
PEXT-Parallel Bits Extract
Vol. 2B
4-284
Operation
TEMP := SRC1;
MASK := SRC2;
DEST := 0 ;
m := 0, k := 0;
DO WHILE m < OperandSize
IF MASK[ m] = 1 THEN
DEST[ k] := TEMP[ m];
k := k+ 1;
FI
m := m+ 1;
OD
Flags Affected
None.
Intel C/C++ Compiler Intrinsic Equivalent
PEXT unsigned __int32 _pext_u32(unsigned __int32 src, unsigned __int32 mask);
PEXT unsigned __int64 _pext_u64(unsigned __int64 src, unsigned __int32 mask);
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-29, “Type 13 Class Exception Conditions.”
PEXT-Parallel Bits Extract
Vol. 2B
4-285
PEXTRB/PEXTRD/PEXTRQ-Extract Byte/Dword/Qword
Opcode/
Op/ En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
66 0F 3A 14 /r ib
A
V/V
SSE4_1
Extract a byte integer value from xmm2 at the
PEXTRB reg/m8, xmm2, imm8
source byte offset specified by imm8 into reg or
m8. The upper bits of r32 or r64 are zeroed.
66 0F 3A 16 /r ib
A
V/V
SSE4_1
Extract a dword integer value from xmm2 at the
PEXTRD r/m32, xmm2, imm8
source dword offset specified by imm8 into r/m32.
66 REX.W 0F 3A 16 /r ib
A
V/N.E.
SSE4_1
Extract a qword integer value from xmm2 at the
PEXTRQ r/m64, xmm2, imm8
source qword offset specified by imm8 into r/m64.
VEX.128.66.0F3A.W0 14 /r ib
A
V1/V
AVX
Extract a byte integer value from xmm2 at the
VPEXTRB reg/m8, xmm2, imm8
source byte offset specified by imm8 into reg or
m8. The upper bits of r64/r32 is filled with zeros.
VEX.128.66.0F3A.W0 16 /r ib
A
V/V
AVX
Extract a dword integer value from xmm2 at the
VPEXTRD r32/m32, xmm2, imm8
source dword offset specified by imm8 into
r32/m32.
VEX.128.66.0F3A.W1 16 /r ib
A
V/I2
AVX
Extract a qword integer value from xmm2 at the
VPEXTRQ r64/m64, xmm2, imm8
source dword offset specified by imm8 into
r64/m64.
EVEX.128.66.0F3A.WIG 14 /r ib
B
V/V
AVX512BW
Extract a byte integer value from xmm2 at the
VPEXTRB reg/m8, xmm2, imm8
OR AVX10.1
source byte offset specified by imm8 into reg or
m8. The upper bits of r64/r32 is filled with zeros.
EVEX.128.66.0F3A.W0 16 /r ib
B
V/V
AVX512DQ
Extract a dword integer value from xmm2 at the
VPEXTRD r32/m32, xmm2, imm8
OR AVX10.1
source dword offset specified by imm8 into
r32/m32.
EVEX.128.66.0F3A.W1 16 /r ib
B
V/N.E.2
AVX512DQ
Extract a qword integer value from xmm2 at the
VPEXTRQ r64/m64, xmm2, imm8
OR AVX10.1
source dword offset specified by imm8 into
r64/m64.
NOTES:
1. In 64-bit mode, VEX.W1 is ignored for VPEXTRB (similar to legacy REX.W=1 prefix in PEXTRB).
2. VEX.W/EVEX.W in non-64 bit is ignored; the instructions behaves as if the W0 version is used.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:r/m (w)
ModRM:reg (r)
imm8
N/A
B
Tuple1 Scalar
ModRM:r/m (w)
ModRM:reg (r)
imm8
N/A
Description
Extract a byte/dword/qword integer value from the source XMM register at a byte/dword/qword offset determined
from imm8[3:0]. The destination can be a register or byte/dword/qword memory location. If the destination is a
register, the upper bits of the register are zero extended.
In legacy non-VEX encoded version and if the destination operand is a register, the default operand size in 64-bit
mode for PEXTRB/PEXTRD is 64 bits, the bits above the least significant byte/dword data are filled with zeros.
PEXTRQ is not encodable in non-64-bit modes and requires REX.W in 64-bit mode.
Note: In VEX.128 encoded versions, VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the
instruction will #UD. In EVEX.128 encoded versions, EVEX.vvvv is reserved and must be 1111b, EVEX.L”L must be
0, otherwise the instruction will #UD. If the destination operand is a register, the default operand size in 64-bit
mode for VPEXTRB/VPEXTRD is 64 bits, the bits above the least significant byte/word/dword data are filled with
zeros.
PEXTRB/PEXTRD/PEXTRQ-Extract Byte/Dword/Qword
Vol. 2B
4-286
Operation
CASE of
PEXTRB: SEL := COUNT[3:0];
TEMP := (Src >> SEL*8) AND FFH;
IF (DEST = Mem8)
THEN
Mem8 := TEMP[7:0];
ELSE IF (64-Bit Mode and 64-bit register selected)
THEN
R64[7:0] := TEMP[7:0];
r64[63:8] := ZERO_FILL; };
ELSE
R32[7:0] := TEMP[7:0];
r32[31:8] := ZERO_FILL; };
FI;
PEXTRD:SEL := COUNT[1:0];
TEMP := (Src >> SEL*32) AND FFFF_FFFFH;
DEST := TEMP;
PEXTRQ: SEL := COUNT[0];
TEMP := (Src >> SEL*64);
DEST := TEMP;
EASC:
VPEXTRTD/VPEXTRQ
IF (64-Bit Mode and 64-bit dest operand)
THEN
Src_Offset := imm8[0]
r64/m64 := (Src >> Src_Offset * 64)
ELSE
Src_Offset := imm8[1:0]
r32/m32 := ((Src >> Src_Offset *32) AND 0FFFFFFFFh);
FI
VPEXTRB ( dest=m8)
SRC_Offset := imm8[3:0]
Mem8 := (Src >> Src_Offset*8)
VPEXTRB ( dest=reg)
IF (64-Bit Mode )
THEN
SRC_Offset := imm8[3:0]
DEST[7:0] := ((Src >> Src_Offset*8) AND 0FFh)
DEST[63:8] := ZERO_FILL;
ELSE
SRC_Offset := imm8[3:0];
DEST[7:0] := ((Src >> Src_Offset*8) AND 0FFh);
DEST[31:8] := ZERO_FILL;
FI
Intel C/C++ Compiler Intrinsic Equivalent
PEXTRB int _mm_extract_epi8 (__m128i src, const int ndx);
PEXTRD int _mm_extract_epi32 (__m128i src, const int ndx);
PEXTRQ __int64 _mm_extract_epi64 (__m128i src, const int ndx);
PEXTRB/PEXTRD/PEXTRQ-Extract Byte/Dword/Qword
Vol. 2B
4-287
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
Non-EVEX-encoded instruction, see Table 2-22, “Type 5 Class Exception Conditions.”
EVEX-encoded instruction, see Table 2-59, “Type E9NF Class Exception Conditions.”
Additionally:
#UD
If VEX.L = 1 or EVEX.L’L > 0.
If VEX.vvvv != 1111B or EVEX.vvvv != 1111B.
PEXTRB/PEXTRD/PEXTRQ-Extract Byte/Dword/Qword
Vol. 2B
4-288
PEXTRW-Extract Word
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
NP 0F C5 /r ib1
A
V/V
SSE
Extract the word specified by imm8 from mm and
move it to reg, bits 15-0. The upper bits of r32 or r64
PEXTRW reg, mm, imm8
is zeroed.
66 0F C5 /r ib
A
V/V
SSE2
Extract the word specified by imm8 from xmm and
move it to reg, bits 15-0. The upper bits of r32 or r64
PEXTRW reg, xmm, imm8
is zeroed.
66 0F 3A 15 /r ib
B
V/V
SSE4_1
Extract the word specified by imm8 from xmm and
PEXTRW reg/m16, xmm, imm8
copy it to lowest 16 bits of reg or m16. Zero-extend
the result in the destination, r32 or r64.
VEX.128.66.0F.W0 C5 /r ib
A
V2/V
AVX
Extract the word specified by imm8 from xmm1 and
VPEXTRW reg, xmm1, imm8
move it to reg, bits 15:0. Zero-extend the result. The
upper bits of r64/r32 is filled with zeros.
VEX.128.66.0F3A.W0 15 /r ib
B
V/V
AVX
Extract a word integer value from xmm2 at the
VPEXTRW reg/m16, xmm2, imm8
source word offset specified by imm8 into reg or
m16. The upper bits of r64/r32 is filled with zeros.
EVEX.128.66.0F.WIG C5 /r ib
A
V/V
AVX512BW
Extract the word specified by imm8 from xmm1 and
VPEXTRW reg, xmm1, imm8
OR AVX10.1
move it to reg, bits 15:0. Zero-extend the result. The
upper bits of r64/r32 is filled with zeros.
EVEX.128.66.0F3A.WIG 15 /r ib
C
V/V
AVX512BW
Extract a word integer value from xmm2 at the
VPEXTRW reg/m16, xmm2, imm8
OR AVX10.1
source word offset specified by imm8 into reg or
m16. The upper bits of r64/r32 is filled with zeros.
NOTES:
1. See note in Section 2.5, “Intel® AVX and Intel® SSE Instruction Exception Classification,” in the Intel® 64 and IA-32 Architectures Soft-
ware Developer’s Manual, Volume 2A, and Section 25.25.3, “Exception Conditions of Legacy SIMD Instructions Operating on MMX
Registers,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B.
2. In 64-bit mode, VEX.W1 is ignored for VPEXTRW (similar to legacy REX.W=1 prefix in PEXTRW).
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (w)
ModRM:r/m (r)
imm8
N/A
B
N/A
ModRM:r/m (w)
ModRM:reg (r)
imm8
N/A
C
Tuple1 Scalar
ModRM:r/m (w)
ModRM:reg (r)
imm8
N/A
Description
Copies the word in the source operand (second operand) specified by the count operand (third operand) to the
destination operand (first operand). The source operand can be an MMX technology register or an XMM register.
The destination operand can be the low word of a general-purpose register or a 16-bit memory address. The count
operand is an 8-bit immediate. When specifying a word location in an MMX technology register, the 2 least-signifi-
cant bits of the count operand specify the location; for an XMM register, the 3 least-significant bits specify the loca-
tion. The content of the destination register above bit 16 is cleared (set to all 0s).
In 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers
(XMM8-XMM15, R8-15). If the destination operand is a general-purpose register, the default operand size is 64-bits
in 64-bit mode.
Note: In VEX.128 encoded versions, VEX.vvvv is reserved and must be 1111b, VEX.L must be 0, otherwise the
instruction will #UD. In EVEX.128 encoded versions, EVEX.vvvv is reserved and must be 1111b, EVEX.L must be 0,
PEXTRW-Extract Word
Vol. 2B
4-289
otherwise the instruction will #UD. If the destination operand is a register, the default operand size in 64-bit mode
for VPEXTRW is 64 bits, the bits above the least significant byte/word/dword data are filled with zeros.
Operation
IF (DEST = Mem16)
THEN
SEL := COUNT[2:0];
TEMP := (Src >> SEL*16) AND FFFFH;
Mem16 := TEMP[15:0];
ELSE IF (64-Bit Mode and destination is a general-purpose register)
THEN
FOR (PEXTRW instruction with 64-bit source operand)
{ SEL := COUNT[1:0];
TEMP := (SRC >> (SEL ∗ 16)) AND FFFFH;
r64[15:0] := TEMP[15:0];
r64[63:16] := ZERO_FILL; };
FOR (PEXTRW instruction with 128-bit source operand)
{ SEL := COUNT[2:0];
TEMP := (SRC >> (SEL ∗ 16)) AND FFFFH;
r64[15:0] := TEMP[15:0];
r64[63:16] := ZERO_FILL; }
ELSE
FOR (PEXTRW instruction with 64-bit source operand)
{ SEL := COUNT[1:0];
TEMP := (SRC >> (SEL ∗ 16)) AND FFFFH;
r32[15:0] := TEMP[15:0];
r32[31:16] := ZERO_FILL; };
FOR (PEXTRW instruction with 128-bit source operand)
{ SEL := COUNT[2:0];
TEMP := (SRC >> (SEL ∗ 16)) AND FFFFH;
r32[15:0] := TEMP[15:0];
r32[31:16] := ZERO_FILL; };
FI;
FI;
VPEXTRW ( dest=m16)
SRC_Offset := imm8[2:0]
Mem16 := (Src >> Src_Offset*16)
VPEXTRW ( dest=reg)
IF (64-Bit Mode )
THEN
SRC_Offset := imm8[2:0]
DEST[15:0] := ((Src >> Src_Offset*16) AND 0FFFFh)
DEST[63:16] := ZERO_FILL;
ELSE
SRC_Offset := imm8[2:0]
DEST[15:0] := ((Src >> Src_Offset*16) AND 0FFFFh)
DEST[31:16] := ZERO_FILL;
FI
Intel C/C++ Compiler Intrinsic Equivalent
PEXTRW int _mm_extract_pi16 (__m64 a, int n)
PEXTRW-Extract Word
Vol. 2B
4-290
PEXTRW int _mm_extract_epi16 ( __m128i a, int imm)
Flags Affected
None.
Numeric Exceptions
None.
Other Exceptions
Non-EVEX-encoded instruction, see Table 2-22, “Type 5 Class Exception Conditions.”
EVEX-encoded instruction, see Table 2-59, “Type E9NF Class Exception Conditions.”
Additionally:
#UD
If VEX.L = 1 or EVEX.L’L > 0.
If VEX.vvvv != 1111B or EVEX.vvvv != 1111B.
PEXTRW-Extract Word
Vol. 2B
4-291
PHADDSW-Packed Horizontal Add and Saturate
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
NP 0F 38 03 /r1
RM
V/V
SSSE3
Add 16-bit signed integers horizontally, pack
saturated integers to mm1.
PHADDSW mm1, mm2/m64
66 0F 38 03 /r
RM
V/V
SSSE3
Add 16-bit signed integers horizontally, pack
saturated integers to xmm1.
PHADDSW xmm1, xmm2/m128
VEX.128.66.0F38.WIG 03 /r
RVM
V/V
AVX
Add 16-bit signed integers horizontally, pack
saturated integers to xmm1.
VPHADDSW xmm1, xmm2, xmm3/m128
VEX.256.66.0F38.WIG 03 /r
RVM
V/V
AVX2
Add 16-bit signed integers horizontally, pack
saturated integers to ymm1.
VPHADDSW ymm1, ymm2, ymm3/m256
NOTES:
1. See note in Section 2.5, “Intel® AVX and Intel® SSE Instruction Exception Classification,” in the Intel® 64 and IA-32 Architectures Soft-
ware Developer’s Manual, Volume 2A, and Section 25.25.3, “Exception Conditions of Legacy SIMD Instructions Operating on MMX
Registers,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
RVM
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
(V)PHADDSW adds two adjacent signed 16-bit integers horizontally from the source and destination operands and
saturates the signed results; packs the signed, saturated 16-bit results to the destination operand (first operand)
When the source operand is a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a
general-protection exception (#GP) will be generated.
Legacy SSE version: Both operands can be MMX registers. The second source operand can be an MMX register or
a 64-bit memory location.
128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source
operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destina-
tion register remain unchanged.
In 64-bit mode, use the REX prefix to access additional registers.
VEX.128 encoded version: The first source and destination operands are XMM registers. The second source
operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are
zeroed.
VEX.256 encoded version: The first source and destination operands are YMM registers. The second source
operand can be an YMM register or a 256-bit memory location.
Operation
PHADDSW (With 64-bit Operands)
mm1[15-0] = SaturateToSignedWord((mm1[31-16] + mm1[15-0]);
mm1[31-16] = SaturateToSignedWord(mm1[63-48] + mm1[47-32]);
mm1[47-32] = SaturateToSignedWord(mm2/m64[31-16] + mm2/m64[15-0]);
mm1[63-48] = SaturateToSignedWord(mm2/m64[63-48] + mm2/m64[47-32]);
PHADDSW-Packed Horizontal Add and Saturate
Vol. 2B
4-292
PHADDSW (With 128-bit Operands)
xmm1[15-0]= SaturateToSignedWord(xmm1[31-16] + xmm1[15-0]);
xmm1[31-16] = SaturateToSignedWord(xmm1[63-48] + xmm1[47-32]);
xmm1[47-32] = SaturateToSignedWord(xmm1[95-80] + xmm1[79-64]);
xmm1[63-48] = SaturateToSignedWord(xmm1[127-112] + xmm1[111-96]);
xmm1[79-64] = SaturateToSignedWord(xmm2/m128[31-16] + xmm2/m128[15-0]);
xmm1[95-80] = SaturateToSignedWord(xmm2/m128[63-48] + xmm2/m128[47-32]);
xmm1[111-96] = SaturateToSignedWord(xmm2/m128[95-80] + xmm2/m128[79-64]);
xmm1[127-112] = SaturateToSignedWord(xmm2/m128[127-112] + xmm2/m128[111-96]);
VPHADDSW (VEX.128 Encoded Version)
DEST[15:0]= SaturateToSignedWord(SRC1[31:16] + SRC1[15:0])
DEST[31:16] = SaturateToSignedWord(SRC1[63:48] + SRC1[47:32])
DEST[47:32] = SaturateToSignedWord(SRC1[95:80] + SRC1[79:64])
DEST[63:48] = SaturateToSignedWord(SRC1[127:112] + SRC1[111:96])
DEST[79:64] = SaturateToSignedWord(SRC2[31:16] + SRC2[15:0])
DEST[95:80] = SaturateToSignedWord(SRC2[63:48] + SRC2[47:32])
DEST[111:96] = SaturateToSignedWord(SRC2[95:80] + SRC2[79:64])
DEST[127:112] = SaturateToSignedWord(SRC2[127:112] + SRC2[111:96])
DEST[MAXVL-1:128] := 0
VPHADDSW (VEX.256 Encoded Version)
DEST[15:0]= SaturateToSignedWord(SRC1[31:16] + SRC1[15:0])
DEST[31:16] = SaturateToSignedWord(SRC1[63:48] + SRC1[47:32])
DEST[47:32] = SaturateToSignedWord(SRC1[95:80] + SRC1[79:64])
DEST[63:48] = SaturateToSignedWord(SRC1[127:112] + SRC1[111:96])
DEST[79:64] = SaturateToSignedWord(SRC2[31:16] + SRC2[15:0])
DEST[95:80] = SaturateToSignedWord(SRC2[63:48] + SRC2[47:32])
DEST[111:96] = SaturateToSignedWord(SRC2[95:80] + SRC2[79:64])
DEST[127:112] = SaturateToSignedWord(SRC2[127:112] + SRC2[111:96])
DEST[143:128]= SaturateToSignedWord(SRC1[159:144] + SRC1[143:128])
DEST[159:144] = SaturateToSignedWord(SRC1[191:176] + SRC1[175:160])
DEST[175:160] = SaturateToSignedWord( SRC1[223:208] + SRC1[207:192])
DEST[191:176] = SaturateToSignedWord(SRC1[255:240] + SRC1[239:224])
DEST[207:192] = SaturateToSignedWord(SRC2[127:112] + SRC2[143:128])
DEST[223:208] = SaturateToSignedWord(SRC2[159:144] + SRC2[175:160])
DEST[239:224] = SaturateToSignedWord(SRC2[191-160] + SRC2[159-128])
DEST[255:240] = SaturateToSignedWord(SRC2[255:240] + SRC2[239:224])
Intel C/C++ Compiler Intrinsic Equivalent
PHADDSW __m64 _mm_hadds_pi16 (__m64 a, __m64 b)
(V)PHADDSW __m128i _mm_hadds_epi16 (__m128i a, __m128i b)
VPHADDSW __m256i _mm256_hadds_epi16 (__m256i a, __m256i b)
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally:
#UD
If VEX.L = 1.
PHADDSW-Packed Horizontal Add and Saturate
Vol. 2B
4-293
PHADDW/PHADDD-Packed Horizontal Add
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
NP 0F 38 01 /r1
RM
V/V
SSSE3
Add 16-bit integers horizontally, pack to mm1.
PHADDW mm1, mm2/m64
66 0F 38 01 /r
RM
V/V
SSSE3
Add 16-bit integers horizontally, pack to
xmm1.
PHADDW xmm1, xmm2/m128
NP 0F 38 02 /r
RM
V/V
SSSE3
Add 32-bit integers horizontally, pack to mm1.
PHADDD mm1, mm2/m64
66 0F 38 02 /r
RM
V/V
SSSE3
Add 32-bit integers horizontally, pack to
xmm1.
PHADDD xmm1, xmm2/m128
VEX.128.66.0F38.WIG 01 /r
RVM
V/V
AVX
Add 16-bit integers horizontally, pack to
xmm1.
VPHADDW xmm1, xmm2, xmm3/m128
VEX.128.66.0F38.WIG 02 /r
RVM
V/V
AVX
Add 32-bit integers horizontally, pack to
xmm1.
VPHADDD xmm1, xmm2, xmm3/m128
VEX.256.66.0F38.WIG 01 /r
RVM
V/V
AVX2
Add 16-bit signed integers horizontally, pack
to ymm1.
VPHADDW ymm1, ymm2, ymm3/m256
VEX.256.66.0F38.WIG 02 /r
RVM
V/V
AVX2
Add 32-bit signed integers horizontally, pack
to ymm1.
VPHADDD ymm1, ymm2, ymm3/m256
NOTES:
1. See note in Section 2.5, “Intel® AVX and Intel® SSE Instruction Exception Classification,” in the Intel® 64 and IA-32 Architectures Soft-
ware Developer’s Manual, Volume 2A, and Section 25.25.3, “Exception Conditions of Legacy SIMD Instructions Operating on MMX Reg-
isters,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
RVM
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
(V)PHADDW adds two adjacent 16-bit signed integers horizontally from the source and destination operands and
packs the 16-bit signed results to the destination operand (first operand). (V)PHADDD adds two adjacent 32-bit
signed integers horizontally from the source and destination operands and packs the 32-bit signed results to the
destination operand (first operand). When the source operand is a 128-bit memory operand, the operand must be
aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.
Note that these instructions can operate on either unsigned or signed (two’s complement notation) integers;
however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected
overflow conditions, software must control the ranges of the values operated on.
Legacy SSE instructions: Both operands can be MMX registers. The second source operand can be an MMX register
or a 64-bit memory location.
128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source
operand can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM
destination register remain unchanged.
In 64-bit mode, use the REX prefix to access additional registers.
PHADDW/PHADDD-Packed Horizontal Add
Vol. 2B
4-294
VEX.128 encoded version: The first source and destination operands are XMM registers. The second source
operand can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM
register are zeroed.
VEX.256 encoded version: Horizontal addition of two adjacent data elements of the low 16-bytes of the first and
second source operands are packed into the low 16-bytes of the destination operand. Horizontal addition of two
adjacent data elements of the high 16-bytes of the first and second source operands are packed into the high 16-
bytes of the destination operand. The first source and destination operands are YMM registers. The second source
operand can be an YMM register or a 256-bit memory location.
SRC2
Y7
Y6
Y5
Y4
Y3
Y2
Y1
Y0
X7
X6
X5
X4
X3
X2
X1
X0
SRC1
S7
S3
S3
S4
S3
S2
S1
S0
255
0
Dest
Figure 4-10. 256-bit VPHADDD Instruction Operation
Operation
PHADDW (With 64-bit Operands)
mm1[15-0] = mm1[31-16] + mm1[15-0];
mm1[31-16] = mm1[63-48] + mm1[47-32];
mm1[47-32] = mm2/m64[31-16] + mm2/m64[15-0];
mm1[63-48] = mm2/m64[63-48] + mm2/m64[47-32];
PHADDW (With 128-bit Operands)
xmm1[15-0] = xmm1[31-16] + xmm1[15-0];
xmm1[31-16] = xmm1[63-48] + xmm1[47-32];
xmm1[47-32] = xmm1[95-80] + xmm1[79-64];
xmm1[63-48] = xmm1[127-112] + xmm1[111-96];
xmm1[79-64] = xmm2/m128[31-16] + xmm2/m128[15-0];
xmm1[95-80] = xmm2/m128[63-48] + xmm2/m128[47-32];
xmm1[111-96] = xmm2/m128[95-80] + xmm2/m128[79-64];
xmm1[127-112] = xmm2/m128[127-112] + xmm2/m128[111-96];
VPHADDW (VEX.128 Encoded Version)
DEST[15:0] := SRC1[31:16] + SRC1[15:0]
DEST[31:16] := SRC1[63:48] + SRC1[47:32]
DEST[47:32] := SRC1[95:80] + SRC1[79:64]
DEST[63:48] := SRC1[127:112] + SRC1[111:96]
DEST[79:64] := SRC2[31:16] + SRC2[15:0]
DEST[95:80] := SRC2[63:48] + SRC2[47:32]
DEST[111:96] := SRC2[95:80] + SRC2[79:64]
DEST[127:112] := SRC2[127:112] + SRC2[111:96]
DEST[MAXVL-1:128] := 0
PHADDW/PHADDD-Packed Horizontal Add
Vol. 2B
4-295
VPHADDW (VEX.256 Encoded Version)
DEST[15:0] := SRC1[31:16] + SRC1[15:0]
DEST[31:16] := SRC1[63:48] + SRC1[47:32]
DEST[47:32] := SRC1[95:80] + SRC1[79:64]
DEST[63:48] := SRC1[127:112] + SRC1[111:96]
DEST[79:64] := SRC2[31:16] + SRC2[15:0]
DEST[95:80] := SRC2[63:48] + SRC2[47:32]
DEST[111:96] := SRC2[95:80] + SRC2[79:64]
DEST[127:112] := SRC2[127:112] + SRC2[111:96]
DEST[143:128] := SRC1[159:144] + SRC1[143:128]
DEST[159:144] := SRC1[191:176] + SRC1[175:160]
DEST[175:160] := SRC1[223:208] + SRC1[207:192]
DEST[191:176] := SRC1[255:240] + SRC1[239:224]
DEST[207:192] := SRC2[127:112] + SRC2[143:128]
DEST[223:208] := SRC2[159:144] + SRC2[175:160]
DEST[239:224] := SRC2[191:176] + SRC2[207:192]
DEST[255:240] := SRC2[223:208] + SRC2[239:224]
PHADDD (With 64-bit Operands)
mm1[31-0] = mm1[63-32] + mm1[31-0];
mm1[63-32] = mm2/m64[63-32] + mm2/m64[31-0];
PHADDD (With 128-bit Operands)
xmm1[31-0] = xmm1[63-32] + xmm1[31-0];
xmm1[63-32] = xmm1[127-96] + xmm1[95-64];
xmm1[95-64] = xmm2/m128[63-32] + xmm2/m128[31-0];
xmm1[127-96] = xmm2/m128[127-96] + xmm2/m128[95-64];
VPHADDD (VEX.128 Encoded Version)
DEST[31-0] := SRC1[63-32] + SRC1[31-0]
DEST[63-32] := SRC1[127-96] + SRC1[95-64]
DEST[95-64] := SRC2[63-32] + SRC2[31-0]
DEST[127-96] := SRC2[127-96] + SRC2[95-64]
DEST[MAXVL-1:128] := 0
VPHADDD (VEX.256 Encoded Version)
DEST[31-0] := SRC1[63-32] + SRC1[31-0]
DEST[63-32] := SRC1[127-96] + SRC1[95-64]
DEST[95-64] := SRC2[63-32] + SRC2[31-0]
DEST[127-96] := SRC2[127-96] + SRC2[95-64]
DEST[159-128] := SRC1[191-160] + SRC1[159-128]
DEST[191-160] := SRC1[255-224] + SRC1[223-192]
DEST[223-192] := SRC2[191-160] + SRC2[159-128]
DEST[255-224] := SRC2[255-224] + SRC2[223-192]
Intel C/C++ Compiler Intrinsic Equivalents
PHADDW __m64 _mm_hadd_pi16 (__m64 a, __m64 b)
PHADDD __m64 _mm_hadd_pi32 (__m64 a, __m64 b)
(V)PHADDW __m128i _mm_hadd_epi16 (__m128i a, __m128i b)
(V)PHADDD __m128i _mm_hadd_epi32 (__m128i a, __m128i b)
VPHADDW __m256i _mm256_hadd_epi16 (__m256i a, __m256i b)
VPHADDD __m256i _mm256_hadd_epi32 (__m256i a, __m256i b)
PHADDW/PHADDD-Packed Horizontal Add
Vol. 2B
4-296
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally:
#UD
If VEX.L = 1.
PHADDW/PHADDD-Packed Horizontal Add
Vol. 2B
4-297
PHMINPOSUW-Packed Horizontal Word Minimum
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
66 0F 38 41 /r
RM
V/V
SSE4_1
Find the minimum unsigned word in xmm2/m128 and
PHMINPOSUW xmm1, xmm2/m128
place its value in the low word of xmm1 and its index
in the second-lowest word of xmm1.
VEX.128.66.0F38.WIG 41 /r
RM
V/V
AVX
Find the minimum unsigned word in xmm2/m128 and
VPHMINPOSUW xmm1, xmm2/m128
place its value in the low word of xmm1 and its index
in the second-lowest word of xmm1.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (w)
ModRM:r/m (r)
N/A
N/A
Description
Determine the minimum unsigned word value in the source operand (second operand) and place the unsigned
word in the low word (bits 0-15) of the destination operand (first operand). The word index of the minimum value
is stored in bits 16-18 of the destination operand. The remaining upper bits of the destination are set to zero.
128-bit Legacy SSE version: Bits (MAXVL-1:128) of the corresponding XMM destination register remain
unchanged.
VEX.128 encoded version: Bits (MAXVL-1:128) of the destination XMM register are zeroed. VEX.vvvv is reserved
and must be 1111b, VEX.L must be 0, otherwise the instruction will #UD.
Operation
PHMINPOSUW (128-bit Legacy SSE Version)
INDEX := 0;
MIN := SRC[15:0]
IF (SRC[31:16] < MIN)
THEN INDEX := 1; MIN := SRC[31:16]; FI;
IF (SRC[47:32] < MIN)
THEN INDEX := 2; MIN := SRC[47:32]; FI;
* Repeat operation for words 3 through 6
IF (SRC[127:112] < MIN)
THEN INDEX := 7; MIN := SRC[127:112]; FI;
DEST[15:0] := MIN;
DEST[18:16] := INDEX;
DEST[127:19] := 0000000000000000000000000000H;
VPHMINPOSUW (VEX.128 Encoded Version)
INDEX := 0
MIN := SRC[15:0]
IF (SRC[31:16] < MIN) THEN INDEX := 1; MIN := SRC[31:16]
IF (SRC[47:32] < MIN) THEN INDEX := 2; MIN := SRC[47:32]
* Repeat operation for words 3 through 6
IF (SRC[127:112] < MIN) THEN INDEX := 7; MIN := SRC[127:112]
DEST[15:0] := MIN
DEST[18:16] := INDEX
DEST[127:19] := 0000000000000000000000000000H
DEST[MAXVL-1:128] := 0
PHMINPOSUW-Packed Horizontal Word Minimum
Vol. 2B
4-298
Intel C/C++ Compiler Intrinsic Equivalent
PHMINPOSUW __m128i _mm_minpos_epu16( __m128i packed_words);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally:
#UD
If VEX.L = 1.
If VEX.vvvv ≠ 1111B.
PHMINPOSUW-Packed Horizontal Word Minimum
Vol. 2B
4-299
PHSUBSW-Packed Horizontal Subtract and Saturate
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
NP 0F 38 07 /r1
RM
V/V
SSSE3
Subtract 16-bit signed integer horizontally,
pack saturated integers to mm1.
PHSUBSW mm1, mm2/m64
66 0F 38 07 /r
RM
V/V
SSSE3
Subtract 16-bit signed integer horizontally,
pack saturated integers to xmm1.
PHSUBSW xmm1, xmm2/m128
VEX.128.66.0F38.WIG 07 /r
RVM
V/V
AVX
Subtract 16-bit signed integer horizontally,
pack saturated integers to xmm1.
VPHSUBSW xmm1, xmm2, xmm3/m128
VEX.256.66.0F38.WIG 07 /r
RVM
V/V
AVX2
Subtract 16-bit signed integer horizontally,
pack saturated integers to ymm1.
VPHSUBSW ymm1, ymm2, ymm3/m256
NOTES:
1. See note in Section 2.5, “Intel® AVX and Intel® SSE Instruction Exception Classification,” in the Intel® 64 and IA-32 Architectures Soft-
ware Developer’s Manual, Volume 2A, and Section 25.25.3, “Exception Conditions of Legacy SIMD Instructions Operating on MMX
Registers,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3B.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
RVM
ModRM:reg (r, w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
(V)PHSUBSW performs horizontal subtraction on each adjacent pair of 16-bit signed integers by subtracting the
most significant word from the least significant word of each pair in the source and destination operands. The
signed, saturated 16-bit results are packed to the destination operand (first operand). When the source operand is
a 128-bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception
(#GP) will be generated.
Legacy SSE version: Both operands can be MMX registers. The second source operand can be an MMX register or
a 64-bit memory location.
128-bit Legacy SSE version: The first source and destination operands are XMM registers. The second source
operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the corresponding YMM destina-
tion register remain unchanged.
In 64-bit mode, use the REX prefix to access additional registers.
VEX.128 encoded version: The first source and destination operands are XMM registers. The second source
operand is an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destination YMM register are
zeroed.
VEX.256 encoded version: The first source and destination operands are YMM registers. The second source
operand can be an YMM register or a 256-bit memory location.
Operation
PHSUBSW (With 64-bit Operands)
mm1[15-0] = SaturateToSignedWord(mm1[15-0] - mm1[31-16]);
mm1[31-16] = SaturateToSignedWord(mm1[47-32] - mm1[63-48]);
mm1[47-32] = SaturateToSignedWord(mm2/m64[15-0] - mm2/m64[31-16]);
mm1[63-48] = SaturateToSignedWord(mm2/m64[47-32] - mm2/m64[63-48]);
PHSUBSW-Packed Horizontal Subtract and Saturate
Vol. 2B
4-300
PHSUBSW (With 128-bit Operands)
xmm1[15-0] = SaturateToSignedWord(xmm1[15-0] - xmm1[31-16]);
xmm1[31-16] = SaturateToSignedWord(xmm1[47-32] - xmm1[63-48]);
xmm1[47-32] = SaturateToSignedWord(xmm1[79-64] - xmm1[95-80]);
xmm1[63-48] = SaturateToSignedWord(xmm1[111-96] - xmm1[127-112]);
xmm1[79-64] = SaturateToSignedWord(xmm2/m128[15-0] - xmm2/m128[31-16]);
xmm1[95-80] =SaturateToSignedWord(xmm2/m128[47-32] - xmm2/m128[63-48]);
xmm1[111-96] =SaturateToSignedWord(xmm2/m128[79-64] - xmm2/m128[95-80]);
xmm1[127-112]= SaturateToSignedWord(xmm2/m128[111-96] - xmm2/m128[127-112]);
VPHSUBSW (VEX.128 Encoded Version)
DEST[15:0]= SaturateToSignedWord(SRC1[15:0] - SRC1[31:16])
DEST[31:16] = SaturateToSignedWord(SRC1[47:32] - SRC1[63:48])
DEST[47:32] = SaturateToSignedWord(SRC1[79:64] - SRC1[95:80])
DEST[63:48] = SaturateToSignedWord(SRC1[111:96] - SRC1[127:112])
DEST[79:64] = SaturateToSignedWord(SRC2[15:0] - SRC2[31:16])
DEST[95:80] = SaturateToSignedWord(SRC2[47:32] - SRC2[63:48])
DEST[111:96] = SaturateToSignedWord(SRC2[79:64] - SRC2[95:80])
DEST[127:112] = SaturateToSignedWord(SRC2[111:96] - SRC2[127:112])
DEST[MAXVL-1:128] := 0
VPHSUBSW (VEX.256 Encoded Version)
DEST[15:0]= SaturateToSignedWord(SRC1[15:0] - SRC1[31:16])
DEST[31:16] = SaturateToSignedWord(SRC1[47:32] - SRC1[63:48])
DEST[47:32] = SaturateToSignedWord(SRC1[79:64] - SRC1[95:80])
DEST[63:48] = SaturateToSignedWord(SRC1[111:96] - SRC1[127:112])
DEST[79:64] = SaturateToSignedWord(SRC2[15:0] - SRC2[31:16])
DEST[95:80] = SaturateToSignedWord(SRC2[47:32] - SRC2[63:48])
DEST[111:96] = SaturateToSignedWord(SRC2[79:64] - SRC2[95:80])
DEST[127:112] = SaturateToSignedWord(SRC2[111:96] - SRC2[127:112])
DEST[143:128]= SaturateToSignedWord(SRC1[143:128] - SRC1[159:144])
DEST[159:144] = SaturateToSignedWord(SRC1[175:160] - SRC1[191:176])
DEST[175:160] = SaturateToSignedWord(SRC1[207:192] - SRC1[223:208])
DEST[191:176] = SaturateToSignedWord(SRC1[239:224] - SRC1[255:240])
DEST[207:192] = SaturateToSignedWord(SRC2[143:128] - SRC2[159:144])
DEST[223:208] = SaturateToSignedWord(SRC2[175:160] - SRC2[191:176])
DEST[239:224] = SaturateToSignedWord(SRC2[207:192] - SRC2[223:208])
DEST[255:240] = SaturateToSignedWord(SRC2[239:224] - SRC2[255:240])
Intel C/C++ Compiler Intrinsic Equivalent
PHSUBSW __m64 _mm_hsubs_pi16 (__m64 a, __m64 b)
(V)PHSUBSW __m128i _mm_hsubs_epi16 (__m128i a, __m128i b)
VPHSUBSW __m256i _mm256_hsubs_epi16 (__m256i a, __m256i b)
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions,” additionally:
#UD
If VEX.L = 1.
PHSUBSW-Packed Horizontal Subtract and Saturate
Vol. 2B
4-301
|
||
|
|
|