Extensions
Forms
16 (4 Legacy, 12 EVEX)
Data
Intel XED v2026.08.23

SHLD shifts its destination left and fills the vacated low bits from the top of a second register, as if the two formed one value of twice the width with the destination above. The second register is only read. SHRD is the mirror image: it shifts right and fills the top from the bottom of the second register.

That is the step a wide shift needs. GCC 14 and Clang 23 at -O2 compile x << 5 on an unsigned __int128 to shld rdx, rdi, 5 for the high half and a SHL by 5 for the low one, and take 64 bits from the middle of a 128-bit value, (uint64_t)(x >> 20), with a single shrd rax, rsi, 20. A constant funnel shift such as (hi << 52) | (lo >> 12) becomes shld rax, rsi, 52.

The count

The count is masked to 5 bits, or 6 for a 64-bit operand, as for SHL. For a 128-bit x << n with n in a register, both compilers therefore run SHLD and SHL by CL on the two halves, then test bit 6 of the count and, when n is 64 or more, use two CMOVs to move the low result into the high half and clear the low half.

A masked count of 0 leaves the destination and the flags alone. So the variable funnel shift (hi << n) | (lo >> (-n & 63)) does not become SHLD: for n = 0 it gives hi | lo, where SHLD would give hi. Both compilers build it from two shifts and an OR instead.

16-bit operands

With a 16-bit operand, the masked count can reach 31, more than the 16 bits the second register supplies. Intel’s and AMD’s manuals leave the result undefined then, and Intel’s leaves all the flags undefined too. Zen 5 shifted the 48 bits of the destination above two copies of the source, so that the source’s bits came in a second time, and cleared CF.

Speed

Intel’s optimization manual lists SHLD among the instructions of the one “Slow Int” execution unit of Golden Cove, beside MUL and BSR (Table 2-4). AMD’s Zen 5 guide gives SHLD and SHRD a latency of three cycles (Section 2.10.2), and its instruction table lists them as microcoded. APX adds forms with a new destination and forms that leave the flags unchanged (NF).

In the optimization guide

What the optimization guide says about SHLD, a line per claim. Each links to the claim in the guide, with its sources and where they differ.

Bulldozer to Excavator

Golden Cove and Raptor Cove

  • Integer execution: Port 1 alone runs the slower integer operations: multiplication, PDEP and PEXT, popcnt, bsr, crc32 and the double shifts with an immediate count, which LLVM’s models give a latency of three cycles and one per cycle.

Jaguar and Puma

  • Integer execution: SHLD and SHRD are microcoded, six to eight macro-ops in AMD’s spreadsheet, and LLVM treats double shifts as slow on these cores.

Silvermont to Goldmont Plus

Skylake to Cooper Lake

  • Integer execution: Port 1 alone runs integer multiplication, PDEP and PEXT, popcnt, lzcnt, tzcnt, bsf, bsr and the double shifts, with a latency of three cycles and one a cycle in LLVM’s models, as on Golden Cove.

Zen and Zen+

  • Integer execution: SHLD is microcoded, taking four cycles in AMD’s spreadsheet, and LLVM treats double shifts as slow for -march=znver1. sources differ

Zen 2

  • Integer execution: SHLD and SHRD are microcoded, and LLVM treats them as slow for -march=znver2, as it stops doing for Zen 3. sources differ

Zen 3

  • Integer execution: SHLD and SHRD have a latency of three cycles, and LLVM’s -march=znver3 no longer treats them as slow, as it does for the Zen cores before. sources differ

Zen 4

Forms

