gcc/ChangeLog:
* config/loongarch/loongarch.cc (loongarch_call_tls_get_addr): Use
call30
for __tls_get_addr on LA32 and adjust indentation.
* config/loongarch/loongarch.md: Add call30.
* config/loongarch/predicates.md: Return true for
const_call_insn_operand
on LA32.
---
gcc/config/loongarch/loongarch.cc | 27 +++++++-------
gcc/config/loongarch/loongarch.md | 60 ++++++++++++++++++++++++------
gcc/config/loongarch/predicates.md | 4 ++
3 files changed, 66 insertions(+), 25 deletions(-)
diff --git a/gcc/config/loongarch/loongarch.cc
b/gcc/config/loongarch/loongarch.cc
index f54cd4cc054..44e97e6fc86 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2950,19 +2950,20 @@ loongarch_call_tls_get_addr (rtx sym, enum
loongarch_symbol_type type, rtx v0)
{
rtx call;
- if (HAVE_AS_SUPPORT_CALL36)
- call = gen_call_value_internal (v0, loongarch_tls_symbol,
- const0_rtx);
- else
- {
- rtx reg = gen_reg_rtx (Pmode);
- emit_insn (gen_pcalau12i (Pmode, reg,
- loongarch_tls_symbol));
- call = gen_call_value_internal_1 (Pmode, v0, reg,
- loongarch_tls_symbol,
- const0_rtx);
- }
- insn = emit_call_insn (call);
+ /* !TARGET_64BIT always support call30. */
+ if (HAVE_AS_SUPPORT_CALL36 || !TARGET_64BIT)
+ call = gen_call_value_internal (v0, loongarch_tls_symbol,
+ const0_rtx);
+ else
+ {
+ rtx reg = gen_reg_rtx (Pmode);
+ emit_insn (gen_pcalau12i (Pmode, reg,
+ loongarch_tls_symbol));
+ call = gen_call_value_internal_1 (Pmode, v0, reg,
+ loongarch_tls_symbol,
+ const0_rtx);
+ }
+ insn = emit_call_insn (call);
}
else
{
diff --git a/gcc/config/loongarch/loongarch.md
b/gcc/config/loongarch/loongarch.md
index f3bcea2cb4e..eaad21c400b 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -4033,12 +4033,18 @@ (define_insn "sibcall_internal"
return "jr\t%0";
case 1:
if (TARGET_CMODEL_MEDIUM)
- return "pcaddu18i\t$r12,%%call36(%0)\n\tjirl\t$r0,$r12,0";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r12,%%call36(%0)\n\tjirl\t$r0,$r12,0";
+ else
+ return "pcaddu12i\t$r12,%%call30(%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";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r12,%%call36(%0)\n\tjirl\t$r0,$r12,0";
+ else
+ return "pcaddu12i\t$r12,%%call30(%0)\n\tjirl\t$r0,$r12,0";
else
return "b\t%%plt(%0)";
default:
@@ -4126,12 +4132,18 @@ (define_insn "sibcall_value_internal"
return "jr\t%1";
case 1:
if (TARGET_CMODEL_MEDIUM)
- return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
+ else
+ return "pcaddu12i\t$r12,%%call30(%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";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
+ else
+ return "pcaddu12i\t$r12,%%call30(%1)\n\tjirl\t$r0,$r12,0";
else
return "b\t%%plt(%1)";
default:
@@ -4164,12 +4176,18 @@ (define_insn "sibcall_value_multiple_internal"
return "jr\t%1";
case 1:
if (TARGET_CMODEL_MEDIUM)
- return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
+ else
+ return "pcaddu12i\t$r12,%%call30(%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";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
+ else
+ return "pcaddu12i\t$r12,%%call30(%1)\n\tjirl\t$r0,$r12,0";
else
return "b\t%%plt(%1)";
default:
@@ -4222,12 +4240,18 @@ (define_insn "call_internal"
return "jirl\t$r1,%0,0";
case 1:
if (TARGET_CMODEL_MEDIUM)
- return "pcaddu18i\t$r1,%%call36(%0)\n\tjirl\t$r1,$r1,0";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r1,%%call36(%0)\n\tjirl\t$r1,$r1,0";
+ else
+ return "pcaddu12i\t$r1,%%call30(%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";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r1,%%call36(%0)\n\tjirl\t$r1,$r1,0";
+ else
+ return "pcaddu12i\t$r1,%%call30(%0)\n\tjirl\t$r1,$r1,0";
else
return "bl\t%%plt(%0)";
default:
@@ -4299,12 +4323,18 @@ (define_insn "call_value_internal"
return "jirl\t$r1,%1,0";
case 1:
if (TARGET_CMODEL_MEDIUM)
- return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
+ else
+ return "pcaddu12i\t$r1,%%call30(%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";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
+ else
+ return "pcaddu12i\t$r1,%%call30(%1)\n\tjirl\t$r1,$r1,0";
else
return "bl\t%%plt(%1)";
default:
@@ -4339,12 +4369,18 @@ (define_insn "call_value_multiple_internal"
return "jirl\t$r1,%1,0";
case 1:
if (TARGET_CMODEL_MEDIUM)
- return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
+ else
+ return "pcaddu12i\t$r1,%%call30(%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";
+ if (TARGET_64BIT)
+ return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
+ else
+ return "pcaddu12i\t$r1,%%call30(%1)\n\tjirl\t$r1,$r1,0";
else
return "bl\t%%plt(%1)";
default:
diff --git a/gcc/config/loongarch/predicates.md
b/gcc/config/loongarch/predicates.md
index fd4922c5e94..845d42a287b 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -438,6 +438,10 @@ (define_predicate "const_call_insn_operand"
if (offset != const0_rtx)
return false;
+ /* !TARGET_64BIT always support call30. */
+ if (!TARGET_64BIT)
+ return true;
+
/* When compiling with '-mcmodel=medium -mexplicit-relocs'
symbols are splited in loongarch_legitimize_call_address.
--
2.34.1