[PATCH] bpf: add may_goto instruction [PR32176]

David Faust david.faust@oracle.com
Thu Feb 5 20:30:59 GMT 2026



On 2/5/26 12:01, Jose E. Marchesi wrote:
> 
> Hi David.
> Thanks for the patch.

Pushed as git bdb4d0030dedaaf18f09690218a2896ea57a4cdd
Thanks.

> 
> OK.
> 
>> 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.
>>
>> Tested on x86_64-linux-gnu for bpf-unknown-none.
>> Sanity checked building Linux kernel bpf-next selftests.
>>
>> 	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            |  6 ++++++
>>  gas/testsuite/gas/bpf/jcond-be-pseudoc.d | 14 ++++++++++++++
>>  gas/testsuite/gas/bpf/jcond-be.d         | 14 ++++++++++++++
>>  gas/testsuite/gas/bpf/jcond-pseudoc.d    | 14 ++++++++++++++
>>  gas/testsuite/gas/bpf/jcond-pseudoc.s    |  8 ++++++++
>>  gas/testsuite/gas/bpf/jcond.d            | 14 ++++++++++++++
>>  gas/testsuite/gas/bpf/jcond.s            |  8 ++++++++
>>  include/opcode/bpf.h                     |  4 ++++
>>  opcodes/bpf-opc.c                        |  4 ++++
>>  9 files changed, 86 insertions(+)
>>  create mode 100644 gas/testsuite/gas/bpf/jcond-be-pseudoc.d
>>  create mode 100644 gas/testsuite/gas/bpf/jcond-be.d
>>  create mode 100644 gas/testsuite/gas/bpf/jcond-pseudoc.d
>>  create mode 100644 gas/testsuite/gas/bpf/jcond-pseudoc.s
>>  create mode 100644 gas/testsuite/gas/bpf/jcond.d
>>  create mode 100644 gas/testsuite/gas/bpf/jcond.s
>>
>> diff --git a/gas/testsuite/gas/bpf/bpf.exp b/gas/testsuite/gas/bpf/bpf.exp
>> index 89955e1a9e4..f1932212252 100644
>> --- a/gas/testsuite/gas/bpf/bpf.exp
>> +++ b/gas/testsuite/gas/bpf/bpf.exp
>> @@ -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
>> index 00000000000..5bd24e194a7
>> --- /dev/null
>> +++ b/gas/testsuite/gas/bpf/jcond-be-pseudoc.d
>> @@ -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
>> index 00000000000..da2cfbaf481
>> --- /dev/null
>> +++ b/gas/testsuite/gas/bpf/jcond-be.d
>> @@ -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
>> index 00000000000..34c14c2bdd2
>> --- /dev/null
>> +++ b/gas/testsuite/gas/bpf/jcond-pseudoc.d
>> @@ -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
>> index 00000000000..b48ef38d97a
>> --- /dev/null
>> +++ b/gas/testsuite/gas/bpf/jcond-pseudoc.s
>> @@ -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
>> index 00000000000..69570e2f4d8
>> --- /dev/null
>> +++ b/gas/testsuite/gas/bpf/jcond.d
>> @@ -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
>> index 00000000000..9c61644ca18
>> --- /dev/null
>> +++ b/gas/testsuite/gas/bpf/jcond.s
>> @@ -0,0 +1,8 @@
>> +# Test for conditional pseudo-jump instruction
>> +    .text
>> +    jcond 1f
>> +1:
>> +    jcond 2f
>> +    jcond 1b
>> +2:
>> +    jcond 1b
>> diff --git a/include/opcode/bpf.h b/include/opcode/bpf.h
>> index d4d4f6d8557..e4ccd430f0c 100644
>> --- a/include/opcode/bpf.h
>> +++ b/include/opcode/bpf.h
>> @@ -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,
>>  };
>> diff --git a/opcodes/bpf-opc.c b/opcodes/bpf-opc.c
>> index 91ee561ea10..aa5493280ea 100644
>> --- a/opcodes/bpf-opc.c
>> +++ b/opcodes/bpf-opc.c
>> @@ -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",



More information about the Binutils mailing list