]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
bpf: add may_goto instruction [PR32176]
authorDavid Faust <david.faust@oracle.com>
Wed, 4 Feb 2026 21:53:34 +0000 (13:53 -0800)
committerDavid Faust <david.faust@oracle.com>
Thu, 5 Feb 2026 20:26:09 +0000 (12:26 -0800)
The BPF "may_goto" instruction is a special sort of conditional jump
where the condition is determined by the BPF runtime.  That is, it is
a no-op until the runtime decides otherwise.

For normal asm syntax, the mnemonic "jcond" is chosen in keeping with
the style of following the opcode definitions in the Linux kernel uapi
BPF headers.

This instruction is not currently emitted by GCC, but it can be inserted
into BPF programs via macros defined in the Linux kernel.

PR gas/32176

include/
* opcode/bpf.h (BPF_CODE_JCOND): New.
(bpf_insn_id): Add BPF_INSN_JCOND.

opcodes/
* bpf-opc.c: Add entry for BPF_INSN_JCOND.

gas/testsuite/
* gas/bpf/bpf.exp: Run new dump tests.
* gas/bpf/jcond-be-pseudoc.d: New.
* gas/bpf/jcond-be.d: New.
* gas/bpf/jcond-pseudoc.d: New.
* gas/bpf/jcond-pseudoc.s: New.
* gas/bpf/jcond.d: New.
* gas/bpf/jcond.s: New.

gas/testsuite/gas/bpf/bpf.exp
gas/testsuite/gas/bpf/jcond-be-pseudoc.d [new file with mode: 0644]
gas/testsuite/gas/bpf/jcond-be.d [new file with mode: 0644]
gas/testsuite/gas/bpf/jcond-pseudoc.d [new file with mode: 0644]
gas/testsuite/gas/bpf/jcond-pseudoc.s [new file with mode: 0644]
gas/testsuite/gas/bpf/jcond.d [new file with mode: 0644]
gas/testsuite/gas/bpf/jcond.s [new file with mode: 0644]
include/opcode/bpf.h
opcodes/bpf-opc.c

