gas: documentation for the BPF pseudo-c asm syntax
authorJose E. Marchesi <jose.marchesi@oracle.com>
Thu, 20 Apr 2023 14:46:08 +0000 (16:46 +0200)
committerJose E. Marchesi <jose.marchesi@oracle.com>
Wed, 26 Apr 2023 17:29:09 +0000 (19:29 +0200)
This patch expands the GAS manual in order to specify the alternate
pseudo-C assembly syntax used in BPF, and now supported by the
assembler.

gas/ChangeLog:

2023-04-19  Jose E. Marchesi  <jose.marchesi@oracle.com>

PR gas/29757
* doc/c-bpf.texi (BPF Pseudo-C Syntax): New section.

gas/ChangeLog
gas/doc/c-bpf.texi

index 88a9d2eff95d65485f8e29ed76873d89cccee689..2659601f793ef2d0126f48358d287ad1956c7711 100644 (file)
@@ -1,3 +1,8 @@
+2023-04-19  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+       PR gas/29757
+       * doc/c-bpf.texi (BPF Pseudo-C Syntax): New section.
+
 2023-04-20  Guillermo E. Martinez  <guillermo.e.martinez@oracle.com>
 
        PR gas/29728
index bb1c452f115dc7cd2b2df9c9619705a86bc01c4b..0756796adc98789b902342ab3b9684688817ecee 100644 (file)
@@ -19,6 +19,7 @@
 * BPF Syntax::                 Syntax
 * BPF Directives::             Machine Directives
 * BPF Opcodes::                        Opcodes
+* BPF Pseudo-C Syntax::         Alternative Pseudo-C Assembly Syntax
 @end menu
 
 @node BPF Options
@@ -228,11 +229,11 @@ in @code{%d}.
 @subsubsection Endianness conversion instructions
 
 @table @code
-@item endle %d, (8|16|32)
-Convert the 8-bit, 16-bit or 32-bit value in @code{%d} to
+@item endle %d, (16|32|64)
+Convert the 16-bit, 32-bit or 64-bit value in @code{%d} to
 little-endian.
-@item endbe %d, (8|16|32)
-Convert the 8-bit, 16-bit or 32-bit value in @code{%d} to big-endian.
+@item endbe %d, (16|32|64)
+Convert the 16-bit, 32-bit or 64-bit value in @code{%d} to big-endian.
 @end table
 
 @subsubsection 64-bit load and pseudo maps
@@ -335,9 +336,9 @@ holds true.
 @item ja %d,(%s|imm32),disp16
 Jump-always.
 @item jeq %d,(%s|imm32),disp16
-Jump if equal.
+Jump if equal, unsigned.
 @item jgt %d,(%s|imm32),disp16
-Jump if greater.
+Jump if greater, unsigned.
 @item jge %d,(%s|imm32),disp16
 Jump if greater or equal.
 @item jlt %d,(%s|imm32),disp16
@@ -385,3 +386,192 @@ Exchange-and-add a 64-bit value at the specified location.
 @item xaddw [%d+offset16],%s
 Exchange-and-add a 32-bit value at the specified location.
 @end table
