BPF Dependent Features
**********************

BPF Options
===========

-EB
     This option specifies that the assembler should emit big-endian eBPF.

-EL
     This option specifies that the assembler should emit little-endian eBPF.

-mdialect=DIALECT
     This option specifies the assembly language dialect to recognize while assembling.  The assembler supports normal and pseudoc.

-misa-spec=SPEC
     This option specifies the version of the BPF instruction set to use when assembling.  The BPF ISA versions supported are v1 v2, v3 and v4.

     The value xbpf can be specified to recognize extra instructions that are used by GCC for testing purposes.  But beware this is not valid BPF.

-mno-relax
     This option tells the assembler to not relax instructions.

Note that if no endianness option is specified in the command line, the host endianness is used.

BPF Special Characters
======================

The presence of a # or // anywhere on a line indicates the start of a comment that extends to the end of the line.

The presence of the /* sequence indicates the beginning of a block (multi-line) comment, whose contents span until the next */ sequence.  It is not possible to nest block comments.

Statements and assembly directives are separated by newlines and ; characters.

BPF Registers
=============

The eBPF processor provides ten general-purpose 64-bit registers, which are read-write, and a read-only frame pointer register:

In normal syntax:

%r0 .. %r9
     General-purpose registers.

%r10
%fp
     Read-only frame pointer register.

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:

In pseudoc syntax:

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.

r10
     Read-only frame pointer register.

Note that in the Pseudo-C syntax register names are not preceded by % characters.  A consequence of that is that in contexts like instruction operands, where both register names and expressions involving symbols are expected, there is no way to disambiguate between them.  In order to keep things simple, this assembler does not allow to refer to symbols whose names collide with register names in instruction operands.

BPF Directives
==============

The BPF version of AS supports the following additional machine directives:

.word
     The .half directive produces a 16 bit value.

.word
     The .word directive produces a 32 bit value.

.dword
     The .dword directive produces a 64 bit value.

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 two's 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.

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.

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.

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.

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.

64-bit load and pseudo maps
---------------------------

lddw rd, imm64
rd = imm64 ll
     Load the given signed 64-bit immediate to the destination register rd.

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:

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:

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.

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.

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.

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.

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.

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.