Every encoding of SHLD that Intel XED knows, one row per XED instruction form (iform). How to read the notation.
InstructionEncodingRequires
SHLD m16/32/64, r16/32/64, imm8 SHLD_MEMv_GPRv_IMMb0F A4 /r ibBase instruction set
SHLD r16/32/64, r16/32/64, imm8 SHLD_GPRv_GPRv_IMMb0F A4 /r ibBase instruction set
SHLD m16/32/64, r16/32/64, CL SHLD_MEMv_GPRv_CL0F A5 /rBase instruction set
SHLD r16/32/64, r16/32/64, CL SHLD_GPRv_GPRv_CL0F A5 /rBase instruction set
SHLD r16/32/64, r16/32/64, imm8 SHLD_GPRv_GPRv_IMM8_APXEVEX.LLZ.NP.MAP4.SCALABLE 24 /r ibAPX_F
SHLD m16/32/64, r16/32/64, imm8 SHLD_MEMv_GPRv_IMM8_APXEVEX.LLZ.NP.MAP4.SCALABLE 24 /r ibAPX_F
SHLD r16/32/64, r16/32/64, imm8 NF SHLD_GPRv_GPRv_IMM8_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 24 /r ib NF=1APX_F + APX_NCI_NDD_NF
SHLD m16/32/64, r16/32/64, imm8 NF SHLD_MEMv_GPRv_IMM8_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 24 /r ib NF=1APX_F + APX_NCI_NDD_NF
SHLD r16/32/64, r16/32/64, r16/32/64, imm8 NDD NF optional SHLD_GPRv_GPRv_GPRv_IMM8_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 24 /r ib ND=1 NF=0/1APX_F + APX_NCI_NDD_NF
SHLD r16/32/64, m16/32/64, r16/32/64, imm8 NDD NF optional SHLD_GPRv_MEMv_GPRv_IMM8_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 24 /r ib ND=1 NF=0/1APX_F + APX_NCI_NDD_NF
SHLD r16/32/64, r16/32/64, CL SHLD_GPRv_GPRv_CL_APXEVEX.LLZ.NP.MAP4.SCALABLE A5 /rAPX_F
SHLD m16/32/64, r16/32/64, CL SHLD_MEMv_GPRv_CL_APXEVEX.LLZ.NP.MAP4.SCALABLE A5 /rAPX_F
SHLD r16/32/64, r16/32/64, CL NF SHLD_GPRv_GPRv_CL_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE A5 /r NF=1APX_F + APX_NCI_NDD_NF
SHLD m16/32/64, r16/32/64, CL NF SHLD_MEMv_GPRv_CL_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE A5 /r NF=1APX_F + APX_NCI_NDD_NF
SHLD r16/32/64, r16/32/64, r16/32/64, CL NDD NF optional SHLD_GPRv_GPRv_GPRv_CL_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE A5 /r ND=1 NF=0/1APX_F + APX_NCI_NDD_NF
SHLD r16/32/64, m16/32/64, r16/32/64, CL NDD NF optional SHLD_GPRv_MEMv_GPRv_CL_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE A5 /r ND=1 NF=0/1APX_F + APX_NCI_NDD_NF

Latency and throughput

