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 212EE385840E for ; Wed, 20 Mar 2024 10:07:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 212EE385840E Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 212EE385840E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1710929246; cv=none; b=ns25Vri4TGZNUf8CIrxvaMky8w632ajJSB4Wp7pwPUuUrB6IgbISr97u+1QtEukZv73NkLuRLFqUtXv7BeUZvf9YhemdRBzOwAARdQ0E2+leoy/O9NuRxcIlCfWcO8tElbWBFXuRJl2pNf5ObJVK07OfS/NuRh7guttyucETltg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1710929246; c=relaxed/simple; bh=WI1wTbAmzHjZk2XGSMEOyRktbg1hDzWE3rzRpv+SgYQ=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=SrG+hh3BeAtfohTe+ZTacyFy6KDQkqHeunInoJGRxqzGcQvUufS0t9CSvZSb5vLW8XEtLS9nuX407Hn4rIesb9//YFwgbh690HVBytuIFdNqqGxOrowZDX7Wfdz6PAWaC2NJnVgioeKlFB7zqqKdfAD1OIPkb3FfmvI/txWcvQo= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from loongson.cn (unknown [10.2.6.5]) by gateway (Coremail) with SMTP id _____8CxmehXtfplcjYbAA--.45518S3; Wed, 20 Mar 2024 18:07:20 +0800 (CST) Received: from 5.5.5 (unknown [10.2.6.5]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Cxbs1XtfplsU9eAA--.49112S2; Wed, 20 Mar 2024 18:07:19 +0800 (CST) From: mengqinggang To: binutils@sourceware.org Cc: xuchenghua@loongson.cn, chenglulu@loongson.cn, liuzhensong@loongson.cn, cailulu@loongson.cn, xry111@xry111.site, i.swmail@xen0n.name, maskray@google.com, luweining@loongson.cn, wanglei@loongson.cn, hejinyang@loongson.cn, mengqinggang@loongson.cn Subject: [PATCH v1] LoongArch: gas: Ignore .align if it is at the start of a section Date: Wed, 20 Mar 2024 18:07:18 +0800 Message-Id: <20240320100718.3033397-1-mengqinggang@loongson.cn> X-Mailer: git-send-email 2.39.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID:AQAAf8Cxbs1XtfplsU9eAA--.49112S2 X-CM-SenderInfo: 5phqw15lqjwttqj6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBj93XoWxKFWxZr18KF4fWFWfZw4UZFc_yoWfJr48p3 yUAF95Cw48JFnrGw1DK3y5XF4DKw4IgF129rWSqa40krn8Xry0qw10yrW7XFs8K3y7u3WY vr1Iv3WY9F1jyagCm3ZEXasCq-sJn29KB7ZKAUJUUUU7529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUU9Yb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r106r15M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_JFI_Gr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2kKe7AKxVWUXVWUAwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07 AIYIkI8VC2zVCFFI0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWU AVWUtwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7V AKI48JMxAIw28IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMxCIbckI1I0E14v2 6r1Y6r17MI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17 CEb7AF67AKxVWUtVW8ZwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r1xMIIF 0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIx AIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVWUJVW8JbIYCTnIWIev Ja73UjIFyTuYvjxU2NB_UUUUU X-Spam-Status: No, score=-12.8 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: Ignore .align if it is at the start of a section, the section alignment can ensure correct alignment. --- gas/config/tc-loongarch.c | 105 ++++++++++++++---- .../gas/loongarch/relax-align-first.d | 12 ++ .../gas/loongarch/relax-align-first.s | 7 ++ .../ld-loongarch-elf/relax-align-first.d | 15 +++ .../ld-loongarch-elf/relax-align-first.s | 13 +++ ld/testsuite/ld-loongarch-elf/relax.exp | 1 + 6 files changed, 133 insertions(+), 20 deletions(-) create mode 100644 gas/testsuite/gas/loongarch/relax-align-first.d create mode 100644 gas/testsuite/gas/loongarch/relax-align-first.s create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-first.d create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-first.s diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index 30aefce36fd..b009186e66f 100644 --- a/gas/config/tc-loongarch.c +++ b/gas/config/tc-loongarch.c @@ -128,6 +128,11 @@ static bool call36 = 0; #define RELAX_BRANCH_ENCODE(x) \ (BFD_RELOC_LARCH_B16 == (x) ? RELAX_BRANCH_16 : RELAX_BRANCH_21) +#define ALIGN_MAX_ADDEND(n, max) ((max << 8) | n) +#define ALIGN_MAX_NOP_BYTES(addend) ((1 << (addend & 0xff)) - 4) +#define FRAG_AT_START_OF_SECTION(frag) \ + (0 == frag->fr_address && 0 == frag->fr_fix) + enum options { OPTION_IGNORE = OPTION_MD_BASE, @@ -1647,11 +1652,22 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) } } +/* Before relax, return the fixed size of a frag to calculate address. */ + int md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED, asection *segtype ATTRIBUTE_UNUSED) { - return (fragp->fr_var = 4); + if (RELAX_BRANCH (fragp->fr_subtype)) + return (fragp->fr_var = 4); + else /* R_LARCH_ALIGN */ + if (FRAG_AT_START_OF_SECTION (fragp)) + return (fragp->fr_var = 0); + else + if (NULL == fragp->fr_symbol) + return (fragp->fr_var = fragp->fr_offset); + else + return (fragp->fr_var = ALIGN_MAX_NOP_BYTES (fragp->fr_offset)); } /* Translate internal representation of relocation info to BFD target @@ -1767,8 +1783,7 @@ bool loongarch_frag_align_code (int n, int max) { char *nops; - symbolS *s; - expressionS ex; + symbolS *s = NULL; bfd_vma insn_alignment = 4; bfd_vma bytes = (bfd_vma) 1 << n; @@ -1783,8 +1798,6 @@ loongarch_frag_align_code (int n, int max) if (!LARCH_opts.relax) return false; - nops = frag_more (worst_case_bytes); - /* If max <= 0, ignore max. If max >= worst_case_bytes, max has no effect. Similar to gas/write.c relax_segment function rs_align_code case: @@ -1795,21 +1808,22 @@ loongarch_frag_align_code (int n, int max) if (s == NULL) s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg, &zero_address_frag, 0); - ex.X_add_symbol = s; - ex.X_op = O_symbol; - ex.X_add_number = (max << 8) | n; - } - else - { - ex.X_op = O_constant; - ex.X_add_number = worst_case_bytes; } + frag_grow (worst_case_bytes); + /* Use relaxable frag for .align. + If .align at the start of section, do nothing. Section alignment can + ensure correct alignment. + If .align is not at the start of a section, reserve NOP instructions + and R_LARCH_ALIGN relocation. */ + nops = frag_var (rs_machine_dependent, worst_case_bytes, worst_case_bytes, + rs_align_code, s, + s ? (bfd_vma) ALIGN_MAX_ADDEND (n, max) : worst_case_bytes, + NULL); + + /* Default write NOP for aligned bytes. */ loongarch_make_nops (nops, worst_case_bytes); - fix_new_exp (frag_now, nops - frag_now->fr_literal, 0, - &ex, false, BFD_RELOC_LARCH_ALIGN); - /* We need to start a new frag after the alignment which may be removed by the linker, to prevent the assembler from computing static offsets. This is necessary to get correct EH info. */ @@ -1976,6 +1990,20 @@ loongarch_relax_frag (asection *sec ATTRIBUTE_UNUSED, fragp->fr_var = loongarch_relaxed_branch_length (fragp, sec, true); return fragp->fr_var - old_var; } + else if (rs_align_code == fragp->fr_subtype) + { + offsetT old_var = fragp->fr_var; + /* If .align at the start of a section, do nothing. Section alignment + * can ensure correct alignment. */ + if (FRAG_AT_START_OF_SECTION (fragp)) + fragp->fr_var = 0; + else + if (NULL == fragp->fr_symbol) + fragp->fr_var = fragp->fr_offset; + else + fragp->fr_var = ALIGN_MAX_NOP_BYTES (fragp->fr_offset); + return fragp->fr_var - old_var; + } return 0; } @@ -2051,13 +2079,50 @@ loongarch_convert_frag_branch (fragS *fragp) fragp->fr_fix += fragp->fr_var; } -/* Relax a machine dependent frag. This returns the amount by which - the current size of the frag should change. */ +/* Relax .align frag. */ + +static void +loongarch_convert_frag_align (fragS *fragp) +{ + bfd_byte *buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix; + + if (!FRAG_AT_START_OF_SECTION (fragp)) + { + expressionS exp; + exp.X_op = O_symbol; + exp.X_add_symbol = fragp->fr_symbol; + exp.X_add_number = fragp->fr_offset; + + unsigned long size = 0; + if (NULL == fragp->fr_symbol) + size = fragp->fr_offset; + else + size = ALIGN_MAX_NOP_BYTES (fragp->fr_offset); + + fixS *fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, + size, &exp, false, BFD_RELOC_LARCH_ALIGN); + fixp->fx_file = fragp->fr_file; + fixp->fx_line = fragp->fr_line; + + buf += size; + } + + gas_assert (buf == (bfd_byte *)fragp->fr_literal + + fragp->fr_fix + fragp->fr_var); + + fragp->fr_fix += fragp->fr_var; +} + +/* Relax a machine dependent frag. */ void md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED, fragS *fragp) { - gas_assert (RELAX_BRANCH (fragp->fr_subtype)); - loongarch_convert_frag_branch (fragp); + gas_assert (RELAX_BRANCH (fragp->fr_subtype) + || rs_align_code == fragp->fr_subtype); + if (RELAX_BRANCH (fragp->fr_subtype)) + loongarch_convert_frag_branch (fragp); + else if (rs_align_code == fragp->fr_subtype) + loongarch_convert_frag_align (fragp); } diff --git a/gas/testsuite/gas/loongarch/relax-align-first.d b/gas/testsuite/gas/loongarch/relax-align-first.d new file mode 100644 index 00000000000..ec0698b6995 --- /dev/null +++ b/gas/testsuite/gas/loongarch/relax-align-first.d @@ -0,0 +1,12 @@ +#as: +#objdump: -dr + +.*:[ ]+file format .* + + +Disassembly of section .text: +0* <.text>: +[ ]+0:[ ]+4c000020[ ]+ret +Disassembly of section abc: +0* : +[ ]+0:[ ]+4c000020[ ]+ret diff --git a/gas/testsuite/gas/loongarch/relax-align-first.s b/gas/testsuite/gas/loongarch/relax-align-first.s new file mode 100644 index 00000000000..a4c3d68fee3 --- /dev/null +++ b/gas/testsuite/gas/loongarch/relax-align-first.s @@ -0,0 +1,7 @@ +.text +.align 3 +ret + +.section "abc", "ax" +.align 4, ,4 +ret diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-first.d b/ld/testsuite/ld-loongarch-elf/relax-align-first.d new file mode 100644 index 00000000000..9a4fad8ea46 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relax-align-first.d @@ -0,0 +1,15 @@ +#ld: -e0 +#objdump: -d + +.*:[ ]+file format .* + + +Disassembly of section aaa: +0000000120000078 : +[ ]+120000078:[ ]+4c000020[ ]+ret +Disassembly of section bbb: +0000000120000080 : +[ ]+120000080:[ ]+4c000020[ ]+ret +Disassembly of section ccc: +0000000120000090 <__bss_start-0x4004>: +[ ]+120000090:[ ]+4c000020[ ]+ret diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-first.s b/ld/testsuite/ld-loongarch-elf/relax-align-first.s new file mode 100644 index 00000000000..0a9115b5bcf --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relax-align-first.s @@ -0,0 +1,13 @@ +# If .align at the start of a section, do not add NOP instructions +# and do not emit R_LARCH_ALIGN relocations. +# Section alignment can ensure correct alignment. +.section "aaa", "ax" +ret + +.section "bbb", "ax" +.align 3 +ret + +.section "ccc", "ax" +.align 4, ,4 +ret diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp index 7d95a9ca41d..969918955e3 100644 --- a/ld/testsuite/ld-loongarch-elf/relax.exp +++ b/ld/testsuite/ld-loongarch-elf/relax.exp @@ -20,6 +20,7 @@ # if [istarget loongarch64-*-*] { + run_dump_test "relax-align-first" if [isbuild loongarch64-*-*] { set testname "loongarch relax .exe build" -- 2.36.0