Extensions
Forms
6 (6 Legacy)
Data
Intel XED v2026.08.23

Compiled 64-bit code calls a function in one of two ways:

  • CALL rel32 (E8) when the target is fixed at link time. The displacement counts from the end of the instruction and reaches 2 GiB either way.
  • CALL r/m64 (FF /2) when the target is known only at run time, such as a function pointer or a C++ virtual function read from its table.

Both push the address of the next instruction, so RSP drops by 8, and RET pops it again. System V and Microsoft x64 both want RSP to be a multiple of 16 just before the CALL, so a function starts with RSP 8 bytes past one (see stack frames).

Things to know:

  • Faults. A non-canonical target raises #GP(0) at the CALL itself, with nothing pushed, as Zen 5 recorded. A canonical target on an unmapped page faults only at the target, after the push, so the return address on the stack still names the caller.
  • Return prediction. Processors predict each RET from a stack of the addresses that CALLs pushed (52 entries per thread on Zen 5, by AMD’s optimization guide). Intel’s optimization manual therefore asks for calls and returns in pairs, not a PUSH of an address followed by a JMP, and suggests turning a call in tail position into a JMP.
  • CET. With shadow stacks enabled, which Intel and AMD both have, CALL also writes the return address to the shadow stack, and RET raises #CP when the two copies differ. With Intel’s indirect branch tracking, an indirect CALL must land on ENDBR64 (#CP otherwise) unless a 3E (NOTRACK) prefix exempts it where the OS allows that; AMD’s manuals do not describe this part.
  • 66 prefix. Intel’s manual fixes the operand size of near calls at 64 bits in 64-bit mode. AMD’s lets a 66 prefix make it 16 bits: a 2-byte displacement, a 2-byte push and RIP cut to 16 bits. The same bytes thus have different lengths on the two; the forms table lists only Intel’s rel32 form for 64-bit mode.
  • Far calls through memory remain for changing code segments. With REX.W, Intel’s processors read a 64-bit offset (m16:64); AMD’s manual allows only a 32-bit one.

32-bit position-independent code learns its own address from the return address that a CALL pushes (see the i386 ABI); 64-bit code uses RIP-relative addressing instead, as in LEA.

In the optimization guide

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

Front end

  • Decoded-instruction caches: Each unconditional jump or call ends a line of Intel’s decoded cache, so at most three of them in a 32-byte block can be cached.

Branches

  • Calls and returns: Returns are predicted by a return stack, which every call pushes and every return pops.
  • Calls and returns: The return stack predicts returns only while calls and returns pair up, so pushing an address and jumping, or returning to a computed address, costs mispredictions.
  • Calls and returns: A call that is the last thing a function does can become a jump to the callee, whose return then goes straight to the original caller.
  • Calls and returns: Even predicted calls and returns cost time: each leaves the predictor idle for a cycle on Zen 3 and Zen 4, a return for two on Zen 5, and Agner Fog measured one every two cycles.
  • Indirect branches: An indirect jmp or call that always goes to the same place is predicted from its BTB entry like a direct one. sources differ
  • Indirect branches: An indirect branch the predictor has no target for is assumed to fall through, so the bytes after it are fetched and may be decoded and run.
  • Indirect branches: An indirect branch to a distant target is predicted worse: Zen 3 and Zen 4 track only a few targets beyond a 64 MB aligned boundary, and Intel’s cores mispredict more often beyond 2 GB.
  • Indirect branches: LLVM’s retpoline options send indirect calls and jumps through a sequence that does not speculate on their target, and turn each switch into conditional branches rather than a jump table.

Bulldozer to Excavator

  • Branches: The return address stack has 24 entries, so each call should have its ret: a deeper chain loses the oldest and an unpaired call desynchronises it, except a call to the very next instruction, which the core recognises.

Golden Cove and Raptor Cove

  • Branches: An indirect jmp or call through a register or memory whose target lies more than 2 GB away takes more of the predictor and mispredicts more often.

Jaguar and Puma

  • Branches: A 16-entry return stack that a call to the next instruction puts out of step, and no need for rep ret.

Silvermont to Goldmont Plus

  • Front end: On Silvermont these instructions come from the microcode ROM; Goldmont decodes them directly, except an indirect call through memory.
  • Branches: Silvermont predicts an indirect branch from its last target alone, Goldmont from patterns.
  • Out-of-order and in-order execution: LLVM’s tuning for all four cores loads the operand of push and call into a register first, and prefers movbe to a load and a bswap.

Skylake to Cooper Lake

  • The JCC erratum: Under rare conditions a jump that crosses a 64-byte line could make these cores misbehave (erratum SKX102).

Tremont

  • Integer execution: LLVM’s tuning treats push, pop and call with a memory operand as slow on this core and loads the operand into a register first.

Zen and Zen+

  • Branches: The return address stack has 32 entries, of which 31 can be used, and 15 per thread with two threads.

Zen 2

  • Branches: The return address stack has 32 entries, 31 of them usable, and 15 per thread with two threads.

Zen 3

  • Branches: The return address stack has 32 entries per thread.
  • Integer execution: PUSH, POP, CALL and RET update RSP without a dependency, and loads, stores, lea and mov from RSP can use the tracked value.

Zen 4

  • Branches: The return address stack has 32 entries per thread, against 52 on Zen 5.
  • Integer execution: PUSH, POP, CALL and RET update RSP without a dependency, and loads, stores, lea and mov from RSP can use the tracked value.

Zen 5

  • Branches: The return address stack has 52 entries per thread.
  • Integer execution: PUSH, POP, CALL and RET update RSP without a dependency, and loads, stores, lea and add or sub of a small immediate through RSP can use the tracked value.

Vulnerability mitigations