What the scheduling models of LLVM 23.1.2 give for each form, not measurements: latency / reciprocal throughput in cycles, the ports under them. A row is a model, or models that agree; a dash, a form that its processors lack. Memory forms: latency from the address, ports without the load and store units. Which processors each model covers.
Modelm16, r16, imm8m32, r32, imm8m64, r64, imm8r16, r16, imm8r32, r32, imm8r64, r64, imm8m16, r16, CLm32, r32, CLm64, r64, CLr16, r16, CLr32, r32, CLr64, r64, CL
Sandy Bridge8 / 1p0158 / 1p0158 / 1p0152 / 0.67p0152 / 0.67p0152 / 0.67p01510 / 1.5p01510 / 1.5p01510 / 1.5p0154 / 1.5p0154 / 1.5p0154 / 1.5p015
Haswell10 / 1p015610 / 1p015610 / 1p01563 / 1p13 / 1p13 / 1p112 / 1p015612 / 1p015612 / 1p01566 / 1p01566 / 1p01566 / 1p0156
Broadwell, Skylake, Skylake-SP, Ice Lake9 / 1p01569 / 1p01569 / 1p01563 / 1p13 / 1p13 / 1p111 / 1p015611 / 1p015611 / 1p01566 / 1p01566 / 1p01566 / 1p0156
Alder Lake, Sapphire Rapids12 / 1p0 p1 p5 p6 p1112 / 1p0 p1 p5 p6 p1112 / 1p0 p1 p5 p6 p113 / 1p13 / 1p13 / 1p112 / 1p0 p1 p5 p6 p1112 / 1p0 p1 p5 p6 p1112 / 1p0 p1 p5 p6 p115 / 1p0 p1 p5 p6 p115 / 1p0 p1 p5 p6 p115 / 1p0 p1 p5 p6 p11
Lunar Lake12 / 0.5p01234512 / 0.5p01234512 / 0.5p0123453 / 0.33p1353 / 0.33p1353 / 0.33p13512 / 0.67p01234512 / 0.67p01234512 / 0.67p0123455 / 0.67p0123455 / 0.67p0123455 / 0.67p012345
Bonnell6 / 3p14 / 2p19 / 4.5p16 / 3p012 / 1p019 / 4.5p016 / 3p14 / 2p19 / 4.5p16 / 3p012 / 1p018 / 4p01
Silvermont4 / 2IEC0 MEC4 / 2IEC0 MEC4 / 2IEC0 MEC1 / 1IEC01 / 1IEC01 / 1IEC04 / 2IEC0 MEC4 / 2IEC0 MEC4 / 2IEC0 MEC1 / 1IEC01 / 1IEC01 / 1IEC0
Piledriver4 / 11EX0 EX14 / 11EX0 EX14 / 11EX0 EX13 / 3EX0 EX13 / 3EX0 EX13 / 3EX0 EX14 / 11EX0 EX14 / 11EX0 EX14 / 11EX0 EX13 / 3EX0 EX13 / 3EX0 EX13 / 4EX0 EX1
Zen, Zen 27 / 3ALU0 ALU1 ALU2 ALU37 / 3ALU0 ALU1 ALU2 ALU37 / 3ALU0 ALU1 ALU2 ALU33 / 3ALU0 ALU1 ALU2 ALU33 / 3ALU0 ALU1 ALU2 ALU33 / 3ALU0 ALU1 ALU2 ALU37 / 3ALU0 ALU1 ALU2 ALU37 / 3ALU0 ALU1 ALU2 ALU37 / 3ALU0 ALU1 ALU2 ALU33 / 3ALU0 ALU1 ALU2 ALU33 / 3ALU0 ALU1 ALU2 ALU33 / 3ALU0 ALU1 ALU2 ALU3
Zen 3, Zen 46 / 2ALU1 ALU26 / 2ALU1 ALU26 / 2ALU1 ALU22 / 1.5ALU1 ALU22 / 1.5ALU1 ALU22 / 1.5ALU1 ALU26 / 2ALU1 ALU26 / 2ALU1 ALU26 / 2ALU1 ALU22 / 1.5ALU1 ALU22 / 1.5ALU1 ALU22 / 1.5ALU1 ALU2
Jaguar9 / 11ALU0 ALU19 / 11ALU0 ALU19 / 11ALU0 ALU13 / 3ALU0 ALU13 / 3ALU0 ALU13 / 3ALU0 ALU19 / 11ALU0 ALU19 / 11ALU0 ALU19 / 11ALU0 ALU14 / 4ALU0 ALU14 / 4ALU0 ALU14 / 4ALU0 ALU1

Operation

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

All forms but the NDD forms
a = dest.read()
b = src.read()
n = count & (0x3F if OSIZE == 64 else 0x1F)   # the count is masked
if OSIZE == 16 and n > 16:
    # Intel's manual leaves the result and the flags undefined. Zen 5
    # shifts the 48 bits of dest:src:src, so that src comes in
    # again, and clears CF.
    dest.write(UNDEFINED)
    if not nf:
        of = sf = zf = UNDEFINED
        af = pf = cf = UNDEFINED
else:
    x = a << OSIZE | b           # dest above src
    r = low(x << n >> OSIZE)     # the top half: dest, with the top n
                                 # bits of src coming in from below
    if n != 0 and not nf:        # a count of 0 changes no flag; NF=1
                                 # (APX) none at all
        cf = x >> (2 * OSIZE - n) & 1   # the last bit shifted out
        flip = msb(r) ^ msb(a)
        of = flip if n == 1 else UNDEFINED   # the sign changed
        sf = msb(r)
        zf = r == 0
        pf = parity(r)
        af = UNDEFINED
    dest.write(r)                # even for a count of 0, a 32-bit
                                 # register gets bits 63:32 cleared

Run on AMD Zen 5 (EPYC 9645): 131 cases. The APX forms were not run: none of these processors has APX.

NDD forms
a = src1.read()
b = src2.read()
n = count & (0x3F if OSIZE == 64 else 0x1F)   # the count is masked
if OSIZE == 16 and n > 16:
    # Intel's manual leaves the result and the flags undefined
    dest.write(UNDEFINED)
    if not nf:
        of = sf = zf = UNDEFINED
        af = pf = cf = UNDEFINED