+
+@node BPF Pseudo-C Syntax
+@section 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 @dfn{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.
+
+@subsubsection 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:
+
+@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.
+@end table
+
+@noindent
+Note that in the Pseudo-C syntax register names are not preceded by
+@code{%} characters.
+
+@subsubsection 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
+@code{r3 += r2} will perform 64-bit addition, whereas @code{w3 += w2}
+will perform 32-bit addition.  Mixing register prefixes is an error,
+for example @code{r3 += w2}.
+
+@table @code
+@item dst_reg += (imm32|src_reg)
+Arithmetic addition.
+@item dst_reg -= (imm32|src_reg)
+Arithmetic subtraction.
+@item dst_reg *= (imm32|src_reg)
+Arithmetic multiplication.
+@item dst_reg /= (imm32|src_reg)
+Arithmetic integer unsigned division.
+@item dst_reg %= (imm32|src_reg)
+Arithmetic integer unsigned remainder.
+@item dst_reg &= (imm32|src_reg)
+Bit-wise ``and'' operation.
+@item dst_reg |= (imm32|src_reg)
+Bit-wise ``or'' operation.
+@item dst_reg ^= (imm32|src_reg)
+Bit-wise exclusive-or operation.
+@item dst_reg <<= (imm32|src_reg)
+Left shift, by whatever specified number of bits.
+@item dst_reg >>= (imm32|src_reg)
+Right logical shift, by whatever specified number of bits.
+@item dst_reg s>>= (imm32|src_reg)
+Right arithmetic shift, by whatever specified number of bits.
+@item dst_reg = (imm32|src_reg)
+Move the value in @code{imm32} or @code{src_reg} in @code{dst_reg}.
+@item dst_reg = -dst_reg
+Arithmetic negation.
+@end table
+
+@subsubsection Endianness conversion instructions
+
+@table @code
+@item dst_reg = le16 src_reg
+Convert the 16-bit value in @code{src_reg} to little-endian.
+@item dst_reg = le32 src_reg
+Convert the 32-bit value in @code{src_reg} to little-endian.
+@item dst_reg = le64 src_reg
+Convert the 64-bit value in @code{src_reg} to little-endian.
+@item dst_reg = be16 src_reg
+Convert the 16-bit value in @code{src_reg} to big-endian.
+@item dst_reg = be32 src_reg
+Convert the 32-bit value in @code{src_reg} to big-endian.
+@item dst_reg = be64 src_reg
+Convert the 64-bit value in @code{src_reg} to big-endian.
+@end table
+
+@subsubsection 64-bit load and pseudo maps
+
+@table @code
+@item dst_reg = imm64 ll
+Load the given signed 64-bit immediate, or pseudo map descriptor, to
+the destination register @code{dst_reg}.
+@end table
+
+@subsubsection Load instructions for socket filters
+
+@table @code
+@item r0 = *(u8 *)skb[imm32]
+Absolute 8-bit load.
+@item r0 = *(u16 *)skb[imm32]
+Absolute 16-bit load.
+@item r0 = *(u32 *)skb[imm32]
+Absolute 32-bit load.
+@item r0 = *(u64 *)skb[imm32]
+Absolute 64-bit load.
+@item r0 = *(u8 *)skb[src_reg + imm32]
+Indirect 8-bit load.
+@item r0 = *(u16 *)skb[src_reg + imm32]
+Indirect 16-bit load.
+@item r0 = *(u32 *)skb[src_reg + imm32]
+Indirect 32-bit load.
+@item r0 = *(u64 *)skb[src_reg + imm32]
+Indirect 64-bit load.
+@end table
+
+@subsubsection Generic load/store instructions
+
+@table @code
+@item dst_reg = *(u8 *)(src_reg + offset16)
+Generic 8-bit load.
+@item dst_reg = *(u16 *)(src_reg + offset16)
+Generic 16-bit load.
+@item dst_reg = *(u32 *)(src_reg + offset16)
+Generic 32-bit load.
+@item dst_reg = *(u64 *)(src_reg + offset16)
+Generic 64-bit load.
+@c XXX stb
+@c NO PSEUDOC-SYNTAX
+@c XXX sth
+@c NO PSEUDOC-SYNTAX
+@c XXX stw
+@c NO PSEUDOC-SYNTAX
+@c XXX stdw
+@c NO PSEUDOC-SYNTAX
+@item *(u8 *)(dst_reg + offset16) = src_reg
+Generic 8-bit store.
+@item *(u16 *)(dst_reg + offset16) = src_reg
+Generic 16-bit store.
+@item *(u32 *)(dst_reg + offset16) = src_reg
+Generic 32-bit store.
+@item *(u64 *)(dst_reg + offset16) = src_reg
+Generic 64-bit store.
+@end table
+
+@subsubsection Jump instructions
+
+@table @code
+@item goto disp16
+Jump-always.
+@item if dst_reg == (imm32|src_reg) goto disp16
+Jump if equal.
+@item if dst_reg & (imm32|src_reg) goto disp16
+Jump if signed equal.
+@item if dst_reg != (imm32|src_reg) goto disp16
+Jump if not equal.
+@item if dst_reg > (imm32|src_reg) goto disp16
+Jump if bigger, unsigned.
+@item if dst_reg < (imm32|src_reg) goto disp16
+Jump if smaller, unsigned.
+@item if dst_reg >= (imm32|src_reg) goto disp16
+Jump if bigger or equal, unsigned.
+@item if dst_reg <= (imm32|src_reg) goto disp16
+Jump if smaller or equal, unsigned.
+@item if dst_reg s> (imm32|src_reg) goto disp16
+Jump if bigger, signed.
+@item if dst_reg s< (imm32|src_reg) goto disp16
+Jump if smaller, signed.
+@item if dst_reg s>= (imm32|src_reg) goto disp16
+Jump if bigger or equal, signed.
+@item if dst_reg s<= (imm32|src_reg) goto disp16
+Jump if smaller or equal, signed.
+@item call imm32
+Jump and link.
+@item exit
+Terminate the eBPF program.
+@end table
+
+@subsubsection Atomic instructions
+
+@table @code
+@item lock *(u64 *)(dst_reg + offset16) += src_reg
+Exchange-and-add a 64-bit value at the specified location.
+@item lock *(u32 *)(dst_reg + offset16) += src_reg
+Exchange-and-add a 32-bit value at the specified location.
+@end table