Previous: , Up: BPF-Dependent   [Contents][Index]


9.7.5 BPF Instructions

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.

9.7.5.1 Arithmetic instructions

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.

9.7.5.2 32-bit arithmetic instructions

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.

9.7.5.3 Endianness conversion instructions

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.

9.7.5.4 Byte swap instructions

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.

9.7.5.5 64-bit load and pseudo maps

lddw rd, imm64
rd = imm64 ll

Load the given signed 64-bit immediate to the destination register rd.

9.7.5.6 Load instructions for socket filters

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.

9.7.5.7 Generic load/store instructions

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.

9.7.5.8 Jump instructions

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.

9.7.5.9 32-bit jump instructions

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.

9.7.5.10 Atomic instructions

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.

9.7.5.11 32-bit atomic instructions

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.


Previous: , Up: BPF-Dependent   [Contents][Index]