Introduce LoongArch32 (LA32) ilp32d abi and LoongArch32 Reduced (LA32R) ilp32s
abi.
Add march la32v1.0 and la32rv1.0.
Add mtune loongarch32 as a general 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.cc (loongarch_explicit_relocs_p): Set
EXPLICIT_RELOCS_NONE on LA32.
* 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 | 5 ++
gcc/config/loongarch/loongarch-def.cc | 51 ++++++++++++++++---
gcc/config/loongarch/loongarch-def.h | 28 +++++++---
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.cc | 3 ++
gcc/config/loongarch/loongarch.opt | 24 +++++++++
gcc/config/loongarch/t-linux | 6 +++
16 files changed, 246 insertions(+), 33 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 b0fa43b5eba..3e647dae1c8 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..6e2f8f43818 100644
--- a/gcc/config/loongarch/loongarch-c.cc
+++ b/gcc/config/loongarch/loongarch-c.cc
@@ -55,6 +55,11 @@ 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 ("__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..82ced44e77f 100644
--- a/gcc/config/loongarch/loongarch-def.h
+++ b/gcc/config/loongarch/loongarch-def.h
@@ -55,7 +55,9 @@ 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 = 1, /* LoongArch32 */
+ ISA_BASE_LA32R = 2, /* LoongArch32 Reduced */
+ N_ISA_BASE_TYPES = 3
};
extern loongarch_def_array<const char *, N_ISA_BASE_TYPES>
@@ -81,25 +83,32 @@ extern loongarch_def_array<const char *, N_ISA_EXT_TYPES>
#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 3
+#define ABI_BASE_ILP32F 4
+#define ABI_BASE_ILP32S 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,7 +199,9 @@ 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=*) */
@@ -200,7 +211,8 @@ enum {
TUNE_LOONGARCH64 = 2,
TUNE_LA464 = 3,
TUNE_LA664 = 4,
- N_TUNE_TYPES = 5,
+ TUNE_LOONGARCH32 = 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 cacfe370345..c2a23fc16e1 100644
--- a/gcc/config/loongarch/loongarch-opts.cc
+++ b/gcc/config/loongarch/loongarch-opts.cc
@@ -46,6 +46,9 @@ abi_priority_list[] = {
{ABI_BASE_LP64D, ABI_EXT_BASE},
{ABI_BASE_LP64F, ABI_EXT_BASE},
{ABI_BASE_LP64S, ABI_EXT_BASE},
+ {ABI_BASE_ILP32D, ABI_EXT_BASE},
+ {ABI_BASE_ILP32F, ABI_EXT_BASE},
+ {ABI_BASE_ILP32S, ABI_EXT_BASE},
};
/* Initialize enabled_abi_types from TM_MULTILIB_LIST. */
@@ -567,6 +570,10 @@ fallback:
/* Cleanup and return. */
obstack_free (&msg_obstack, NULL);
*target = t;
+
+ /* TODO: mexplicit-relocs support for LA32. */
+ if (!TARGET_64BIT)
+ la_opt_explicit_relocs = EXPLICIT_RELOCS_NONE;
}
/* Returns the default ABI for the given instruction set. */
@@ -578,18 +585,24 @@ 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_LA64)
abi.base = ABI_BASE_LP64D;
+ else if (isa->base == ISA_BASE_LA32 || isa->base == ISA_BASE_LA32R)
+ abi.base = ABI_BASE_ILP32D;
break;
case ISA_EXT_FPU32:
- if (isa->base >= ISA_BASE_LA64)
+ if (isa->base == ISA_BASE_LA64)
abi.base = ABI_BASE_LP64F;
+ else if (isa->base == ISA_BASE_LA32 || isa->base == ISA_BASE_LA32R)
+ abi.base = ABI_BASE_ILP32F;
break;
case ISA_EXT_NONE:
- if (isa->base >= ISA_BASE_LA64)
+ if (isa->base == ISA_BASE_LA64)
abi.base = ABI_BASE_LP64S;
+ else if (isa->base == ISA_BASE_LA32 || isa->base == ISA_BASE_LA32R)
+ abi.base = ABI_BASE_ILP32S;
break;
default:
@@ -608,7 +621,13 @@ isa_base_compat_p (const struct loongarch_isa *set1,
switch (set2->base)
{
case ISA_BASE_LA64:
- return (set1->base >= ISA_BASE_LA64);
+ return (set1->base == ISA_BASE_LA64);
+
+ 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);
default:
gcc_unreachable ();
@@ -661,6 +680,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 +717,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;
}
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.cc
b/gcc/config/loongarch/loongarch.cc
index b558efde4c7..38518c9edec 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2087,6 +2087,9 @@ loongarch_symbolic_constant_p (rtx x, enum
loongarch_symbol_type *symbol_type)
bool
loongarch_explicit_relocs_p (enum loongarch_symbol_type type)
{
+ if (TARGET_32BIT)
+ return false;
+
if (la_opt_explicit_relocs != EXPLICIT_RELOCS_AUTO)
return la_opt_explicit_relocs == EXPLICIT_RELOCS_ALWAYS;
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