Add support for call30 and change the default code model to medium.

gcc/ChangeLog:

        * config/loongarch/loongarch-opts.cc: Change to CMODEL_MEDIUM.
        * config/loongarch/loongarch.cc (loongarch_call_tls_get_addr): Use
        call30 for tls_get_addr on LA32.
        * config/loongarch/loongarch.md: Use call30 on LA32.
        * config/loongarch/predicates.md: Return true on LA32 for
        const_call_insn_operand.
---
 gcc/config/loongarch/loongarch-opts.cc |  5 ++-
 gcc/config/loongarch/loongarch.cc      |  3 +-
 gcc/config/loongarch/loongarch.md      | 60 ++++++++++++++++++++------
 gcc/config/loongarch/predicates.md     |  4 ++
 4 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/gcc/config/loongarch/loongarch-opts.cc 
b/gcc/config/loongarch/loongarch-opts.cc
index 17ee2b6a487..489c217f423 100644
--- a/gcc/config/loongarch/loongarch-opts.cc
+++ b/gcc/config/loongarch/loongarch-opts.cc
@@ -549,7 +549,10 @@ fallback:
 
 
   /* 5.  Target code model */
-  t.cmodel = constrained.cmodel ? target->cmodel : CMODEL_NORMAL;
+  t.cmodel
+      = constrained.cmodel
+           ? target->cmodel
+           : (t.isa.base == ISA_BASE_LA64 ? CMODEL_NORMAL : CMODEL_MEDIUM);
 
   switch (t.cmodel)
     {
diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 125e888aa58..b905c75fb62 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2927,7 +2927,8 @@ loongarch_call_tls_get_addr (rtx sym, enum 
loongarch_symbol_type type, rtx v0)
                {
                  rtx call;
 
-                if (HAVE_AS_SUPPORT_CALL36)
+                /* !TARGET_64BIT always support call30.  */
+                if (HAVE_AS_SUPPORT_CALL36 || !TARGET_64BIT)
                   call = gen_call_value_internal (v0, loongarch_tls_symbol,
                                                   const0_rtx);
                 else
diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index c20f5724ba2..0cbef28dfc0 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -3988,12 +3988,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:
@@ -4081,12 +4087,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:
@@ -4119,12 +4131,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:
@@ -4177,12 +4195,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:
@@ -4254,12 +4278,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:
@@ -4294,12 +4324,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 77c9230fac2..c700410788e 100644
--- a/gcc/config/loongarch/predicates.md
+++ b/gcc/config/loongarch/predicates.md
@@ -434,6 +434,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

Reply via email to