Introduce LoongArch32 (LA32) ilp32d abi and LoongArch32 Reduced (LA32R) ilp32s 
abi.
Add march la32v1.0 and la32rv1.0.
Add mtune loongarch32 as a common tune.

contrib/ChangeLog:

        * config-list.mk: Add loongarch32-linux-gnu*.

gcc/ChangeLog:

        * config.gcc: Add target triple loongarch32-*-*-* and
        corresponding abi ilp32f, ilp32d and ilp32s.
        * config/loongarch/genopts/loongarch-strings: Add strings for
        loongarch32 and ilp32 abi variants.
        * config/loongarch/genopts/loongarch.opt.in: Add
        -march=la32v1.0/la32rv1.0 and -mabi=ilp32d/ilp32f/ilp32s.
        * config/loongarch/gnu-user.h: Add ilp32 abi variants to spec.
        * config/loongarch/linux.h: Add ABI_LIBDIR for ilp32 abi
        variants.
        * config/loongarch/loongarch-c.cc 
(loongarch_define_unconditional_macros):
        Add builtin definitions for loongarch32 target.
        * config/loongarch/loongarch-def.cc: Add loongarch32 and ilp32
        definitions.
        * config/loongarch/loongarch-def.h: Add loongarch32 and ilp32
        definitions.
        * config/loongarch/loongarch-driver.h: Add ilp32 abi variants to
        spec.
        * config/loongarch/loongarch-opts.cc: Handle ilp32 abi variants.
        * config/loongarch/loongarch-opts.h: Add loongarch32 case to
        macros.
        * config/loongarch/loongarch-str.h: Add loongarch32 and ilp32
        strings.
        * config/loongarch/loongarch.opt: Add -march=la32v1.0/la32rv1.0
        and -mabi=ilp32d/ilp32f/ilp32s.
        * config/loongarch/t-linux: Add ilp32 abi variants to multilib.
---
 contrib/config-list.mk                        |  1 +
 gcc/config.gcc                                | 48 +++++++++++++----
 .../loongarch/genopts/loongarch-strings       | 10 ++++
 gcc/config/loongarch/genopts/loongarch.opt.in | 24 +++++++++
 gcc/config/loongarch/gnu-user.h               |  3 ++
 gcc/config/loongarch/linux.h                  |  8 ++-
 gcc/config/loongarch/loongarch-c.cc           |  9 ++++
 gcc/config/loongarch/loongarch-def.cc         | 51 ++++++++++++++++---
 gcc/config/loongarch/loongarch-def.h          | 42 +++++++++------
 gcc/config/loongarch/loongarch-driver.h       |  4 ++
 gcc/config/loongarch/loongarch-opts.cc        | 35 +++++++++++--
 gcc/config/loongarch/loongarch-opts.h         | 19 +++++--
 gcc/config/loongarch/loongarch-str.h          | 10 ++++
 gcc/config/loongarch/loongarch.opt            | 24 +++++++++
 gcc/config/loongarch/t-linux                  |  6 +++
 15 files changed, 254 insertions(+), 40 deletions(-)

diff --git a/contrib/config-list.mk b/contrib/config-list.mk
index 27aabf421b1..076fc8fb49e 100644
--- a/contrib/config-list.mk
+++ b/contrib/config-list.mk
@@ -64,6 +64,7 @@ LIST = \
   ia64-linux ia64-hpuxOPT-enable-obsolete \
   ia64-hp-vmsOPT-enable-obsolete iq2000-elf lm32-elf \
   lm32-rtems lm32-uclinux \
+  loongarch32-linux-gnuf64 loongarch32-linux-gnuf32 loongarch32-linux-gnusf \
   loongarch64-linux-gnuf64 loongarch64-linux-gnuf32 loongarch64-linux-gnusf \
   m32c-elfOPT-enable-obsolete m32r-elf m32rle-elf \
   m68k-elf m68k-netbsdelf \
diff --git a/gcc/config.gcc b/gcc/config.gcc
index c678b801f70..314db0627e7 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -5140,6 +5140,10 @@ case "${target}" in
 
                # Infer ABI from the triplet.
                case ${target} in
+               loongarch32-*f64) abi_base="ilp32d"; abi_ext="base" ;;
+               loongarch32-*f32) abi_base="ilp32f"; abi_ext="base" ;;
+               loongarch32-*sf)  abi_base="ilp32s"; abi_ext="base" ;;
+               loongarch32-*)    abi_base="ilp32d"; abi_ext="base" ;;
                loongarch64-*f64) abi_base="lp64d"; abi_ext="base" ;;
                loongarch64-*f32) abi_base="lp64f"; abi_ext="base" ;;
                loongarch64-*sf)  abi_base="lp64s"; abi_ext="base" ;;
@@ -5152,6 +5156,9 @@ case "${target}" in
 
                # Get the canonical triplet (multiarch specifier).
                case ${abi_base},${abi_ext} in
+               ilp32d,base) triplet_abi="";;
+               ilp32f,base) triplet_abi="f32";;
+               ilp32s,base) triplet_abi="sf";;
                lp64d,base) triplet_abi="";;
                lp64f,base) triplet_abi="f32";;
                lp64s,base) triplet_abi="sf";;
@@ -5166,12 +5173,21 @@ case "${target}" in
                          exit 1
                          ;;
                esac
