gcc/ChangeLog:

        * config/loongarch/loongarch.cc (loongarch_call_tls_get_addr): Use 
call30
        to call __tls_get_addr.
        * config/loongarch/loongarch.md: Add call30.
        * config/loongarch/predicates.md: Return true for 
const_call_insn_operand
        on LA32.
---
 gcc/config/loongarch/loongarch.cc  | 29 +++++++------
 gcc/config/loongarch/loongarch.md  | 66 +++++++++++++++++++++++-------
 gcc/config/loongarch/predicates.md |  4 ++
 3 files changed, 71 insertions(+), 28 deletions(-)

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 2c70f8c4e0a..f3077f81d5d 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2980,19 +2980,22 @@ 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);
+                 /* Use call36 or call30.
+                   TARGET_32BIT always support call30.  */
+                 if ((TARGET_64BIT && HAVE_AS_SUPPORT_CALL36)
+                     || TARGET_32BIT)
+                   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 1ea71a84403..acde1edd00c 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -2865,13 +2865,13 @@ (define_insn "@got_load_tls_desc<mode>"
     (clobber (reg:SI FCC5_REGNUM))
     (clobber (reg:SI FCC6_REGNUM))
     (clobber (reg:SI FCC7_REGNUM))
-    (clobber (reg:SI RETURN_ADDR_REGNUM))]
+    (clobber (reg:P RETURN_ADDR_REGNUM))]
   "TARGET_TLS_DESC"
 {
   return TARGET_EXPLICIT_RELOCS
     ? "pcalau12i\t$r4,%%desc_pc_hi20(%0)\n\t"
-      "addi.d\t$r4,$r4,%%desc_pc_lo12(%0)\n\t"
-      "ld.d\t$r1,$r4,%%desc_ld(%0)\n\t"
+      "addi.<d>\t$r4,$r4,%%desc_pc_lo12(%0)\n\t"
+      "ld.<d>\t$r1,$r4,%%desc_ld(%0)\n\t"
       "jirl\t$r1,$r1,%%desc_call(%0)"
     : "la.tls.desc\t$r4,%0";
 }
@@ -3920,12 +3920,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:
@@ -4013,12 +4019,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:
@@ -4051,12 +4063,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:
@@ -4109,12 +4127,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:
@@ -4186,12 +4210,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:
@@ -4226,12 +4256,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 ccfc5189247..6672e494f39 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -436,6 +436,10 @@ (define_predicate "const_call_insn_operand"
   if (offset != const0_rtx)
     return false;
 
+  /* TARGET_32BIT always support call30.  */
+  if (TARGET_32BIT)
+    return true;
+
   /* When compiling with '-mcmodel=medium -mexplicit-relocs'
      symbols are splited in loongarch_legitimize_call_address.
 
-- 
2.34.1

Reply via email to