[binutils-gdb] PR 34029: bpf: add %dR/%sR register format specifiers

"Jose E. Marchesi via Binutils-cvs" <[email protected]>
Newsgroups gmane.comp.gnu.binutils.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=350f9e8adbf2a30912162437bebb4f4b7579f689

commit 350f9e8adbf2a30912162437bebb4f4b7579f689
Author: Vineet Gupta <[email protected]>
Date:   Tue Mar 31 13:42:11 2026 -0700

    PR 34029: bpf: add %dR/%sR register format specifiers
    
    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.
    
    Signed-off-by: Vineet Gupta <[email protected]>

Diff:
---
 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 ecb6c5a7053..8d48b128fb9 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, &regno);
+                  char *news = parse_bpf_register (s, rw == 'R' ? 'r' : rw,
+                                                   &regno);
 
+                  if (rw == 'R' && news == NULL)
+                    news = parse_bpf_register (s, 'w', &regno);
                   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, &regno);
+                  char *news = parse_bpf_register (s, rw == 'R' ? 'r' : rw,
+                                                   &regno);
 
+                  if (rw == 'R' && news == NULL)
+                    news = parse_bpf_register (s, 'w', &regno);
                   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 e4ccd430f0c..e17ca2fdd2c 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 de8d417dcd3..07aacb621a3 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;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.