-               la_canonical_triplet="loongarch64-${triplet_os}${triplet_abi}"
+
+               case ${target} in
+               loongarch32-*)    
la_canonical_triplet="loongarch32-${triplet_os}${triplet_abi}" ;;
+               loongarch64-*)    
la_canonical_triplet="loongarch64-${triplet_os}${triplet_abi}" ;;
+               *)
+                       echo "Unsupported target ${target}." 1>&2
+                       exit 1
+                       ;;
+               esac
 
 
                # Perform initial sanity checks on --with-* options.
                case ${with_arch} in
-               "" | la64v1.[01] | abi-default | loongarch64 | la[46]64) ;; # 
OK, append here.
+               "" | la64v1.[01] | abi-default | loongarch64 | la[46]64 | 
la32v1.0 | la32rv1.0)
+                       ;; # OK, append here.
                native)
                        if test x${host} != x${target}; then
                                echo "--with-arch=native is illegal for 
cross-compiler." 1>&2
@@ -5232,6 +5248,13 @@ case "${target}" in
                        # default architecture for lp64[fs] ABI
                        arch_default="abi-default"
                        ;;
+               ilp32[dfs]/base)
+                       # architectures that support ilp32* ABI
+                       arch_pattern="native|abi-default|la32v1.0|la32rv1.0"
+
+                       # default architecture for ilp32* ABI
+                       arch_default="abi-default"
+                       ;;
                *)
                        echo "Unsupported ABI type ${abi_base}/${abi_ext}." 1>&2
                        exit 1
@@ -5240,14 +5263,14 @@ case "${target}" in
 
                # Infer ISA-related default options from the ABI: pass 2
                case ${abi_base}/${abi_ext} in
-               lp64d/base)
+               ilp32d/base | lp64d/base)
                        fpu_pattern="64"
                        ;;
-               lp64f/base)
+               ilp32f/base | lp64f/base)
                        fpu_pattern="32|64"
                        fpu_default="32"
                        ;;
-               lp64s/base)
+               ilp32s/base | lp64s/base)
                        fpu_pattern="none|32|64"
                        fpu_default="none"
                        ;;
@@ -5301,7 +5324,14 @@ case "${target}" in
 
 
                # Check default with_tune configuration using with_arch.
-               tune_pattern="native|generic|loongarch64|la[46]64"
+               case ${with_arch} in
+               la32v1.0 | la32rv1.0)
+                       tune_pattern="loongarch32"
+                       ;;
+               loongarch64)
+                       tune_pattern="native|generic|loongarch64|la[46]64"
+                       ;;
+               esac
 
                case ${with_tune} in
                "") ;; # OK
@@ -5351,7 +5381,7 @@ case "${target}" in
                                        # Fixed: use the default gcc 
configuration for all multilib
                                        # builds by default.
                                        with_multilib_default="" ;;
-                               
arch,native|arch,la64v1.[01]|arch,loongarch64|arch,la[46]64) # OK, append here.
+                               
arch,native|arch,la64v1.[01]|arch,loongarch64|arch,la[46]64|arch,la32v1.0|arch,la32rv1.0)
 # OK, append here.
                                        
with_multilib_default="/march=${component}" ;;
                                arch,*)
                                        
with_multilib_default="/march=abi-default"
@@ -5415,7 +5445,7 @@ case "${target}" in
                                if test x${parse_state} = x"abi-base"; then
                                        # Base ABI type
                                        case ${component} in
-                                       lp64d | lp64f | lp64s) 
elem_tmp="ABI_BASE_$(echo ${component} | tr a-z A-Z),";;
+                                       ilp32d | ilp32f | ilp32s |lp64d | lp64f 
| lp64s) elem_tmp="ABI_BASE_$(echo ${component} | tr a-z A-Z),";;
                                        *)
                                                echo "Unknown base ABI 
\"${component}\" in --with-multilib-list." 1>&2
                                                exit 1
@@ -5451,7 +5481,7 @@ case "${target}" in
                                if test x${parse_state} = x"arch"; then
                                        # -march option
                                        case ${component} in
-                                       native | abi-default | la64v1.[01] | 
loongarch64 | la[46]64) # OK, append here.
+                                       native | abi-default | la64v1.[01] | 
loongarch64 | la[46]64 | la32v1.0 | la32rv1.0) # OK, append here.
                                                # Append -march spec for each 
multilib variant.
                                                
loongarch_multilib_list_make="${loongarch_multilib_list_make}/march=${component}"
                                                parse_state="opts"
diff --git a/gcc/config/loongarch/genopts/loongarch-strings 
b/gcc/config/loongarch/genopts/loongarch-strings
index ffbcfa25427..0346ef78117 100644
--- a/gcc/config/loongarch/genopts/loongarch-strings
+++ b/gcc/config/loongarch/genopts/loongarch-strings
@@ -31,7 +31,14 @@ STR_CPU_LA664              la664
 STR_ARCH_LA64V1_0     la64v1.0
 STR_ARCH_LA64V1_1     la64v1.1
 
+STR_ARCH_LA32V1_0     la32v1.0
+STR_ARCH_LA32RV1_0    la32rv1.0
+
+STR_TUNE_LOONGARCH32  loongarch32 # No loongarch32 arch, only loongarch32 tune
+
 # Base architecture
+STR_ISA_BASE_LA32 la32
+STR_ISA_BASE_LA32R la32r
 STR_ISA_BASE_LA64 la64
 
 # -mfpu
@@ -52,6 +59,9 @@ STR_ISA_EXT_LASX      lasx
 
 # -mabi=
 OPTSTR_ABI_BASE              abi
