Extensions
Forms
10 (4 VEX, 6 EVEX)
Data
Intel XED v2026.08.23

VSM4KEY4 computes four of SM4’s 32 round keys. SM4 derives them from the 128-bit key MK in a chain much like its rounds: the four key words are first XORed with fixed words FK[0] to FK[3], giving K[0] to K[3], and then

K[i+4] = K[i] ^ T'(K[i+1] ^ K[i+2] ^ K[i+3] ^ CK[i])

for i from 0 to 31, where K[i+4] is round key rk[i]. T’ passes each byte through the same S-box as the rounds of VSM4RNDS4, but then XORs the word only with itself rotated left by 13 and 23 bits. VSM4KEY4 takes K[i] to K[i+3] in its second operand and CK[i] to CK[i+3] in its third, a register or memory, and writes the next four, rk[i] to rk[i+3], to the first.

What software supplies

  • FK, before the first instruction. The XOR with FK is one VPXOR of the key with a constant.
  • The 32 constants CK[i], four per instruction. They are fixed (byte j of CK[i] is (4i + j) times 7, modulo 256), but VSM4KEY4 does not generate them, as VSM3RNDS2 generates SM3’s; they come from a table of eight 16-byte rows, and the third operand can read each row from memory.
  • Byte order. SM4 numbers bytes from the most significant, so a key loaded from memory is byte-swapped in each word first.

Eight VSM4KEY4s give all 32 round keys, each one’s result being the next one’s second operand, and each result is also directly the third operand of one VSM4RNDS4. Decryption uses the same keys in reverse order, rk[31] first, which takes reversing the dwords of each result and the order of the eight registers.

Wider forms

Each 128-bit lane works alone, so the YMM form, and the EVEX form on ZMM, expand two or four keys at once; with the same key in every lane they compute the same schedule twice or four times over. The VEX forms need the SM4 extension (CPUID leaf 7, subleaf 1, EAX bit 2) and AVX, the EVEX forms AVX10 as well. Zen 5 has neither, and all ten of its recorded cases raised #UD. GCC 14 and Clang 23 provide _mm_sm4key4_epi32(k, ck) and the 256-bit form with -msm4.

Forms

Every encoding of VSM4KEY4 that Intel XED knows, one row per XED instruction form (iform). How to read the notation.
InstructionEncodingRequires
VSM4KEY4 xmm, xmm, xmm VSM4KEY4_XMMu32_XMMu32_XMMu32VEX.128.F3.0F38.W0 DA /rSM4 + AVX
VSM4KEY4 xmm, xmm, m128 VSM4KEY4_XMMu32_XMMu32_MEMu32VEX.128.F3.0F38.W0 DA /rSM4 + AVX
VSM4KEY4 ymm, ymm, ymm VSM4KEY4_YMMu32_YMMu32_YMMu32VEX.256.F3.0F38.W0 DA /rSM4 + AVX
VSM4KEY4 ymm, ymm, m256 VSM4KEY4_YMMu32_YMMu32_MEMu32VEX.256.F3.0F38.W0 DA /rSM4 + AVX
VSM4KEY4 xmm, xmm, xmm VSM4KEY4_XMMu32_XMMu32_XMMu32_AVX512EVEX.128.F3.0F38.W0 DA /rSM4 + AVX10
VSM4KEY4 xmm, xmm, m128 VSM4KEY4_XMMu32_XMMu32_MEMu32_AVX512EVEX.128.F3.0F38.W0 DA /rSM4 + AVX10
VSM4KEY4 ymm, ymm, ymm VSM4KEY4_YMMu32_YMMu32_YMMu32_AVX512EVEX.256.F3.0F38.W0 DA /rSM4 + AVX10
VSM4KEY4 ymm, ymm, m256 VSM4KEY4_YMMu32_YMMu32_MEMu32_AVX512EVEX.256.F3.0F38.W0 DA /rSM4 + AVX10
VSM4KEY4 zmm, zmm, zmm VSM4KEY4_ZMMu32_ZMMu32_ZMMu32_AVX512EVEX.512.F3.0F38.W0 DA /rSM4 + AVX10
VSM4KEY4 zmm, zmm, m512 VSM4KEY4_ZMMu32_ZMMu32_MEMu32_AVX512EVEX.512.F3.0F38.W0 DA /rSM4 + AVX10

Operation

What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.

VEX forms
if not cpuid_leaf(7, 1)[0] >> 2 & 1:
    fault(UD)                    # CPUID: no SM4
