In the instruction descriptions below the following field descriptors are used:
rd
Destination general-purpose register whose role is to be the destination of an operation.
rs
Source general-purpose register whose role is to be the source of an operation.
disp16
16-bit signed PC-relative offset, measured in number of 64-bit words, minus one.
disp32
32-bit signed PC-relative offset, measured in number of 64-bit words, minus one.
offset16
Signed 16-bit immediate representing an offset in bytes.
disp16
Signed 16-bit immediate representing a displacement to a target, measured in number of 64-bit words minus one.
disp32
Signed 32-bit immediate representing a displacement to a target, measured in number of 64-bit words minus one.
imm32
Signed 32-bit immediate.
imm64
Signed 64-bit immediate.
Note that the assembler allows to express the value for an immediate using any numerical literal whose twos complement encoding fits in the immediate field. For example, -2
, 0xfffffffe
and 4294967294
all denote the same encoded 32-bit immediate, whose value may be then interpreted by different instructions as either as a negative or a positive number.
The destination register in these instructions act like an accumulator.
Note that in pseudoc syntax these instructions should use r
registers.
add rd, rs
add rd, imm32
rd += rs
rd += imm32
64-bit arithmetic addition.
sub rd, rs
sub rd, rs
rd -= rs
rd -= imm32
64-bit arithmetic subtraction.
mul rd, rs
mul rd, imm32
rd *= rs
rd *= imm32
64-bit arithmetic multiplication.
div rd, rs
div rd, imm32
rd /= rs
rd /= imm32
64-bit arithmetic integer division.
mod rd, rs
mod rd, imm32
rd %= rs
rd %= imm32
64-bit integer remainder.
and rd, rs
and rd, imm32
rd &= rs
rd &= imm32
64-bit bit-wise and operation.
or rd, rs
or rd, imm32
rd |= rs
rd |= imm32
64-bit bit-wise or operation.
xor rd, imm32
xor rd, rs
rd ^= rs
rd ^= imm32
64-bit bit-wise exclusive-or operation.
lsh rd, rs
ldh rd, imm32
rd <<= rs
rd <<= imm32
64-bit left shift, by rs
or imm32
bits.
rsh %d, %s
rsh rd, imm32
rd >>= rs
rd >>= imm32
64-bit right logical shift, by rs
or imm32
bits.
arsh rd, rs
arsh rd, imm32
rd s>>= rs
rd s>>= imm32
64-bit right arithmetic shift, by rs
or imm32
bits.
neg rd
rd = - rd
64-bit arithmetic negation.
mov rd, rs
mov rd, imm32
rd = rs
rd = imm32
Move the 64-bit value of rs
in rd
, or load imm32
in rd
.
movs rd, rs, 8
rd = (s8) rs
Move the sign-extended 8-bit value in rs
to rd
.
movs rd, rs, 16
rd = (s16) rs
Move the sign-extended 16-bit value in rs
to rd
.
movs rd, rs, 32
rd = (s32) rs
Move the sign-extended 32-bit value in rs
to rd
.
The destination register in these instructions act as an accumulator.
Note that in pseudoc syntax these instructions should use w
registers. It is not allowed to mix w
and r
registers in the same instruction.
add32 rd, rs
add32 rd, imm32
rd += rs
rd += imm32
32-bit arithmetic addition.
sub32 rd, rs
sub32 rd, imm32
rd -= rs
rd += imm32
32-bit arithmetic subtraction.
mul32 rd, rs
mul32 rd, imm32
rd *= rs
rd *= imm32
32-bit arithmetic multiplication.
div32 rd, rs
div32 rd, imm32
rd /= rs
rd /= imm32
32-bit arithmetic integer division.
mod32 rd, rs
mod32 rd, imm32
rd %= rs
rd %= imm32
32-bit integer remainder.
and32 rd, rs
and32 rd, imm32
rd &= rs
rd &= imm32
32-bit bit-wise and operation.
or32 rd, rs
or32 rd, imm32
rd |= rs
rd |= imm32
32-bit bit-wise or operation.
xor32 rd, rs
xor32 rd, imm32
rd ^= rs
rd ^= imm32
32-bit bit-wise exclusive-or operation.
lsh32 rd, rs
lsh32 rd, imm32
rd <<= rs
rd <<= imm32
32-bit left shift, by rs
or imm32
bits.
rsh32 rd, rs
rsh32 rd, imm32
rd >>= rs
rd >>= imm32
32-bit right logical shift, by rs
or imm32
bits.
arsh32 rd, rs
arsh32 rd, imm32
rd s>>= rs
rd s>>= imm32
32-bit right arithmetic shift, by rs
or imm32
bits.
neg32 rd
rd = - rd
32-bit arithmetic negation.
mov32 rd, rs
mov32 rd, imm32
rd = rs
rd = imm32
Move the 32-bit value of rs
in rd
, or load imm32
in rd
.
mov32s rd, rs, 8
rd = (s8) rs
Move the sign-extended 8-bit value in rs
to rd
.
mov32s rd, rs, 16
rd = (s16) rs
Move the sign-extended 16-bit value in rs
to rd
.
mov32s rd, rs, 32
rd = (s32) rs
Move the sign-extended 32-bit value in rs
to rd
.
endle rd, 16
endle rd, 32
endle rd, 64
rd = le16 rd
rd = le32 rd
rd = le64 rd
Convert the 16-bit, 32-bit or 64-bit value in rd
to little-endian and store it back in rd
.
endbe %d, 16
endbe %d, 32
endbe %d, 64
rd = be16 rd
rd = be32 rd
rd = be64 rd
Convert the 16-bit, 32-bit or 64-bit value in rd
to big-endian and store it back in rd
.
bswap rd, 16
rd = bswap16 rd
Swap the least-significant 16-bit word in rd
with the most-significant 16-bit word.
bswap rd, 32
rd = bswap32 rd
Swap the least-significant 32-bit word in rd
with the most-significant 32-bit word.
bswap rd, 64
rd = bswap64 rd
Swap the least-significant 64-bit word in rd
with the most-significant 64-bit word.
lddw rd, imm64
rd = imm64 ll
Load the given signed 64-bit immediate to the destination register rd
.
The following instructions are intended to be used in socket filters, and are therefore not general-purpose: they make assumptions on the contents of several registers. See the file Documentation/networking/filter.txt in the Linux kernel source tree for more information.
Absolute loads:
ldabsdw imm32
r0 = *(u64 *) skb[imm32]
Absolute 64-bit load.
ldabsw imm32
r0 = *(u32 *) skb[imm32]
Absolute 32-bit load.
ldabsh imm32
r0 = *(u16 *) skb[imm32]
Absolute 16-bit load.
ldabsb imm32
r0 = *(u8 *) skb[imm32]
Absolute 8-bit load.
Indirect loads:
ldinddw rs, imm32
r0 = *(u64 *) skb[rs + imm32]
Indirect 64-bit load.
ldindw rs, imm32
r0 = *(u32 *) skb[rs + imm32]
Indirect 32-bit load.
ldindh rs, imm32
r0 = *(u16 *) skb[rs + imm32]
Indirect 16-bit load.
ldindb %s, imm32
r0 = *(u8 *) skb[rs + imm32]
Indirect 8-bit load.
General-purpose load and store instructions are provided for several word sizes.
Load to register instructions:
ldxdw rd, [rs + offset16]
rd = *(u64 *) (rs + offset16)
Generic 64-bit load.
ldxw rd, [rs + offset16]
rd = *(u32 *) (rs + offset16)
Generic 32-bit load.
ldxh rd, [rs + offset16]
rd = *(u16 *) (rs + offset16)
Generic 16-bit load.
ldxb rd, [rs + offset16]
rd = *(u8 *) (rs + offset16)
Generic 8-bit load.
Signed load to register instructions:
ldxsdw rd, [rs + offset16]
rd = *(s64 *) (rs + offset16)
Generic 64-bit signed load.
ldxsw rd, [rs + offset16]
rd = *(s32 *) (rs + offset16)
Generic 32-bit signed load.
ldxsh rd, [rs + offset16]
rd = *(s16 *) (rs + offset16)
Generic 16-bit signed load.
ldxsb rd, [rs + offset16]
rd = *(s8 *) (rs + offset16)
Generic 8-bit signed load.
Store from register instructions:
stxdw [rd + offset16], %s
*(u64 *) (rd + offset16)
Generic 64-bit store.
stxw [rd + offset16], %s
*(u32 *) (rd + offset16)
Generic 32-bit store.
stxh [rd + offset16], %s
*(u16 *) (rd + offset16)
Generic 16-bit store.
stxb [rd + offset16], %s
*(u8 *) (rd + offset16)
Generic 8-bit store.
Store from immediates instructions:
stdw [rd + offset16], imm32
*(u64 *) (rd + offset16) = imm32
Store immediate as 64-bit.
stw [rd + offset16], imm32
*(u32 *) (rd + offset16) = imm32
Store immediate as 32-bit.
sth [rd + offset16], imm32
*(u16 *) (rd + offset16) = imm32
Store immediate as 16-bit.
stb [rd + offset16], imm32
*(u8 *) (rd + offset16) = imm32
Store immediate as 8-bit.
eBPF provides the following compare-and-jump instructions, which compare the values of the two given registers, or the values of a register and an immediate, and perform a branch in case the comparison holds true.
ja disp16
goto disp16
Jump-always.
jal disp32
gotol disp32
Jump-always, long range.
jeq rd, rs, disp16
jeq rd, imm32, disp16
if rd == rs goto disp16
if rd == imm32 goto disp16
Jump if equal, unsigned.
jgt rd, rs, disp16
jgt rd, imm32, disp16
if rd > rs goto disp16
if rd > imm32 goto disp16
Jump if greater, unsigned.
jge rd, rs, disp16
jge rd, imm32, disp16
if rd >= rs goto disp16
if rd >= imm32 goto disp16
Jump if greater or equal.
jlt rd, rs, disp16
jlt rd, imm32, disp16
if rd < rs goto disp16
if rd < imm32 goto disp16
Jump if lesser.
jle rd , rs, disp16
jle rd, imm32, disp16
if rd <= rs goto disp16
if rd <= imm32 goto disp16
Jump if lesser or equal.
jset rd, rs, disp16
jset rd, imm32, disp16
if rd & rs goto disp16
if rd & imm32 goto disp16
Jump if signed equal.
jne rd, rs, disp16
jne rd, imm32, disp16
if rd != rs goto disp16
if rd != imm32 goto disp16
Jump if not equal.
jsgt rd, rs, disp16
jsgt rd, imm32, disp16
if rd s> rs goto disp16
if rd s> imm32 goto disp16
Jump if signed greater.
jsge rd, rs, disp16
jsge rd, imm32, disp16
if rd s>= rd goto disp16
if rd s>= imm32 goto disp16
Jump if signed greater or equal.
jslt rd, rs, disp16
jslt rd, imm32, disp16
if rd s< rs goto disp16
if rd s< imm32 goto disp16
Jump if signed lesser.
jsle rd, rs, disp16
jsle rd, imm32, disp16
if rd s<= rs goto disp16
if rd s<= imm32 goto disp16
Jump if signed lesser or equal.
A call instruction is provided in order to perform calls to other eBPF functions, or to external kernel helpers:
call disp32
call imm32
Jump and link to the offset disp32, or to the kernel helper function identified by imm32.
Finally:
exit
Terminate the eBPF program.
eBPF provides the following compare-and-jump instructions, which compare the 32-bit values of the two given registers, or the values of a register and an immediate, and perform a branch in case the comparison holds true.
These instructions are only available in BPF v3 or later.
jeq32 rd, rs, disp16
jeq32 rd, imm32, disp16
if rd == rs goto disp16
if rd == imm32 goto disp16
Jump if equal, unsigned.
jgt32 rd, rs, disp16
jgt32 rd, imm32, disp16
if rd > rs goto disp16
if rd > imm32 goto disp16
Jump if greater, unsigned.
jge32 rd, rs, disp16
jge32 rd, imm32, disp16
if rd >= rs goto disp16
if rd >= imm32 goto disp16
Jump if greater or equal.
jlt32 rd, rs, disp16
jlt32 rd, imm32, disp16
if rd < rs goto disp16
if rd < imm32 goto disp16
Jump if lesser.
jle32 rd , rs, disp16
jle32 rd, imm32, disp16
if rd <= rs goto disp16
if rd <= imm32 goto disp16
Jump if lesser or equal.
jset32 rd, rs, disp16
jset32 rd, imm32, disp16
if rd & rs goto disp16
if rd & imm32 goto disp16
Jump if signed equal.
jne32 rd, rs, disp16
jne32 rd, imm32, disp16
if rd != rs goto disp16
if rd != imm32 goto disp16
Jump if not equal.
jsgt32 rd, rs, disp16
jsgt32 rd, imm32, disp16
if rd s> rs goto disp16
if rd s> imm32 goto disp16
Jump if signed greater.
jsge32 rd, rs, disp16
jsge32 rd, imm32, disp16
if rd s>= rd goto disp16
if rd s>= imm32 goto disp16
Jump if signed greater or equal.
jslt32 rd, rs, disp16
jslt32 rd, imm32, disp16
if rd s< rs goto disp16
if rd s< imm32 goto disp16
Jump if signed lesser.
jsle32 rd, rs, disp16
jsle32 rd, imm32, disp16
if rd s<= rs goto disp16
if rd s<= imm32 goto disp16
Jump if signed lesser or equal.
Atomic exchange instructions are provided in two flavors: one for compare-and-swap, one for unconditional exchange.
acmp [rd + offset16], rs
r0 = cmpxchg_64 (rd + offset16, r0, rs)
Atomic compare-and-swap. Compares value in r0
to value addressed by rd + offset16
. On match, the value addressed by rd + offset16
is replaced with the value in rs
. Regardless, the value that was at rd + offset16
is zero-extended and loaded into r0
.
axchg [rd + offset16], rs
rs = xchg_64 (rd + offset16, rs)
Atomic exchange. Atomically exchanges the value in rs
with the value addressed by rd + offset16
.
The following instructions provide atomic arithmetic operations.
aadd [rd + offset16], rs
lock *(u64 *)(rd + offset16) = rs
Atomic add instruction.
aor [rd + offset16], rs
lock *(u64 *) (rd + offset16) |= rs
Atomic or instruction.
aand [rd + offset16], rs
lock *(u64 *) (rd + offset16) &= rs
Atomic and instruction.
axor [rd + offset16], rs
lock *(u64 *) (rd + offset16) ^= rs
Atomic xor instruction.
The following variants perform fetching before the atomic operation.
afadd [rd + offset16], rs
rs = atomic_fetch_add ((u64 *)(rd + offset16), rs)
Atomic fetch-and-add instruction.
afor [rd + offset16], rs
rs = atomic_fetch_or ((u64 *)(rd + offset16), rs)
Atomic fetch-and-or instruction.
afand [rd + offset16], rs
rs = atomic_fetch_and ((u64 *)(rd + offset16), rs)
Atomic fetch-and-and instruction.
afxor [rd + offset16], rs
rs = atomic_fetch_xor ((u64 *)(rd + offset16), rs)
Atomic fetch-and-or instruction.
The above instructions were introduced in the V3 of the BPF instruction set. The following instruction is supported for backwards compatibility:
xadddw [rd + offset16], rs
Alias to aadd
.
32-bit atomic exchange instructions are provided in two flavors: one for compare-and-swap, one for unconditional exchange.
acmp32 [rd + offset16], rs
w0 = cmpxchg32_32 (rd + offset16, w0, ws)
Atomic compare-and-swap. Compares value in w0
to value addressed by rd + offset16
. On match, the value addressed by rd + offset16
is replaced with the value in ws
. Regardless, the value that was at rd + offset16
is zero-extended and loaded into w0
.
axchg [rd + offset16], rs
ws = xchg32_32 (rd + offset16, ws)
Atomic exchange. Atomically exchanges the value in ws
with the value addressed by rd + offset16
.
The following instructions provide 32-bit atomic arithmetic operations.
aadd32 [rd + offset16], rs
lock *(u32 *)(rd + offset16) = rs
Atomic add instruction.
aor32 [rd + offset16], rs
lock *(u32 *) (rd + offset16) |= rs
Atomic or instruction.
aand32 [rd + offset16], rs
lock *(u32 *) (rd + offset16) &= rs
Atomic and instruction.
axor32 [rd + offset16], rs
lock *(u32 *) (rd + offset16) ^= rs
Atomic xor instruction
The following variants perform fetching before the atomic operation.
afadd32 [dr + offset16], rs
ws = atomic_fetch_add ((u32 *)(rd + offset16), ws)
Atomic fetch-and-add instruction.
afor32 [dr + offset16], rs
ws = atomic_fetch_or ((u32 *)(rd + offset16), ws)
Atomic fetch-and-or instruction.
afand32 [dr + offset16], rs
ws = atomic_fetch_and ((u32 *)(rd + offset16), ws)
Atomic fetch-and-and instruction.
afxor32 [dr + offset16], rs
ws = atomic_fetch_xor ((u32 *)(rd + offset16), ws)
Atomic fetch-and-or instruction
The above instructions were introduced in the V3 of the BPF instruction set. The following instruction is supported for backwards compatibility:
xaddw [rd + offset16], rs
Alias to aadd32
.