[PATCH] bpf: add the addr_space_cast instruction
Vineet Gupta
vineet.gupta@linux.dev
Tue Sep 29 18:36:03 GMT 2026
gas doesn't support bpf arenas as it is missing addr_space_cast BPF
instruction. It is essentially a `mov' with a distinguised offset and
the two address spaces supported (0: generic, 1: arena) ecoded in the
immediate.
To keep implementation simple, spell out the two combinations as literal
template text. The entries have to precede `mov', whose mask covers only
the opcode byte and would otherwise match first; movs8 and friends are
already written this way.
The instruction is available at every ISA spec (just as clang).
gas/
* testsuite/gas/bpf/ascast.s: New test.
* testsuite/gas/bpf/ascast.d: New test.
* testsuite/gas/bpf/ascast-pseudoc.s: New test.
* testsuite/gas/bpf/ascast-pseudoc.d: New test.
* testsuite/gas/bpf/bpf.exp: Run them.
include/
* opcode/bpf.h (BPF_OFFSET16_ASCAST): Define.
(BPF_IMM32_ASCAST_K, BPF_IMM32_ASCAST_U): Likewise.
(enum bpf_insn_id): Add BPF_INSN_ASCASTK and BPF_INSN_ASCASTU.
opcodes/
* bpf-opc.c (bpf_opcodes): Add entries for addr_space_cast.
Signed-off-by: Vineet Gupta <vineet.gupta@linux.dev>
---
gas/testsuite/gas/bpf/ascast-pseudoc.d | 14 ++++++++++++++
gas/testsuite/gas/bpf/ascast-pseudoc.s | 6 ++++++
gas/testsuite/gas/bpf/ascast.d | 14 ++++++++++++++
gas/testsuite/gas/bpf/ascast.s | 6 ++++++
gas/testsuite/gas/bpf/bpf.exp | 2 ++
include/opcode/bpf.h | 12 ++++++++++++
opcodes/bpf-opc.c | 8 ++++++++
7 files changed, 62 insertions(+)
create mode 100644 gas/testsuite/gas/bpf/ascast-pseudoc.d
create mode 100644 gas/testsuite/gas/bpf/ascast-pseudoc.s
create mode 100644 gas/testsuite/gas/bpf/ascast.d
create mode 100644 gas/testsuite/gas/bpf/ascast.s
diff --git a/gas/testsuite/gas/bpf/ascast-pseudoc.d b/gas/testsuite/gas/bpf/ascast-pseudoc.d
new file mode 100644
index 000000000000..07cf304a4bd8
--- /dev/null
+++ b/gas/testsuite/gas/bpf/ascast-pseudoc.d
@@ -0,0 +1,14 @@
+#as: -EL -mdialect=pseudoc
+#objdump: -dr -M dec,pseudoc
+#source: ascast-pseudoc.s
+#name: BPF address space cast instructions, pseudoc syntax
+
+.*: +file format .*bpf.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+ 0: bf 11 01 00 01 00 00 00 r1 = addr_space_cast\(r1, 0, 1\)
+ 8: bf 10 01 00 00 00 01 00 r0 = addr_space_cast\(r1, 1, 0\)
+ 10: bf 29 01 00 01 00 00 00 r9 = addr_space_cast\(r2, 0, 1\)
+ 18: bf 32 00 00 00 00 00 00 r2=r3
diff --git a/gas/testsuite/gas/bpf/ascast-pseudoc.s b/gas/testsuite/gas/bpf/ascast-pseudoc.s
new file mode 100644
index 000000000000..0d0c35a278f8
--- /dev/null
+++ b/gas/testsuite/gas/bpf/ascast-pseudoc.s
@@ -0,0 +1,6 @@
+# Test for address space cast instructions
+ .text
+ r1 = addr_space_cast(r1, 0, 1)
+ r0 = addr_space_cast(r1, 1, 0)
+ r9 = addr_space_cast(r2, 0, 1)
+ r2 = r3
diff --git a/gas/testsuite/gas/bpf/ascast.d b/gas/testsuite/gas/bpf/ascast.d
new file mode 100644
index 000000000000..6069bbb1b00e
--- /dev/null
+++ b/gas/testsuite/gas/bpf/ascast.d
@@ -0,0 +1,14 @@
+#as: -EL -mdialect=normal
+#objdump: -dr -M dec
+#source: ascast.s
+#name: BPF address space cast instructions, normal syntax
+
+.*: +file format .*bpf.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+ 0: bf 11 01 00 01 00 00 00 addr_space_cast %r1,%r1,0,1
+ 8: bf 10 01 00 00 00 01 00 addr_space_cast %r0,%r1,1,0
+ 10: bf 29 01 00 01 00 00 00 addr_space_cast %r9,%r2,0,1
+ 18: bf 32 00 00 00 00 00 00 mov %r2,%r3
diff --git a/gas/testsuite/gas/bpf/ascast.s b/gas/testsuite/gas/bpf/ascast.s
new file mode 100644
index 000000000000..1411f236b64a
--- /dev/null
+++ b/gas/testsuite/gas/bpf/ascast.s
@@ -0,0 +1,6 @@
+# Test for address space cast instructions
+ .text
+ addr_space_cast %r1, %r1, 0, 1
+ addr_space_cast %r0, %r1, 1, 0
+ addr_space_cast %r9, %r2, 0, 1
+ mov %r2, %r3
diff --git a/gas/testsuite/gas/bpf/bpf.exp b/gas/testsuite/gas/bpf/bpf.exp
index 9884b36678c2..f58387b90705 100644
--- a/gas/testsuite/gas/bpf/bpf.exp
+++ b/gas/testsuite/gas/bpf/bpf.exp
@@ -43,6 +43,8 @@ if {[istarget bpf*-*-*]} {
run_dump_test atomic-v1
run_dump_test atomic
run_dump_test atomic-pseudoc
+ run_dump_test ascast
+ run_dump_test ascast-pseudoc
run_dump_test indcall-1
run_dump_test indcall-1-pseudoc
diff --git a/include/opcode/bpf.h b/include/opcode/bpf.h
index 1128c8307c5f..0ab542d5de03 100644
--- a/include/opcode/bpf.h
+++ b/include/opcode/bpf.h
@@ -136,6 +136,15 @@ typedef uint64_t bpf_insn_word;
#define BPF_OFFSET16_MOVS8 ((uint64_t)8 << 32)
#define BPF_OFFSET16_MOVS16 ((uint64_t)16 << 32)
#define BPF_OFFSET16_MOVS32 ((uint64_t)32 << 32)
+#define BPF_OFFSET16_ASCAST ((uint64_t)0x1 << 32)
+
+/* In an address space cast the immediate holds the destination address
+ space in its upper half and the source address space in its lower
+ half. Only the generic address space 0 and the arena address space
+ 1 exist, so only these two combinations are meaningful. */
+
+#define BPF_IMM32_ASCAST_K ((uint64_t)0x00000001) /* 0 <- 1. */
+#define BPF_IMM32_ASCAST_U ((uint64_t)0x00010000) /* 1 <- 0. */
#define BPF_IMM32_END16 ((uint64_t)0x00000010)
#define BPF_IMM32_END32 ((uint64_t)0x00000020)
@@ -172,6 +181,9 @@ enum bpf_insn_id
BPF_INSN_NEGR, BPF_INSN_LSHR, BPF_INSN_LSHI,
BPF_INSN_RSHR, BPF_INSN_RSHI, BPF_INSN_ARSHR, BPF_INSN_ARSHI,
BPF_INSN_MOVS8R, BPF_INSN_MOVS16R, BPF_INSN_MOVS32R,
+ /* Address space casts. ASCASTK yields a pointer in the generic
+ address space, ASCASTU one in the arena address space. */
+ BPF_INSN_ASCASTK, BPF_INSN_ASCASTU,
BPF_INSN_MOVR, BPF_INSN_MOVI,
/* ALU32 instructions. */
BPF_INSN_ADD32R, BPF_INSN_ADD32I, BPF_INSN_SUB32R, BPF_INSN_SUB32I,
diff --git a/opcodes/bpf-opc.c b/opcodes/bpf-opc.c
index 15fe5dfd1163..bbadd5e2c827 100644
--- a/opcodes/bpf-opc.c
+++ b/opcodes/bpf-opc.c
@@ -93,6 +93,14 @@ const struct bpf_opcode bpf_opcodes[] =
BPF_V4, BPF_CODE|BPF_OFFSET16, BPF_CLASS_ALU64|BPF_CODE_MOV|BPF_SRC_X|BPF_OFFSET16_MOVS16},
{BPF_INSN_MOVS32R, "movs%W%dr , %sr , 32", "%dr%w=%w( s32 )%w%sr",
BPF_V4, BPF_CODE|BPF_OFFSET16, BPF_CLASS_ALU64|BPF_CODE_MOV|BPF_SRC_X|BPF_OFFSET16_MOVS32},
+ {BPF_INSN_ASCASTK, "addr_space_cast%W%dr , %sr , 0 , 1",
+ "%dr%w=%waddr_space_cast ( %sr ,%w0 ,%w1 )",
+ BPF_V1, BPF_CODE|BPF_OFFSET16|BPF_IMM32,
+ BPF_CLASS_ALU64|BPF_CODE_MOV|BPF_SRC_X|BPF_OFFSET16_ASCAST|BPF_IMM32_ASCAST_K},
+ {BPF_INSN_ASCASTU, "addr_space_cast%W%dr , %sr , 1 , 0",
+ "%dr%w=%waddr_space_cast ( %sr ,%w1 ,%w0 )",
+ BPF_V1, BPF_CODE|BPF_OFFSET16|BPF_IMM32,
+ BPF_CLASS_ALU64|BPF_CODE_MOV|BPF_SRC_X|BPF_OFFSET16_ASCAST|BPF_IMM32_ASCAST_U},
{BPF_INSN_MOVR, "mov%W%dr , %sr", "%dr = %sr",
BPF_V1, BPF_CODE, BPF_CLASS_ALU64|BPF_CODE_MOV|BPF_SRC_X},
{BPF_INSN_MOVI, "mov%W%dr , %i32", "%dr = %i32",
--
2.53.0-Meta
More information about the bpf
mailing list