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.
Add la32 march and mtune to gcc/doc/invoke.texi.
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.
* doc/invoke.texi: Add LA32 arch and tune.
libitm/ChangeLog:
* config/loongarch/asm.h: Fix ilp32 detection.
Co-authored-by: Jiajie Chen <c@jia.je>
Reviewed-by: Xi Ruoyao <xry111@xry111.site>
Reviewed-by: Lulu Cheng <chenglulu@loongson.cn>
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 \
# 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" ;;
# 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";;
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
# 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
# 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"
;;
# 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
# 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"
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
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"
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
# -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
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)
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.
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.
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)
"/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}"
&& 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"
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)
{
.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> ()
.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_NONE))
+ .set (ARCH_LA32RV1_0,
+ loongarch_isa ()
+ .base_ (ISA_BASE_LA32R)
+ .fpu_ (ISA_EXT_NONE));
static inline loongarch_cache la464_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 ()
{
.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 ()
.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
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 =
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);
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,
/* 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>
#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 {
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=*) */
TUNE_LOONGARCH64 = 2,
TUNE_LA464 = 3,
TUNE_LA664 = 4,
- N_TUNE_TYPES = 5,
+ TUNE_LOONGARCH32 = 5,
+ N_TUNE_TYPES = 6,
};
/* TLS types. */
/* 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}" \
{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. */
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:
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 ();
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:
case ARCH_ABI_DEFAULT:
case ARCH_LA64V1_0:
case ARCH_LA64V1_1:
+ case ARCH_LA32V1_0:
+ case ARCH_LA32RV1_0:
ret = fallback;
}
#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)
#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"
#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"
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)
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.
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.
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)
# 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)
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)
LoongArch64 ISA version 1.0.
@item la64v1.1
LoongArch64 ISA version 1.1.
+@item la32v1.0
+LoongArch32 ISA version 1.0.
+@item la32rv1.0
+LoongArch32 Reduced ISA version 1.0.
@end table
More information about LoongArch ISA versions can be found at
LoongArch LA464 core.
@item la664
LoongArch LA664 core.
+@item loongarch32
+Generic LoongArch 32-bit processor.
@end table
# define GPR_S st.d
# define SZ_GPR 8
# define ADDSP(si) addi.d $sp, $sp, si
-#elif defined(__loongarch64_ilp32)
+#elif defined(__loongarch_ilp32)
# define GPR_L ld.w
# define GPR_S st.w
# define SZ_GPR 4