[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, ®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 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;