gas: documentation for the BPF pseudo-c asm syntax

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.
This commit is contained in:
Jose E. Marchesi 2023-04-20 16:46:08 +02:00
parent bba4624d03
commit dcdec68b0b
2 changed files with 201 additions and 6 deletions

View 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

View 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