[v2 3/4] PR 34029: bpf: add %dR/%sR register format specifiers
Jose E. Marchesi
jemarch@gnu.org
Thu Apr 2 10:58:39 GMT 2026
Hi Vineet.
> These accept either r or w prefix registers during assembly
> (pseudoc dialect), while disassembling canonically as r registers.
>
> This eliminates the need for duplicate opcode table entries for
> instructions that accept both w and r register forms.
Nicely done. Thank you for the patch.
I suppose this will be tested when the corresponding load/store
instructions get updated and their respective new tests.
OK.
>
> Signed-off-by: Vineet Gupta <vineet.gupta@linux.dev>
> ---
> gas/config/tc-bpf.c | 16 ++++++++++++----
> include/opcode/bpf.h | 4 +++-
> opcodes/bpf-dis.c | 6 ++++--
> 3 files changed, 19 insertions(+), 7 deletions(-)
>
> diff --git a/gas/config/tc-bpf.c b/gas/config/tc-bpf.c
> index ecb6c5a70535..8d48b128fb90 100644
> --- a/gas/config/tc-bpf.c
> +++ b/gas/config/tc-bpf.c
> @@ -1525,12 +1525,16 @@ md_assemble (char *str ATTRIBUTE_UNUSED)
> p += 2;
> }
> else if (strncmp (p, "%dr", 3) == 0
> - || strncmp (p, "%dw", 3) == 0)
> + || strncmp (p, "%dw", 3) == 0
> + || strncmp (p, "%dR", 3) == 0)
> {
> char rw = *(p + 2);
> uint8_t regno;
> - char *news = parse_bpf_register (s, rw, ®no);
> + char *news = parse_bpf_register (s, rw == 'R' ? 'r' : rw,
> + ®no);
>
> + if (rw == 'R' && news == NULL)
> + news = parse_bpf_register (s, 'w', ®no);
> if (news == NULL || (insn.has_dst && regno != insn.dst))
> {
> if (news != NULL)
> @@ -1546,12 +1550,16 @@ md_assemble (char *str ATTRIBUTE_UNUSED)
> p += 3;
> }
> else if (strncmp (p, "%sr", 3) == 0
> - || strncmp (p, "%sw", 3) == 0)
> + || strncmp (p, "%sw", 3) == 0
> + || strncmp (p, "%sR", 3) == 0)
> {
> char rw = *(p + 2);
> uint8_t regno;
> - char *news = parse_bpf_register (s, rw, ®no);
> + char *news = parse_bpf_register (s, rw == 'R' ? 'r' : rw,
> + ®no);
>
> + if (rw == 'R' && news == NULL)
> + news = parse_bpf_register (s, 'w', ®no);
> if (news == NULL || (insn.has_src && regno != insn.src))
> {
> if (news != NULL)
> diff --git a/include/opcode/bpf.h b/include/opcode/bpf.h
> index e4ccd430f0ce..e17ca2fdd2c1 100644
> --- a/include/opcode/bpf.h
> +++ b/include/opcode/bpf.h
> @@ -252,8 +252,10 @@ struct bpf_opcode
> %% - literal %.
> %dr - destination 64-bit register.
> %dw - destination 32-bit register.
> + %dR - destination register, either r or w prefix accepted.
> %sr - source 64-bit register.
> %sw - source 32-bit register.
> + %sR - source register, either r or w prefix accepted.
> %d32 - 32-bit signed displacement (in 64-bit words minus one.)
> %d16 - 16-bit signed displacement (in 64-bit words minus one.)
> %o16 - 16-bit signed offset (in bytes.)
> @@ -268,7 +270,7 @@ struct bpf_opcode
> denote something like `[%r3 + 10]', please use a template like `[
> %sr %o16]' instead of `[ %sr + %o16 ]'.
>
> - If %dr, %dw, %sr or %sw are found multiple times in a template,
> + If %dr, %dw, %dR, %sr, %sw or %sR are found multiple times in a template,
> they refer to the same register, i.e. `%rd = le64 %rd' denotes
> `r2 = le64 r2', but not `r2 = le64 r1'.
>
> diff --git a/opcodes/bpf-dis.c b/opcodes/bpf-dis.c
> index de8d417dcd38..07aacb621a3b 100644
> --- a/opcodes/bpf-dis.c
> +++ b/opcodes/bpf-dis.c
> @@ -215,13 +215,15 @@ print_insn_bpf (bfd_vma pc, disassemble_info *info)
> p += 2;
> }
> else if (strncmp (p, "%dr", 3) == 0
> - || strncmp (p, "%dw", 3) == 0)
> + || strncmp (p, "%dw", 3) == 0
> + || strncmp (p, "%dR", 3) == 0)
> {
> print_register (info, p, bpf_extract_dst (word, endian));
> p += 3;
> }
> else if (strncmp (p, "%sr", 3) == 0
> - || strncmp (p, "%sw", 3) == 0)
> + || strncmp (p, "%sw", 3) == 0
> + || strncmp (p, "%sR", 3) == 0)
> {
> print_register (info, p, bpf_extract_src (word, endian));
> p += 3;
More information about the Binutils
mailing list