for i in range(VL // 128):  # each lane:
    a = ymm2.d[4 * i]      # the expansion's
    b = ymm2.d[4 * i + 1]  # four words,
    c = ymm2.d[4 * i + 2]  # the first in
    d = ymm2.d[4 * i + 3]  # dword 0
    for j in range(4):     # src3: four CK
        x = b ^ c ^ d ^ src3.d[4 * i + j]
        x = a ^ sm4_l_key(sm4_sub_word(x))
        ymm1.d[4 * i + j] = x  # the next
        a = b
        b = c
        c = d
        d = x
# ymm1 is zeroed from bit VL up

Run on AMD Zen 5 (EPYC 9645): 4 cases. Its cases ran where CPUID reported no SM4, and every one raised an exception.

EVEX forms
if not cpuid_leaf(7, 1)[0] >> 2 & 1:
    fault(UD)                    # CPUID: no SM4
if not cpuid_leaf(7, 1)[3] >> 19 & 1:
    fault(UD)                    # CPUID: no AVX10
for i in range(VL // 128):  # each lane:
    a = zmm2.d[4 * i]      # the expansion's
    b = zmm2.d[4 * i + 1]  # four words,
    c = zmm2.d[4 * i + 2]  # the first in
    d = zmm2.d[4 * i + 3]  # dword 0
    for j in range(4):     # src3: four CK
        x = b ^ c ^ d ^ src3.d[4 * i + j]
        x = a ^ sm4_l_key(sm4_sub_word(x))
        zmm1.d[4 * i + j] = x  # the next
        a = b
        b = c
        c = d
        d = x
# zmm1 is zeroed from bit VL up

Run on AMD Zen 5 (EPYC 9645): 6 cases. Its cases ran where CPUID reported no SM4, and every one raised an exception.

Operands

What each form reads and writes, as Intel XED records it: the operands of its syntax, in order, and the implicit ones that the syntax does not name. How to read.
OperandKindAction
VSM4KEY4 xmm, xmm, xmm/m128 VSM4KEY4 ymm, ymm, ymm/m256 VSM4KEY4 zmm, zmm, zmm/m512
xmm, ymm, zmmexplicitwrite
xmm, ymm, zmmexplicitread
xmm/m128, ymm/m256, zmm/m512explicitread

Flags

None: XED records no flag that the forms test or change.

Exceptions

The exception class is XED's name for the set of exception conditions that a form follows. How to read.

VEX forms
avx-type-6
EVEX forms
AVX512-E6

Intrinsics

The C intrinsics of Clang 23.1.2 that compile to VSM4KEY4, each with the form it compiles to and the Clang options it needs. The forms come from compiling every intrinsic and decoding the result with Intel XED; all intrinsics A–Z explains the method.

IntrinsicCompiles to
_mm_sm4key4_epi32 __m128i _mm_sm4key4_epi32(__m128i A, __m128i B)

VSM4KEY4 xmm, xmm, xmm VEX.128 -msm4

VSM4KEY4 xmm, xmm, xmm VEX.128 -mavx -msm4with AVX enabled

_mm256_sm4key4_epi32 __m256i _mm256_sm4key4_epi32(__m256i A, __m256i B)

VSM4KEY4 ymm, ymm, ymm VEX.256 -msm4

VSM4KEY4 ymm, ymm, ymm VEX.256 -mavx -msm4with AVX enabled

_mm512_sm4key4_epi32 __m512i _mm512_sm4key4_epi32(__m512i __A, __m512i __B)

VSM4KEY4 zmm, zmm, zmm EVEX.512 -msm4 -mavx10.2

CPUID and processors

Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.

CPUID requirements and processors of the XED ISA sets above. Alternatives are separated by “or”; processors follow XED’s chip model, whose AMD processors end with Zen 2, and the CPU data of this site for Zen 3 to Zen 6.
ISA setCPUIDProcessors
SM4

SM4 + AVX
CPUID.(EAX=07H,ECX=1):EAX[2] SM4
CPUID.01H:ECX[28] AVX

Arrow Lake, Panther Lake, Nova Lake, Diamond Rapids, Clearwater Forest

Note: Intel's extensions reference introduces these instructions with Arrow Lake S, and GCC's -march=arrowlake, which it selects for Arrow Lake H and U, leaves them out.

SM4_128

SM4 + AVX10
CPUID.(EAX=07H,ECX=1):EAX[2] SM4
CPUID.(EAX=07H,ECX=1):EDX[19] AVX10

Nova Lake, Diamond Rapids
SM4_256
Same as SM4_128Same as SM4_128
SM4_512
Same as SM4_128Same as SM4_128

More SM4 instructions

Sources

  1. Intel XED v2026.08.23 (commit 0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model.
  2. Clang's x86 intrinsic headers, LLVM 23.1.2 (commit 85ac56026243): the intrinsics, their signatures and doc comments, and the Clang of that release, which compiled each of them.
  3. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2C, page 5-761 (VSM4KEY4)
  4. Intel Architecture Instruction Set Extensions and Future Features Programming Reference (319433-062, June 2026)
  5. IETF draft-ribose-cfrg-sm4-10: The SM4 Blockcipher Algorithm and Its Modes of Operations (April 2018)

The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The intrinsics and their signatures come from Clang, part of the LLVM Project, licensed under the Apache License 2.0 with LLVM Exceptions. The text is our own.