From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 7CC9C3857723 for ; Tue, 11 Jul 2023 08:49:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7CC9C3857723 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [111.9.175.10]) by gateway (Coremail) with SMTP id _____8Dx_+ugF61kinADAA--.8873S3; Tue, 11 Jul 2023 16:49:36 +0800 (CST) Received: from localhost.localdomain (unknown [111.9.175.10]) by localhost.localdomain (Coremail) with SMTP id AQAAf8AxjiOcF61kDGkoAA--.8841S3; Tue, 11 Jul 2023 16:49:35 +0800 (CST) From: Jinyang He To: Chenghua Xu , Zhensong Liu , mengqinggang , WANG Xuerui Cc: binutils@sourceware.org, Xing Li , yala , Peng Fan Subject: [PATCH 2/2] LoongArch: bfd: Add counter to get real relax region Date: Tue, 11 Jul 2023 16:49:31 +0800 Message-Id: <20230711084931.18978-2-hejinyang@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20230711084931.18978-1-hejinyang@loongson.cn> References: <20230711084931.18978-1-hejinyang@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID:AQAAf8AxjiOcF61kDGkoAA--.8841S3 X-CM-SenderInfo: pkhmx0p1dqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBj93XoWxKF1UWr47GFy5AFW3Ww48AFc_yoW3WFyrp3 sxZrWrKF48AFn7GrnxC3y3uwn5Xwn7GFyfZa43t34IkrsYqry8Xr10yry3WF45G3y5Wr1f Zw10qw15uF1kAwcCm3ZEXasCq-sJn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUkYb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r106r15M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Jr0_Gr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVWxJr0_GcWle2I262IYc4CY6c8Ij28IcVAaY2xG8wAqjxCEc2xF0cIa020Ex4CE44I27w Aqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_Jrv_JF1lYx0Ex4A2jsIE 14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04k20xvY0x 0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E 7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFylIxkGc2Ij64vIr41lIxAIcV C0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr1lIxAIcVCF 04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7 CjxVAFwI0_Jr0_GrUvcSsGvfC2KfnxnUUI43ZEXa7IU8r9N3UUUUU== X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00,GIT_PATCH_0,KAM_DMARC_STATUS,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: The relax action, loongarch_relax_pcala_addi and loongarch_relax_align, may reduce the pc value of later instructions. Add counter to count the number of bytes or instructions deleted. And recalculate the relax region in loongarch_relax_pcala_addi. bfd/ChangeLog: * elfnn-loongarch.c (loongarch_elf_relax_section): Add vars to count the deleted instructions and the maximum number of instructions that may be deleted due to R_LARCH_ALIGN. (loongarch_relax_pcala_addi): Adjust the relax decision range. ld/ChangeLog: * testsuite/ld-loongarch-elf/relax.exp: Add test. * testsuite/ld-loongarch-elf/relax-edge1.s: New test. * testsuite/ld-loongarch-elf/relax-edge2.s: New test. * testsuite/ld-loongarch-elf/relax-edge1.dd: New test. * testsuite/ld-loongarch-elf/relax-edge2.dd: New test. --- bfd/elfnn-loongarch.c | 31 +++++++++++++++----- ld/testsuite/ld-loongarch-elf/relax-edge1.dd | 6 ++++ ld/testsuite/ld-loongarch-elf/relax-edge1.s | 25 ++++++++++++++++ ld/testsuite/ld-loongarch-elf/relax-edge2.dd | 8 +++++ ld/testsuite/ld-loongarch-elf/relax-edge2.s | 15 ++++++++++ ld/testsuite/ld-loongarch-elf/relax.exp | 20 +++++++++++++ 6 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 ld/testsuite/ld-loongarch-elf/relax-edge1.dd create mode 100644 ld/testsuite/ld-loongarch-elf/relax-edge1.s create mode 100644 ld/testsuite/ld-loongarch-elf/relax-edge2.dd create mode 100644 ld/testsuite/ld-loongarch-elf/relax-edge2.s diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index 01f349a24..52f8ab764 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -3700,16 +3700,19 @@ loongarch_relax_delete_bytes (bfd *abfd, /* Relax pcalau12i,addi.d => pcaddi. */ static bool loongarch_relax_pcala_addi (bfd *abfd, asection *sec, - Elf_Internal_Rela *rel_hi, bfd_vma symval) + Elf_Internal_Rela *rel_hi, bfd_vma symval, + uint32_t align_max_deleted, uint32_t *pcnt_deleted) { bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; Elf_Internal_Rela *rel_lo = rel_hi + 2; uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset); uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset); uint32_t rd = pca & 0x1f; - bfd_vma pc = sec_addr (sec) + rel_hi->r_offset; + bfd_vma pc = sec_addr (sec) + rel_hi->r_offset - *pcnt_deleted * 4; const uint32_t addi_d = 0x02c00000; const uint32_t pcaddi = 0x18000000; + bfd_signed_vma low = (bfd_signed_vma)(int32_t)0xffe00000; + bfd_signed_vma high = (bfd_signed_vma)(int32_t)0x1ffffc - align_max_deleted; /* Is pcalau12i + addi.d insns? */ if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12) @@ -3722,8 +3725,8 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, || (((add >> 5) & 0x1f) != rd) /* Can be relaxed to pcaddi? */ || (symval & 0x3) /* 4 bytes align. */ - || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000) - || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc)) + || ((bfd_signed_vma)(symval - pc) < low) + || ((bfd_signed_vma)(symval - pc) > high)) return false; pca = pcaddi | rd; @@ -3734,6 +3737,7 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, R_LARCH_PCREL20_S2); rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info), R_LARCH_DELETE); + (*pcnt_deleted) += 1; return true; } @@ -3840,6 +3844,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, struct bfd_elf_section_data *data = elf_section_data (sec); Elf_Internal_Rela *relocs; *again = false; + uint32_t cnt_deleted = 0, align_max_deleted = 0; if (bfd_link_relocatable (info) || sec->sec_flg0 @@ -3881,6 +3886,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, bool local_got = false; char symtype; struct elf_link_hash_entry *h = NULL; + bool relaxed = false; if (r_symndx < symtab_hdr->sh_info) { @@ -3954,6 +3960,8 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, case R_LARCH_ALIGN: if (2 == info->relax_pass) loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval); + else if (0 == info->relax_pass) + align_max_deleted += rel->r_addend; break; case R_LARCH_DELETE: if (info->relax_pass == 1) @@ -3961,23 +3969,32 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info); rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE); } + else if (0 == info->relax_pass) + cnt_deleted += 1; break; case R_LARCH_PCALA_HI20: if (info->relax_pass == 0) { if (i + 4 > sec->reloc_count) break; - loongarch_relax_pcala_addi (abfd, sec, rel, symval); + relaxed = loongarch_relax_pcala_addi (abfd, sec, rel, symval, + align_max_deleted, &cnt_deleted); + /* Skip the next R_LARCH_{RELAX, PCALA_LO12, RELAX} relocs. */ + if (relaxed) + i += 3; } break; case R_LARCH_GOT_PC_HI20: - if (local_got) + if (info->relax_pass == 0 && local_got) { if (i + 4 > sec->reloc_count) break; if (loongarch_relax_pcala_ld (abfd, sec, rel)) { - loongarch_relax_pcala_addi (abfd, sec, rel, symval); + relaxed = loongarch_relax_pcala_addi (abfd, sec, rel, symval, + align_max_deleted, &cnt_deleted); + if (relaxed) + i += 3; } } break; diff --git a/ld/testsuite/ld-loongarch-elf/relax-edge1.dd b/ld/testsuite/ld-loongarch-elf/relax-edge1.dd new file mode 100644 index 000000000..92836e679 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relax-edge1.dd @@ -0,0 +1,6 @@ +#... +.*pcaddi.* +.*pcalau12i.* +.*addi.* +.*pcaddi.* +#pass diff --git a/ld/testsuite/ld-loongarch-elf/relax-edge1.s b/ld/testsuite/ld-loongarch-elf/relax-edge1.s new file mode 100644 index 000000000..df16c1384 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relax-edge1.s @@ -0,0 +1,25 @@ + .data + .type obj1, @object +obj1: + .word 0 + .size obj1, .-obj1 + + .space 8 + + .type obj2, @object +obj2: + .word 0 + .size obj2, .-obj2 + + .text +main: + la.local $a0, obj1 + la.local $a0, obj3 + la.local $a0, obj2 + + .bss + .space 0x4 + .type obj3, @object +obj3: + .word 0 + .size obj3, .-obj3 diff --git a/ld/testsuite/ld-loongarch-elf/relax-edge2.dd b/ld/testsuite/ld-loongarch-elf/relax-edge2.dd new file mode 100644 index 000000000..5610cc8ed --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relax-edge2.dd @@ -0,0 +1,8 @@ +#... +.*nop.* +.*nop.* +.*nop.* +.*nop.* +.*pcalau12i.* +.*addi.* +#pass diff --git a/ld/testsuite/ld-loongarch-elf/relax-edge2.s b/ld/testsuite/ld-loongarch-elf/relax-edge2.s new file mode 100644 index 000000000..c2a42e705 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relax-edge2.s @@ -0,0 +1,15 @@ + .text +main: + nop + nop + nop + nop + .align 4 + la.local $a0, obj1 + + .data + .space 0x10 + .type obj1, @object +obj1: + .word 0 + .size obj1, .-obj1 diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp index d2bb967c6..19ade4970 100644 --- a/ld/testsuite/ld-loongarch-elf/relax.exp +++ b/ld/testsuite/ld-loongarch-elf/relax.exp @@ -43,6 +43,26 @@ if [istarget loongarch64-*-*] { ] \ "relax" \ ] \ + [list \ + "relax-edge1" \ + "-e 0 -Ttext 0x400000 -Tdata 0x200000 -Tbss 0x600000" "" \ + "" \ + {relax-edge1.s} \ + [list \ + [list objdump -d relax-edge1.dd] \ + ] \ + "relax-edge1" \ + ] \ + [list \ + "relax-edge2" \ + "-e 0 -Ttext 0x400000 -Tdata 0x600000" "" \ + "" \ + {relax-edge2.s} \ + [list \ + [list objdump -d relax-edge2.dd] \ + ] \ + "relax-edge2" \ + ] \ ] set objdump_flags "-s -j .data" -- 2.33.0