Re: [PATCH v5] RISC-V: Add new relocation types for global array accesses with non-constant indices
Jiawei <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils |
|---|---|
| Message-ID | <[email protected]> |
Hi Liqin, The patch looks good to me overall. Before committing, please add the declaration of 'riscv_elf_reloc_type_lookup' to elfxx-riscv.h, since it is defined in elfxx-riscv.c and used by elfnn-riscv.c. Please also remove the temporary TODO and fix the remaining GNU comment formatting, for example: /* Make the fourth operand optional. */ BR, Jiawei On 2026/8/4 15:52, Liqin Weng wrote: > From: wengliqin <[email protected]> > > This patch introduces support for new RISC-V relocation types > (R_RISCV_BASE_IDX_*) to enable more efficient code generation for > global array accesses with non-constant array subscripts. > > New Reloc includes : > R_RISCV_BASE_IDX_LO12_I/R_RISCV_BASE_IDX_LO12_S/R_RISCV_BASE_IDX_ADD > > RISC-V PSABI specification: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/489 > > bfd/ChangeLog: > > * bfd-in2.h : Add new relocation type. > * elfnn-riscv.c : Define relocation information for new > relocation type. Convert the internal > R_RISCV_BASE_IDX_GPREL_* relocations produced by relaxation > back to their public equivalents before they can be written > out, e.g. via --emit-relocs/-r. > * elfxx-riscv.c : Add HOWTOs for new relocation type. Add > riscv_internal_reloc_map and riscv_elf_reloc_type_lookup to > map each internal-only relaxed relocation type to the > elf type that should be emitted in its place. > * libbfd.h: Regenerate. > * reloc.c: Document BFD_RELOC_RISCV_BASE_IDX_* type. > > gas/ChangeLog: > > * config/tc-riscv.c: Add support for RISC-V Base IDX relocations > * testsuite/gas/riscv/base-idx-add.s: New test for BASE_IDX*. > * testsuite/gas/riscv/base-idx-add.d: New test. > * testsuite/gas/riscv/base-idx-add.l: New test. > > include/ChangeLog: > > * elf/riscv.h: Update relocation definitions for new BASE_IDX* > Type. > > ld/ChangeLog: > > * testsuite/ld-riscv-elf/base-idx-relax-gp.s: New test source > exercising base-idx relaxation to gp. > * testsuite/ld-riscv-elf/base-idx-relax-x0.s: New test source > exercising base-idx relaxation to x0 only, covering both a > defined symbol (symL) and an undefined weak symbol referenced > with a non-zero addend (weakL+0x8). > * testsuite/ld-riscv-elf/base-idx-relax-near.ld: New linker > script placing __global_pointer$ within gp-relaxable range. > * testsuite/ld-riscv-elf/base-idx-relax-far.ld: New linker > script keeping data out of gp/x0 range so relaxation cannot > fire. > * testsuite/ld-riscv-elf/base-idx-relax-x0.ld: New linker > script exercising the x0-only relaxation path. > * testsuite/ld-riscv-elf/base-idx-relax-medlow-near.d, > testsuite/ld-riscv-elf/base-idx-relax-medlow-near-emit-relocs.d, > testsuite/ld-riscv-elf/base-idx-relax-medlow-far.d, > testsuite/ld-riscv-elf/base-idx-relax-medlow-far-emit-relocs.d, > testsuite/ld-riscv-elf/base-idx-relax-x0.d, > testsuite/ld-riscv-elf/base-idx-relax-x0-emit-relocs.d: New > dump tests covering base-idx relaxation to gp and x0 for both > defined and weak symbols, with and without --emit-relocs; > confirm the internal R_RISCV_BASE_IDX_GPREL_* relocation types > never leak into --emit-relocs output. > * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Register the new > base-idx-relax dump tests. > > opcodes/ChangeLog: > > * riscv-opc.c : add new pattern for add/shaxadd/add.uw/shxadd.uw > * riscv-dis.c (print_insn_args): Add a no-op case for the '1' > relaxation-marker operand, so that disassembling an instruction > whose only matching opcode-table row now includes it (e.g. add, > shNadd) no longer hits "undefined modifier" -- the marker > carries no encoding bits, so nothing is printed for it. > --- > This Patch update: > 1. clang-format > 2. add the weak symbol tests && remove the implement add x0, x0, zero(weak symbol > may relax gp, so remove 'add a0, a0, zero' will be implemented in the new patch) > 3. Convert the internal 'R_RISCV_BASE_IDX_GPREL_*' relocations produced > by relaxation back to their elf equivalents before they can be written > out, eg. via --emit-relocs/-r. > > bfd/bfd-in2.h | 3 + > bfd/elfnn-riscv.c | 92 +++++++++++- > bfd/elfxx-riscv.c | 138 +++++++++++++++++- > bfd/libbfd.h | 3 + > bfd/reloc.c | 6 + > gas/config/tc-riscv.c | 34 ++++- > gas/testsuite/gas/riscv/base-idx-add.d | 3 + > gas/testsuite/gas/riscv/base-idx-add.l | 10 ++ > gas/testsuite/gas/riscv/base-idx-add.s | 19 +++ > include/elf/riscv.h | 6 + > .../ld-riscv-elf/base-idx-relax-far.ld | 21 +++ > ld/testsuite/ld-riscv-elf/base-idx-relax-gp.s | 36 +++++ > .../base-idx-relax-medlow-far-emit-relocs.d | 65 +++++++++ > .../ld-riscv-elf/base-idx-relax-medlow-far.d | 29 ++++ > .../base-idx-relax-medlow-near-emit-relocs.d | 63 ++++++++ > .../ld-riscv-elf/base-idx-relax-medlow-near.d | 27 ++++ > .../ld-riscv-elf/base-idx-relax-near.ld | 22 +++ > .../base-idx-relax-x0-emit-relocs.d | 63 ++++++++ > ld/testsuite/ld-riscv-elf/base-idx-relax-x0.d | 27 ++++ > .../ld-riscv-elf/base-idx-relax-x0.ld | 28 ++++ > ld/testsuite/ld-riscv-elf/base-idx-relax-x0.s | 34 +++++ > ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 6 + > opcodes/riscv-dis.c | 6 + > opcodes/riscv-opc.c | 20 +-- > 24 files changed, 743 insertions(+), 18 deletions(-) > create mode 100644 gas/testsuite/gas/riscv/base-idx-add.d > create mode 100644 gas/testsuite/gas/riscv/base-idx-add.l > create mode 100644 gas/testsuite/gas/riscv/base-idx-add.s > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-far.ld > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-gp.s > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-far-emit-relocs.d > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-far.d > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-near-emit-relocs.d > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-near.d > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-near.ld > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-x0-emit-relocs.d > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-x0.d > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-x0.ld > create mode 100644 ld/testsuite/ld-riscv-elf/base-idx-relax-x0.s > > diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h > index d4e4f8e4375..71044bcd3f1 100644 > --- a/bfd/bfd-in2.h > +++ b/bfd/bfd-in2.h > @@ -5351,6 +5351,9 @@ enum bfd_reloc_code_real > BFD_RELOC_RISCV_TLSDESC_LOAD_LO12, > BFD_RELOC_RISCV_TLSDESC_ADD_LO12, > BFD_RELOC_RISCV_TLSDESC_CALL, > + BFD_RELOC_RISCV_BASE_IDX_LO12_I, > + BFD_RELOC_RISCV_BASE_IDX_LO12_S, > + BFD_RELOC_RISCV_BASE_IDX_ADD, > BFD_RELOC_RISCV_ALIGN, > BFD_RELOC_RISCV_RVC_BRANCH, > BFD_RELOC_RISCV_RVC_JUMP, > diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c > index d3963ec9a58..f8ed892edf3 100644 > --- a/bfd/elfnn-riscv.c > +++ b/bfd/elfnn-riscv.c > @@ -1999,7 +1999,9 @@ perform_relocation (const reloc_howto_type *howto, > break; > > case R_RISCV_LO12_I: > + case R_RISCV_BASE_IDX_LO12_I: > case R_RISCV_GPREL_I: > + case R_RISCV_BASE_IDX_GPREL_I: > case R_RISCV_TPREL_LO12_I: > case R_RISCV_TPREL_I: > case R_RISCV_PCREL_LO12_I: > @@ -2009,7 +2011,9 @@ perform_relocation (const reloc_howto_type *howto, > break; > > case R_RISCV_LO12_S: > + case R_RISCV_BASE_IDX_LO12_S: > case R_RISCV_GPREL_S: > + case R_RISCV_BASE_IDX_GPREL_S: > case R_RISCV_TPREL_LO12_S: > case R_RISCV_TPREL_S: > case R_RISCV_PCREL_LO12_S: > @@ -2130,6 +2134,8 @@ perform_relocation (const reloc_howto_type *howto, > case R_RISCV_32_PCREL: > case R_RISCV_TLS_DTPREL32: > case R_RISCV_TLS_DTPREL64: > + case R_RISCV_BASE_IDX_ADD: > + case R_RISCV_BASE_IDX_GPREL_ADD: > break; > > case R_RISCV_DELETE: > @@ -2389,6 +2395,21 @@ riscv_resolve_pcrel_lo_relocs (riscv_pcrel_relocs *p) > return true; > } > > +static void > +change_internal_relocs_to_elf_relocs (Elf_Internal_Rela *relocs, > + Elf_Internal_Rela *relend) > +{ > + Elf_Internal_Rela *rel; > + > + for (rel = relocs; rel < relend; rel++) > + { > + unsigned int r_type = ELFNN_R_TYPE (rel->r_info); > + unsigned int elf_type = riscv_elf_reloc_type_lookup (r_type); > + if (elf_type != r_type) > + rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), elf_type); > + } > +} > + > /* Relocate a RISC-V ELF section. > > The RELOCATE_SECTION function is called by the new ELF backend linker > @@ -2722,6 +2743,9 @@ riscv_elf_relocate_section (bfd *output_bfd, > case R_RISCV_HI20: > case R_RISCV_LO12_I: > case R_RISCV_LO12_S: > + case R_RISCV_BASE_IDX_LO12_I: > + case R_RISCV_BASE_IDX_LO12_S: > + case R_RISCV_BASE_IDX_ADD: > goto do_relocation; > > case R_RISCV_PCREL_HI20: > @@ -2788,6 +2812,9 @@ riscv_elf_relocate_section (bfd *output_bfd, > case R_RISCV_RVC_LUI: > case R_RISCV_LO12_I: > case R_RISCV_LO12_S: > + case R_RISCV_BASE_IDX_LO12_I: > + case R_RISCV_BASE_IDX_LO12_S: > + case R_RISCV_BASE_IDX_ADD: > case R_RISCV_SET6: > case R_RISCV_SET8: > case R_RISCV_SET16: > @@ -3089,6 +3116,48 @@ riscv_elf_relocate_section (bfd *output_bfd, > break; > } > > + case R_RISCV_BASE_IDX_GPREL_I: > + case R_RISCV_BASE_IDX_GPREL_S: > + { > + /* After relaxation, the ld/st uses (gp + index) as its base > + register, so the immediate encodes the symbol's displacement > + from gp. perform_relocation will encode the final value > + from (relocation + r_addend). */ > + bfd_vma gp = riscv_global_pointer_value (info); > + bfd_vma disp = relocation + rel->r_addend - gp; > + bool x0_base = VALID_ITYPE_IMM (relocation + rel->r_addend); > + bool gp_base = (r_type == R_RISCV_BASE_IDX_GPREL_I) > + ? VALID_ITYPE_IMM (disp) > + : VALID_STYPE_IMM (disp); > + if (!x0_base) > + { > + /* Only when gp is actually used as the base do we need to > + express the immediate as a displacement from gp. */ > + if (gp_base) > + rel->r_addend -= gp; > + else > + r = bfd_reloc_overflow; > + } > + break; > + } > + > + case R_RISCV_BASE_IDX_GPREL_ADD: > + { > + /* Rewrite rs2 of the add/shXadd instruction to use gp or x0 as the > + base register after relaxation. The same encoding change > + applies to both add and shXadd — the opcode itself is left > + intact. */ > + bfd_vma insn = bfd_getl32 (contents + rel->r_offset); > + bool x0_base = VALID_ITYPE_IMM (relocation + rel->r_addend); > + insn &= ~(OP_MASK_RS2 << OP_SH_RS2); > + if (!x0_base) > + { > + insn |= X_GP << OP_SH_RS2; > + } > + bfd_putl32 (insn, contents + rel->r_offset); > + break; > + } > + > case R_RISCV_PCREL_HI20: > absolute = riscv_zero_pcrel_hi_reloc (rel, info, pc, &relocation, > contents, howto); > @@ -3434,6 +3503,8 @@ riscv_elf_relocate_section (bfd *output_bfd, > goto out; > } > > + change_internal_relocs_to_elf_relocs (relocs, relend); > + > ret = riscv_resolve_pcrel_lo_relocs (&pcrel_relocs); > out: > riscv_free_pcrel_relocs (&pcrel_relocs); > @@ -5148,6 +5219,18 @@ _bfd_riscv_relax_lui (bfd *abfd, > rel->r_info = ELFNN_R_INFO (sym, R_RISCV_GPREL_S); > return true; > > + case R_RISCV_BASE_IDX_LO12_I: > + rel->r_info = ELFNN_R_INFO (sym, R_RISCV_BASE_IDX_GPREL_I); > + return true; > + > + case R_RISCV_BASE_IDX_LO12_S: > + rel->r_info = ELFNN_R_INFO (sym, R_RISCV_BASE_IDX_GPREL_S); > + return true; > + > + case R_RISCV_BASE_IDX_ADD: > + rel->r_info = ELFNN_R_INFO (sym, R_RISCV_BASE_IDX_GPREL_ADD); > + return true; > + > case R_RISCV_HI20: > /* Delete unnecessary LUI and reuse the reloc. */ > *again = true; > @@ -5160,7 +5243,7 @@ _bfd_riscv_relax_lui (bfd *abfd, > } > > /* Can we relax LUI to C.LUI? Alignment might move the section forward; > - account for this assuming page alignment at worst. In the presence of > + account for this assuming page alignment at worst. In the presence of > RELRO segment the linker aligns it by one page size, therefore sections > after the segment can be moved more than one page. */ > > @@ -5537,9 +5620,10 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec, > if (type == R_RISCV_CALL > || type == R_RISCV_CALL_PLT) > relax_func = _bfd_riscv_relax_call; > - else if (type == R_RISCV_HI20 > - || type == R_RISCV_LO12_I > - || type == R_RISCV_LO12_S) > + else if (type == R_RISCV_HI20 || type == R_RISCV_LO12_I > + || type == R_RISCV_LO12_S || type == R_RISCV_BASE_IDX_LO12_I > + || type == R_RISCV_BASE_IDX_LO12_S > + || type == R_RISCV_BASE_IDX_ADD) > relax_func = _bfd_riscv_relax_lui; > else if (type == R_RISCV_TPREL_HI20 > || type == R_RISCV_TPREL_ADD > diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c > index ee962b4f6f1..0db219b5521 100644 > --- a/bfd/elfxx-riscv.c > +++ b/bfd/elfxx-riscv.c > @@ -876,7 +876,63 @@ static const reloc_howto_type howto_table[] = > false, /* partial_inplace */ > 0, /* src_mask */ > ENCODE_ITYPE_IMM (-1U), /* dst_mask */ > - false) /* pcrel_offset */ > + false), /* pcrel_offset */ > + > + /* Reserved slots 66-76. */ > + EMPTY_HOWTO (66), > + EMPTY_HOWTO (67), > + EMPTY_HOWTO (68), > + EMPTY_HOWTO (69), > + EMPTY_HOWTO (70), > + EMPTY_HOWTO (71), > + EMPTY_HOWTO (72), > + EMPTY_HOWTO (73), > + EMPTY_HOWTO (74), > + EMPTY_HOWTO (75), > + EMPTY_HOWTO (76), > + > + /* Global array accesses with non-constant subscript (base + index). */ > + HOWTO (R_RISCV_BASE_IDX_LO12_I, /* type */ > + 0, /* rightshift */ > + 4, /* size */ > + 32, /* bitsize */ > + false, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_RISCV_BASE_IDX_LO12_I", /* name */ > + false, /* partial_inplace */ > + 0, /* src_mask */ > + ENCODE_ITYPE_IMM (-1U), /* dst_mask */ > + false), /* pcrel_offset */ > + > + HOWTO (R_RISCV_BASE_IDX_LO12_S, /* type */ > + 0, /* rightshift */ > + 4, /* size */ > + 32, /* bitsize */ > + false, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_RISCV_BASE_IDX_LO12_S", /* name */ > + false, /* partial_inplace */ > + 0, /* src_mask */ > + ENCODE_STYPE_IMM (-1U), /* dst_mask */ > + false), /* pcrel_offset */ > + > + HOWTO (R_RISCV_BASE_IDX_ADD, /* type */ > + 0, /* rightshift */ > + 4, /* size */ > + 32, /* bitsize */ > + false, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_RISCV_BASE_IDX_ADD", /* name */ > + false, /* partial_inplace */ > + 0, /* src_mask */ > + 0, /* dst_mask */ > + false), /* pcrel_offset */ > }; > > static const reloc_howto_type howto_table_internal[] = > @@ -961,6 +1017,50 @@ static const reloc_howto_type howto_table_internal[] = > 0, /* src_mask */ > ENCODE_STYPE_IMM (-1U), /* dst_mask */ > false), /* pcrel_offset */ > + > + /* Global array accesses with non-constant subscript (base + index), > + after relaxation. */ > + HOWTO (R_RISCV_BASE_IDX_GPREL_I, /* type */ > + 0, /* rightshift */ > + 4, /* size */ > + 32, /* bitsize */ > + false, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_RISCV_BASE_IDX_GPREL_I", /* name */ > + false, /* partial_inplace */ > + 0, /* src_mask */ > + ENCODE_ITYPE_IMM (-1U), /* dst_mask */ > + false), /* pcrel_offset */ > + > + HOWTO (R_RISCV_BASE_IDX_GPREL_S, /* type */ > + 0, /* rightshift */ > + 4, /* size */ > + 32, /* bitsize */ > + false, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_RISCV_BASE_IDX_GPREL_S", /* name */ > + false, /* partial_inplace */ > + 0, /* src_mask */ > + ENCODE_STYPE_IMM (-1U), /* dst_mask */ > + false), /* pcrel_offset */ > + > + HOWTO (R_RISCV_BASE_IDX_GPREL_ADD, /* type */ > + 0, /* rightshift */ > + 4, /* size */ > + 32, /* bitsize */ > + false, /* pc_relative */ > + 0, /* bitpos */ > + complain_overflow_dont, /* complain_on_overflow */ > + bfd_elf_generic_reloc, /* special_function */ > + "R_RISCV_BASE_IDX_GPREL_ADD", /* name */ > + false, /* partial_inplace */ > + 0, /* src_mask */ > + 0, /* dst_mask */ > + false) > }; > > /* A mapping from BFD reloc types to RISC-V ELF reloc types. */ > @@ -1023,6 +1123,26 @@ static const struct elf_reloc_map riscv_reloc_map[] = > { BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL }, > { BFD_RELOC_RISCV_SET_ULEB128, R_RISCV_SET_ULEB128 }, > { BFD_RELOC_RISCV_SUB_ULEB128, R_RISCV_SUB_ULEB128 }, > + { BFD_RELOC_RISCV_BASE_IDX_LO12_I, R_RISCV_BASE_IDX_LO12_I }, > + { BFD_RELOC_RISCV_BASE_IDX_LO12_S, R_RISCV_BASE_IDX_LO12_S }, > + { BFD_RELOC_RISCV_BASE_IDX_ADD, R_RISCV_BASE_IDX_ADD }, > +}; > + > +/* A mapping from internal-only relocation types (produced by the linker's > + relaxation passes; numbered after R_RISCV_max and never valid in an > + object file) to the elf relocation type that should be substituted > + before the type is written out, e.g. for --emit-relocs/-r output. */ > +struct internal_reloc_map > +{ > + unsigned int internal_type; > + enum elf_riscv_reloc_type elf_val; > +}; > + > +/* TODO: add another internal relocation type */ > +static const struct internal_reloc_map riscv_internal_reloc_map[] = { > + { R_RISCV_BASE_IDX_GPREL_I, R_RISCV_BASE_IDX_LO12_I }, > + { R_RISCV_BASE_IDX_GPREL_S, R_RISCV_BASE_IDX_LO12_S }, > + { R_RISCV_BASE_IDX_GPREL_ADD, R_RISCV_BASE_IDX_ADD }, > }; > > struct riscv_profiles > @@ -1059,6 +1179,22 @@ riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) > return NULL; > } > > +/* If R_TYPE is one of the internal-only relocation types produced by > + relaxation, return the elf relocation type that should be emitted > + in its place. Otherwise return R_TYPE unchanged. */ > + > +unsigned int > +riscv_elf_reloc_type_lookup (unsigned int r_type) > +{ > + unsigned int i; > + > + for (i = 0; i < ARRAY_SIZE (riscv_internal_reloc_map); i++) > + if (riscv_internal_reloc_map[i].internal_type == r_type) > + return riscv_internal_reloc_map[i].elf_val; > + > + return r_type; > +} > + > reloc_howto_type * > riscv_elf_rtype_to_howto (bfd *abfd, unsigned int r_type) > { > diff --git a/bfd/libbfd.h b/bfd/libbfd.h > index a27134dcd78..ef4f96a1747 100644 > --- a/bfd/libbfd.h > +++ b/bfd/libbfd.h > @@ -2362,6 +2362,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", > "BFD_RELOC_RISCV_TLSDESC_LOAD_LO12", > "BFD_RELOC_RISCV_TLSDESC_ADD_LO12", > "BFD_RELOC_RISCV_TLSDESC_CALL", > + "BFD_RELOC_RISCV_BASE_IDX_LO12_I", > + "BFD_RELOC_RISCV_BASE_IDX_LO12_S", > + "BFD_RELOC_RISCV_BASE_IDX_ADD", > "BFD_RELOC_RISCV_ALIGN", > "BFD_RELOC_RISCV_RVC_BRANCH", > "BFD_RELOC_RISCV_RVC_JUMP", > diff --git a/bfd/reloc.c b/bfd/reloc.c > index 98343696a33..6f6ff98c4a5 100644 > --- a/bfd/reloc.c > +++ b/bfd/reloc.c > @@ -4861,6 +4861,12 @@ ENUMX > BFD_RELOC_RISCV_TLSDESC_ADD_LO12 > ENUMX > BFD_RELOC_RISCV_TLSDESC_CALL > +ENUMX > + BFD_RELOC_RISCV_BASE_IDX_LO12_I > +ENUMX > + BFD_RELOC_RISCV_BASE_IDX_LO12_S > +ENUMX > + BFD_RELOC_RISCV_BASE_IDX_ADD > ENUMX > BFD_RELOC_RISCV_ALIGN > ENUMX > diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c > index 6bcf53832a0..11d9db0f977 100644 > --- a/gas/config/tc-riscv.c > +++ b/gas/config/tc-riscv.c > @@ -1953,9 +1953,11 @@ riscv_apply_const_reloc (bfd_reloc_code_real_type reloc_type, bfd_vma value) > return ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)); > > case BFD_RELOC_RISCV_LO12_S: > + case BFD_RELOC_RISCV_BASE_IDX_LO12_S: > return ENCODE_STYPE_IMM (value); > > case BFD_RELOC_RISCV_LO12_I: > + case BFD_RELOC_RISCV_BASE_IDX_LO12_I: > return ENCODE_ITYPE_IMM (value); > > default: > @@ -2022,7 +2024,8 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr, > if (reloc_type == BFD_RELOC_RISCV_HI20 > || reloc_type == BFD_RELOC_RISCV_PCREL_HI20 > || reloc_type == BFD_RELOC_RISCV_TPREL_HI20 > - || reloc_type == BFD_RELOC_RISCV_TPREL_ADD) > + || reloc_type == BFD_RELOC_RISCV_TPREL_ADD > + || reloc_type == BFD_RELOC_RISCV_BASE_IDX_ADD) > { > frag_wane (frag_now); > frag_new (0); > @@ -2455,6 +2458,7 @@ static const struct percent_op_match percent_op_utype[] = > static const struct percent_op_match percent_op_itype[] = > { > {"lo", BFD_RELOC_RISCV_LO12_I}, > + {"base_idx_lo", BFD_RELOC_RISCV_BASE_IDX_LO12_I}, > {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I}, > {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I}, > {"tlsdesc_load_lo", BFD_RELOC_RISCV_TLSDESC_LOAD_LO12}, > @@ -2465,6 +2469,7 @@ static const struct percent_op_match percent_op_itype[] = > static const struct percent_op_match percent_op_stype[] = > { > {"lo", BFD_RELOC_RISCV_LO12_S}, > + {"base_idx_lo", BFD_RELOC_RISCV_BASE_IDX_LO12_S}, > {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_S}, > {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_S}, > {0, 0} > @@ -2474,6 +2479,7 @@ static const struct percent_op_match percent_op_relax_only[] = > { > {"tlsdesc_call", BFD_RELOC_RISCV_TLSDESC_CALL}, > {"tprel_add", BFD_RELOC_RISCV_TPREL_ADD}, > + {"base_idx_add", BFD_RELOC_RISCV_BASE_IDX_ADD}, > {0, 0} > }; > > @@ -3644,9 +3650,23 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, > *imm_reloc = BFD_RELOC_RISCV_LO12_I; > goto load_store; > case '1': > - /* This is used for TLS relocations that acts as relaxation > - markers and do not change the instruction encoding, > - i.e. %tprel_add and %tlsdesc_call. */ > + /* This operand is a relaxation marker that does not change > + the instruction encoding, e.g. %tprel_add, %tlsdesc_call > + and %base_idx_add. It is mandatory when a literal ',' > + precedes it in the operand string (e.g. "d,s,1" for > + jalr's %tlsdesc_call), in which case that ',' is already > + consumed by the general ',' handling above and *asarg > + points straight at the marker text. It is optional when > + it directly follows another operand letter with no > + separating ',' in the operand string (e.g. "d,s,t1" on > + add/shNadd/add.uw for %base_idx_add), in which case we > + must recognise here whether it was actually given -- > + mirrors the "optional vector mask" handling of 'Vm' > + above. */ > + if (*asarg == '\0') > + continue; > + if (*asarg == ',') > + ++asarg; > p = percent_op_relax_only; > goto alu_op; > case '0': /* AMO displacement, which must be zero. */ > @@ -4687,6 +4707,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) > case BFD_RELOC_RISCV_HI20: > case BFD_RELOC_RISCV_LO12_I: > case BFD_RELOC_RISCV_LO12_S: > + case BFD_RELOC_RISCV_BASE_IDX_LO12_I: > + case BFD_RELOC_RISCV_BASE_IDX_LO12_S: > bfd_putl32 (riscv_apply_const_reloc (fixP->fx_r_type, *valP) > | bfd_getl32 (buf), buf); > if (fixP->fx_addsy == NULL) > @@ -4694,6 +4716,10 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) > relaxable = true; > break; > > + case BFD_RELOC_RISCV_BASE_IDX_ADD: > + relaxable = true; > + break; > + > case BFD_RELOC_RISCV_GOT_HI20: > /* R_RISCV_GOT_HI20 and the following R_RISCV_LO12_I are relaxable > only if it is created as a result of la or lga assembler macros. */ > diff --git a/gas/testsuite/gas/riscv/base-idx-add.d b/gas/testsuite/gas/riscv/base-idx-add.d > new file mode 100644 > index 00000000000..488ffbc1956 > --- /dev/null > +++ b/gas/testsuite/gas/riscv/base-idx-add.d > @@ -0,0 +1,3 @@ > +#as: -march=rv64imafdc_zbb_zba > +#source: base-idx-add.s > +#error_output: base-idx-add.l > diff --git a/gas/testsuite/gas/riscv/base-idx-add.l b/gas/testsuite/gas/riscv/base-idx-add.l > new file mode 100644 > index 00000000000..8321b40ccc6 > --- /dev/null > +++ b/gas/testsuite/gas/riscv/base-idx-add.l > @@ -0,0 +1,10 @@ > +.*: Assembler messages: > +.*: Error: illegal operands `amoadd.w x8,x9,%base_idx_add\(sym\)\(x10\)' > +.*: Error: illegal operands `add a5,a5,a0,0' > +.*: Error: illegal operands `sh1add a0,a0,a5,0' > +.*: Error: illegal operands `sh1add.uw a0,a0,a5,0' > +.*: Error: illegal operands `sh2add a0,a0,a5,0' > +.*: Error: illegal operands `sh2add.uw a0,a0,a5,0' > +.*: Error: illegal operands `sh3add a0,a0,a5,0' > +.*: Error: illegal operands `sh3add.uw a0,a0,a5,0' > +.*: Error: illegal operands `add.uw a0,a0,a5,0' > diff --git a/gas/testsuite/gas/riscv/base-idx-add.s b/gas/testsuite/gas/riscv/base-idx-add.s > new file mode 100644 > index 00000000000..47d1b3b5aa3 > --- /dev/null > +++ b/gas/testsuite/gas/riscv/base-idx-add.s > @@ -0,0 +1,19 @@ > +.option arch, +a > + # Don't allow base_idx_add in amoadd. > + amoadd.w x8,x9,%base_idx_add(sym)(x10) > + # Do require base_idx_add in 4-operand add. > + add a5,a5,a0,0 > + sh1add a0,a0,a5,0 > + sh1add.uw a0,a0,a5,0 > + sh2add a0,a0,a5,0 > + sh2add.uw a0,a0,a5,0 > + sh3add a0,a0,a5,0 > + sh3add.uw a0,a0,a5,0 > + add.uw a0,a0,a5,0 > + .globl sym > + .section .tbss,"awT",@nobits > + .align 2 > + .type sym, @object > + .size sym, 4 > +sym: > + .zero 4 > diff --git a/include/elf/riscv.h b/include/elf/riscv.h > index f6ca3d4acd8..a19bee4b684 100644 > --- a/include/elf/riscv.h > +++ b/include/elf/riscv.h > @@ -95,6 +95,9 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type) > RELOC_NUMBER (R_RISCV_TLSDESC_LOAD_LO12, 63) > RELOC_NUMBER (R_RISCV_TLSDESC_ADD_LO12, 64) > RELOC_NUMBER (R_RISCV_TLSDESC_CALL, 65) > + RELOC_NUMBER (R_RISCV_BASE_IDX_LO12_I, 77) > + RELOC_NUMBER (R_RISCV_BASE_IDX_LO12_S, 78) > + RELOC_NUMBER (R_RISCV_BASE_IDX_ADD, 79) > END_RELOC_NUMBERS (R_RISCV_max) > > /* Internal relocations used exclusively by the relaxation pass. */ > @@ -105,6 +108,9 @@ END_RELOC_NUMBERS (R_RISCV_max) > #define R_RISCV_GPREL_S (R_RISCV_max + 4) > #define R_RISCV_TPREL_I (R_RISCV_max + 5) > #define R_RISCV_TPREL_S (R_RISCV_max + 6) > +#define R_RISCV_BASE_IDX_GPREL_I (R_RISCV_max + 7) > +#define R_RISCV_BASE_IDX_GPREL_S (R_RISCV_max + 8) > +#define R_RISCV_BASE_IDX_GPREL_ADD (R_RISCV_max + 9) > > /* Processor specific flags for the ELF header e_flags field. */ > > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-far.ld b/ld/testsuite/ld-riscv-elf/base-idx-relax-far.ld > new file mode 100644 > index 00000000000..123f9c4cbe9 > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-far.ld > @@ -0,0 +1,21 @@ > +/* Data symbols reachable by lui/auipc+addi but far from __global_pointer$, > + so BASE_IDX gp-relaxation cannot fire. The original instruction sequence > + is preserved. */ > + > +ENTRY(_start) > +MEMORY > +{ > + rom (rx) : ORIGIN = 0x10000, LENGTH = 0x1000 > + ram (!rx) : ORIGIN = 0x100000, LENGTH = 0x1000 > +} > +SECTIONS { > + .text : { > + *(.text*) > + } >rom > + > + .data : { > + *(.data*) > + } >ram > + > + __global_pointer$ = 0x20000; > +} > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-gp.s b/ld/testsuite/ld-riscv-elf/base-idx-relax-gp.s > new file mode 100644 > index 00000000000..b157b0b79bb > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-gp.s > @@ -0,0 +1,36 @@ > + .text > + .global _start > +_start: > + > +.ifdef __medlow__ > + lui a1, %hi(symL) > + add a2, a0, a1, %base_idx_add(symL) > + add.uw a2, a0, a1, %base_idx_add(symL) > + sh1add a2, a0, a1, %base_idx_add(symL) > + sh2add a2, a0, a1, %base_idx_add(symL) > + sh3add a2, a0, a1, %base_idx_add(symL) > + sh3add.uw a2, a0, a1, %base_idx_add(symL) > + lbu a3, %base_idx_lo(symL)(a2) > + sb a3, %base_idx_lo(symL)(a2) > + > + lui a1, %hi(weakL) > + add a2, a0, a1, %base_idx_add(weakL) > + add.uw a2, a0, a1, %base_idx_add(weakL) > + sh1add a2, a0, a1, %base_idx_add(weakL) > + sh2add a2, a0, a1, %base_idx_add(weakL) > + sh3add a2, a0, a1, %base_idx_add(weakL) > + sh3add.uw a2, a0, a1, %base_idx_add(weakL) > + lbu a3, %base_idx_lo(weakL)(a2) > + sb a3, %base_idx_lo(weakL)(a2) > +.endif > + > + .size _start, .-_start > + > + .data > + .global symL > +symL: > + .dword 0x1111222233334444 > + > + .weak weakL > +weakL: > + .dword 0x5555666677778888 > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-far-emit-relocs.d b/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-far-emit-relocs.d > new file mode 100644 > index 00000000000..64a2aeb65cc > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-far-emit-relocs.d > @@ -0,0 +1,65 @@ > +#source: base-idx-relax-gp.s > +#as: -march=rv64i_zba -mabi=lp64 --defsym __medlow__=1 > +#ld: -Tbase-idx-relax-far.ld -melf64lriscv --relax --emit-relocs > +#objdump: -dr -Mno-aliases > + > +.*:[ ]+file format .* > + > + > +Disassembly of section .text: > + > +0+10000 <_start>: > +[ ]+[0-9a-f]+:[ ]+001005b7[ ]+lui[ ]+a1,0x100 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_HI20[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+00b50633[ ]+add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+08b5063b[ ]+add\.uw[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20b52633[ ]+sh1add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20b54633[ ]+sh2add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20b56633[ ]+sh3add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20b5663b[ ]+sh3add\.uw[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+00064683[ ]+lbu[ ]+a3,0\(a2\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_I[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+00d60023[ ]+sb[ ]+a3,0\(a2\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_S[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+001005b7[ ]+lui[ ]+a1,0x100 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_HI20[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+00b50633[ ]+add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+08b5063b[ ]+add\.uw[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20b52633[ ]+sh1add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20b54633[ ]+sh2add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20b56633[ ]+sh3add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20b5663b[ ]+sh3add\.uw[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+00864683[ ]+lbu[ ]+a3,8\(a2\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_I[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+00d60423[ ]+sb[ ]+a3,8\(a2\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_S[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-far.d b/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-far.d > new file mode 100644 > index 00000000000..753518183fe > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-far.d > @@ -0,0 +1,29 @@ > +#source: base-idx-relax-gp.s > +#as: -march=rv64i_zba -mabi=lp64 --defsym __medlow__=1 > +#ld: -Tbase-idx-relax-far.ld -melf64lriscv --relax > +#objdump: -d -Mno-aliases > + > +.*:[ ]+file format .* > + > + > +Disassembly of section .text: > + > +0+10000 <_start>: > +[ ]+[0-9a-f]+:[ ]+001005b7[ ]+lui[ ]+a1,0x100 > +[ ]+[0-9a-f]+:[ ]+00b50633[ ]+add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+08b5063b[ ]+add\.uw[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+20b52633[ ]+sh1add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+20b54633[ ]+sh2add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+20b56633[ ]+sh3add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+20b5663b[ ]+sh3add\.uw[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+00064683[ ]+lbu[ ]+a3,0\(a2\) > +[ ]+[0-9a-f]+:[ ]+00d60023[ ]+sb[ ]+a3,0\(a2\) > +[ ]+[0-9a-f]+:[ ]+001005b7[ ]+lui[ ]+a1,0x100 > +[ ]+[0-9a-f]+:[ ]+00b50633[ ]+add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+08b5063b[ ]+add\.uw[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+20b52633[ ]+sh1add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+20b54633[ ]+sh2add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+20b56633[ ]+sh3add[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+20b5663b[ ]+sh3add\.uw[ ]+a2,a0,a1 > +[ ]+[0-9a-f]+:[ ]+00864683[ ]+lbu[ ]+a3,8\(a2\) > +[ ]+[0-9a-f]+:[ ]+00d60423[ ]+sb[ ]+a3,8\(a2\) > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-near-emit-relocs.d b/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-near-emit-relocs.d > new file mode 100644 > index 00000000000..71caba35bb1 > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-near-emit-relocs.d > @@ -0,0 +1,63 @@ > +#source: base-idx-relax-gp.s > +#as: -march=rv64i_zba -mabi=lp64 --defsym __medlow__=1 > +#ld: -Tbase-idx-relax-near.ld -melf64lriscv --relax --emit-relocs > +#objdump: -dr -Mno-aliases > + > +.*:[ ]+file format .* > + > + > +Disassembly of section .text: > + > +0+10000 <_start>: > +[ ]+[0-9a-f]+:[ ]+00350633[ ]+add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_NONE[ ]+\*ABS\*\+0x4 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+0835063b[ ]+add\.uw[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20352633[ ]+sh1add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20354633[ ]+sh2add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20356633[ ]+sh3add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+2035663b[ ]+sh3add\.uw[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+10064683[ ]+lbu[ ]+a3,256\(a2\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_I[ ]+symL-0x20000 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+10d60023[ ]+sb[ ]+a3,256\(a2\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_S[ ]+symL-0x20000 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+00350633[ ]+add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_NONE[ ]+\*ABS\*\+0x4 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+0835063b[ ]+add\.uw[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20352633[ ]+sh1add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20354633[ ]+sh2add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20356633[ ]+sh3add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+2035663b[ ]+sh3add\.uw[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+10864683[ ]+lbu[ ]+a3,264\(a2\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_I[ ]+weakL-0x20000 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+10d60423[ ]+sb[ ]+a3,264\(a2\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_S[ ]+weakL-0x20000 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-near.d b/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-near.d > new file mode 100644 > index 00000000000..2249dcde471 > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-medlow-near.d > @@ -0,0 +1,27 @@ > +#source: base-idx-relax-gp.s > +#as: -march=rv64i_zba -mabi=lp64 --defsym __medlow__=1 > +#ld: -Tbase-idx-relax-near.ld -melf64lriscv --relax > +#objdump: -d -Mno-aliases > + > +.*:[ ]+file format .* > + > + > +Disassembly of section .text: > + > +0+10000 <_start>: > +[ ]+[0-9a-f]+:[ ]+00350633[ ]+add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+0835063b[ ]+add\.uw[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+20352633[ ]+sh1add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+20354633[ ]+sh2add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+20356633[ ]+sh3add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+2035663b[ ]+sh3add\.uw[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+10064683[ ]+lbu[ ]+a3,256\(a2\) > +[ ]+[0-9a-f]+:[ ]+10d60023[ ]+sb[ ]+a3,256\(a2\) > +[ ]+[0-9a-f]+:[ ]+00350633[ ]+add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+0835063b[ ]+add\.uw[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+20352633[ ]+sh1add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+20354633[ ]+sh2add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+20356633[ ]+sh3add[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+2035663b[ ]+sh3add\.uw[ ]+a2,a0,gp > +[ ]+[0-9a-f]+:[ ]+10864683[ ]+lbu[ ]+a3,264\(a2\) > +[ ]+[0-9a-f]+:[ ]+10d60423[ ]+sb[ ]+a3,264\(a2\) > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-near.ld b/ld/testsuite/ld-riscv-elf/base-idx-relax-near.ld > new file mode 100644 > index 00000000000..b04e15d2fb8 > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-near.ld > @@ -0,0 +1,22 @@ > +/* Data symbols sit right next to __global_pointer$ so the gp-relaxable > + range is satisfied and R_RISCV_BASE_IDX_* are fully relaxed. */ > + > +ENTRY(_start) > +MEMORY > +{ > + rom (rx) : ORIGIN = 0x10000, LENGTH = 0x1000 > + ram (!rx) : ORIGIN = 0x20000, LENGTH = 0x1000 > +} > +SECTIONS { > + .text : { > + *(.text*) > + } >rom > + > + .data : { > + __global_pointer$ = .; > + /* Pad so that symL sits at gp + 0x100, giving the relaxed > + lbu/sb a non-zero gp-relative immediate. */ > + . = . + 0x100; > + *(.data*) > + } >ram > +} > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-x0-emit-relocs.d b/ld/testsuite/ld-riscv-elf/base-idx-relax-x0-emit-relocs.d > new file mode 100644 > index 00000000000..59ca62578c7 > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-x0-emit-relocs.d > @@ -0,0 +1,63 @@ > +#source: base-idx-relax-x0.s > +#as: -march=rv64i_zba -mabi=lp64 --defsym __medlow__=1 > +#ld: -Tbase-idx-relax-x0.ld -melf64lriscv --relax --emit-relocs > +#objdump: -dr -Mno-aliases > + > +.*:[ ]+file format .* > + > + > +Disassembly of section .text: > + > +0+10000 <_start>: > +[ ]+[0-9a-f]+:[ ]+00050533[ ]+add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_NONE[ ]+\*ABS\*\+0x4 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+0805053b[ ]+add\.uw[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20052533[ ]+sh1add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20054533[ ]+sh2add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+20056533[ ]+sh3add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+2005653b[ ]+sh3add\.uw[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+10054603[ ]+lbu[ ]+a2,256\(a0\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_I[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+10c50023[ ]+sb[ ]+a2,256\(a0\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_S[ ]+symL > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\* > +[ ]+[0-9a-f]+:[ ]+00050533[ ]+add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_NONE[ ]+\*ABS\*\+0x4 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*\+0x8 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL\+0x8 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*\+0x8 > +[ ]+[0-9a-f]+:[ ]+0805053b[ ]+add\.uw[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL\+0x8 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*\+0x8 > +[ ]+[0-9a-f]+:[ ]+20052533[ ]+sh1add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL\+0x8 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*\+0x8 > +[ ]+[0-9a-f]+:[ ]+20054533[ ]+sh2add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL\+0x8 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*\+0x8 > +[ ]+[0-9a-f]+:[ ]+20056533[ ]+sh3add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL\+0x8 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*\+0x8 > +[ ]+[0-9a-f]+:[ ]+2005653b[ ]+sh3add\.uw[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_ADD[ ]+weakL\+0x8 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*\+0x8 > +[ ]+[0-9a-f]+:[ ]+00854603[ ]+lbu[ ]+a2,8\(a0\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_I[ ]+weakL\+0x8 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*\+0x8 > +[ ]+[0-9a-f]+:[ ]+00c50423[ ]+sb[ ]+a2,8\(a0\) > +[ ]+[0-9a-f]+:[ ]+R_RISCV_BASE_IDX_LO12_S[ ]+weakL\+0x8 > +[ ]+[0-9a-f]+:[ ]+R_RISCV_RELAX[ ]+\*ABS\*\+0x8 > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-x0.d b/ld/testsuite/ld-riscv-elf/base-idx-relax-x0.d > new file mode 100644 > index 00000000000..c1687ee0699 > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-x0.d > @@ -0,0 +1,27 @@ > +#source: base-idx-relax-x0.s > +#as: -march=rv64i_zba -mabi=lp64 --defsym __medlow__=1 > +#ld: -Tbase-idx-relax-x0.ld -melf64lriscv --relax > +#objdump: -d -Mno-aliases > + > +.*:[ ]+file format .* > + > + > +Disassembly of section .text: > + > +0+10000 <_start>: > +[ ]+[0-9a-f]+:[ ]+00050533[ ]+add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+0805053b[ ]+add\.uw[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+20052533[ ]+sh1add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+20054533[ ]+sh2add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+20056533[ ]+sh3add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+2005653b[ ]+sh3add\.uw[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+10054603[ ]+lbu[ ]+a2,256\(a0\) > +[ ]+[0-9a-f]+:[ ]+10c50023[ ]+sb[ ]+a2,256\(a0\) > +[ ]+[0-9a-f]+:[ ]+00050533[ ]+add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+0805053b[ ]+add\.uw[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+20052533[ ]+sh1add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+20054533[ ]+sh2add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+20056533[ ]+sh3add[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+2005653b[ ]+sh3add\.uw[ ]+a0,a0,zero > +[ ]+[0-9a-f]+:[ ]+00854603[ ]+lbu[ ]+a2,8\(a0\) > +[ ]+[0-9a-f]+:[ ]+00c50423[ ]+sb[ ]+a2,8\(a0\) > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-x0.ld b/ld/testsuite/ld-riscv-elf/base-idx-relax-x0.ld > new file mode 100644 > index 00000000000..883ebeae167 > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-x0.ld > @@ -0,0 +1,28 @@ > +/* Three base-idx-relax cases sharing one gp placement (__global_pointer$ = > + 0x1000): > + > + - symL is a defined symbol whose address (0x100) fits a 12-bit signed > + immediate directly, while its displacement from gp does not, so x0 is > + selected both at relaxation time and at final relocation time. > + > + - weakL is an undefined weak symbol referenced with a +0x8 addend, so > + both relaxation time (undefined_weak forces x0) and final relocation > + time (0 + 0x8 fits a 12-bit immediate) agree on x0. */ > + > +ENTRY(_start) > +MEMORY > +{ > + rom (rx) : ORIGIN = 0x10000, LENGTH = 0x1000 > + ram (!rx) : ORIGIN = 0x100, LENGTH = 0x1000 > +} > +SECTIONS { > + .text : { > + *(.text*) > + } >rom > + > + .data : { > + *(.data*) > + } >ram > + > + __global_pointer$ = 0x1000; > +} > diff --git a/ld/testsuite/ld-riscv-elf/base-idx-relax-x0.s b/ld/testsuite/ld-riscv-elf/base-idx-relax-x0.s > new file mode 100644 > index 00000000000..caa2fe7124f > --- /dev/null > +++ b/ld/testsuite/ld-riscv-elf/base-idx-relax-x0.s > @@ -0,0 +1,34 @@ > + .text > + .global _start > +_start: > + > +.ifdef __medlow__ > + lui a1, %hi(symL) > + add a0, a0, a1, %base_idx_add(symL) > + add.uw a0, a0, a1, %base_idx_add(symL) > + sh1add a0, a0, a1, %base_idx_add(symL) > + sh2add a0, a0, a1, %base_idx_add(symL) > + sh3add a0, a0, a1, %base_idx_add(symL) > + sh3add.uw a0, a0, a1, %base_idx_add(symL) > + lbu a2, %base_idx_lo(symL)(a0) > + sb a2, %base_idx_lo(symL)(a0) > + > + lui a1, %hi(weakL+0x8) > + add a0, a0, a1, %base_idx_add(weakL+0x8) > + add.uw a0, a0, a1, %base_idx_add(weakL+0x8) > + sh1add a0, a0, a1, %base_idx_add(weakL+0x8) > + sh2add a0, a0, a1, %base_idx_add(weakL+0x8) > + sh3add a0, a0, a1, %base_idx_add(weakL+0x8) > + sh3add.uw a0, a0, a1, %base_idx_add(weakL+0x8) > + lbu a2, %base_idx_lo(weakL+0x8)(a0) > + sb a2, %base_idx_lo(weakL+0x8)(a0) > +.endif > + > + .size _start, .-_start > + > + .data > + .global symL > +symL: > + .dword 0x1111222233334444 > + > + .weak weakL > diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp > index 8e26ccff10a..82e906503d4 100644 > --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp > +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp > @@ -154,6 +154,12 @@ if [istarget "riscv*-*-*"] { > run_dump_test "code-model-relax-medany-02" > run_dump_test "code-model-relax-medany-weakref-01" > run_dump_test "code-model-relax-medany-weakref-02" > + run_dump_test "base-idx-relax-medlow-near" > + run_dump_test "base-idx-relax-medlow-near-emit-relocs" > + run_dump_test "base-idx-relax-medlow-far" > + run_dump_test "base-idx-relax-medlow-far-emit-relocs" > + run_dump_test "base-idx-relax-x0" > + run_dump_test "base-idx-relax-x0-emit-relocs" > run_dump_test "attr-merge-arch-01" > run_dump_test "attr-merge-arch-02" > run_dump_test "attr-merge-arch-03" > diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c > index 03c8cf1e344..5a53367fdd6 100644 > --- a/opcodes/riscv-dis.c > +++ b/opcodes/riscv-dis.c > @@ -513,6 +513,12 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info > print (info->stream, dis_style_immediate, "0"); > break; > > + case '1': > + /* This is a relaxation marker operand (e.g. %tprel_add, > + %tlsdesc_call, %base_idx_add) that does not correspond to > + any encoding bits, so there is nothing to print for it. */ > + break; > + > case 'r': > print (info->stream, dis_style_register, "%s", > pd->riscv_gpr_names[EXTRACT_OPERAND (RS3, l)]); > diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c > index 54887c97880..86084dbe091 100644 > --- a/opcodes/riscv-opc.c > +++ b/opcodes/riscv-opc.c > @@ -556,8 +556,8 @@ const struct riscv_opcode riscv_opcodes[] = > {"add", 0, INSN_CLASS_ZCA, "Ct,Cc,CK", MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN, match_c_addi4spn, INSN_ALIAS }, > {"add", 0, INSN_CLASS_ZCA, "Cc,Cc,CL", MATCH_C_ADDI16SP, MASK_C_ADDI16SP, match_c_addi16sp, INSN_ALIAS }, > {"add", 0, INSN_CLASS_ZCA, "d,Cz,CV", MATCH_C_MV, MASK_C_MV, match_c_add, INSN_ALIAS }, > -{"add", 0, INSN_CLASS_I, "d,s,t", MATCH_ADD, MASK_ADD, match_opcode, 0 }, > -{"add", 0, INSN_CLASS_I, "d,s,t,1", MATCH_ADD, MASK_ADD, match_opcode, 0 }, > +/* make fourth operand (tprel_add/base_idx_add) of add an optional operand. */ > +{"add", 0, INSN_CLASS_I, "d,s,t1", MATCH_ADD, MASK_ADD, match_opcode, 0 }, > {"add", 0, INSN_CLASS_I, "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, INSN_ALIAS }, > {"la", 0, INSN_CLASS_I, "d,B", 0, (int) M_LA, match_rd_nonzero, INSN_MACRO }, > {"lla", 0, INSN_CLASS_I, "d,B", 0, (int) M_LLA, NULL, INSN_MACRO }, > @@ -1378,16 +1378,18 @@ const struct riscv_opcode riscv_opcodes[] = > {"rorw", 64, INSN_CLASS_ZBB_OR_ZBKB, "d,s,<", MATCH_RORIW, MASK_RORIW, match_opcode, INSN_ALIAS }, > > /* Zba instructions. */ > -{"sh1add", 0, INSN_CLASS_ZBA, "d,s,t", MATCH_SH1ADD, MASK_SH1ADD, match_opcode, 0 }, > -{"sh2add", 0, INSN_CLASS_ZBA, "d,s,t", MATCH_SH2ADD, MASK_SH2ADD, match_opcode, 0 }, > -{"sh3add", 0, INSN_CLASS_ZBA, "d,s,t", MATCH_SH3ADD, MASK_SH3ADD, match_opcode, 0 }, > -{"sh1add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_SH1ADD_UW, MASK_SH1ADD_UW, match_opcode, 0 }, > -{"sh2add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_SH2ADD_UW, MASK_SH2ADD_UW, match_opcode, 0 }, > -{"sh3add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_SH3ADD_UW, MASK_SH3ADD_UW, match_opcode, 0 }, > +/* make fourth operand (base_idx_add) of shxadd/shxadd.uw an optional operand. */ > +{"sh1add", 0, INSN_CLASS_ZBA, "d,s,t1", MATCH_SH1ADD, MASK_SH1ADD, match_opcode, 0 }, > +{"sh2add", 0, INSN_CLASS_ZBA, "d,s,t1", MATCH_SH2ADD, MASK_SH2ADD, match_opcode, 0 }, > +{"sh3add", 0, INSN_CLASS_ZBA, "d,s,t1", MATCH_SH3ADD, MASK_SH3ADD, match_opcode, 0 }, > +{"sh1add.uw", 64, INSN_CLASS_ZBA, "d,s,t1", MATCH_SH1ADD_UW, MASK_SH1ADD_UW, match_opcode, 0 }, > +{"sh2add.uw", 64, INSN_CLASS_ZBA, "d,s,t1", MATCH_SH2ADD_UW, MASK_SH2ADD_UW, match_opcode, 0 }, > +{"sh3add.uw", 64, INSN_CLASS_ZBA, "d,s,t1", MATCH_SH3ADD_UW, MASK_SH3ADD_UW, match_opcode, 0 }, > {"zext.w", 64, INSN_CLASS_ZCB_AND_ZBA, "Cs,Cw", MATCH_C_ZEXT_W, MASK_C_ZEXT_W, match_opcode, INSN_ALIAS }, > {"zext.w", 64, INSN_CLASS_ZBA, "d,s", MATCH_ADD_UW, MASK_ADD_UW | MASK_RS2, match_opcode, INSN_ALIAS }, > {"zext.w", 64, INSN_CLASS_I, "d,s", 0, (int) M_ZEXTW, NULL, INSN_MACRO }, > -{"add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_ADD_UW, MASK_ADD_UW, match_opcode, 0 }, > +/* make fourth operand (base_idx_add) of add.uw an optional operand. */ > +{"add.uw", 64, INSN_CLASS_ZBA, "d,s,t1", MATCH_ADD_UW, MASK_ADD_UW, match_opcode, 0 }, > {"slli.uw", 64, INSN_CLASS_ZBA, "d,s,>", MATCH_SLLI_UW, MASK_SLLI_UW, match_opcode, 0 }, > > /* Zbc or zbkc instructions. */