| @c Copyright (C) 2019-2024 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 @samp{//} anywhere on a line indicates |
| the start of a comment that extends to the end of the line. |
| |
| @cindex block comments, BPF |
| @cindex BPF block comments |
| The presence of the @samp{/*} sequence indicates the beginning of a |
| block (multi-line) comment, whose contents span until the next |
| @samp{*/} sequence. It is not possible to nest block comments. |
| |
| @cindex statement separator, BPF |
| Statements and assembly directives are separated by newlines and |
| @samp{;} characters. |
| |
| @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. 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. |
| |
| @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 |
| |
| @noindent |
| 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, @code{-2}, @code{0xfffffffe} and |
| @code{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. |
| |
| @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 rd = - rd |
| 64-bit arithmetic negation. |
| |
| @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 rd = - rd |
| 32-bit arithmetic negation. |
| |
| @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 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 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 |