@c Copyright (C) 2019-2023 Free Software Foundation, Inc. @c This is part of the GAS manual. @c For copying conditions, see the file as.texinfo. @ifset GENERIC @page @node BPF-Dependent @chapter BPF Dependent Features @end ifset @ifclear GENERIC @node Machine Dependencies @chapter BPF Dependent Features @end ifclear @cindex BPF support @menu * BPF Options:: BPF specific command-line options. * BPF Special Characters:: Comments and statements. * BPF Registers:: Register names. * BPF Directives:: Machine directives. * BPF Instructions:: Machine instructions. @end menu @node BPF Options @section BPF Options @cindex BPF options (none) @cindex options for BPF (none) @c man begin OPTIONS @table @gcctabopt @cindex @option{-EB} command-line option, BPF @item -EB This option specifies that the assembler should emit big-endian eBPF. @cindex @option{-EL} command-line option, BPF @item -EL This option specifies that the assembler should emit little-endian eBPF. @cindex @option{-mdialect} command-line options, BPF @item -mdialect=@var{dialect} This option specifies the assembly language dialect to recognize while assembling. The assembler supports @option{normal} and @option{pseudoc}. @cindex @option{-misa-spec} command-line options, BPF @item -misa-spec=@var{spec} This option specifies the version of the BPF instruction set to use when assembling. The BPF ISA versions supported are @option{v1} @option{v2}, @option{v3} and @option{v4}. The value @option{xbpf} can be specified to recognize extra instructions that are used by GCC for testing purposes. But beware this is not valid BPF. @cindex @option{-mno-relax} command-line options, BPF @item -mno-relax This option tells the assembler to not relax instructions. @end table Note that if no endianness option is specified in the command line, the host endianness is used. @c man end @node BPF Special Characters @section BPF Special Characters @cindex line comment character, BPF @cindex BPF line comment character The presence of a @samp{;} or a @samp{#} on a line indicates the start of a comment that extends to the end of the current line. @cindex statement separator, BPF Statements and assembly directives are separated by newlines. @node BPF Registers @section BPF Registers @cindex BPF register names @cindex register names, BPF The eBPF processor provides ten general-purpose 64-bit registers, which are read-write, and a read-only frame pointer register: @noindent In normal syntax: @table @samp @item %r0 .. %r9 General-purpose registers. @item %r10 @itemx %fp Read-only frame pointer register. @end table 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: @noindent In pseudoc syntax: @table @samp @item r0..r9 General-purpose register in an instruction that operates on its value as if it was a 64-bit value. @item w0..w9 General-purpose register in an instruction that operates on its value as if it was a 32-bit value. @item r10 Read-only frame pointer register. @end table @noindent Note that in the Pseudo-C syntax register names are not preceded by @code{%} characters. @node BPF Directives @section BPF Directives @cindex machine directives, BPF The BPF version of @code{@value{AS}} supports the following additional machine directives: @table @code @cindex @code{half} directive, BPF @item .word The @code{.half} directive produces a 16 bit value. @cindex @code{word} directive, BPF @item .word The @code{.word} directive produces a 32 bit value. @cindex @code{dword} directive, BPF @item .dword The @code{.dword} directive produces a 64 bit value. @end table @node BPF Instructions @section BPF Instructions @cindex BPF opcodes @cindex opcodes for BPF In the instruction descriptions below the following field descriptors are used: @table @code @item rd Destination general-purpose register whose role is to be the destination of an operation. @item rs Source general-purpose register whose role is to be the source of an operation. @item disp16 16-bit signed PC-relative offset, measured in number of 64-bit words, minus one. @item disp32 32-bit signed PC-relative offset, measured in number of 64-bit words, minus one. @item offset16 Signed 16-bit immediate representing an offset in bytes. @item disp16 Signed 16-bit immediate representing a displacement to a target, measured in number of 64-bit words @emph{minus one}. @item disp32 Signed 32-bit immediate representing a displacement to a target, measured in number of 64-bit words @emph{minus one}. @item imm32 Signed 32-bit immediate. @item imm64 Signed 64-bit immediate. @end table @subsection Arithmetic instructions The destination register in these instructions act like an accumulator. Note that in pseudoc syntax these instructions should use @code{r} registers. @table @code @item add rd, rs @itemx add rd, imm32 @itemx rd += rs @itemx rd += imm32 64-bit arithmetic addition. @item sub rd, rs @itemx sub rd, rs @itemx rd -= rs @itemx rd -= imm32 64-bit arithmetic subtraction. @item mul rd, rs @itemx mul rd, imm32 @itemx rd *= rs @itemx rd *= imm32 64-bit arithmetic multiplication. @item div rd, rs @itemx div rd, imm32 @itemx rd /= rs @itemx rd /= imm32 64-bit arithmetic integer division. @item mod rd, rs @itemx mod rd, imm32 @itemx rd %= rs @itemx rd %= imm32 64-bit integer remainder. @item and rd, rs @itemx and rd, imm32 @itemx rd &= rs @itemx rd &= imm32 64-bit bit-wise ``and'' operation. @item or rd, rs @itemx or rd, imm32 @itemx rd |= rs @itemx rd |= imm32 64-bit bit-wise ``or'' operation. @item xor rd, imm32 @itemx xor rd, rs @itemx rd ^= rs @itemx rd ^= imm32 64-bit bit-wise exclusive-or operation. @item lsh rd, rs @itemx ldh rd, imm32 @itemx rd <<= rs @itemx rd <<= imm32 64-bit left shift, by @code{rs} or @code{imm32} bits. @item rsh %d, %s @itemx rsh rd, imm32 @itemx rd >>= rs @itemx rd >>= imm32 64-bit right logical shift, by @code{rs} or @code{imm32} bits. @item arsh rd, rs @itemx arsh rd, imm32 @itemx rd s>>= rs @itemx rd s>>= imm32 64-bit right arithmetic shift, by @code{rs} or @code{imm32} bits. @item neg rd @itemx neg rd, imm32 @itemx rd = - rd @itemx rd = - imm32 64-bit arithmetic negation. Note that in the @code{rd = - imm32} syntax there must be at least one white space between @code{-} and @code{imm32}. Otherwise the instruction is parsed as a @code{mov rd, imm32} instruction with a negative 32-bit immediate. This is a consequence of a syntactic ambiguity in the pseudoc syntax. @item mov rd, rs @itemx mov rd, imm32 @itemx rd = rs @itemx rd = imm32 Move the 64-bit value of @code{rs} in @code{rd}, or load @code{imm32} in @code{rd}. @item movs rd, rs, 8 @itemx rd = (s8) rs Move the sign-extended 8-bit value in @code{rs} to @code{rd}. @item movs rd, rs, 16 @itemx rd = (s16) rs Move the sign-extended 16-bit value in @code{rs} to @code{rd}. @item movs rd, rs, 32 @itemx rd = (s32) rs Move the sign-extended 32-bit value in @code{rs} to @code{rd}. @end table @subsection 32-bit arithmetic instructions The destination register in these instructions act as an accumulator. Note that in pseudoc syntax these instructions should use @code{w} registers. It is not allowed to mix @code{w} and @code{r} registers in the same instruction. @table @code @item add32 rd, rs @itemx add32 rd, imm32 @itemx rd += rs @itemx rd += imm32 32-bit arithmetic addition. @item sub32 rd, rs @itemx sub32 rd, imm32 @itemx rd -= rs @itemx rd += imm32 32-bit arithmetic subtraction. @item mul32 rd, rs @itemx mul32 rd, imm32 @itemx rd *= rs @itemx rd *= imm32 32-bit arithmetic multiplication. @item div32 rd, rs @itemx div32 rd, imm32 @itemx rd /= rs @itemx rd /= imm32 32-bit arithmetic integer division. @item mod32 rd, rs @itemx mod32 rd, imm32 @itemx rd %= rs @itemx rd %= imm32 32-bit integer remainder. @item and32 rd, rs @itemx and32 rd, imm32 @itemx rd &= rs @itemx rd &= imm32 32-bit bit-wise ``and'' operation. @item or32 rd, rs @itemx or32 rd, imm32 @itemx rd |= rs @itemx rd |= imm32 32-bit bit-wise ``or'' operation. @item xor32 rd, rs @itemx xor32 rd, imm32 @itemx rd ^= rs @itemx rd ^= imm32 32-bit bit-wise exclusive-or operation. @item lsh32 rd, rs @itemx lsh32 rd, imm32 @itemx rd <<= rs @itemx rd <<= imm32 32-bit left shift, by @code{rs} or @code{imm32} bits. @item rsh32 rd, rs @itemx rsh32 rd, imm32 @itemx rd >>= rs @itemx rd >>= imm32 32-bit right logical shift, by @code{rs} or @code{imm32} bits. @item arsh32 rd, rs @itemx arsh32 rd, imm32 @itemx rd s>>= rs @itemx rd s>>= imm32 32-bit right arithmetic shift, by @code{rs} or @code{imm32} bits. @item neg32 rd @itemx neg32 rd, imm32 @itemx rd = - rd @itemx rd = - imm32 32-bit arithmetic negation. Note that in the @code{rd = - imm32} syntax there must be at least one white space between @code{-} and @code{imm32}. Otherwise the instruction is parsed as a @code{mov32 rd, imm32} instruction with a negative 32-bit immediate. This is a consequence of a syntactic ambiguity in the pseudoc syntax. @item mov32 rd, rs @itemx mov32 rd, imm32 @itemx rd = rs @itemx rd = imm32 Move the 32-bit value of @code{rs} in @code{rd}, or load @code{imm32} in @code{rd}. @item mov32s rd, rs, 8 @itemx rd = (s8) rs Move the sign-extended 8-bit value in @code{rs} to @code{rd}. @item mov32s rd, rs, 16 @itemx rd = (s16) rs Move the sign-extended 16-bit value in @code{rs} to @code{rd}. @item mov32s rd, rs, 32 @itemx rd = (s32) rs Move the sign-extended 32-bit value in @code{rs} to @code{rd}. @end table @subsection Endianness conversion instructions @table @code @item endle rd, 16 @itemx endle rd, 32 @itemx endle rd, 64 @itemx rd = le16 rd @itemx rd = le32 rd @itemx rd = le64 rd Convert the 16-bit, 32-bit or 64-bit value in @code{rd} to little-endian and store it back in @code{rd}. @item endbe %d, 16 @itemx endbe %d, 32 @itemx endbe %d, 64 @itemx rd = be16 rd @itemx rd = be32 rd @itemx rd = be64 rd Convert the 16-bit, 32-bit or 64-bit value in @code{rd} to big-endian and store it back in @code{rd}. @end table @subsection Byte swap instructions @table @code @item bswap rd, 16 @itemx rd = bswap16 rd Swap the least-significant 16-bit word in @code{rd} with the most-significant 16-bit word. @item bswap rd, 32 @itemx rd = bswap32 rd Swap the least-significant 32-bit word in @code{rd} with the most-significant 32-bit word. @item bswap rd, 64 @itemx rd = bswap64 rd Swap the least-significant 64-bit word in @code{rd} with the most-significant 64-bit word. @end table @subsection 64-bit load and pseudo maps @table @code @item lddw rd, imm64 @itemx rd = imm64 ll Load the given signed 64-bit immediate to the destination register @code{rd}. @end table @subsection 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 @file{Documentation/networking/filter.txt} in the Linux kernel source tree for more information. Absolute loads: @table @code @item ldabsdw imm32 @itemx r0 = *(u64 *) skb[imm32] Absolute 64-bit load. @item ldabsw imm32 @itemx r0 = *(u32 *) skb[imm32] Absolute 32-bit load. @item ldabsh imm32 @itemx r0 = *(u16 *) skb[imm32] Absolute 16-bit load. @item ldabsb imm32 @itemx r0 = *(u8 *) skb[imm32] Absolute 8-bit load. @end table Indirect loads: @table @code @item ldinddw rs, imm32 @itemx r0 = *(u64 *) skb[rs + imm32] Indirect 64-bit load. @item ldindw rs, imm32 @itemx r0 = *(u32 *) skb[rs + imm32] Indirect 32-bit load. @item ldindh rs, imm32 @itemx r0 = *(u16 *) skb[rs + imm32] Indirect 16-bit load. @item ldindb %s, imm32 @itemx r0 = *(u8 *) skb[rs + imm32] Indirect 8-bit load. @end table @subsection Generic load/store instructions General-purpose load and store instructions are provided for several word sizes. Load to register instructions: @table @code @item ldxdw rd, [rs + offset16] @itemx rd = *(u64 *) (rs + offset16) Generic 64-bit load. @item ldxw rd, [rs + offset16] @itemx rd = *(u32 *) (rs + offset16) Generic 32-bit load. @item ldxh rd, [rs + offset16] @itemx rd = *(u16 *) (rs + offset16) Generic 16-bit load. @item ldxb rd, [rs + offset16] @itemx rd = *(u8 *) (rs + offset16) Generic 8-bit load. @end table Signed load to register instructions: @table @code @item ldxsdw rd, [rs + offset16] @itemx rd = *(s64 *) (rs + offset16) Generic 64-bit signed load. @item ldxsw rd, [rs + offset16] @itemx rd = *(s32 *) (rs + offset16) Generic 32-bit signed load. @item ldxsh rd, [rs + offset16] @itemx rd = *(s16 *) (rs + offset16) Generic 16-bit signed load. @item ldxsb rd, [rs + offset16] @itemx rd = *(s8 *) (rs + offset16) Generic 8-bit signed load. @end table Store from register instructions: @table @code @item stxdw [rd + offset16], %s @itemx *(u64 *) (rd + offset16) Generic 64-bit store. @item stxw [rd + offset16], %s @itemx *(u32 *) (rd + offset16) Generic 32-bit store. @item stxh [rd + offset16], %s @itemx *(u16 *) (rd + offset16) Generic 16-bit store. @item stxb [rd + offset16], %s @itemx *(u8 *) (rd + offset16) Generic 8-bit store. @end table Store from immediates instructions: @table @code @item stdw [rd + offset16], imm32 @itemx *(u64 *) (rd + offset16) = imm32 Store immediate as 64-bit. @item stw [rd + offset16], imm32 @itemx *(u32 *) (rd + offset16) = imm32 Store immediate as 32-bit. @item sth [rd + offset16], imm32 @itemx *(u16 *) (rd + offset16) = imm32 Store immediate as 16-bit. @item stb [rd + offset16], imm32 @itemx *(u8 *) (rd + offset16) = imm32 Store immediate as 8-bit. @end table @subsection 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. @table @code @item ja disp16 @itemx goto disp16 Jump-always. @item jal disp32 @itemx gotol disp32 Jump-always, long range. @item jeq rd, rs, disp16 @itemx jeq rd, imm32, disp16 @itemx if rd == rs goto disp16 @itemx if rd == imm32 goto disp16 Jump if equal, unsigned. @item jgt rd, rs, disp16 @itemx jgt rd, imm32, disp16 @itemx if rd > rs goto disp16 @itemx if rd > imm32 goto disp16 Jump if greater, unsigned. @item jge rd, rs, disp16 @itemx jge rd, imm32, disp16 @itemx if rd >= rs goto disp16 @itemx if rd >= imm32 goto disp16 Jump if greater or equal. @item jlt rd, rs, disp16 @itemx jlt rd, imm32, disp16 @itemx if rd < rs goto disp16 @itemx if rd < imm32 goto disp16 Jump if lesser. @item jle rd , rs, disp16 @itemx jle rd, imm32, disp16 @itemx if rd <= rs goto disp16 @itemx if rd <= imm32 goto disp16 Jump if lesser or equal. @item jset rd, rs, disp16 @itemx jset rd, imm32, disp16 @itemx if rd & rs goto disp16 @itemx if rd & imm32 goto disp16 Jump if signed equal. @item jne rd, rs, disp16 @itemx jne rd, imm32, disp16 @itemx if rd != rs goto disp16 @itemx if rd != imm32 goto disp16 Jump if not equal. @item jsgt rd, rs, disp16 @itemx jsgt rd, imm32, disp16 @itemx if rd s> rs goto disp16 @itemx if rd s> imm32 goto disp16 Jump if signed greater. @item jsge rd, rs, disp16 @itemx jsge rd, imm32, disp16 @itemx if rd s>= rd goto disp16 @itemx if rd s>= imm32 goto disp16 Jump if signed greater or equal. @item jslt rd, rs, disp16 @itemx jslt rd, imm32, disp16 @itemx if rd s< rs goto disp16 @itemx if rd s< imm32 goto disp16 Jump if signed lesser. @item jsle rd, rs, disp16 @itemx jsle rd, imm32, disp16 @itemx if rd s<= rs goto disp16 @itemx if rd s<= imm32 goto disp16 Jump if signed lesser or equal. @end table A call instruction is provided in order to perform calls to other eBPF functions, or to external kernel helpers: @table @code @item call disp32 @item call imm32 Jump and link to the offset @emph{disp32}, or to the kernel helper function identified by @emph{imm32}. @end table Finally: @table @code @item exit Terminate the eBPF program. @end table @subsection 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. @table @code @item jeq32 rd, rs, disp16 @itemx jeq32 rd, imm32, disp16 @itemx if rd == rs goto disp16 @itemx if rd == imm32 goto disp16 Jump if equal, unsigned. @item jgt32 rd, rs, disp16 @itemx jgt32 rd, imm32, disp16 @itemx if rd > rs goto disp16 @itemx if rd > imm32 goto disp16 Jump if greater, unsigned. @item jge32 rd, rs, disp16 @itemx jge32 rd, imm32, disp16 @itemx if rd >= rs goto disp16 @itemx if rd >= imm32 goto disp16 Jump if greater or equal. @item jlt32 rd, rs, disp16 @itemx jlt32 rd, imm32, disp16 @itemx if rd < rs goto disp16 @itemx if rd < imm32 goto disp16 Jump if lesser. @item jle32 rd , rs, disp16 @itemx jle32 rd, imm32, disp16 @itemx if rd <= rs goto disp16 @itemx if rd <= imm32 goto disp16 Jump if lesser or equal. @item jset32 rd, rs, disp16 @itemx jset32 rd, imm32, disp16 @itemx if rd & rs goto disp16 @itemx if rd & imm32 goto disp16 Jump if signed equal. @item jne32 rd, rs, disp16 @itemx jne32 rd, imm32, disp16 @itemx if rd != rs goto disp16 @itemx if rd != imm32 goto disp16 Jump if not equal. @item jsgt32 rd, rs, disp16 @itemx jsgt32 rd, imm32, disp16 @itemx if rd s> rs goto disp16 @itemx if rd s> imm32 goto disp16 Jump if signed greater. @item jsge32 rd, rs, disp16 @itemx jsge32 rd, imm32, disp16 @itemx if rd s>= rd goto disp16 @itemx if rd s>= imm32 goto disp16 Jump if signed greater or equal. @item jslt32 rd, rs, disp16 @itemx jslt32 rd, imm32, disp16 @itemx if rd s< rs goto disp16 @itemx if rd s< imm32 goto disp16 Jump if signed lesser. @item jsle32 rd, rs, disp16 @itemx jsle32 rd, imm32, disp16 @itemx if rd s<= rs goto disp16 @itemx if rd s<= imm32 goto disp16 Jump if signed lesser or equal. @end table @subsection Atomic instructions Atomic exchange instructions are provided in two flavors: one for compare-and-swap, one for unconditional exchange. @table @code @item acmp [rd + offset16], rs @itemx r0 = cmpxchg_64 (rd + offset16, r0, rs) Atomic compare-and-swap. Compares value in @code{r0} to value addressed by @code{rd + offset16}. On match, the value addressed by @code{rd + offset16} is replaced with the value in @code{rs}. Regardless, the value that was at @code{rd + offset16} is zero-extended and loaded into @code{r0}. @item axchg [rd + offset16], rs @itemx rs = xchg_64 (rd + offset16, rs) Atomic exchange. Atomically exchanges the value in @code{rs} with the value addressed by @code{rd + offset16}. @end table @noindent The following instructions provide atomic arithmetic operations. @table @code @item aadd [rd + offset16], rs @itemx lock *(u64 *)(rd + offset16) = rs Atomic add instruction. @item aor [rd + offset16], rs @itemx lock *(u64 *) (rd + offset16) |= rs Atomic or instruction. @item aand [rd + offset16], rs @itemx lock *(u64 *) (rd + offset16) &= rs Atomic and instruction. @item axor [rd + offset16], rs @itemx lock *(u64 *) (rd + offset16) ^= rs Atomic xor instruction. @end table @noindent The following variants perform fetching before the atomic operation. @table @code @item afadd [rd + offset16], rs @itemx rs = atomic_fetch_add ((u64 *)(rd + offset16), rs) Atomic fetch-and-add instruction. @item afor [rd + offset16], rs @itemx rs = atomic_fetch_or ((u64 *)(rd + offset16), rs) Atomic fetch-and-or instruction. @item afand [rd + offset16], rs @itemx rs = atomic_fetch_and ((u64 *)(rd + offset16), rs) Atomic fetch-and-and instruction. @item afxor [rd + offset16], rs @itemx rs = atomic_fetch_xor ((u64 *)(rd + offset16), rs) Atomic fetch-and-or instruction. @end table The above instructions were introduced in the V3 of the BPF instruction set. The following instruction is supported for backwards compatibility: @table @code @item xadddw [rd + offset16], rs Alias to @code{aadd}. @end table @subsection 32-bit atomic instructions 32-bit atomic exchange instructions are provided in two flavors: one for compare-and-swap, one for unconditional exchange. @table @code @item acmp32 [rd + offset16], rs @itemx w0 = cmpxchg32_32 (rd + offset16, w0, ws) Atomic compare-and-swap. Compares value in @code{w0} to value addressed by @code{rd + offset16}. On match, the value addressed by @code{rd + offset16} is replaced with the value in @code{ws}. Regardless, the value that was at @code{rd + offset16} is zero-extended and loaded into @code{w0}. @item axchg [rd + offset16], rs @itemx ws = xchg32_32 (rd + offset16, ws) Atomic exchange. Atomically exchanges the value in @code{ws} with the value addressed by @code{rd + offset16}. @end table @noindent The following instructions provide 32-bit atomic arithmetic operations. @table @code @item aadd32 [rd + offset16], rs @itemx lock *(u32 *)(rd + offset16) = rs Atomic add instruction. @item aor32 [rd + offset16], rs @itemx lock *(u32 *) (rd + offset16) |= rs Atomic or instruction. @item aand32 [rd + offset16], rs @itemx lock *(u32 *) (rd + offset16) &= rs Atomic and instruction. @item axor32 [rd + offset16], rs @itemx lock *(u32 *) (rd + offset16) ^= rs Atomic xor instruction @end table @noindent The following variants perform fetching before the atomic operation. @table @code @item afadd32 [dr + offset16], rs @itemx ws = atomic_fetch_add ((u32 *)(rd + offset16), ws) Atomic fetch-and-add instruction. @item afor32 [dr + offset16], rs @itemx ws = atomic_fetch_or ((u32 *)(rd + offset16), ws) Atomic fetch-and-or instruction. @item afand32 [dr + offset16], rs @itemx ws = atomic_fetch_and ((u32 *)(rd + offset16), ws) Atomic fetch-and-and instruction. @item afxor32 [dr + offset16], rs @itemx ws = atomic_fetch_xor ((u32 *)(rd + offset16), ws) Atomic fetch-and-or instruction @end table The above instructions were introduced in the V3 of the BPF instruction set. The following instruction is supported for backwards compatibility: @table @code @item xaddw [rd + offset16], rs Alias to @code{aadd32}. @end table