+STR_ABI_BASE_ILP32D   ilp32d
+STR_ABI_BASE_ILP32F   ilp32f
+STR_ABI_BASE_ILP32S   ilp32s
 STR_ABI_BASE_LP64D    lp64d
 STR_ABI_BASE_LP64F    lp64f
 STR_ABI_BASE_LP64S    lp64s
diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in 
b/gcc/config/loongarch/genopts/loongarch.opt.in
index f0c089a928e..dab99222a8f 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -32,6 +32,12 @@ Enum
 Name(isa_base) Type(int)
 Basic ISAs of LoongArch:
 
+EnumValue
+Enum(isa_base) String(@@STR_ISA_BASE_LA32@@) Value(ISA_BASE_LA32)
+
+EnumValue
+Enum(isa_base) String(@@STR_ISA_BASE_LA32R@@) Value(ISA_BASE_LA32R)
+
 EnumValue
 Enum(isa_base) String(@@STR_ISA_BASE_LA64@@) Value(ISA_BASE_LA64)
 
@@ -119,6 +125,12 @@ Enum(arch_type) String(@@STR_ARCH_LA64V1_0@@) 
Value(ARCH_LA64V1_0)
 EnumValue
 Enum(arch_type) String(@@STR_ARCH_LA64V1_1@@) Value(ARCH_LA64V1_1)
 
+EnumValue
+Enum(arch_type) String(@@STR_ARCH_LA32V1_0@@) Value(ARCH_LA32V1_0)
+
+EnumValue
+Enum(arch_type) String(@@STR_ARCH_LA32RV1_0@@) Value(ARCH_LA32RV1_0)
+
 m@@OPTSTR_ARCH@@=
 Target RejectNegative Joined Enum(arch_type) Var(la_opt_cpu_arch) 
Init(M_OPT_UNSET) Save
 -m@@OPTSTR_ARCH@@=PROCESSOR    Generate code for the given PROCESSOR ISA.
@@ -142,6 +154,9 @@ Enum(tune_type) String(@@STR_CPU_LA464@@) Value(TUNE_LA464)
 EnumValue
 Enum(tune_type) String(@@STR_CPU_LA664@@) Value(TUNE_LA664)
 
+EnumValue
+Enum(tune_type) String(@@STR_TUNE_LOONGARCH32@@) Value(TUNE_LOONGARCH32)
+
 m@@OPTSTR_TUNE@@=
 Target RejectNegative Joined Enum(tune_type) Var(la_opt_cpu_tune) 
Init(M_OPT_UNSET) Save
 -m@@OPTSTR_TUNE@@=PROCESSOR    Generate optimized code for PROCESSOR.
@@ -155,6 +170,15 @@ Enum
 Name(abi_base) Type(int)
 Base ABI types for LoongArch:
 
+EnumValue
+Enum(abi_base) String(@@STR_ABI_BASE_ILP32D@@) Value(ABI_BASE_ILP32D)
+
+EnumValue
+Enum(abi_base) String(@@STR_ABI_BASE_ILP32F@@) Value(ABI_BASE_ILP32F)
+
+EnumValue
+Enum(abi_base) String(@@STR_ABI_BASE_ILP32S@@) Value(ABI_BASE_ILP32S)
+
 EnumValue
 Enum(abi_base) String(@@STR_ABI_BASE_LP64D@@) Value(ABI_BASE_LP64D)
 
diff --git a/gcc/config/loongarch/gnu-user.h b/gcc/config/loongarch/gnu-user.h
index fbc75a90ad5..f86ffd9d64d 100644
--- a/gcc/config/loongarch/gnu-user.h
+++ b/gcc/config/loongarch/gnu-user.h
@@ -34,6 +34,9 @@ along with GCC; see the file COPYING3.  If not see
   "/lib" ABI_GRLEN_SPEC "/ld-linux-loongarch-" ABI_SPEC ".so.1"
 
 #define MUSL_ABI_SPEC \
+  "%{mabi=ilp32d:}" \
+  "%{mabi=ilp32f:-sp}" \
+  "%{mabi=ilp32s:-sf}" \
   "%{mabi=lp64d:}" \
   "%{mabi=lp64f:-sp}" \
   "%{mabi=lp64s:-sf}"
diff --git a/gcc/config/loongarch/linux.h b/gcc/config/loongarch/linux.h
index b95a11f0241..e2e3d868a73 100644
--- a/gcc/config/loongarch/linux.h
+++ b/gcc/config/loongarch/linux.h
@@ -25,7 +25,13 @@ along with GCC; see the file COPYING3.  If not see
   && defined(LA_DISABLE_MULTILIB) \
   && defined(LA_DISABLE_MULTIARCH)
 
-  #if DEFAULT_ABI_BASE == ABI_BASE_LP64D
+  #if DEFAULT_ABI_BASE == ABI_BASE_ILP32D
+    #define ABI_LIBDIR "lib32"
+  #elif DEFAULT_ABI_BASE == ABI_BASE_ILP32F
+    #define ABI_LIBDIR "lib32/f32"
+  #elif DEFAULT_ABI_BASE == ABI_BASE_ILP32S
+    #define ABI_LIBDIR "lib32/sf"
+  #elif DEFAULT_ABI_BASE == ABI_BASE_LP64D
     #define ABI_LIBDIR "lib64"
   #elif DEFAULT_ABI_BASE == ABI_BASE_LP64F
     #define ABI_LIBDIR "lib64/f32"
