diff --git a/contrib/config-list.mk b/contrib/config-list.mk
index e570b13c71b..3c00ce5410a 100644
--- a/contrib/config-list.mk
+++ b/contrib/config-list.mk
@@ -57,6 +57,7 @@ LIST = aarch64-elf aarch64-freebsd13 aarch64-linux-gnu aarch64-rtems \
   i686-cygwinOPT-enable-threads=yes i686-mingw32crt ia64-elf \
   ia64-linux ia64-hpux ia64-hp-vms 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-elf m32r-elf m32rle-elf \
   m68k-elf m68k-netbsdelf \
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 415e0e1ebc5..45e69b24b44 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4901,10 +4901,24 @@ case "${target}" in
 			arch_pattern     arch_default   \
 			fpu_pattern      fpu_default    \
 			tune_pattern     tune_default   \
-			triplet_os       triplet_abi
+			triplet_os       triplet_abi    \
+			triplet_cpu
 
 		# Infer ABI from the triplet.
 		case ${target} in
+		loongarch32-*-*-*f64)
+			abi_pattern="ilp32d"
+			;;
+		loongarch32-*-*-*f32)
+			abi_pattern="ilp32f"
+			;;
+		loongarch32-*-*-*sf)
+			abi_pattern="ilp32s"
+			;;
+		loongarch32-*-*-*)
+			abi_pattern="ilp32[dfs]"
+			abi_default="ilp32d"
+			;;
 		loongarch64-*-*-*f64)
 			abi_pattern="lp64d"
 			;;
@@ -4939,7 +4953,7 @@ case "${target}" in
 
 		# Perform initial sanity checks on --with-* options.
 		case ${with_arch} in
-		"" | loongarch64 | la464) ;; # OK, append here.
+		"" | loongarch32 | loongarch64 | la464) ;; # OK, append here.
 		native)
 			if test x${host} != x${target}; then
 				echo "--with-arch=native is illegal for cross-compiler." 1>&2
@@ -4958,7 +4972,7 @@ case "${target}" in
 		esac
 
 		case ${with_abi} in
-		"" | lp64d | lp64f | lp64s) ;; # OK, append here.
+		"" | ilp32d | ilp32f | ilp32s | lp64d | lp64f | lp64s) ;; # OK, append here.
 		*)
 			echo "Unsupported ABI given in --with-abi=$with_abi" 1>&2
 			exit 1
@@ -5007,12 +5021,21 @@ case "${target}" in
 			;;
 		esac
 
+		case ${target} in
+		loongarch32-*-*-*)
+			triplet_cpu="loongarch32"
+			;;
+		loongarch64-*-*-*)
+			triplet_cpu="loongarch64"
+			;;
+		esac
+
 		case ${with_abi} in
-		  "lp64d") triplet_abi="";;
-		  "lp64f") triplet_abi="f32";;
-		  "lp64s") triplet_abi="sf";;
+		  "ilp32d" | "lp64d") triplet_abi="";;
+		  "ilp32f" | "lp64f") triplet_abi="f32";;
+		  "ilp32s" | "lp64s") triplet_abi="sf";;
 		esac
-		la_canonical_triplet="loongarch64-${triplet_os}${triplet_abi}"
+		la_canonical_triplet="${triplet_cpu}-${triplet_os}${triplet_abi}"
 
 		# Set default value for with_abiext (internal)
 		case ${with_abiext} in
@@ -5038,6 +5061,12 @@ case "${target}" in
 
 		# Infer ISA-related default options from the ABI: pass 1
 		case ${with_abi}/${with_abiext} in
+		ilp32*/base)
+			# architectures that support ilp32* ABI
+			arch_pattern="native|loongarch32"
+			# default architecture for ilp32* ABI
+			arch_default="loongarch32"
+			;;
 		lp64*/base)
 			# architectures that support lp64* ABI
 			arch_pattern="native|loongarch64|la464"
@@ -5052,14 +5081,14 @@ case "${target}" in
 
 		# Infer ISA-related default options from the ABI: pass 2
 		case ${with_abi}/${with_abiext} 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"
 			;;