Mitigations of these processor vulnerabilities use CALL:

  • CVE-2022-27672: Cross-Thread Return Address Predictions
  • CVE-2022-23824: Incomplete Branch Prediction Barrier (IBPB and Return Stack Buffer Interactions)

Forms

Every encoding of CALL that Intel XED knows, one row per XED instruction form (iform). How to read the notation.
InstructionEncodingRequires
CALL m16/32/64 CALL_NEAR_MEMvFF /2Base instruction set
CALL r16/32/64 CALL_NEAR_GPRvFF /2Base instruction set
CALL rel16/32 not in 64-bit mode CALL_NEAR_RELBRzE8 cw/cdBase instruction set
CALL rel32 64-bit mode only CALL_NEAR_RELBRdE8 cdBase instruction set
CALL m16:16/32/64 CALL_FAR_MEMp2FF /3Base instruction set
CALL ptr16:16/32 not in 64-bit mode CALL_FAR_PTRp_IMMw9A cw/cd iwBase instruction set

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.
Modelm64r64rel32
Sandy Bridge7 / 1p55 / 1p4 p5 p235 / 1p4 p5 p23
Haswell8 / 1p01563 / 1p012345673 / 1p01234567
Broadwell, Skylake, Skylake-SP7 / 1p01563 / 1p012345673 / 1p01234567
Ice Lake7 / 1p01563 / 1p014567893 / 0.5p01456789
Alder Lake, Sapphire Rapids7 / 0.5p0 p1 p5 p6 p113 / 0.5p0467893 / 0.5p4789
Lunar Lake7 / 0.5p0123453 / 0.5p0 p2 p4 p10 p11 p25 p26 p273 / 0.5p10 p11 p25 p26 p27
Bonnell1 / 1p11 / 1p11 / 1p1
Silvermont1 / 1IEC11 / 1IEC11 / 1IEC1
Piledriver1 / 1Branch EX11 / 1Branch EX11 / 1Branch EX1
Zen, Zen 21 / 0.25ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU3
Zen 3, Zen 41 / 0.5ALU0 BRU11 / 0.5ALU0 BRU11 / 0.5ALU0 BRU1
Jaguar1 / 0.5ALU0 ALU11 / 0.5ALU0 ALU11 / 0.5ALU0 ALU1

Operation

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

CALL rel16/32 not in 64-bit mode CALL rel32 64-bit mode only
w = OSIZE                        # the size of the target and of
n = 0                            # the return address
if OSIZE == 16:                  # a 66 prefix
    if INTEL:
        w = 64                   # ignored: SDM
    else:
        if rel.bits == 32:
            n = 2                # a rel16, as JMP's: APM, Zen 5
r = rip - n                      # the next instruction
t = low(r + signed(rel), w)
if not canonical(t):
    fault(GP, 0)                 # before the push
a = rsp - w // 8                 # 2 bytes with 66 on AMD's
store(a, w, r)                   # the return address
rsp = a
rip = t

Run on AMD Zen 5 (EPYC 9645): 5 cases. Its branches for Intel's processors were not run: no Intel processor ran these forms. The forms that 64-bit mode lacks were not run: the probe runs in 64-bit mode.

CALL r/m16/32/64
t = target.read()                # CALL RSP: RSP from before; r/m64,
                                 # or with 66 r/m16 on AMD's,
                                 # zero-extended
w = OSIZE                        # the size of the return address:
if OSIZE == 16:                  # with 66, 2 bytes on AMD's (APM,
    if INTEL:                    # Zen 5)
        w = 64                   # ignored: SDM
if not canonical(t):
    fault(GP, 0)
a = rsp - w // 8                 # 8 bytes, or 2 with 66 on AMD's
store(a, w, rip)
rsp = a
rip = t

Run on AMD Zen 5 (EPYC 9645): 8 cases. Its branches for Intel's processors were not run: no Intel processor ran these forms.

CALL ptr16:16/32 not in 64-bit mode CALL m16:16/32/64
v = target.read()                # the offset, then a 16-bit selector
n = OSIZE // 8
a = rsp - 2 * n
store(a + n, OSIZE, cs)          # CS, zero-extended, then the return
store(a, OSIZE, rip)             # address
rsp = a
cs = v >> OSIZE & 0xFFFF         # with the checks of a far JMP; a
rip = low(v, OSIZE)              # call gate to a more privileged
                                 # level switches stacks first

Not run on a processor: a far call loads CS from a descriptor table, which the probe does not record.

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
CALL r/m16/32/64
r/m16/32/64explicitread
stackimplicitwrite
rSPimplicitread, write
rIPimplicitread, write
CALL rel16/32 not in 64-bit mode CALL rel32 64-bit mode only
rel16/32explicitread
stackimplicitwrite
rSPimplicitread, write
rIPimplicitread, write
CALL m16:16/32/64
m16:16/32/64explicitread
stackimplicitwrite
rSPimplicitread, write
rIPimplicitwrite
CALL ptr16:16/32 not in 64-bit mode
ptr16:16/32explicitread
stackimplicitwrite
rSPimplicitread, write
EIPimplicitwrite

Flags

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

Attributes

What else XED records about the forms. How to read.

CALL r/m16/32/64 CALL m16:16/32/64
indirect branch
CALL ptr16:16/32 not in 64-bit mode CALL m16:16/32/64
far transfer; may abort a TSX transaction

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
I86

No CPUID bit: part of the base instruction set.

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

More General-purpose instructions

All 109 General-purpose 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 2A, page 3-121 (CALL)
  5. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 2026)
  6. AMD64 Architecture Programmer's Manual, Volume 2: System Programming (24593, rev. 3.46, October 2026)
  7. AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, October 2026)
  8. Intel 64 and IA-32 Architectures Optimization Reference Manual, Volume 1 (248966-051, October 2026)
  9. 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.