diff --git a/gcc/config/loongarch/loongarch-c.cc 
b/gcc/config/loongarch/loongarch-c.cc
index fc031a6fe90..89e8d7ff149 100644
--- a/gcc/config/loongarch/loongarch-c.cc
+++ b/gcc/config/loongarch/loongarch-c.cc
@@ -55,6 +55,15 @@ loongarch_define_unconditional_macros (cpp_reader *pfile)
       builtin_define ("__loongarch_grlen=64");
       builtin_define ("__loongarch64");
     }
+  else
+      builtin_define ("__loongarch_grlen=32");
+
+  if (TARGET_ABI_ILP32)
+    {
+      builtin_define ("_ABILP32=3");
+      builtin_define ("_LOONGARCH_SIM=_ABILP32");
+      builtin_define ("__loongarch_ilp32");
+    }
 
   if (TARGET_ABI_LP64)
     {
diff --git a/gcc/config/loongarch/loongarch-def.cc 
b/gcc/config/loongarch/loongarch-def.cc
index dcd8d905c5f..81939118be0 100644
--- a/gcc/config/loongarch/loongarch-def.cc
+++ b/gcc/config/loongarch/loongarch-def.cc
@@ -43,14 +43,17 @@ array_arch<const char *> loongarch_arch_strings = 
array_arch<const char *> ()
   .set (ARCH_LA464, STR_CPU_LA464)
   .set (ARCH_LA664, STR_CPU_LA664)
   .set (ARCH_LA64V1_0, STR_ARCH_LA64V1_0)
-  .set (ARCH_LA64V1_1, STR_ARCH_LA64V1_1);
+  .set (ARCH_LA64V1_1, STR_ARCH_LA64V1_1)
+  .set (ARCH_LA32V1_0, STR_ARCH_LA32V1_0)
+  .set (ARCH_LA32RV1_0, STR_ARCH_LA32RV1_0);
 
 array_tune<const char *> loongarch_tune_strings = array_tune<const char *> ()
   .set (TUNE_NATIVE, STR_CPU_NATIVE)
   .set (TUNE_GENERIC, STR_TUNE_GENERIC)
   .set (TUNE_LOONGARCH64, STR_CPU_LOONGARCH64)
   .set (TUNE_LA464, STR_CPU_LA464)
-  .set (TUNE_LA664, STR_CPU_LA664);
+  .set (TUNE_LA664, STR_CPU_LA664)
+  .set (TUNE_LOONGARCH32, STR_TUNE_LOONGARCH32);
 
 array_arch<loongarch_isa> loongarch_cpu_default_isa =
   array_arch<loongarch_isa> ()
@@ -86,8 +89,17 @@ array_arch<loongarch_isa> loongarch_cpu_default_isa =
            .simd_ (ISA_EXT_SIMD_LSX)
            .evolution_ (OPTION_MASK_ISA_DIV32 | OPTION_MASK_ISA_LD_SEQ_SA
                         | OPTION_MASK_ISA_LAM_BH | OPTION_MASK_ISA_LAMCAS
-                        | OPTION_MASK_ISA_FRECIPE | OPTION_MASK_ISA_SCQ));
+                        | OPTION_MASK_ISA_FRECIPE | OPTION_MASK_ISA_SCQ))
+
+    .set (ARCH_LA32V1_0,
+         loongarch_isa ()
+           .base_ (ISA_BASE_LA32)
+           .fpu_ (ISA_EXT_FPU64))
 
