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


9.7.5 BPF Pseudo-C Syntax

This assembler supports another syntax to denote BPF instructions, which is an alternative to the normal looking syntax documented above. This alternatative syntax, which we call pseudo-C syntax, is supported by the LLVM/clang integrated assembler.

This syntax is very unconventional, but we need to support it in order to support inline assembly in existing BPF programs.

Note that the assembler is able to parse sources in which both syntaxes coexist: some instructions can use the usual assembly like syntax, whereas some other instructions in the same file can use the pseudo-C syntax.

9.7.5.1 Pseudo-C Register Names

All BPF registers are 64-bit long. However, in the Pseudo-C syntax registers can be referred using different names, which actually reflect the kind of instruction they appear on:

r0..r9

General-purpose register in an instruction that operates on its value as if it was a 64-bit value.

w0..w9

General-purpose register in an instruction that operates on its value as if it was a 32-bit value.

Note that in the Pseudo-C syntax register names are not preceded by % characters.

9.7.5.2 Arithmetic instructions

In all the instructions below, the operations are 64-bit or 32-bit depending on the names used to refer to the registers. For example r3 += r2 will perform 64-bit addition, whereas w3 += w2 will perform 32-bit addition. Mixing register prefixes is an error, for example r3 += w2.

dst_reg += (imm32|src_reg)

Arithmetic addition.

dst_reg -= (imm32|src_reg)

Arithmetic subtraction.

dst_reg *= (imm32|src_reg)

Arithmetic multiplication.

dst_reg /= (imm32|src_reg)

Arithmetic integer unsigned division.

dst_reg %= (imm32|src_reg)

Arithmetic integer unsigned remainder.

dst_reg &= (imm32|src_reg)

Bit-wise and operation.

dst_reg |= (imm32|src_reg)

Bit-wise or operation.

dst_reg ^= (imm32|src_reg)

Bit-wise exclusive-or operation.

dst_reg <<= (imm32|src_reg)

Left shift, by whatever specified number of bits.

dst_reg >>= (imm32|src_reg)

Right logical shift, by whatever specified number of bits.

dst_reg s>>= (imm32|src_reg)

Right arithmetic shift, by whatever specified number of bits.

dst_reg = (imm32|src_reg)

Move the value in imm32 or src_reg in dst_reg.

dst_reg = -dst_reg

Arithmetic negation.

9.7.5.3 Endianness conversion instructions

dst_reg = le16 src_reg

Convert the 16-bit value in src_reg to little-endian.

dst_reg = le32 src_reg

Convert the 32-bit value in src_reg to little-endian.

dst_reg = le64 src_reg

Convert the 64-bit value in src_reg to little-endian.

dst_reg = be16 src_reg

Convert the 16-bit value in src_reg to big-endian.

dst_reg = be32 src_reg

Convert the 32-bit value in src_reg to big-endian.

dst_reg = be64 src_reg

Convert the 64-bit value in src_reg to big-endian.

9.7.5.4 64-bit load and pseudo maps

dst_reg = imm64 ll

Load the given signed 64-bit immediate, or pseudo map descriptor, to the destination register dst_reg.

9.7.5.5 Load instructions for socket filters

r0 = *(u8 *)skb[imm32]

Absolute 8-bit load.

r0 = *(u16 *)skb[imm32]

Absolute 16-bit load.

r0 = *(u32 *)skb[imm32]

Absolute 32-bit load.

r0 = *(u64 *)skb[imm32]

Absolute 64-bit load.

r0 = *(u8 *)skb[src_reg + imm32]

Indirect 8-bit load.

r0 = *(u16 *)skb[src_reg + imm32]

Indirect 16-bit load.

r0 = *(u32 *)skb[src_reg + imm32]

Indirect 32-bit load.

r0 = *(u64 *)skb[src_reg + imm32]

Indirect 64-bit load.

9.7.5.6 Generic load/store instructions

dst_reg = *(u8 *)(src_reg + offset16)

Generic 8-bit load.

dst_reg = *(u16 *)(src_reg + offset16)

Generic 16-bit load.

dst_reg = *(u32 *)(src_reg + offset16)

Generic 32-bit load.

dst_reg = *(u64 *)(src_reg + offset16)

Generic 64-bit load.

*(u8 *)(dst_reg + offset16) = src_reg

Generic 8-bit store.

*(u16 *)(dst_reg + offset16) = src_reg

Generic 16-bit store.

*(u32 *)(dst_reg + offset16) = src_reg

Generic 32-bit store.

*(u64 *)(dst_reg + offset16) = src_reg

Generic 64-bit store.

9.7.5.7 Jump instructions

goto disp16

Jump-always.

if dst_reg == (imm32|src_reg) goto disp16

Jump if equal.

if dst_reg & (imm32|src_reg) goto disp16

Jump if signed equal.

if dst_reg != (imm32|src_reg) goto disp16

Jump if not equal.

if dst_reg > (imm32|src_reg) goto disp16

Jump if bigger, unsigned.

if dst_reg < (imm32|src_reg) goto disp16

Jump if smaller, unsigned.

if dst_reg >= (imm32|src_reg) goto disp16

Jump if bigger or equal, unsigned.

if dst_reg <= (imm32|src_reg) goto disp16

Jump if smaller or equal, unsigned.

if dst_reg s> (imm32|src_reg) goto disp16

Jump if bigger, signed.

if dst_reg s< (imm32|src_reg) goto disp16

Jump if smaller, signed.

if dst_reg s>= (imm32|src_reg) goto disp16

Jump if bigger or equal, signed.

if dst_reg s<= (imm32|src_reg) goto disp16

Jump if smaller or equal, signed.

call imm32

Jump and link.

exit

Terminate the eBPF program.

9.7.5.8 Atomic instructions

lock *(u64 *)(dst_reg + offset16) += src_reg

Exchange-and-add a 64-bit value at the specified location.

lock *(u32 *)(dst_reg + offset16) += src_reg

Exchange-and-add a 32-bit value at the specified location.


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