From: Lulu Cheng <chenglulu@loongson.cn>
To: gcc-patches@gcc.gnu.org
Cc: xry111@xry111.site, i@xen0n.name, xuchenghua@loongson.cn,
Lulu Cheng <chenglulu@loongson.cn>
Subject: [PATCH v1] LoongArch: Added code generation support for call36 function calls.
Date: Tue, 14 Nov 2023 17:45:01 +0800 [thread overview]
Message-ID: <20231114094500.8160-1-chenglulu@loongson.cn> (raw)
When compiling with '-mcmodel=medium', the function call is made through
'pcaddu18i+jirl' if binutils supports call36, otherwise the
native implementation 'pcalau12i+jirl' is used.
gcc/ChangeLog:
* config.in: Regenerate.
* config/loongarch/loongarch-opts.h (HAVE_AS_SUPPORT_CALL36): Define macro.
* config/loongarch/loongarch.cc (loongarch_legitimize_call_address):
If binutils supports call36, the function call is not split over expand.
(loongarch_option_override_internal): If use call36, then turn off fipa-ra.
* config/loongarch/loongarch.md: Add call36 generation code.
* config/loongarch/predicates.md: Likewise.
* configure: Regenerate.
* configure.ac: Check whether binutils supports call36.
---
gcc/config.in | 6 ++
gcc/config/loongarch/loongarch-opts.h | 4 +
gcc/config/loongarch/loongarch.cc | 20 +++-
gcc/config/loongarch/loongarch.md | 138 +++++++++++++++++++++-----
gcc/config/loongarch/predicates.md | 7 +-
gcc/configure | 32 ++++++
gcc/configure.ac | 6 ++
7 files changed, 182 insertions(+), 31 deletions(-)
diff --git a/gcc/config.in b/gcc/config.in
index 0509ba7e6a7..946b8fe39c7 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -775,6 +775,12 @@
#endif
+/* Define if your assembler supports call36. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_SUPPORT_CALL36
+#endif
+
+
/* Define if your assembler and linker support thread-local storage. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_TLS
diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h
index f204828015e..f1d36e8acfd 100644
--- a/gcc/config/loongarch/loongarch-opts.h
+++ b/gcc/config/loongarch/loongarch-opts.h
@@ -97,6 +97,10 @@ loongarch_update_gcc_opt_status (struct loongarch_target *target,
#define HAVE_AS_EXPLICIT_RELOCS 0
#endif
+#ifndef HAVE_AS_SUPPORT_CALL36
+#define HAVE_AS_SUPPORT_CALL36 0
+#endif
+
#ifndef HAVE_AS_MRELAX_OPTION
#define HAVE_AS_MRELAX_OPTION 0
#endif
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index c782f571abc..5c8ba96118e 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -3006,12 +3006,16 @@ loongarch_legitimize_call_address (rtx addr)
enum loongarch_symbol_type symbol_type = loongarch_classify_symbol (addr);
- /* Split function call insn 'bl sym' or 'bl %plt(sym)' to :
- pcalau12i $rd, %pc_hi20(sym)
- jr $rd, %pc_lo12(sym). */
+ /* If add the compilation option '-cmodel=medium', and the assembler does
+ not support call36. The following sequence of instructions will be
+ used for the function call:
+ pcalau12i $rd, %pc_hi20(sym)
+ jr $rd, %pc_lo12(sym)
+ */
if (TARGET_CMODEL_MEDIUM
- && TARGET_EXPLICIT_RELOCS
+ && !HAVE_AS_SUPPORT_CALL36
+ && (la_opt_explicit_relocs != EXPLICIT_RELOCS_NONE)
&& (SYMBOL_REF_P (addr) || LABEL_REF_P (addr))
&& (symbol_type == SYMBOL_PCREL
|| (symbol_type == SYMBOL_GOT_DISP && flag_plt)))
@@ -7478,8 +7482,14 @@ loongarch_option_override_internal (struct gcc_options *opts,
}
break;
- case CMODEL_TINY_STATIC:
+ /* When function calls are made through call36, t0 register will be
+ implicitly modified, so '-fno-ipa-ra' needs to be set here. */
case CMODEL_MEDIUM:
+ if (HAVE_AS_SUPPORT_CALL36)
+ opts->x_flag_ipa_ra = 0;
+ break;
+
+ case CMODEL_TINY_STATIC:
case CMODEL_NORMAL:
case CMODEL_TINY:
case CMODEL_LARGE:
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 4dd716e1941..7febb7bf8ba 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -3274,10 +3274,25 @@ (define_insn "sibcall_internal"
[(call (mem:SI (match_operand 0 "call_insn_operand" "j,c,b"))
(match_operand 1 "" ""))]
"SIBLING_CALL_P (insn)"
- "@
- jr\t%0
- b\t%0
- b\t%%plt(%0)"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "jr\t%0";
+ case 1:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r12,%%call36(%0)\n\tjirl\t$r0,$r12,0";
+ else
+ return "b\t%0";
+ case 2:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r12,%%call36(%0)\n\tjirl\t$r0,$r12,0";
+ else
+ return "b\t%%plt(%0)";
+ default:
+ gcc_unreachable ();
+ }
+}
[(set_attr "jirl" "indirect,direct,direct")])
(define_insn "@sibcall_internal_1<mode>"
@@ -3337,10 +3352,25 @@ (define_insn "sibcall_value_internal"
(call (mem:SI (match_operand 1 "call_insn_operand" "j,c,b"))
(match_operand 2 "" "")))]
"SIBLING_CALL_P (insn)"
- "@
- jr\t%1
- b\t%1
- b\t%%plt(%1)"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "jr\t%1";
+ case 1:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
+ else
+ return "b\t%1";
+ case 2:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
+ else
+ return "b\t%%plt(%1)";
+ default:
+ gcc_unreachable ();
+ }
+}
[(set_attr "jirl" "indirect,direct,direct")])
(define_insn "@sibcall_value_internal_1<mode>"
@@ -3360,10 +3390,25 @@ (define_insn "sibcall_value_multiple_internal"
(call (mem:SI (match_dup 1))
(match_dup 2)))]
"SIBLING_CALL_P (insn)"
- "@
- jr\t%1
- b\t%1
- b\t%%plt(%1)"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "jr\t%1";
+ case 1:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
+ else
+ return "b\t%1";
+ case 2:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
+ else
+ return "b\t%%plt(%1)";
+ default:
+ gcc_unreachable ();
+ }
+}
[(set_attr "jirl" "indirect,direct,direct")])
(define_insn "@sibcall_value_multiple_internal_1<mode>"
@@ -3403,10 +3448,25 @@ (define_insn "call_internal"
(match_operand 1 "" ""))
(clobber (reg:SI RETURN_ADDR_REGNUM))]
""
- "@
- jirl\t$r1,%0,0
- bl\t%0
- bl\t%%plt(%0)"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "jirl\t$r1,%0,0";
+ case 1:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r1,%%call36(%0)\n\tjirl\t$r1,$r1,0";
+ else
+ return "bl\t%0";
+ case 2:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r1,%%call36(%0)\n\tjirl\t$r1,$r1,0";
+ else
+ return "bl\t%%plt(%0)";
+ default:
+ gcc_unreachable ();
+ }
+}
[(set_attr "jirl" "indirect,direct,direct")])
(define_insn "@call_internal_1<mode>"
@@ -3465,10 +3525,25 @@ (define_insn "call_value_internal"
(match_operand 2 "" "")))
(clobber (reg:SI RETURN_ADDR_REGNUM))]
""
- "@
- jirl\t$r1,%1,0
- bl\t%1
- bl\t%%plt(%1)"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "jirl\t$r1,%1,0";
+ case 1:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
+ else
+ return "bl\t%1";
+ case 2:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
+ else
+ return "bl\t%%plt(%1)";
+ default:
+ gcc_unreachable ();
+ }
+}
[(set_attr "jirl" "indirect,direct,direct")])
(define_insn "@call_value_internal_1<mode>"
@@ -3490,10 +3565,25 @@ (define_insn "call_value_multiple_internal"
(match_dup 2)))
(clobber (reg:SI RETURN_ADDR_REGNUM))]
""
- "@
- jirl\t$r1,%1,0
- bl\t%1
- bl\t%%plt(%1)"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "jirl\t$r1,%1,0";
+ case 1:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
+ else
+ return "bl\t%1";
+ case 2:
+ if (TARGET_CMODEL_MEDIUM)
+ return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
+ else
+ return "bl\t%%plt(%1)";
+ default:
+ gcc_unreachable ();
+ }
+}
[(set_attr "jirl" "indirect,direct,direct")])
(define_insn "@call_value_multiple_internal_1<mode>"
diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md
index 946ed0d8212..56f7c48e126 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -443,7 +443,9 @@ (define_predicate "const_call_insn_operand"
{
case SYMBOL_PCREL:
if (TARGET_CMODEL_EXTREME
- || (TARGET_CMODEL_MEDIUM && !TARGET_EXPLICIT_RELOCS))
+ || (TARGET_CMODEL_MEDIUM
+ && HAVE_AS_SUPPORT_CALL36
+ && (la_opt_explicit_relocs == EXPLICIT_RELOCS_NONE)))
return false;
else
return 1;
@@ -452,7 +454,8 @@ (define_predicate "const_call_insn_operand"
if (TARGET_CMODEL_EXTREME
|| !flag_plt
|| (flag_plt && TARGET_CMODEL_MEDIUM
- && !TARGET_EXPLICIT_RELOCS))
+ && HAVE_AS_SUPPORT_CALL36
+ && (la_opt_explicit_relocs == EXPLICIT_RELOCS_NONE)))
return false;
else
return 1;
diff --git a/gcc/configure b/gcc/configure
index 0d818ae6850..d28a4536f45 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -29349,6 +29349,38 @@ if test $gcc_cv_as_loongarch_explicit_relocs = yes; then
$as_echo "#define HAVE_AS_EXPLICIT_RELOCS 1" >>confdefs.h
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for call36 support" >&5
+$as_echo_n "checking assembler for call36 support... " >&6; }
+if ${gcc_cv_as_loongarch_call36+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_loongarch_call36=no
+ if test x$gcc_cv_as != x; then
+ $as_echo 'pcaddu18i $r1, %call36(a)
+ jirl $r1, $r1, 0' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ gcc_cv_as_loongarch_call36=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_loongarch_call36" >&5
+$as_echo "$gcc_cv_as_loongarch_call36" >&6; }
+if test $gcc_cv_as_loongarch_call36 = yes; then
+
+$as_echo "#define HAVE_AS_SUPPORT_CALL36 1" >>confdefs.h
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for eh_frame pcrel encoding support" >&5
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 764a33f0b04..c489ba6a39b 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -5441,6 +5441,12 @@ x:
[a:pcalau12i $t0,%pc_hi20(a)],,
[AC_DEFINE(HAVE_AS_EXPLICIT_RELOCS, 1,
[Define if your assembler supports explicit relocation.])])
+ gcc_GAS_CHECK_FEATURE([call36 support],
+ gcc_cv_as_loongarch_call36,,
+ [pcaddu18i $r1, %call36(a)
+ jirl $r1, $r1, 0],,
+ [AC_DEFINE(HAVE_AS_SUPPORT_CALL36, 1,
+ [Define if your assembler supports call36.])])
gcc_GAS_CHECK_FEATURE([eh_frame pcrel encoding support],
gcc_cv_as_loongarch_eh_frame_pcrel_encoding_support,,
[.cfi_startproc
--
2.31.1
next reply other threads:[~2023-11-14 9:45 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-14 9:45 Lulu Cheng [this message]
2023-11-14 9:55 ` Xi Ruoyao
2023-11-14 12:46 ` chenglulu
2023-11-14 20:26 ` Xi Ruoyao
2023-11-14 20:42 ` Xi Ruoyao
2023-11-14 20:46 ` Xi Ruoyao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231114094500.8160-1-chenglulu@loongson.cn \
--to=chenglulu@loongson.cn \
--cc=gcc-patches@gcc.gnu.org \
--cc=i@xen0n.name \
--cc=xry111@xry111.site \
--cc=xuchenghua@loongson.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).