[PATCH v4] LoongArch: get the opcode of instruction approriately

Jinyang He hejinyang@loongson.cn
Fri Aug 2 02:11:47 GMT 2024


On 2024-08-02 09:47, Xin Wang wrote:

> ---
>   bfd/elfnn-loongarch.c      | 10 +++++-----
>   include/opcode/loongarch.h |  4 ++++
>   2 files changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index db6d419a052..ea0477635b3 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -4061,7 +4061,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
>   	  /* For 2G jump, generate pcalau12i, jirl.  */
>   	  /* If use jirl, turns to R_LARCH_B16.  */
>   	  uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
> -	  if ((insn & 0x4c000000) == 0x4c000000)
> +	  if ((insn & LARCH_BRANCH_OPCODE_MASK) == 0x4c000000)
>   	    {
>   	      relocation &= 0xfff;
>   	      /* Signed extend.  */
> @@ -4965,7 +4965,7 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
>         || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
>         || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
>         || (rel_hi->r_offset + 4 != rel_lo->r_offset)
> -      || ((add & addi_d) != addi_d)
> +      || ((add & LARCH_ADDI_OPCODE_MASK) != addi_d)
>         /* Is pcalau12i $rd + addi.d $rd,$rd?  */
>         || ((add & 0x1f) != rd)
>         || (((add >> 5) & 0x1f) != rd)
> @@ -5026,7 +5026,7 @@ loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
>   
>     /* Is pcalau12i + addi.d insns?  */
>     if ((ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX)
> -      || ((jirl & jirl_opcode) != jirl_opcode)
> +      || ((jirl & LARCH_BRANCH_OPCODE_MASK) != jirl_opcode)
>         || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xf8000000)
>         || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x7fffffc))
>       return false;
> @@ -5068,7 +5068,7 @@ loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
>         || (rel_hi->r_offset + 4 != rel_lo->r_offset)
>         || ((ld & 0x1f) != rd)
>         || (((ld >> 5) & 0x1f) != rd)
> -      || ((ld & ld_d) != ld_d))
> +      || ((ld & LARCH_LD_OPCODE_MASK) != ld_d))
>       return false;
>   
>     addi_d = addi_d | (rd << 5) | rd;
> @@ -5191,7 +5191,7 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
>         || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
>         || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
>         || (rel_hi->r_offset + 4 != rel_lo->r_offset)
> -      || ((add & addi_d) != addi_d)
> +      || ((add & LARCH_ADDI_OPCODE_MASK) != addi_d)
>         /* Is pcalau12i $rd + addi.d $rd,$rd?  */
>         || ((add & 0x1f) != rd)
>         || (((add >> 5) & 0x1f) != rd)
> diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
> index 965a164307f..ee989ff5bf2 100644
> --- a/include/opcode/loongarch.h
> +++ b/include/opcode/loongarch.h
> @@ -36,6 +36,10 @@ extern "C"
>     #define LARCH_BRANCH_INVERT_BIT 0x04000000
>     #define LARCH_FLOAT_BRANCH_INVERT_BIT 0x00000100
>   
> +  // addi/ld mask
> +  #define LARCH_ADDI_OPCODE_MASK 0xffc00000
> +  #define LARCH_LD_OPCODE_MASK 0xffc00000

As there are so many op-check operations with format like
"(insn & mask) == op", I'd suggest we can provide a macro like follows
to make these codes regular.

#define LARCH_MK_ADDI_D 0xffc00000
#define LARCH_OP_ADDI_D 0x02c00000
#define LARCH_INSN_OPS(insn, op) ((insn & LARCH_MK_##op) == LARCH_OP_##op)
#define LARCH_INSN_ADDI_D(insn) LARCH_INSN_OPS((insn), ADDI_D)

Thanks,
Jinyang
> +
>     #define ENCODE_BRANCH16_IMM(x) (((x) >> 2) << 10)
>   
>     #define OUT_OF_RANGE(value, bits, align)	\



More information about the Binutils mailing list