[PATCH v5] RISC-V: Add new relocation types for global array accesses with non-constant indices
Jiawei
jiawei@iscas.ac.cn
Wed Aug 5 13:13:04 GMT 2026
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 <liqin.weng@spacemit.com>
>
> 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. */
More information about the Binutils
mailing list