+    .set (ARCH_LA32RV1_0,
+         loongarch_isa ()
+           .base_ (ISA_BASE_LA32R)
+           .fpu_ (ISA_EXT_NONE));
 
 static inline loongarch_cache la464_cache ()
 {
@@ -103,7 +115,8 @@ array_tune<loongarch_cache> loongarch_cpu_cache =
     .set (TUNE_GENERIC, la464_cache ())
     .set (TUNE_LOONGARCH64, la464_cache ())
     .set (TUNE_LA464, la464_cache ())
-    .set (TUNE_LA664, la464_cache ());
+    .set (TUNE_LA664, la464_cache ())
+    .set (TUNE_LOONGARCH32, la464_cache ());
 
 static inline loongarch_align la464_align ()
 {
@@ -120,7 +133,8 @@ array_tune<loongarch_align> loongarch_cpu_align =
     .set (TUNE_GENERIC, la664_align ())
     .set (TUNE_LOONGARCH64, la664_align ())
     .set (TUNE_LA464, la464_align ())
-    .set (TUNE_LA664, la664_align ());
+    .set (TUNE_LA664, la664_align ())
+    .set (TUNE_LOONGARCH32, la664_align ());
 
 /* Default RTX cost initializer.  */
 loongarch_rtx_cost_data::loongarch_rtx_cost_data ()
@@ -172,14 +186,16 @@ array_tune<int> loongarch_cpu_issue_rate = 
array_tune<int> ()
   .set (TUNE_GENERIC, 4)
   .set (TUNE_LOONGARCH64, 4)
   .set (TUNE_LA464, 4)
-  .set (TUNE_LA664, 6);
+  .set (TUNE_LA664, 6)
+  .set (TUNE_LOONGARCH32, 4);
 
 array_tune<int> loongarch_cpu_multipass_dfa_lookahead = array_tune<int> ()
   .set (TUNE_NATIVE, 4)
   .set (TUNE_GENERIC, 4)
   .set (TUNE_LOONGARCH64, 4)
   .set (TUNE_LA464, 4)
-  .set (TUNE_LA664, 6);
+  .set (TUNE_LA664, 6)
+  .set (TUNE_LOONGARCH32, 4);
 
 /* Wiring string definitions from loongarch-str.h to global arrays
    with standard index values from loongarch-opts.h, so we can
@@ -188,6 +204,8 @@ array_tune<int> loongarch_cpu_multipass_dfa_lookahead = 
array_tune<int> ()
 
 array<const char *, N_ISA_BASE_TYPES> loongarch_isa_base_strings =
   array<const char *, N_ISA_BASE_TYPES> ()
+    .set (ISA_BASE_LA32, STR_ISA_BASE_LA32)
+    .set (ISA_BASE_LA32R, STR_ISA_BASE_LA32R)
     .set (ISA_BASE_LA64, STR_ISA_BASE_LA64);
 
 array<const char *, N_ISA_EXT_TYPES> loongarch_isa_ext_strings =
@@ -200,6 +218,9 @@ array<const char *, N_ISA_EXT_TYPES> 
loongarch_isa_ext_strings =
 
 array<const char *, N_ABI_BASE_TYPES> loongarch_abi_base_strings =
   array<const char *, N_ABI_BASE_TYPES> ()
+    .set (ABI_BASE_ILP32D, STR_ABI_BASE_ILP32D)
+    .set (ABI_BASE_ILP32F, STR_ABI_BASE_ILP32F)
+    .set (ABI_BASE_ILP32S, STR_ABI_BASE_ILP32S)
     .set (ABI_BASE_LP64D, STR_ABI_BASE_LP64D)
     .set (ABI_BASE_LP64F, STR_ABI_BASE_LP64F)
     .set (ABI_BASE_LP64S, STR_ABI_BASE_LP64S);
@@ -220,6 +241,22 @@ array<const char *, N_CMODEL_TYPES> 
loongarch_cmodel_strings =
 array<array<loongarch_isa, N_ABI_EXT_TYPES>, N_ABI_BASE_TYPES>
   abi_minimal_isa = array<array<loongarch_isa, N_ABI_EXT_TYPES>,
                          N_ABI_BASE_TYPES> ()
+    .set (ABI_BASE_ILP32D,
+         array<loongarch_isa, N_ABI_EXT_TYPES> ()
+           .set (ABI_EXT_BASE,
+                 loongarch_isa ()
+                   .base_ (ISA_BASE_LA32R)
+                   .fpu_ (ISA_EXT_FPU64)))
+    .set (ABI_BASE_ILP32F,
+         array<loongarch_isa, N_ABI_EXT_TYPES> ()
+           .set (ABI_EXT_BASE,
+                 loongarch_isa ()
+                   .base_ (ISA_BASE_LA32R)
+                   .fpu_ (ISA_EXT_FPU32)))
+    .set (ABI_BASE_ILP32S,
+         array<loongarch_isa, N_ABI_EXT_TYPES> ()
+           .set (ABI_EXT_BASE,
+                 loongarch_isa ().base_ (ISA_BASE_LA32R)))
     .set (ABI_BASE_LP64D,
          array<loongarch_isa, N_ABI_EXT_TYPES> ()
            .set (ABI_EXT_BASE,
diff --git a/gcc/config/loongarch/loongarch-def.h 
b/gcc/config/loongarch/loongarch-def.h
index 0a7d0c923fe..8be8f769964 100644
--- a/gcc/config/loongarch/loongarch-def.h
+++ b/gcc/config/loongarch/loongarch-def.h
@@ -54,8 +54,10 @@ along with GCC; see the file COPYING3.  If not see
 
 /* ISA base */
 enum {
-  ISA_BASE_LA64                = 0,  /* LoongArch64 */
-  N_ISA_BASE_TYPES     = 1
+  ISA_BASE_LA32                = 0,  /* LoongArch32 */
+  ISA_BASE_LA32R       = 1,  /* LoongArch32 Reduced */
+  ISA_BASE_LA64                = 2,  /* LoongArch64 */
+  N_ISA_BASE_TYPES     = 3
 };
 
 extern loongarch_def_array<const char *, N_ISA_BASE_TYPES>
@@ -78,28 +80,35 @@ extern loongarch_def_array<const char *, N_ISA_EXT_TYPES>
 
 
 /* Base ABI */
-#define ABI_BASE_LP64D   0
-#define ABI_BASE_LP64F   1
-#define ABI_BASE_LP64S   2
-#define N_ABI_BASE_TYPES  3
+#define ABI_BASE_ILP32D          0
+#define ABI_BASE_ILP32F          1
+#define ABI_BASE_ILP32S          2
+#define ABI_BASE_LP64D   3
+#define ABI_BASE_LP64F   4
+#define ABI_BASE_LP64S   5
+#define N_ABI_BASE_TYPES  6
 
 extern loongarch_def_array<const char *, N_ABI_BASE_TYPES>
   loongarch_abi_base_strings;
 
 #define TO_LP64_ABI_BASE(C) (C)
 
+#define ABI_ILP32_P(abi_base) \
+  (abi_base == ABI_BASE_ILP32D \
+   || abi_base == ABI_BASE_ILP32F \
+   || abi_base == ABI_BASE_ILP32S)
+
 #define ABI_LP64_P(abi_base) \
   (abi_base == ABI_BASE_LP64D \
    || abi_base == ABI_BASE_LP64F \
    || abi_base == ABI_BASE_LP64S)
 
 #define ABI_FPU64_P(abi_base) \
-  (abi_base == ABI_BASE_LP64D)
+  (abi_base == ABI_BASE_LP64D || abi_base == ABI_BASE_ILP32D)
 #define ABI_FPU32_P(abi_base) \
-  (abi_base == ABI_BASE_LP64F)
+  (abi_base == ABI_BASE_LP64F || abi_base == ABI_BASE_ILP32F)
 #define ABI_NOFPU_P(abi_base) \
-  (abi_base == ABI_BASE_LP64S)
-
+  (abi_base == ABI_BASE_LP64S || abi_base == ABI_BASE_ILP32S)
 
 /* ABI Extension */
 enum {
@@ -190,17 +199,20 @@ enum {
   ARCH_LA664       = 4,
   ARCH_LA64V1_0     = 5,
   ARCH_LA64V1_1     = 6,
-  N_ARCH_TYPES      = 7,
+  ARCH_LA32V1_0     = 7,
+  ARCH_LA32RV1_0    = 8,
+  N_ARCH_TYPES      = 9,
 };
 
 /* Tune target presets (-mtune=*) */
 enum {
   TUNE_NATIVE       = 0,
   TUNE_GENERIC      = 1,
-  TUNE_LOONGARCH64  = 2,
-  TUNE_LA464       = 3,
-  TUNE_LA664       = 4,
-  N_TUNE_TYPES      = 5,
+  TUNE_LOONGARCH32  = 2,
+  TUNE_LOONGARCH64  = 3,
+  TUNE_LA464       = 4,
+  TUNE_LA664       = 5,
+  N_TUNE_TYPES      = 6,
 };
 
 /* TLS types.  */
diff --git a/gcc/config/loongarch/loongarch-driver.h 
b/gcc/config/loongarch/loongarch-driver.h
index 15252962e74..702c4362f98 100644
--- a/gcc/config/loongarch/loongarch-driver.h
+++ b/gcc/config/loongarch/loongarch-driver.h
@@ -118,9 +118,13 @@ driver_get_normalized_m_opts (int argc, const char **argv);
 
 /* ABI spec strings.  */
 #define ABI_GRLEN_SPEC \
+  "%{mabi=ilp32*:32}"   \
   "%{mabi=lp64*:64}"   \
 
 #define ABI_SPEC \
+  "%{mabi=ilp32d:ilp32d}" \
+  "%{mabi=ilp32f:ilp32f}" \
+  "%{mabi=ilp32s:ilp32s}" \
   "%{mabi=lp64d:lp64d}" \
   "%{mabi=lp64f:lp64f}" \
   "%{mabi=lp64s:lp64s}" \
diff --git a/gcc/config/loongarch/loongarch-opts.cc 
b/gcc/config/loongarch/loongarch-opts.cc
index 6e72084b9be..aeb118ab342 100644
--- a/gcc/config/loongarch/loongarch-opts.cc
+++ b/gcc/config/loongarch/loongarch-opts.cc
@@ -43,6 +43,9 @@ const struct loongarch_rtx_cost_data *loongarch_cost;
 #define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi))
 static const struct loongarch_abi
 abi_priority_list[] = {
+    {ABI_BASE_ILP32D, ABI_EXT_BASE},
+    {ABI_BASE_ILP32F, ABI_EXT_BASE},
+    {ABI_BASE_ILP32S, ABI_EXT_BASE},
     {ABI_BASE_LP64D, ABI_EXT_BASE},
     {ABI_BASE_LP64F, ABI_EXT_BASE},
     {ABI_BASE_LP64S, ABI_EXT_BASE},
@@ -578,17 +581,23 @@ isa_default_abi (const struct loongarch_isa *isa)
   switch (isa->fpu)
     {
       case ISA_EXT_FPU64:
-       if (isa->base >= ISA_BASE_LA64)
+       if (isa->base == ISA_BASE_LA32 || isa->base == ISA_BASE_LA32R)
+         abi.base = ABI_BASE_ILP32D;
+       else if (isa->base == ISA_BASE_LA64)
          abi.base = ABI_BASE_LP64D;
        break;
 
       case ISA_EXT_FPU32:
-       if (isa->base >= ISA_BASE_LA64)
+       if (isa->base == ISA_BASE_LA32 || isa->base == ISA_BASE_LA32R)
+         abi.base = ABI_BASE_ILP32F;
+       else if (isa->base == ISA_BASE_LA64)
          abi.base = ABI_BASE_LP64F;
        break;
 
       case ISA_EXT_NONE:
-       if (isa->base >= ISA_BASE_LA64)
+       if (isa->base == ISA_BASE_LA32 || isa->base == ISA_BASE_LA32R)
+         abi.base = ABI_BASE_ILP32S;
+       else if (isa->base == ISA_BASE_LA64)
          abi.base = ABI_BASE_LP64S;
        break;
 
@@ -607,8 +616,14 @@ isa_base_compat_p (const struct loongarch_isa *set1,
 {
   switch (set2->base)
     {
+      case ISA_BASE_LA32:
+       return (set1->base == ISA_BASE_LA32);
+
+      case ISA_BASE_LA32R:
+       return (set1->base == ISA_BASE_LA32R || set1->base == ISA_BASE_LA32);
+
       case ISA_BASE_LA64:
-       return (set1->base >= ISA_BASE_LA64);
+       return (set1->base == ISA_BASE_LA64);
 
       default:
        gcc_unreachable ();
@@ -661,6 +676,12 @@ abi_default_cpu_arch (struct loongarch_abi abi,
   if (abi.ext == ABI_EXT_BASE)
     switch (abi.base)
       {
+       case ABI_BASE_ILP32D:
+       case ABI_BASE_ILP32F:
+       case ABI_BASE_ILP32S:
+         *isa = isa_required (abi);
+         return ARCH_LA32V1_0;
+
        case ABI_BASE_LP64D:
        case ABI_BASE_LP64F:
        case ABI_BASE_LP64S:
@@ -692,6 +713,8 @@ default_tune_for_arch (int arch, int fallback)
     case ARCH_ABI_DEFAULT:
     case ARCH_LA64V1_0:
     case ARCH_LA64V1_1:
+    case ARCH_LA32V1_0:
+    case ARCH_LA32RV1_0:
       ret = fallback;
     }
 
@@ -1085,6 +1108,10 @@ loongarch_init_misc_options (struct gcc_options *opts,
                                         : EXPLICIT_RELOCS_ALWAYS)
                                      : EXPLICIT_RELOCS_NONE);
 
+  /* TODO: mexplicit-relocs support for LA32.  */
+  if (!TARGET_64BIT)
+    opts->x_la_opt_explicit_relocs = EXPLICIT_RELOCS_NONE;
+
   /* Enable sw prefetching at -O3 and higher.  */
   if (opts->x_flag_prefetch_loop_arrays < 0
       && (opts->x_optimize >= 3 || opts->x_flag_profile_use)
diff --git a/gcc/config/loongarch/loongarch-opts.h 
b/gcc/config/loongarch/loongarch-opts.h
index 1b397b12494..b9b68c8db3a 100644
--- a/gcc/config/loongarch/loongarch-opts.h
+++ b/gcc/config/loongarch/loongarch-opts.h
@@ -93,15 +93,26 @@ struct loongarch_flags {
 #define TARGET_CMODEL_EXTREME      (la_target.cmodel == CMODEL_EXTREME)
 
 #define TARGET_HARD_FLOAT          (la_target.isa.fpu != ISA_EXT_NONE)
-#define TARGET_HARD_FLOAT_ABI      (la_target.abi.base == ABI_BASE_LP64D \
+#define TARGET_HARD_FLOAT_ABI      (la_target.abi.base == ABI_BASE_ILP32D \
+                                    || la_target.abi.base == ABI_BASE_ILP32F \
+                                    || la_target.abi.base == ABI_BASE_LP64D \
                                     || la_target.abi.base == ABI_BASE_LP64F)
 
 #define TARGET_SOFT_FLOAT        (la_target.isa.fpu == ISA_EXT_NONE)
-#define TARGET_SOFT_FLOAT_ABI    (la_target.abi.base == ABI_BASE_LP64S)
+#define TARGET_SOFT_FLOAT_ABI    (la_target.abi.base == ABI_BASE_ILP32S \
+                                    || la_target.abi.base == ABI_BASE_LP64S)
 #define TARGET_SINGLE_FLOAT      (la_target.isa.fpu == ISA_EXT_FPU32)
-#define TARGET_SINGLE_FLOAT_ABI          (la_target.abi.base == ABI_BASE_LP64F)
+#define TARGET_SINGLE_FLOAT_ABI          (la_target.abi.base == 
ABI_BASE_ILP32F \
+                                    || la_target.abi.base == ABI_BASE_LP64F)
 #define TARGET_DOUBLE_FLOAT      (la_target.isa.fpu == ISA_EXT_FPU64)
-#define TARGET_DOUBLE_FLOAT_ABI          (la_target.abi.base == ABI_BASE_LP64D)
+#define TARGET_DOUBLE_FLOAT_ABI          (la_target.abi.base == 
ABI_BASE_ILP32D \
+                                    || la_target.abi.base == ABI_BASE_LP64D)
+
+
+#define TARGET_32BIT_S           (la_target.isa.base == ISA_BASE_LA32)
+#define TARGET_32BIT_R           (la_target.isa.base == ISA_BASE_LA32R)
+#define TARGET_32BIT             (TARGET_32BIT_S || TARGET_32BIT_R)
+#define TARGET_ABI_ILP32         ABI_ILP32_P(la_target.abi.base)
 
 #define TARGET_64BIT             (la_target.isa.base == ISA_BASE_LA64)
 #define TARGET_ABI_LP64                  ABI_LP64_P(la_target.abi.base)
diff --git a/gcc/config/loongarch/loongarch-str.h 
b/gcc/config/loongarch/loongarch-str.h
index 583cce8643e..69af956509e 100644
--- a/gcc/config/loongarch/loongarch-str.h
+++ b/gcc/config/loongarch/loongarch-str.h
@@ -35,6 +35,13 @@ along with GCC; see the file COPYING3.  If not see
 #define STR_ARCH_LA64V1_0 "la64v1.0"
 #define STR_ARCH_LA64V1_1 "la64v1.1"
 
+#define STR_ARCH_LA32V1_0 "la32v1.0"
+#define STR_ARCH_LA32RV1_0 "la32rv1.0"
+
+#define STR_TUNE_LOONGARCH32 "loongarch32"
+
+#define STR_ISA_BASE_LA32 "la32"
+#define STR_ISA_BASE_LA32R "la32r"
 #define STR_ISA_BASE_LA64 "la64"
 
 #define OPTSTR_ISA_EXT_FPU "fpu"
@@ -52,6 +59,9 @@ along with GCC; see the file COPYING3.  If not see
 #define STR_ISA_EXT_LASX "lasx"
 
 #define OPTSTR_ABI_BASE "abi"
+#define STR_ABI_BASE_ILP32D "ilp32d"
+#define STR_ABI_BASE_ILP32F "ilp32f"
+#define STR_ABI_BASE_ILP32S "ilp32s"
 #define STR_ABI_BASE_LP64D "lp64d"
 #define STR_ABI_BASE_LP64F "lp64f"
 #define STR_ABI_BASE_LP64S "lp64s"
diff --git a/gcc/config/loongarch/loongarch.opt 
b/gcc/config/loongarch/loongarch.opt
index 628eabe8d59..77162151e95 100644
--- a/gcc/config/loongarch/loongarch.opt
+++ b/gcc/config/loongarch/loongarch.opt
@@ -40,6 +40,12 @@ Enum
 Name(isa_base) Type(int)
 Basic ISAs of LoongArch:
 
+EnumValue
+Enum(isa_base) String(la32) Value(ISA_BASE_LA32)
+
+EnumValue
+Enum(isa_base) String(la32r) Value(ISA_BASE_LA32R)
+
 EnumValue
 Enum(isa_base) String(la64) Value(ISA_BASE_LA64)
 
@@ -127,6 +133,12 @@ Enum(arch_type) String(la64v1.0) Value(ARCH_LA64V1_0)
 EnumValue
 Enum(arch_type) String(la64v1.1) Value(ARCH_LA64V1_1)
 
+EnumValue
+Enum(arch_type) String(la32v1.0) Value(ARCH_LA32V1_0)
+
+EnumValue
+Enum(arch_type) String(la32rv1.0) Value(ARCH_LA32RV1_0)
+
 march=
 Target RejectNegative Joined Enum(arch_type) Var(la_opt_cpu_arch) 
Init(M_OPT_UNSET) Save
 -march=PROCESSOR       Generate code for the given PROCESSOR ISA.
@@ -150,6 +162,9 @@ Enum(tune_type) String(la464) Value(TUNE_LA464)
 EnumValue
 Enum(tune_type) String(la664) Value(TUNE_LA664)
 
+EnumValue
+Enum(tune_type) String(loongarch32) Value(TUNE_LOONGARCH32)
+
 mtune=
 Target RejectNegative Joined Enum(tune_type) Var(la_opt_cpu_tune) 
Init(M_OPT_UNSET) Save
 -mtune=PROCESSOR       Generate optimized code for PROCESSOR.
@@ -163,6 +178,15 @@ Enum
 Name(abi_base) Type(int)
 Base ABI types for LoongArch:
 
+EnumValue
+Enum(abi_base) String(ilp32d) Value(ABI_BASE_ILP32D)
+
+EnumValue
+Enum(abi_base) String(ilp32f) Value(ABI_BASE_ILP32F)
+
+EnumValue
+Enum(abi_base) String(ilp32s) Value(ABI_BASE_ILP32S)
+
 EnumValue
 Enum(abi_base) String(lp64d) Value(ABI_BASE_LP64D)
 
diff --git a/gcc/config/loongarch/t-linux b/gcc/config/loongarch/t-linux
index 45862048abf..857e5b33626 100644
--- a/gcc/config/loongarch/t-linux
+++ b/gcc/config/loongarch/t-linux
@@ -16,6 +16,9 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
+MULTIOSDIR_ilp32d := ../lib32$(call if_multiarch,:loongarch32-linux-gnu)
+MULTIOSDIR_ilp32f := ../lib32/f32$(call if_multiarch,:loongarch32-linux-gnuf32)
+MULTIOSDIR_ilp32s := ../lib32/sf$(call if_multiarch,:loongarch32-linux-gnusf)
 MULTIOSDIR_lp64d := ../lib64$(call if_multiarch,:loongarch64-linux-gnu)
 MULTIOSDIR_lp64f := ../lib64/f32$(call if_multiarch,:loongarch64-linux-gnuf32)
 MULTIOSDIR_lp64s := ../lib64/sf$(call if_multiarch,:loongarch64-linux-gnusf)
@@ -24,6 +27,9 @@ MULTIOSDIR_lp64s := ../lib64/sf$(call 
if_multiarch,:loongarch64-linux-gnusf)
 ifeq ($(filter LA_DISABLE_MULTILIB,$(tm_defines)),)
 
     MULTILIB_OSDIRNAMES = .=$(MULTIOSDIR_$(mlib_default))
+    MULTILIB_OSDIRNAMES += mabi.ilp32d=$(MULTIOSDIR_ilp32d)
+    MULTILIB_OSDIRNAMES += mabi.ilp32f=$(MULTIOSDIR_ilp32f)
+    MULTILIB_OSDIRNAMES += mabi.ilp32s=$(MULTIOSDIR_ilp32s)
     MULTILIB_OSDIRNAMES += mabi.lp64d=$(MULTIOSDIR_lp64d)
     MULTILIB_OSDIRNAMES += mabi.lp64f=$(MULTIOSDIR_lp64f)
     MULTILIB_OSDIRNAMES += mabi.lp64s=$(MULTIOSDIR_lp64s)
-- 
2.34.1

Reply via email to