* [PATCH v1] LoongArch: Add relaxation for R_LARCH_CALL36
@ 2024-03-08 9:16 mengqinggang
2024-03-08 9:28 ` mengqinggang
0 siblings, 1 reply; 2+ messages in thread
From: mengqinggang @ 2024-03-08 9:16 UTC (permalink / raw)
To: libc-alpha
Cc: adhemerval.zanella, xuchenghua, caiyinyu, chenglulu, cailulu,
xry111, i.swmail, maskray, luweining, wanglei, hejinyang,
mengqinggang
This relaxation is effective for both macro instructions (call36, tail36)
and explicit relocation instructions (pcaddu18i + jirl).
call36 f -> bl f
R_LARCH_CALL36 -> R_LARCH_B26
tail36 $t0, f -> b f
R_LARCH_CALL36 -> R_LARCH_B26
---
bfd/elfnn-loongarch.c | 59 +++++++++++++++++++
gas/config/tc-loongarch.c | 19 +++++-
gas/testsuite/gas/loongarch/medium-call.d | 7 ++-
.../relax-cfi-fde-DW_CFA_advance_loc.d | 10 ++--
.../relax-cfi-fde-DW_CFA_advance_loc.s | 4 ++
.../ld-loongarch-elf/ld-loongarch-elf.exp | 2 +
.../ld-loongarch-elf/relax-medium-call-1.d | 21 +++++++
.../ld-loongarch-elf/relax-medium-call-1.s | 43 ++++++++++++++
.../ld-loongarch-elf/relax-medium-call.d | 21 +++++++
.../ld-loongarch-elf/relax-medium-call.s | 35 +++++++++++
10 files changed, 215 insertions(+), 6 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index ee99fd7b2f8..c42052f9321 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4334,6 +4334,60 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
return true;
}
+/* call36 f -> bl f
+ tail36 $t0, f -> b f. */
+static bool
+loongarch_relax_call36 (bfd *abfd, asection *sec,
+ Elf_Internal_Rela *rel, bfd_vma symval,
+ struct bfd_link_info *info, bool *again,
+ bfd_vma max_alignment)
+{
+ bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
+ uint32_t jirl = bfd_get (32, abfd, contents + rel->r_offset + 4);
+ uint32_t rd = jirl & 0x1f;
+
+ /* This section's output_offset need to subtract the bytes of instructions
+ relaxed by the previous sections, so it needs to be updated beforehand.
+ size_input_section already took care of updating it after relaxation,
+ so we additionally update once here. */
+ sec->output_offset = sec->output_section->size;
+ bfd_vma pc = sec_addr (sec) + rel->r_offset;
+
+ /* If pc and symbol not in the same segment, add/sub segment alignment.
+ FIXME: if there are multiple readonly segments? How to determine if
+ two sections are in the same segment. */
+ if (symval > pc)
+ pc -= (max_alignment > 4 ? max_alignment : 0);
+ else if (symval < pc)
+ pc += (max_alignment > 4 ? max_alignment : 0);
+
+ const uint32_t jirl_opcode = 0x4c000000;
+
+ /* Is pcalau12i + addi.d insns? */
+ if ((ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX)
+ || ((jirl & jirl_opcode) != 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;
+
+ /* Continue next relax trip. */
+ *again = true;
+
+ const uint32_t bl = 0x54000000;
+ const uint32_t b = 0x50000000;
+
+ if (rd)
+ bfd_put (32, abfd, bl, contents + rel->r_offset);
+ else
+ bfd_put (32, abfd, b, contents + rel->r_offset);
+
+ /* Adjust relocations. */
+ rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_LARCH_B26);
+ /* Delete jirl instruction. */
+ loongarch_relax_delete_bytes (abfd, sec, rel->r_offset + 4, 4, info);
+ return true;
+}
+
/* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
static bool
loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
@@ -4752,6 +4806,11 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
}
break;
+ case R_LARCH_CALL36:
+ if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
+ loongarch_relax_call36 (abfd, sec, rel, symval, info, again,
+ max_alignment);
+ break;
case R_LARCH_TLS_LE_HI20_R:
case R_LARCH_TLS_LE_LO12_R:
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 4ba547d7bdc..0294771c50f 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -116,6 +116,8 @@ const char *md_shortopts = "O::g::G:";
static const char default_arch[] = DEFAULT_ARCH;
+static bool call36 = 0;
+
/* The lowest 4-bit is the bytes of instructions. */
#define RELAX_BRANCH_16 0xc0000014
#define RELAX_BRANCH_21 0xc0000024
@@ -720,7 +722,8 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
|| BFD_RELOC_LARCH_TLS_LE_HI20 == reloc_type
|| BFD_RELOC_LARCH_TLS_LE_LO12 == reloc_type
|| BFD_RELOC_LARCH_TLS_LE64_LO20 == reloc_type
- || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_type))
+ || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_type
+ || BFD_RELOC_LARCH_CALL36 == reloc_type))
{
ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
ip->reloc_info[ip->reloc_num].value = const_0;
@@ -1015,6 +1018,20 @@ append_fixed_insn (struct loongarch_cl_insn *insn)
char *f = frag_more (insn->insn_length);
move_insn (insn, frag_now, f - frag_now->fr_literal);
+
+ if (call36)
+ {
+ if (strcmp (insn->name, "jirl") == 0)
+ {
+ /* See comment at end of append_fixp_and_insn. */
+ frag_wane (frag_now);
+ frag_new (0);
+ }
+ call36 = 0;
+ }
+
+ if (BFD_RELOC_LARCH_CALL36 == insn->reloc_info[0].type)
+ call36 = 1;
}
/* Add instructions based on the worst-case scenario firstly. */
diff --git a/gas/testsuite/gas/loongarch/medium-call.d b/gas/testsuite/gas/loongarch/medium-call.d
index 3491760b96a..79d74ba358c 100644
--- a/gas/testsuite/gas/loongarch/medium-call.d
+++ b/gas/testsuite/gas/loongarch/medium-call.d
@@ -1,21 +1,26 @@
#as:
#objdump: -dr
+#skip: loongarch32-*-*
.*:[ ]+file format .*
Disassembly of section .text:
-.* <.text>:
+[ ]*0000000000000000 <.text>:
[ ]+0:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
[ ]+0: R_LARCH_CALL36[ ]+a
+[ ]+0: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+4:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
[ ]+8:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
[ ]+8: R_LARCH_CALL36[ ]+a
+[ ]+8: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+c:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
[ ]+10:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
[ ]+10: R_LARCH_CALL36[ ]+a
+[ ]+10: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+14:[ ]+4c000180[ ]+jr[ ]+\$t0
[ ]+18:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
[ ]+18: R_LARCH_CALL36[ ]+a
+[ ]+18: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+1c:[ ]+4c000180[ ]+jr[ ]+\$t0
diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
index 6b164cfbf61..d685bd86b51 100644
--- a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
+++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
@@ -26,7 +26,7 @@ Disassembly of section .eh_frame:
[ ]+2c:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
[ ]+2e: R_LARCH_ADD6[ ]+L0\^A
[ ]+2e: R_LARCH_SUB6[ ]+L0\^A
-[ ]+30:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300044 <L0\^A\+0x2ffffc>
+[ ]+30:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300044 <L0\^A\+0x2ffff4>
[ ]+33: R_LARCH_ADD6[ ]+L0\^A
[ ]+33: R_LARCH_SUB6[ ]+L0\^A
[ ]+34:[ ]+00160cd6[ ]+orn[ ]+\$fp, \$a2, \$sp
@@ -39,14 +39,16 @@ Disassembly of section .eh_frame:
[ ]+40:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
[ ]+42: R_LARCH_ADD6[ ]+L0\^A
[ ]+42: R_LARCH_SUB6[ ]+L0\^A
-[ ]+44:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300058 <L0\^A\+0x300010>
+[ ]+44:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300058 <L0\^A\+0x300008>
[ ]+47: R_LARCH_ADD6[ ]+L0\^A
[ ]+47: R_LARCH_SUB6[ ]+L0\^A
[ ]+48:[ ]+00160cd6[ ]+orn[ ]+\$fp, \$a2, \$sp
[ ]+4c:[ ]+160cd640[ ]+lu32i.d[ ]+\$zero, 26290
[ ]+4c: R_LARCH_ADD6[ ]+L0\^A
[ ]+4c: R_LARCH_SUB6[ ]+L0\^A
-[ ]+50:[ ]+00d64000[ ]+bstrpick.d[ ]+\$zero, \$zero, 0x16, 0x10
+[ ]+50:[ ]+0cd64000[ ]+.word[ ]+[ ]+0x0cd64000
[ ]+51: R_LARCH_ADD6[ ]+L0\^A
[ ]+51: R_LARCH_SUB6[ ]+L0\^A
-[ ]+54:[ ]+00000000[ ]+.word[ ]+[ ]+0x00000000
+[ ]+54:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
+[ ]+56: R_LARCH_ADD6[ ]+L0\^A
+[ ]+56: R_LARCH_SUB6[ ]+L0\^A
diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
index 2c67587b722..021d296a1fc 100644
--- a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
+++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
@@ -38,4 +38,8 @@ la.tls.ie $t0, a
la.tls.le $t0, a
.cfi_restore 22
+.cfi_def_cfa 22, 0
+call36 f
+.cfi_restore 22
+
.cfi_endproc
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 161cc1a4d10..c56bae91c32 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -52,6 +52,8 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "underflow_s_5_20"
run_dump_test "tls-le-norelax"
run_dump_test "tls-le-relax"
+ run_dump_test "relax-medium-call"
+ run_dump_test "relax-medium-call-1"
}
if [istarget "loongarch32-*-*"] {
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
new file mode 100644
index 00000000000..c8ee93337db
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
@@ -0,0 +1,21 @@
+#ld: -e0 -Ttext=0x120000000 --section-start=ta=0x118000000 --section-start=tb=0x127fffffc
+#objdump: -d -j .text
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+[ ]*0000000120000000 <__bss_start-0x4030>:
+[ ]+120000000:[ ]+54000200[ ]+bl[ ]+-134217728[ ]+# 118000000 <a>
+[ ]+120000004:[ ]+1fffc001[ ]+pcaddu18i[ ]+\$ra, -512
+[ ]+120000008:[ ]+4ffffc21[ ]+jirl[ ]+\$ra, \$ra, -4
+[ ]+12000000c:[ ]+50000200[ ]+b[ ]+-134217728[ ]+# 11800000c <b>
+[ ]+120000010:[ ]+1fffc00c[ ]+pcaddu18i[ ]+\$t0, -512
+[ ]+120000014:[ ]+4ffffd80[ ]+jirl[ ]+\$zero, \$t0, -4
+[ ]+120000018:[ ]+1e004001[ ]+pcaddu18i[ ]+\$ra, 512
+[ ]+12000001c:[ ]+4c000421[ ]+jirl[ ]+\$ra, \$ra, 4
+[ ]+120000020:[ ]+57fffdff[ ]+bl[ ]+134217724[ ]+# 12800001c <c>
+[ ]+120000024:[ ]+1e00400c[ ]+pcaddu18i[ ]+\$t0, 512
+[ ]+120000028:[ ]+4c000580[ ]+jirl[ ]+\$zero, \$t0, 4
+[ ]+12000002c:[ ]+53fffdff[ ]+b[ ]+134217724[ ]+# 128000028 <d>
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
new file mode 100644
index 00000000000..5266fdaba7a
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
@@ -0,0 +1,43 @@
+.section "ta", "ax"
+a:
+ ret
+ ret
+ ret
+b:
+ ret
+
+.text
+ pcaddu18i $ra, %call36(a) # min offset, can relax
+ jirl $ra, $ra, 0
+ pcaddu18i $ra, %call36(a) # overflow, not relax
+ jirl $ra, $ra, 0
+ pcaddu18i $t0, %call36(b) # min offset, can relax
+ jirl $zero, $t0, 0
+ pcaddu18i $t0, %call36(b) # overflow, not relax
+ jirl $zero, $t0, 0
+
+ pcaddu18i $ra, %call36(c) # overflow, not relax
+ jirl $ra, $ra, 0
+ pcaddu18i $ra, %call36(c) # max offset, can relax
+ jirl $ra, $ra, 0
+ pcaddu18i $t0, %call36(d) # overflow, no relax
+ jirl $zero, $t0, 0
+ pcaddu18i $t0, %call36(d) # max offset, can relax
+ jirl $zero, $t0, 0
+
+.section "tb", "ax"
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+c:
+ ret
+ ret
+ ret
+d:
+ ret
+
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call.d b/ld/testsuite/ld-loongarch-elf/relax-medium-call.d
new file mode 100644
index 00000000000..c8ee93337db
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call.d
@@ -0,0 +1,21 @@
+#ld: -e0 -Ttext=0x120000000 --section-start=ta=0x118000000 --section-start=tb=0x127fffffc
+#objdump: -d -j .text
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+[ ]*0000000120000000 <__bss_start-0x4030>:
+[ ]+120000000:[ ]+54000200[ ]+bl[ ]+-134217728[ ]+# 118000000 <a>
+[ ]+120000004:[ ]+1fffc001[ ]+pcaddu18i[ ]+\$ra, -512
+[ ]+120000008:[ ]+4ffffc21[ ]+jirl[ ]+\$ra, \$ra, -4
+[ ]+12000000c:[ ]+50000200[ ]+b[ ]+-134217728[ ]+# 11800000c <b>
+[ ]+120000010:[ ]+1fffc00c[ ]+pcaddu18i[ ]+\$t0, -512
+[ ]+120000014:[ ]+4ffffd80[ ]+jirl[ ]+\$zero, \$t0, -4
+[ ]+120000018:[ ]+1e004001[ ]+pcaddu18i[ ]+\$ra, 512
+[ ]+12000001c:[ ]+4c000421[ ]+jirl[ ]+\$ra, \$ra, 4
+[ ]+120000020:[ ]+57fffdff[ ]+bl[ ]+134217724[ ]+# 12800001c <c>
+[ ]+120000024:[ ]+1e00400c[ ]+pcaddu18i[ ]+\$t0, 512
+[ ]+120000028:[ ]+4c000580[ ]+jirl[ ]+\$zero, \$t0, 4
+[ ]+12000002c:[ ]+53fffdff[ ]+b[ ]+134217724[ ]+# 128000028 <d>
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call.s b/ld/testsuite/ld-loongarch-elf/relax-medium-call.s
new file mode 100644
index 00000000000..c0521b65732
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call.s
@@ -0,0 +1,35 @@
+.section "ta", "ax"
+a:
+ ret
+ ret
+ ret
+b:
+ ret
+
+.text
+ call36 a # min offset, can relax
+ call36 a # overflow, not relax
+ tail36 $t0, b # min offset, can relax
+ tail36 $t0, b # overflow, not relax
+
+ call36 c # overflow, not relax
+ call36 c # max offset, can relax
+ tail36 $t0, d # overflow, no relax
+ tail36 $t0, d # max offset, can relax
+
+.section "tb", "ax"
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+c:
+ ret
+ ret
+ ret
+d:
+ ret
+
--
2.36.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH v1] LoongArch: Add relaxation for R_LARCH_CALL36
2024-03-08 9:16 [PATCH v1] LoongArch: Add relaxation for R_LARCH_CALL36 mengqinggang
@ 2024-03-08 9:28 ` mengqinggang
0 siblings, 0 replies; 2+ messages in thread
From: mengqinggang @ 2024-03-08 9:28 UTC (permalink / raw)
To: libc-alpha
Cc: adhemerval.zanella, xuchenghua, caiyinyu, chenglulu, cailulu,
xry111, i.swmail, maskray, luweining, wanglei, hejinyang
I'm sorry, this patch is for binutils.
在 2024/3/8 下午5:16, mengqinggang 写道:
> This relaxation is effective for both macro instructions (call36, tail36)
> and explicit relocation instructions (pcaddu18i + jirl).
>
> call36 f -> bl f
> R_LARCH_CALL36 -> R_LARCH_B26
>
> tail36 $t0, f -> b f
> R_LARCH_CALL36 -> R_LARCH_B26
> ---
> bfd/elfnn-loongarch.c | 59 +++++++++++++++++++
> gas/config/tc-loongarch.c | 19 +++++-
> gas/testsuite/gas/loongarch/medium-call.d | 7 ++-
> .../relax-cfi-fde-DW_CFA_advance_loc.d | 10 ++--
> .../relax-cfi-fde-DW_CFA_advance_loc.s | 4 ++
> .../ld-loongarch-elf/ld-loongarch-elf.exp | 2 +
> .../ld-loongarch-elf/relax-medium-call-1.d | 21 +++++++
> .../ld-loongarch-elf/relax-medium-call-1.s | 43 ++++++++++++++
> .../ld-loongarch-elf/relax-medium-call.d | 21 +++++++
> .../ld-loongarch-elf/relax-medium-call.s | 35 +++++++++++
> 10 files changed, 215 insertions(+), 6 deletions(-)
> create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
> create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
> create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call.d
> create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call.s
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index ee99fd7b2f8..c42052f9321 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -4334,6 +4334,60 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
> return true;
> }
>
> +/* call36 f -> bl f
> + tail36 $t0, f -> b f. */
> +static bool
> +loongarch_relax_call36 (bfd *abfd, asection *sec,
> + Elf_Internal_Rela *rel, bfd_vma symval,
> + struct bfd_link_info *info, bool *again,
> + bfd_vma max_alignment)
> +{
> + bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
> + uint32_t jirl = bfd_get (32, abfd, contents + rel->r_offset + 4);
> + uint32_t rd = jirl & 0x1f;
> +
> + /* This section's output_offset need to subtract the bytes of instructions
> + relaxed by the previous sections, so it needs to be updated beforehand.
> + size_input_section already took care of updating it after relaxation,
> + so we additionally update once here. */
> + sec->output_offset = sec->output_section->size;
> + bfd_vma pc = sec_addr (sec) + rel->r_offset;
> +
> + /* If pc and symbol not in the same segment, add/sub segment alignment.
> + FIXME: if there are multiple readonly segments? How to determine if
> + two sections are in the same segment. */
> + if (symval > pc)
> + pc -= (max_alignment > 4 ? max_alignment : 0);
> + else if (symval < pc)
> + pc += (max_alignment > 4 ? max_alignment : 0);
> +
> + const uint32_t jirl_opcode = 0x4c000000;
> +
> + /* Is pcalau12i + addi.d insns? */
> + if ((ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX)
> + || ((jirl & jirl_opcode) != 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;
> +
> + /* Continue next relax trip. */
> + *again = true;
> +
> + const uint32_t bl = 0x54000000;
> + const uint32_t b = 0x50000000;
> +
> + if (rd)
> + bfd_put (32, abfd, bl, contents + rel->r_offset);
> + else
> + bfd_put (32, abfd, b, contents + rel->r_offset);
> +
> + /* Adjust relocations. */
> + rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_LARCH_B26);
> + /* Delete jirl instruction. */
> + loongarch_relax_delete_bytes (abfd, sec, rel->r_offset + 4, 4, info);
> + return true;
> +}
> +
> /* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
> static bool
> loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
> @@ -4752,6 +4806,11 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
> rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
> }
> break;
> + case R_LARCH_CALL36:
> + if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
> + loongarch_relax_call36 (abfd, sec, rel, symval, info, again,
> + max_alignment);
> + break;
>
> case R_LARCH_TLS_LE_HI20_R:
> case R_LARCH_TLS_LE_LO12_R:
> diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
> index 4ba547d7bdc..0294771c50f 100644
> --- a/gas/config/tc-loongarch.c
> +++ b/gas/config/tc-loongarch.c
> @@ -116,6 +116,8 @@ const char *md_shortopts = "O::g::G:";
>
> static const char default_arch[] = DEFAULT_ARCH;
>
> +static bool call36 = 0;
> +
> /* The lowest 4-bit is the bytes of instructions. */
> #define RELAX_BRANCH_16 0xc0000014
> #define RELAX_BRANCH_21 0xc0000024
> @@ -720,7 +722,8 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
> || BFD_RELOC_LARCH_TLS_LE_HI20 == reloc_type
> || BFD_RELOC_LARCH_TLS_LE_LO12 == reloc_type
> || BFD_RELOC_LARCH_TLS_LE64_LO20 == reloc_type
> - || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_type))
> + || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_type
> + || BFD_RELOC_LARCH_CALL36 == reloc_type))
> {
> ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
> ip->reloc_info[ip->reloc_num].value = const_0;
> @@ -1015,6 +1018,20 @@ append_fixed_insn (struct loongarch_cl_insn *insn)
>
> char *f = frag_more (insn->insn_length);
> move_insn (insn, frag_now, f - frag_now->fr_literal);
> +
> + if (call36)
> + {
> + if (strcmp (insn->name, "jirl") == 0)
> + {
> + /* See comment at end of append_fixp_and_insn. */
> + frag_wane (frag_now);
> + frag_new (0);
> + }
> + call36 = 0;
> + }
> +
> + if (BFD_RELOC_LARCH_CALL36 == insn->reloc_info[0].type)
> + call36 = 1;
> }
>
> /* Add instructions based on the worst-case scenario firstly. */
> diff --git a/gas/testsuite/gas/loongarch/medium-call.d b/gas/testsuite/gas/loongarch/medium-call.d
> index 3491760b96a..79d74ba358c 100644
> --- a/gas/testsuite/gas/loongarch/medium-call.d
> +++ b/gas/testsuite/gas/loongarch/medium-call.d
> @@ -1,21 +1,26 @@
> #as:
> #objdump: -dr
> +#skip: loongarch32-*-*
>
> .*:[ ]+file format .*
>
>
> Disassembly of section .text:
>
> -.* <.text>:
> +[ ]*0000000000000000 <.text>:
> [ ]+0:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
> [ ]+0: R_LARCH_CALL36[ ]+a
> +[ ]+0: R_LARCH_RELAX[ ]+\*ABS\*
> [ ]+4:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
> [ ]+8:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
> [ ]+8: R_LARCH_CALL36[ ]+a
> +[ ]+8: R_LARCH_RELAX[ ]+\*ABS\*
> [ ]+c:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
> [ ]+10:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
> [ ]+10: R_LARCH_CALL36[ ]+a
> +[ ]+10: R_LARCH_RELAX[ ]+\*ABS\*
> [ ]+14:[ ]+4c000180[ ]+jr[ ]+\$t0
> [ ]+18:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
> [ ]+18: R_LARCH_CALL36[ ]+a
> +[ ]+18: R_LARCH_RELAX[ ]+\*ABS\*
> [ ]+1c:[ ]+4c000180[ ]+jr[ ]+\$t0
> diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
> index 6b164cfbf61..d685bd86b51 100644
> --- a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
> +++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
> @@ -26,7 +26,7 @@ Disassembly of section .eh_frame:
> [ ]+2c:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
> [ ]+2e: R_LARCH_ADD6[ ]+L0\^A
> [ ]+2e: R_LARCH_SUB6[ ]+L0\^A
> -[ ]+30:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300044 <L0\^A\+0x2ffffc>
> +[ ]+30:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300044 <L0\^A\+0x2ffff4>
> [ ]+33: R_LARCH_ADD6[ ]+L0\^A
> [ ]+33: R_LARCH_SUB6[ ]+L0\^A
> [ ]+34:[ ]+00160cd6[ ]+orn[ ]+\$fp, \$a2, \$sp
> @@ -39,14 +39,16 @@ Disassembly of section .eh_frame:
> [ ]+40:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
> [ ]+42: R_LARCH_ADD6[ ]+L0\^A
> [ ]+42: R_LARCH_SUB6[ ]+L0\^A
> -[ ]+44:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300058 <L0\^A\+0x300010>
> +[ ]+44:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300058 <L0\^A\+0x300008>
> [ ]+47: R_LARCH_ADD6[ ]+L0\^A
> [ ]+47: R_LARCH_SUB6[ ]+L0\^A
> [ ]+48:[ ]+00160cd6[ ]+orn[ ]+\$fp, \$a2, \$sp
> [ ]+4c:[ ]+160cd640[ ]+lu32i.d[ ]+\$zero, 26290
> [ ]+4c: R_LARCH_ADD6[ ]+L0\^A
> [ ]+4c: R_LARCH_SUB6[ ]+L0\^A
> -[ ]+50:[ ]+00d64000[ ]+bstrpick.d[ ]+\$zero, \$zero, 0x16, 0x10
> +[ ]+50:[ ]+0cd64000[ ]+.word[ ]+[ ]+0x0cd64000
> [ ]+51: R_LARCH_ADD6[ ]+L0\^A
> [ ]+51: R_LARCH_SUB6[ ]+L0\^A
> -[ ]+54:[ ]+00000000[ ]+.word[ ]+[ ]+0x00000000
> +[ ]+54:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
> +[ ]+56: R_LARCH_ADD6[ ]+L0\^A
> +[ ]+56: R_LARCH_SUB6[ ]+L0\^A
> diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
> index 2c67587b722..021d296a1fc 100644
> --- a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
> +++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
> @@ -38,4 +38,8 @@ la.tls.ie $t0, a
> la.tls.le $t0, a
> .cfi_restore 22
>
> +.cfi_def_cfa 22, 0
> +call36 f
> +.cfi_restore 22
> +
> .cfi_endproc
> diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> index 161cc1a4d10..c56bae91c32 100644
> --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
> @@ -52,6 +52,8 @@ if [istarget "loongarch64-*-*"] {
> run_dump_test "underflow_s_5_20"
> run_dump_test "tls-le-norelax"
> run_dump_test "tls-le-relax"
> + run_dump_test "relax-medium-call"
> + run_dump_test "relax-medium-call-1"
> }
>
> if [istarget "loongarch32-*-*"] {
> diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
> new file mode 100644
> index 00000000000..c8ee93337db
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
> @@ -0,0 +1,21 @@
> +#ld: -e0 -Ttext=0x120000000 --section-start=ta=0x118000000 --section-start=tb=0x127fffffc
> +#objdump: -d -j .text
> +
> +.*:[ ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +[ ]*0000000120000000 <__bss_start-0x4030>:
> +[ ]+120000000:[ ]+54000200[ ]+bl[ ]+-134217728[ ]+# 118000000 <a>
> +[ ]+120000004:[ ]+1fffc001[ ]+pcaddu18i[ ]+\$ra, -512
> +[ ]+120000008:[ ]+4ffffc21[ ]+jirl[ ]+\$ra, \$ra, -4
> +[ ]+12000000c:[ ]+50000200[ ]+b[ ]+-134217728[ ]+# 11800000c <b>
> +[ ]+120000010:[ ]+1fffc00c[ ]+pcaddu18i[ ]+\$t0, -512
> +[ ]+120000014:[ ]+4ffffd80[ ]+jirl[ ]+\$zero, \$t0, -4
> +[ ]+120000018:[ ]+1e004001[ ]+pcaddu18i[ ]+\$ra, 512
> +[ ]+12000001c:[ ]+4c000421[ ]+jirl[ ]+\$ra, \$ra, 4
> +[ ]+120000020:[ ]+57fffdff[ ]+bl[ ]+134217724[ ]+# 12800001c <c>
> +[ ]+120000024:[ ]+1e00400c[ ]+pcaddu18i[ ]+\$t0, 512
> +[ ]+120000028:[ ]+4c000580[ ]+jirl[ ]+\$zero, \$t0, 4
> +[ ]+12000002c:[ ]+53fffdff[ ]+b[ ]+134217724[ ]+# 128000028 <d>
> diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
> new file mode 100644
> index 00000000000..5266fdaba7a
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
> @@ -0,0 +1,43 @@
> +.section "ta", "ax"
> +a:
> + ret
> + ret
> + ret
> +b:
> + ret
> +
> +.text
> + pcaddu18i $ra, %call36(a) # min offset, can relax
> + jirl $ra, $ra, 0
> + pcaddu18i $ra, %call36(a) # overflow, not relax
> + jirl $ra, $ra, 0
> + pcaddu18i $t0, %call36(b) # min offset, can relax
> + jirl $zero, $t0, 0
> + pcaddu18i $t0, %call36(b) # overflow, not relax
> + jirl $zero, $t0, 0
> +
> + pcaddu18i $ra, %call36(c) # overflow, not relax
> + jirl $ra, $ra, 0
> + pcaddu18i $ra, %call36(c) # max offset, can relax
> + jirl $ra, $ra, 0
> + pcaddu18i $t0, %call36(d) # overflow, no relax
> + jirl $zero, $t0, 0
> + pcaddu18i $t0, %call36(d) # max offset, can relax
> + jirl $zero, $t0, 0
> +
> +.section "tb", "ax"
> + ret
> + ret
> + ret
> + ret
> + ret
> + ret
> + ret
> + ret
> +c:
> + ret
> + ret
> + ret
> +d:
> + ret
> +
> diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call.d b/ld/testsuite/ld-loongarch-elf/relax-medium-call.d
> new file mode 100644
> index 00000000000..c8ee93337db
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call.d
> @@ -0,0 +1,21 @@
> +#ld: -e0 -Ttext=0x120000000 --section-start=ta=0x118000000 --section-start=tb=0x127fffffc
> +#objdump: -d -j .text
> +
> +.*:[ ]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +[ ]*0000000120000000 <__bss_start-0x4030>:
> +[ ]+120000000:[ ]+54000200[ ]+bl[ ]+-134217728[ ]+# 118000000 <a>
> +[ ]+120000004:[ ]+1fffc001[ ]+pcaddu18i[ ]+\$ra, -512
> +[ ]+120000008:[ ]+4ffffc21[ ]+jirl[ ]+\$ra, \$ra, -4
> +[ ]+12000000c:[ ]+50000200[ ]+b[ ]+-134217728[ ]+# 11800000c <b>
> +[ ]+120000010:[ ]+1fffc00c[ ]+pcaddu18i[ ]+\$t0, -512
> +[ ]+120000014:[ ]+4ffffd80[ ]+jirl[ ]+\$zero, \$t0, -4
> +[ ]+120000018:[ ]+1e004001[ ]+pcaddu18i[ ]+\$ra, 512
> +[ ]+12000001c:[ ]+4c000421[ ]+jirl[ ]+\$ra, \$ra, 4
> +[ ]+120000020:[ ]+57fffdff[ ]+bl[ ]+134217724[ ]+# 12800001c <c>
> +[ ]+120000024:[ ]+1e00400c[ ]+pcaddu18i[ ]+\$t0, 512
> +[ ]+120000028:[ ]+4c000580[ ]+jirl[ ]+\$zero, \$t0, 4
> +[ ]+12000002c:[ ]+53fffdff[ ]+b[ ]+134217724[ ]+# 128000028 <d>
> diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call.s b/ld/testsuite/ld-loongarch-elf/relax-medium-call.s
> new file mode 100644
> index 00000000000..c0521b65732
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call.s
> @@ -0,0 +1,35 @@
> +.section "ta", "ax"
> +a:
> + ret
> + ret
> + ret
> +b:
> + ret
> +
> +.text
> + call36 a # min offset, can relax
> + call36 a # overflow, not relax
> + tail36 $t0, b # min offset, can relax
> + tail36 $t0, b # overflow, not relax
> +
> + call36 c # overflow, not relax
> + call36 c # max offset, can relax
> + tail36 $t0, d # overflow, no relax
> + tail36 $t0, d # max offset, can relax
> +
> +.section "tb", "ax"
> + ret
> + ret
> + ret
> + ret
> + ret
> + ret
> + ret
> + ret
> +c:
> + ret
> + ret
> + ret
> +d:
> + ret
> +
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-03-08 9:28 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-08 9:16 [PATCH v1] LoongArch: Add relaxation for R_LARCH_CALL36 mengqinggang
2024-03-08 9:28 ` mengqinggang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).