@@ -5118,6 +5147,10 @@ case "${target}" in
 			tune_pattern="*"
 			tune_default="native"
 			;;
+		loongarch32)
+			tune_pattern="loongarch32"
+			tune_default="loongarch32"
+			;;
 		loongarch64)
 			tune_pattern="loongarch64|la464"
 			tune_default="la464"
@@ -5187,6 +5220,9 @@ case "${target}" in
 				1)
 					# Component 1: Base ABI type
 					case ${component} in
+					ilp32d) elem_tmp="ABI_BASE_ILP32D,";;
+					ilp32f) elem_tmp="ABI_BASE_ILP32F,";;
+					ilp32s) elem_tmp="ABI_BASE_ILP32S,";;
 					lp64d) elem_tmp="ABI_BASE_LP64D,";;
 					lp64f) elem_tmp="ABI_BASE_LP64F,";;
 					lp64s) elem_tmp="ABI_BASE_LP64S,";;
@@ -5741,17 +5777,22 @@ case ${target} in
 		# See macro definitions from loongarch-opts.h and loongarch-cpu.h.
 		case ${with_arch} in
 		native)		tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_NATIVE" ;;
+		loongarch32)	tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_LOONGARCH32" ;;
 		la464)		tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_LA464" ;;
 		loongarch64)	tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_LOONGARCH64" ;;
 		esac
 
 		case ${with_tune} in
 		native)		tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_NATIVE" ;;
+		loongarch32)	tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_LOONGARCH32" ;;
 		la464)		tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_LA464" ;;
 		loongarch64)	tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_LOONGARCH64" ;;
 		esac
 
 		case ${with_abi} in
+		ilp32d)     tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_ILP32D" ;;
+		ilp32f)     tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_ILP32F" ;;
+		ilp32s)     tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_ILP32S" ;;
 		lp64d)     tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_LP64D" ;;
 		lp64f)     tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_LP64F" ;;
 		lp64s)     tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_LP64S" ;;
diff --git a/gcc/config/loongarch/genopts/loongarch-strings b/gcc/config/loongarch/genopts/loongarch-strings
index a40998ead97..1e20b70dde2 100644
--- a/gcc/config/loongarch/genopts/loongarch-strings
+++ b/gcc/config/loongarch/genopts/loongarch-strings
@@ -23,10 +23,12 @@ OPTSTR_ARCH	      arch
 OPTSTR_TUNE	      tune
 
 STR_CPU_NATIVE	      native
+STR_CPU_LOONGARCH32   loongarch32
 STR_CPU_LOONGARCH64   loongarch64
 STR_CPU_LA464	      la464
 
 # Base architecture
+STR_ISA_BASE_LA32V100 la32
 STR_ISA_BASE_LA64V100 la64
 
 # -mfpu
@@ -42,6 +44,9 @@ OPTSTR_DOUBLE_FLOAT   double-float
 
 # -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 4b9b4ac273e..47f77345890 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -85,6 +85,9 @@ LoongArch CPU types:
 EnumValue
 Enum(cpu_type) String(@@STR_CPU_NATIVE@@) Value(CPU_NATIVE)
 
+EnumValue
+Enum(cpu_type) String(@@STR_CPU_LOONGARCH32@@) Value(CPU_LOONGARCH32)
+
 EnumValue
 Enum(cpu_type) String(@@STR_CPU_LOONGARCH64@@) Value(CPU_LOONGARCH64)
 
@@ -108,6 +111,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 fa1a5211419..bf6d3a4fe98 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:-ilp32d}" \
+  "%{mabi=ilp32f:-ilp32f}" \
+  "%{mabi=ilp32s:-ilp32s}" \
   "%{mabi=lp64d:-lp64d}" \
   "%{mabi=lp64f:-lp64f}" \
   "%{mabi=lp64s:-lp64s}"
diff --git a/gcc/config/loongarch/linux.h b/gcc/config/loongarch/linux.h
index 9059d244190..45aa3531cd3 100644
--- a/gcc/config/loongarch/linux.h
+++ b/gcc/config/loongarch/linux.h
@@ -23,7 +23,13 @@ along with GCC; see the file COPYING3.  If not see
 
 #if 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 67911b78f28..e3783a325d7 100644