else:
    x = a << OSIZE | b           # src1 above src2
    r = low(x << n >> OSIZE)     # the top half: src1, with the top n
                                 # bits of src2 coming in from below
    if n != 0 and not nf:        # a count of 0 changes no flag; NF=1
                                 # none at all
        cf = x >> (2 * OSIZE - n) & 1   # the last bit shifted out
        flip = msb(r) ^ msb(a)
        of = flip if n == 1 else UNDEFINED   # the sign changed
        sf = msb(r)
        zf = r == 0
        pf = parity(r)
        af = UNDEFINED
    dest.write(r)                # the new destination: bits 63:OSIZE
                                 # cleared, even for 16 bits

Not run on a processor: none of these processors has APX.

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
SHLD r/m16/32/64, r16/32/64, imm8
r/m16/32/64explicitread, conditional write
r16/32/64explicitread
imm8explicitread
RFLAGSimplicitwrite
SHLD r/m16/32/64, r16/32/64, CL
r/m16/32/64explicitread, conditional write
r16/32/64explicitread
CLexplicitread
RFLAGSimplicitconditional write
SHLD r/m16/32/64, r16/32/64, imm8 NF
r/m16/32/64explicitread, conditional write
r16/32/64explicitread
imm8explicitread
SHLD r16/32/64, r/m16/32/64, r16/32/64, imm8 NDD NF optional
r16/32/64explicitwrite
r/m16/32/64explicitread
r16/32/64explicitread
imm8explicitread
RFLAGSimplicitwrite (NF=0)
SHLD r/m16/32/64, r16/32/64, CL NF
r/m16/32/64explicitread, conditional write
r16/32/64explicitread
CLexplicitread
SHLD r16/32/64, r/m16/32/64, r16/32/64, CL NDD NF optional
r16/32/64explicitwrite
r/m16/32/64explicitread
r16/32/64explicitread
CLexplicitread
RFLAGSimplicitconditional write (NF=0)

Flags

M modified, U undefined; blank: not affected. With NF=1, the forms with optional NF leave the flags unchanged. How to read.
WhenOFSFZFAFPFCF
SHLD r/m16/32/64, r16/32/64, imm8
count 1MMMUMM
count 2 or moreUMMUMM
SHLD r/m16/32/64, r16/32/64, CL
in some casesUMMUMM
NF forms
Not affected
SHLD r16/32/64, r/m16/32/64, r16/32/64, imm8 NDD NF optional
NF=0, count 1MMMUMM
NF=0, count 2 or moreUMMUMM
SHLD r16/32/64, r/m16/32/64, r16/32/64, CL NDD NF optional
NF=0, in some casesUMMUMM

Exceptions

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

Legacy forms
none in XED
EVEX forms
APX-EVEX-INT

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
I386

No CPUID bit: part of the base instruction set.

Every x86-64 processor in XED’s model and Zen 3 to Zen 6
APX_F

APX_F
CPUID.(EAX=07H,ECX=1):EDX[21] APX_F

Nova Lake, Diamond Rapids
APX_F_N3

APX_F + APX_NCI_NDD_NF
CPUID.(EAX=07H,ECX=1):EDX[21] APX_F
CPUID.(EAX=29H,ECX=0):EBX[0] APX_NCI_NDD_NF

Same as APX_F

More General-purpose instructions

All 109 General-purpose instructions

More APX instructions

All 88 APX 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. The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s -march feature sets and AMD’s Processor Programming References, which the page of each processor cites.
  3. LLVM 23.1.2's x86 scheduling models (commit 85ac56026243): the latency, reciprocal throughput and ports of each form, as llvm-mca reports them.
  4. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2B, page 4-640 (SHLD)
  5. Intel Advanced Performance Extensions (Intel APX) Architecture Specification, revision 9.0 (355828-009, August 2026)
  6. AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, October 2026)
  7. Intel 64 and IA-32 Architectures Optimization Reference Manual, Volume 1 (248966-051, October 2026)
  8. Software Optimization Guide for the AMD Zen5 Microarchitecture (58455, rev. 1.00, August 2024), Wayback Machine copy of AMD's ZIP

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 timings come from LLVM's scheduling models, part of the LLVM Project, licensed under the Apache License 2.0 with LLVM Exceptions. The text is our own.