index 89955e1a9e4e19c4972e0bc254e810dc2293950c..f193221225276bb5965146dc89521512296f2725 100644 (file)
@@ -47,6 +47,9 @@ if {[istarget bpf*-*-*]} {
     run_dump_test jump-relax-ja
     run_dump_test jump-relax-jump
 
+    run_dump_test jcond
+    run_dump_test jcond-pseudoc
+
     # Big-endian BPF tests
     run_dump_test call-be
     run_dump_test exit-be
@@ -70,6 +73,9 @@ if {[istarget bpf*-*-*]} {
     run_dump_test jump-relax-ja-be
     run_dump_test jump-relax-jump-be
 
+    run_dump_test jcond-be
+    run_dump_test jcond-be-pseudoc
+
     # Overflow tests
     run_dump_test offset16-overflow
     run_dump_test disp16-overflow
diff --git a/gas/testsuite/gas/bpf/jcond-be-pseudoc.d b/gas/testsuite/gas/bpf/jcond-be-pseudoc.d
new file mode 100644 (file)
index 0000000..5bd24e1
--- /dev/null
@@ -0,0 +1,14 @@
+#as: -EB -mdialect=pseudoc
+#objdump: -dr -M dec,pseudoc
+#source: jcond-pseudoc.s
+#name: BPF conditional pseudo-jump instruction, pseudoc syntax, big-endian
+
+.*: +file format .*bpf.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+   0:  e5 00 00 00 00 00 00 00         may_goto 0
+   8:  e5 00 00 01 00 00 00 00         may_goto 1
+  10:  e5 00 ff fe 00 00 00 00         may_goto -2
+  18:  e5 00 ff fd 00 00 00 00         may_goto -3
diff --git a/gas/testsuite/gas/bpf/jcond-be.d b/gas/testsuite/gas/bpf/jcond-be.d
new file mode 100644 (file)
index 0000000..da2cfba
--- /dev/null
@@ -0,0 +1,14 @@
+#as: -EB -mdialect=normal
+#objdump: -dr -M dec
+#source: jcond.s
+#name: BPF conditional pseudo-jump instruction, normal syntax, big-endian
+
+.*: +file format .*bpf.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+   0:  e5 00 00 00 00 00 00 00         jcond 0
+   8:  e5 00 00 01 00 00 00 00         jcond 1
+  10:  e5 00 ff fe 00 00 00 00         jcond -2
+  18:  e5 00 ff fd 00 00 00 00         jcond -3
diff --git a/gas/testsuite/gas/bpf/jcond-pseudoc.d b/gas/testsuite/gas/bpf/jcond-pseudoc.d
new file mode 100644 (file)
index 0000000..34c14c2
--- /dev/null
@@ -0,0 +1,14 @@
+#as: -EL -mdialect=pseudoc
+#objdump: -dr -M dec,pseudoc
+#source: jcond-pseudoc.s
+#name: BPF conditional pseudo-jump instruction, pseudoc syntax
+
+.*: +file format .*bpf.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+   0:  e5 00 00 00 00 00 00 00         may_goto 0
+   8:  e5 00 01 00 00 00 00 00         may_goto 1
+  10:  e5 00 fe ff 00 00 00 00         may_goto -2
+  18:  e5 00 fd ff 00 00 00 00         may_goto -3
diff --git a/gas/testsuite/gas/bpf/jcond-pseudoc.s b/gas/testsuite/gas/bpf/jcond-pseudoc.s
new file mode 100644 (file)
index 0000000..b48ef38
--- /dev/null
@@ -0,0 +1,8 @@
+# Test for conditional pseudo-jump instruction in pseudo-c syntax
+    .text
+    may_goto 1f
+1:
+    may_goto 2f
+    may_goto 1b
+2:
+    may_goto 1b
diff --git a/gas/testsuite/gas/bpf/jcond.d b/gas/testsuite/gas/bpf/jcond.d
new file mode 100644 (file)
index 0000000..69570e2
--- /dev/null
@@ -0,0 +1,14 @@
+#as: -EL -mdialect=normal
+#objdump: -dr -M dec
+#source: jcond.s
+#name: BPF conditional pseudo-jump instruction, normal syntax, little-endian
+
+.*: +file format .*bpf.*
+
+Disassembly of section .text:
+
+0+ <.text>:
+   0:  e5 00 00 00 00 00 00 00         jcond 0
+   8:  e5 00 01 00 00 00 00 00         jcond 1
+  10:  e5 00 fe ff 00 00 00 00         jcond -2
+  18:  e5 00 fd ff 00 00 00 00         jcond -3
diff --git a/gas/testsuite/gas/bpf/jcond.s b/gas/testsuite/gas/bpf/jcond.s
new file mode 100644 (file)
index 0000000..9c61644
--- /dev/null
@@ -0,0 +1,8 @@
+# Test for conditional pseudo-jump instruction
+    .text
+    jcond 1f
+1:
+    jcond 2f
+    jcond 1b
+2:
+    jcond 1b
index d4d4f6d855760783ae00bc118f958fb07a3696d9..e4ccd430f0ceb66c2bfb00fcba0e6994cf960590 100644 (file)
@@ -106,6 +106,7 @@ typedef uint64_t bpf_insn_word;
 #define BPF_CODE_JLE  ((uint64_t)0xb0 << 56)
 #define BPF_CODE_JSLT ((uint64_t)0xc0 << 56)
 #define BPF_CODE_JSLE ((uint64_t)0xd0 << 56)
+#define BPF_CODE_JCOND ((uint64_t)0xe0 << 56)
 
 #define BPF_MODE_IMM  ((uint64_t)0x00 << 56)
 #define BPF_MODE_ABS  ((uint64_t)0x20 << 56)
@@ -229,6 +230,9 @@ enum bpf_insn_id
   BPF_INSN_ACMP, BPF_INSN_AXCHG,
   /* Atomic compare-and-swap, atomic exchange (32-bit).  */
   BPF_INSN_ACMP32, BPF_INSN_AXCHG32,
+  /* Conditional pseudo-jump "may_goto".  A NOP until the BPF runtime
+     decides it isn't.  */
+  BPF_INSN_JCOND,
   /* GNU simulator specific instruction.  */
   BPF_INSN_BRKPT,
 };
index 91ee561ea10c001dde8c3a459a55b583bedf0324..aa5493280eaab28612b87a6ec39051eb0bce78ea 100644 (file)
@@ -413,6 +413,10 @@ const struct bpf_opcode bpf_opcodes[] =
   {BPF_INSN_AADD32, "xaddw%W[ %dr %o16 ] , %sr", "* ( u32 * ) ( %dr %o16 ) += %sr",
    BPF_V1, BPF_CODE|BPF_IMM32, BPF_CLASS_STX|BPF_SIZE_W|BPF_MODE_ATOMIC|BPF_IMM32_AADD},
 
+  /* The "conditional pseudo-jump" instruction, a.k.a. "may_goto".  */
+  {BPF_INSN_JCOND, "jcond%W%d16", "may_goto%w%d16",
+   BPF_V4, BPF_CODE|BPF_IMM32, BPF_CLASS_JMP|BPF_CODE_JCOND|BPF_SRC_K},
+
   /* the brkpt instruction is used by the BPF simulator and it doesn't
      really belong to the BPF instruction set.  */
   {BPF_INSN_BRKPT, "brkpt", "brkpt",