--- a/gcc/config/loongarch/loongarch-c.cc
+++ b/gcc/config/loongarch/loongarch-c.cc
@@ -65,12 +65,24 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile)
   LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_TUNE", LARCH_ACTUAL_TUNE);
 
   /* Base architecture / ABI.  */
+  if (TARGET_32BIT)
+    {
+      builtin_define ("__loongarch_grlen=32");
+      builtin_define ("__loongarch32");
+    }
   if (TARGET_64BIT)
     {
       builtin_define ("__loongarch_grlen=64");
       builtin_define ("__loongarch64");
     }
 
+  if (TARGET_ABI_ILP32)
+    {
+      builtin_define ("_ABILP32=3");
+      builtin_define ("_LOONGARCH_SIM=_ABILP32");
+      builtin_define ("__loongarch_ilp32");
+    }
+
   if (TARGET_ABI_LP64)
     {
       builtin_define ("_ABILP64=3");
diff --git a/gcc/config/loongarch/loongarch-def.c b/gcc/config/loongarch/loongarch-def.c
index 6729c857f7c..5ae8bd24c9f 100644
--- a/gcc/config/loongarch/loongarch-def.c
+++ b/gcc/config/loongarch/loongarch-def.c
@@ -40,12 +40,17 @@ along with GCC; see the file COPYING3.  If not see
 const char*
 loongarch_cpu_strings[N_TUNE_TYPES] = {
   [CPU_NATIVE]		  = STR_CPU_NATIVE,
+  [CPU_LOONGARCH32]	  = STR_CPU_LOONGARCH32,
   [CPU_LOONGARCH64]	  = STR_CPU_LOONGARCH64,
   [CPU_LA464]		  = STR_CPU_LA464,
 };
 
 struct loongarch_isa
 loongarch_cpu_default_isa[N_ARCH_TYPES] = {
+  [CPU_LOONGARCH32] = {
+      .base = ISA_BASE_LA32V100,
+      .fpu = ISA_EXT_FPU32,
+  },
   [CPU_LOONGARCH64] = {
       .base = ISA_BASE_LA64V100,
       .fpu = ISA_EXT_FPU64,
@@ -58,6 +63,12 @@ loongarch_cpu_default_isa[N_ARCH_TYPES] = {
 
 struct loongarch_cache
 loongarch_cpu_cache[N_TUNE_TYPES] = {
+  [CPU_LOONGARCH32] = {
+      .l1d_line_size = 64,
+      .l1d_size = 64,
+      .l2d_size = 256,
+      .simultaneous_prefetches = 4,
+  },
   [CPU_LOONGARCH64] = {
       .l1d_line_size = 64,
       .l1d_size = 64,
@@ -74,6 +85,10 @@ loongarch_cpu_cache[N_TUNE_TYPES] = {
 
 struct loongarch_align
 loongarch_cpu_align[N_TUNE_TYPES] = {
+  [CPU_LOONGARCH32] = {
+    .function = "32",
+    .label = "16",
+  },
   [CPU_LOONGARCH64] = {
     .function = "32",
     .label = "16",
@@ -94,6 +109,9 @@ loongarch_cpu_rtx_cost_data[N_TUNE_TYPES] = {
   [CPU_NATIVE] = {
       DEFAULT_COSTS
   },
+  [CPU_LOONGARCH32] = {
+      DEFAULT_COSTS
+  },
   [CPU_LOONGARCH64] = {
       DEFAULT_COSTS
   },
@@ -121,6 +139,7 @@ loongarch_rtx_cost_optimize_size = {
 int
 loongarch_cpu_issue_rate[N_TUNE_TYPES] = {
   [CPU_NATIVE]	      = 4,
+  [CPU_LOONGARCH32]   = 4,
   [CPU_LOONGARCH64]   = 4,
   [CPU_LA464]	      = 4,
 };
@@ -128,6 +147,7 @@ loongarch_cpu_issue_rate[N_TUNE_TYPES] = {
 int
 loongarch_cpu_multipass_dfa_lookahead[N_TUNE_TYPES] = {
   [CPU_NATIVE]	      = 4,
+  [CPU_LOONGARCH32]   = 4,
   [CPU_LOONGARCH64]   = 4,
   [CPU_LA464]	      = 4,
 };
@@ -139,6 +159,7 @@ loongarch_cpu_multipass_dfa_lookahead[N_TUNE_TYPES] = {
 
 const char*
 loongarch_isa_base_strings[N_ISA_BASE_TYPES] = {
+  [ISA_BASE_LA32V100] = STR_ISA_BASE_LA32V100,
   [ISA_BASE_LA64V100] = STR_ISA_BASE_LA64V100,
 };
 
@@ -151,6 +172,9 @@ loongarch_isa_ext_strings[N_ISA_EXT_TYPES] = {
 
 const char*
 loongarch_abi_base_strings[N_ABI_BASE_TYPES] = {
+  [ABI_BASE_ILP32D] = STR_ABI_BASE_ILP32D,
+  [ABI_BASE_ILP32F] = STR_ABI_BASE_ILP32F,
+  [ABI_BASE_ILP32S] = STR_ABI_BASE_ILP32S,
   [ABI_BASE_LP64D] = STR_ABI_BASE_LP64D,
   [ABI_BASE_LP64F] = STR_ABI_BASE_LP64F,
   [ABI_BASE_LP64S] = STR_ABI_BASE_LP64S,
@@ -182,6 +206,15 @@ loongarch_switch_strings[] = {
 /* ABI-related definitions.  */
 const struct loongarch_isa
 abi_minimal_isa[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES] = {
+  [ABI_BASE_ILP32D] = {
+      [ABI_EXT_BASE] = {.base = ISA_BASE_LA32V100, .fpu = ISA_EXT_FPU64},
+  },
+  [ABI_BASE_ILP32F] = {
+      [ABI_EXT_BASE] = {.base = ISA_BASE_LA32V100, .fpu = ISA_EXT_FPU32},
+  },
+  [ABI_BASE_ILP32S] = {
+      [ABI_EXT_BASE] = {.base = ISA_BASE_LA32V100, .fpu = ISA_EXT_NOFPU},
+  },
   [ABI_BASE_LP64D] = {
       [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU64},
   },
diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h
index fb8bb88eb52..6c4b9fa3385 100644
--- a/gcc/config/loongarch/loongarch-def.h
+++ b/gcc/config/loongarch/loongarch-def.h
@@ -54,8 +54,9 @@ extern "C" {
 
 /* enum isa_base */
 extern const char* loongarch_isa_base_strings[];
-#define ISA_BASE_LA64V100     0
-#define N_ISA_BASE_TYPES      1
+#define ISA_BASE_LA32V100     0
+#define ISA_BASE_LA64V100     1
+#define N_ISA_BASE_TYPES      2
 
 /* enum isa_ext_* */
 extern const char* loongarch_isa_ext_strings[];
@@ -67,10 +68,13 @@ extern const char* loongarch_isa_ext_strings[];
 
 /* enum abi_base */
 extern const char* loongarch_abi_base_strings[];
-#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
 
 /* enum abi_ext */
 extern const char* loongarch_abi_ext_strings[];
@@ -132,10 +136,11 @@ struct loongarch_target
 /* CPU properties.  */
 /* index */
 #define CPU_NATIVE	  0
-#define CPU_LOONGARCH64	  1
-#define CPU_LA464	  2
-#define N_ARCH_TYPES	  3
-#define N_TUNE_TYPES	  3
+#define CPU_LOONGARCH32	  1
+#define CPU_LOONGARCH64	  2
+#define CPU_LA464	  3
+#define N_ARCH_TYPES	  4
+#define N_TUNE_TYPES	  4
 
 /* parallel tables.  */
 extern const char* loongarch_cpu_strings[];
diff --git a/gcc/config/loongarch/loongarch-driver.h b/gcc/config/loongarch/loongarch-driver.h
index ba8817a4621..0a22acab803 100644
--- a/gcc/config/loongarch/loongarch-driver.h
+++ b/gcc/config/loongarch/loongarch-driver.h
@@ -58,9 +58,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 a52e25236ea..9fc0bbbcb6e 100644
--- a/gcc/config/loongarch/loongarch-opts.cc
+++ b/gcc/config/loongarch/loongarch-opts.cc
@@ -36,6 +36,9 @@ struct loongarch_target la_target;
 #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},
@@ -410,17 +413,23 @@ isa_default_abi (const struct loongarch_isa *isa)
   switch (isa->fpu)
     {
       case ISA_EXT_FPU64:
-	if (isa->base == ISA_BASE_LA64V100)
+	if (isa->base == ISA_BASE_LA32V100)
+	  abi.base = ABI_BASE_ILP32D;
+	else if (isa->base == ISA_BASE_LA64V100)
 	  abi.base = ABI_BASE_LP64D;
 	break;
 
       case ISA_EXT_FPU32:
-	if (isa->base == ISA_BASE_LA64V100)
+	if (isa->base == ISA_BASE_LA32V100)
+	  abi.base = ABI_BASE_ILP32F;
+	else if (isa->base == ISA_BASE_LA64V100)
 	  abi.base = ABI_BASE_LP64F;
 	break;
 
       case ISA_EXT_NOFPU:
-	if (isa->base == ISA_BASE_LA64V100)
+	if (isa->base == ISA_BASE_LA32V100)
+	  abi.base = ABI_BASE_ILP32S;
+	else if (isa->base == ISA_BASE_LA64V100)
 	  abi.base = ABI_BASE_LP64S;
 	break;
 
@@ -439,6 +448,8 @@ isa_base_compat_p (const struct loongarch_isa *set1,
 {
   switch (set2->base)
     {
+      case ISA_BASE_LA32V100:
+	return (set1->base == ISA_BASE_LA32V100);
       case ISA_BASE_LA64V100:
 	return (set1->base == ISA_BASE_LA64V100);
 
@@ -487,6 +498,11 @@ abi_default_cpu_arch (struct loongarch_abi abi)
 {
   switch (abi.base)
     {
+      case ABI_BASE_ILP32D:
+      case ABI_BASE_ILP32F:
+      case ABI_BASE_ILP32S:
+	if (abi.ext == ABI_EXT_BASE)
+	  return CPU_LOONGARCH32;
       case ABI_BASE_LP64D:
       case ABI_BASE_LP64F:
       case ABI_BASE_LP64S:
diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h
index b1ff54426e4..c8794dff0ad 100644
--- a/gcc/config/loongarch/loongarch-opts.h
+++ b/gcc/config/loongarch/loongarch-opts.h
@@ -51,15 +51,25 @@ loongarch_config_target (struct loongarch_target *target,
 #define TARGET_CMODEL_EXTREME	    (la_target.cmodel == CMODEL_EXTREME)
 
 #define TARGET_HARD_FLOAT	    (la_target.isa.fpu != ISA_EXT_NOFPU)
-#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_NOFPU)
-#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		  (la_target.isa.base == ISA_BASE_LA32V100)
+#define TARGET_ABI_ILP32	  (la_target.abi.base == ABI_BASE_ILP32D \
+				   || la_target.abi.base == ABI_BASE_ILP32F \
+				   || la_target.abi.base == ABI_BASE_ILP32S)
 
 #define TARGET_64BIT		  (la_target.isa.base == ISA_BASE_LA64V100)
 #define TARGET_ABI_LP64		  (la_target.abi.base == ABI_BASE_LP64D	\
@@ -78,9 +88,11 @@ loongarch_config_target (struct loongarch_target *target,
 				    ? (la_target.cpu_native) : (CPU_NATIVE)) \
 				    : (la_target.cpu_tune))
 
+#define TARGET_ARCH_LOONGARCH32	  (LARCH_ACTUAL_ARCH == CPU_LOONGARCH32)
 #define TARGET_ARCH_LOONGARCH64	  (LARCH_ACTUAL_ARCH == CPU_LOONGARCH64)
 #define TARGET_ARCH_LA464	  (LARCH_ACTUAL_ARCH == CPU_LA464)
 
+#define TARGET_TUNE_LOONGARCH32	  (LARCH_ACTUAL_TUNE == CPU_LOONGARCH32)
 #define TARGET_TUNE_LOONGARCH64	  (LARCH_ACTUAL_TUNE == CPU_LOONGARCH64)
 #define TARGET_TUNE_LA464	  (LARCH_ACTUAL_TUNE == CPU_LA464)
 
diff --git a/gcc/config/loongarch/loongarch-str.h b/gcc/config/loongarch/loongarch-str.h
index af2e82a321f..60588da45e2 100644
--- a/gcc/config/loongarch/loongarch-str.h
+++ b/gcc/config/loongarch/loongarch-str.h
@@ -27,9 +27,11 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTSTR_TUNE "tune"
 
 #define STR_CPU_NATIVE "native"
+#define STR_CPU_LOONGARCH32 "loongarch32"
 #define STR_CPU_LOONGARCH64 "loongarch64"
 #define STR_CPU_LA464 "la464"
 
+#define STR_ISA_BASE_LA32V100 "la32"
 #define STR_ISA_BASE_LA64V100 "la64"
 
 #define OPTSTR_ISA_EXT_FPU "fpu"
@@ -43,6 +45,9 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTSTR_DOUBLE_FLOAT "double-float"
 
 #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.cc b/gcc/config/loongarch/loongarch.cc
index 5b8b93eb24b..ff7904d49d5 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -6208,7 +6208,7 @@ loongarch_option_override_internal (struct gcc_options *opts)
 			   la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu,
 			   la_opt_abi_base, la_opt_abi_ext, la_opt_cmodel, 0);
 
-  if (TARGET_ABI_LP64)
+  if (TARGET_ABI_LP64 || TARGET_ABI_ILP32)
     flag_pcc_struct_return = 0;
 
   /* Decide which rtx_costs structure to use.  */
diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt
index 68018ade73f..2cd36c5e8fa 100644
--- a/gcc/config/loongarch/loongarch.opt
+++ b/gcc/config/loongarch/loongarch.opt
@@ -92,6 +92,9 @@ LoongArch CPU types:
 EnumValue
 Enum(cpu_type) String(native) Value(CPU_NATIVE)
 
+EnumValue
+Enum(cpu_type) String(loongarch32) Value(CPU_LOONGARCH32)
+
 EnumValue
 Enum(cpu_type) String(loongarch64) Value(CPU_LOONGARCH64)
 
@@ -115,6 +118,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 e40da179203..1718c3e11a2 100644
--- a/gcc/config/loongarch/t-linux
+++ b/gcc/config/loongarch/t-linux
@@ -17,8 +17,8 @@
 # <http://www.gnu.org/licenses/>.
 
 # Multilib
-MULTILIB_OPTIONS = mabi=lp64d/mabi=lp64f/mabi=lp64s
-MULTILIB_DIRNAMES = base/lp64d base/lp64f base/lp64s
+MULTILIB_OPTIONS = mabi=ilp32d/mabi=ilp32f/mabi=ilp32s/mabi=lp64d/mabi=lp64f/mabi=lp64s
+MULTILIB_DIRNAMES = base/ilp32d base/ilp32f base/ilp32s base/lp64d base/lp64f base/lp64s
 
 # The GCC driver always gets all abi-related options on the command line.
 # (see loongarch-driver.c:driver_get_normalized_m_opts)
@@ -38,6 +38,18 @@ endif
 # Don't define MULTILIB_OSDIRNAMES if multilib is disabled.
 ifeq ($(filter LA_DISABLE_MULTILIB,$(tm_defines)),)
 
+    MULTILIB_OSDIRNAMES = \
+      mabi.ilp32d=../lib32$\
+      $(call if_multiarch,:loongarch32-linux-gnu)
+
+    MULTILIB_OSDIRNAMES += \
+      mabi.ilp32f=../lib32/f32$\
+      $(call if_multiarch,:loongarch32-linux-gnuf32)
+
+    MULTILIB_OSDIRNAMES += \
+      mabi.ilp32s=../lib32/sf$\
+      $(call if_multiarch,:loongarch32-linux-gnusf)
+
     MULTILIB_OSDIRNAMES = \
       mabi.lp64d=../lib64$\
       $(call if_multiarch,:loongarch64-linux-gnu)
