diff --git a/config-ml.in b/config-ml.in
index 68854a4f16c2b..ad0db07817182 100644
--- a/config-ml.in
+++ b/config-ml.in
@@ -301,6 +301,16 @@ arm-*-*)
done
fi
;;
+loongarch*-*)
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ `${CC-gcc} --print-multi-directory`) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ ;;
m68*-*-*)
if [ x$enable_softfloat = xno ]
then
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 0ba1a7f494cc3..543b0ba076ba0 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4891,43 +4891,46 @@ case "${target}" in
esac
;;
- loongarch*-*-*)
- supported_defaults="abi arch tune fpu"
+ loongarch*-*)
+ supported_defaults="abi arch tune fpu simd multilib-default"
# Local variables
unset \
- abi_pattern abi_default \
- abiext_pattern abiext_default \
- arch_pattern arch_default \
- fpu_pattern fpu_default \
- tune_pattern tune_default \
- triplet_os triplet_abi
+ abi_base abi_ext \
+ arch_pattern arch_default \
+ fpu_pattern fpu_default \
+ triplet_os triplet_abi \
+ strict_align_opt
+
+ # --with-abi is now obsolete, emit a warning if given.
+ case ${with_abi} in
+ "") ;;
+ *)
+ echo "warning: --with-abi= is now obsolete," \
+ "the default ABI is derived from your target" \
+ "triplet ${target}" 1>&2
+ ;;
+ esac
# Infer ABI from the triplet.
case ${target} in
- loongarch64-*-*-*f64)
- abi_pattern="lp64d"
- ;;
- loongarch64-*-*-*f32)
- abi_pattern="lp64f"
- ;;
- loongarch64-*-*-*sf)
- abi_pattern="lp64s"
- ;;
- loongarch64-*-*-*)
- abi_pattern="lp64[dfs]"
- abi_default="lp64d"
- ;;
+ loongarch64-*f64) abi_base="lp64d"; abi_ext="base" ;;
+ loongarch64-*f32) abi_base="lp64f"; abi_ext="base" ;;
+ loongarch64-*sf) abi_base="lp64s"; abi_ext="base" ;;
+ loongarch64-*) abi_base="lp64d"; abi_ext="base" ;;
*)
echo "Unsupported target ${target}." 1>&2
exit 1
;;
esac
- abiext_pattern="*"
- abiext_default="base"
-
# Get the canonical triplet (multiarch specifier).
+ case ${abi_base},${abi_ext} in
+ lp64d,base) triplet_abi="";;
+ lp64f,base) triplet_abi="f32";;
+ lp64s,base) triplet_abi="sf";;
+ esac
+
case ${target} in
*-linux-gnu*) triplet_os="linux-gnu";;
*-linux-musl*) triplet_os="linux-musl";;
@@ -4936,42 +4939,24 @@ case "${target}" in
exit 1
;;
esac
+ la_canonical_triplet="loongarch64-${triplet_os}${triplet_abi}"
+
# Perform initial sanity checks on --with-* options.
case ${with_arch} in
- "" | loongarch64 | la464) ;; # OK, append here.
+ "" | abi-default | loongarch64 | la464) ;; # OK, append here.
native)
if test x${host} != x${target}; then
echo "--with-arch=native is illegal for cross-compiler." 1>&2
exit 1
fi
;;
- "")
- echo "Please set a default value for \${with_arch}" \
- "according to your target triplet \"${target}\"." 1>&2
- exit 1
- ;;
*)
echo "Unknown arch in --with-arch=$with_arch" 1>&2
exit 1
;;
esac
- case ${with_abi} in
- "" | lp64d | lp64f | lp64s) ;; # OK, append here.
- *)
- echo "Unsupported ABI given in --with-abi=$with_abi" 1>&2
- exit 1
- ;;
- esac
-
- case ${with_abiext} in
- "" | base) ;; # OK, append here.
- *)
- echo "Unsupported ABI extention type $with_abiext" 1>&2
- exit 1
- ;;
- esac
case ${with_fpu} in
"" | none | 32 | 64) ;; # OK, append here.
@@ -4985,73 +4970,41 @@ case "${target}" in
;;
esac
-
- # Set default value for with_abi.
- case ${with_abi} in
- "")
- if test x${abi_default} != x; then
- with_abi=${abi_default}
- else
- with_abi=${abi_pattern}
- fi
- ;;
-
- *)
- if echo "${with_abi}" | grep -E "^${abi_pattern}$" > /dev/null; then
- : # OK
- else
- echo "Incompatible options:" \
- "--with-abi=${with_abi} and --target=${target}." 1>&2
+ case ${with_simd} in
+ "" | none) ;;
+ lsx | lasx) # OK, append here.
+ case ${with_fpu} in
+ 64) ;;
+ "") with_fpu=64 ;;
+ *)
+ echo "--with-simd=${with_simd} conflicts with --with-fpu=${with_fpu}" 1>&2
exit 1
- fi
- ;;
- esac
-
- case ${with_abi} in
- "lp64d") triplet_abi="";;
- "lp64f") triplet_abi="f32";;
- "lp64s") triplet_abi="sf";;
- esac
- la_canonical_triplet="loongarch64-${triplet_os}${triplet_abi}"
-
- # Set default value for with_abiext (internal)
- case ${with_abiext} in
- "")
- if test x${abiext_default} != x; then
- with_abiext=${abiext_default}
- else
- with_abiext=${abiext_pattern}
- fi
+ ;;
+ esac
;;
*)
- if echo "${with_abiext}" | grep -E "^${abiext_pattern}$" > /dev/null; then
- : # OK
- else
- echo "The ABI extension type \"${with_abiext}\"" \
- "is incompatible with --target=${target}." 1>&2
- exit 1
- fi
-
+ echo "Unknown SIMD extension in --with-simd=$with_simd" 1>&2
+ exit 1
;;
esac
# Infer ISA-related default options from the ABI: pass 1
- case ${with_abi}/${with_abiext} in
+ case ${abi_base}/${abi_ext} in
lp64*/base)
# architectures that support lp64* ABI
- arch_pattern="native|loongarch64|la464"
+ arch_pattern="native|abi-default|loongarch64|la464"
# default architecture for lp64* ABI
- arch_default="loongarch64"
+ arch_default="abi-default"
;;
*)
- echo "Unsupported ABI type ${with_abi}/${with_abiext}." 1>&2
+ echo "Unsupported ABI type ${abi_base}/${abi_ext}." 1>&2
exit 1
;;
esac
# Infer ISA-related default options from the ABI: pass 2
- case ${with_abi}/${with_abiext} in
+ case ${abi_base}/${abi_ext} in
lp64d/base)
fpu_pattern="64"
;;
@@ -5064,7 +5017,7 @@ case "${target}" in
fpu_default="none"
;;
*)
- echo "Unsupported ABI type ${with_abi}/${with_abiext}." 1>&2
+ echo "Unsupported ABI type ${abi_base}/${abi_ext}." 1>&2
exit 1
;;
esac
@@ -5083,7 +5036,7 @@ case "${target}" in
if echo "${with_arch}" | grep -E "^${arch_pattern}$" > /dev/null; then
: # OK
else
- echo "${with_abi}/${with_abiext} ABI cannot be implemented with" \
+ echo "${abi_base}/${abi_ext} ABI cannot be implemented with" \
"--with-arch=${with_arch}." 1>&2
exit 1
fi
@@ -5104,7 +5057,7 @@ case "${target}" in
if echo "${with_fpu}" | grep -E "^${fpu_pattern}$" > /dev/null; then
: # OK
else
- echo "${with_abi}/${with_abiext} ABI cannot be implemented with" \
+ echo "${abi_base}/${abi_ext} ABI cannot be implemented with" \
"--with-fpu=${with_fpu}." 1>&2
exit 1
fi
@@ -5112,32 +5065,19 @@ case "${target}" in
esac
- # Infer default with_tune from with_arch: pass 1
+ # Check default with_tune configuration using with_arch.
case ${with_arch} in
- native)
- tune_pattern="*"
- tune_default="native"
- ;;
loongarch64)
- tune_pattern="loongarch64|la464"
- tune_default="la464"
+ tune_pattern="native|abi-default|loongarch64|la464"
;;
*)
# By default, $with_tune == $with_arch
- tune_pattern="$with_arch"
+ tune_pattern="*"
;;
esac
- ## Set default value for with_tune.
case ${with_tune} in
- "")
- if test x${tune_default} != x; then
- with_tune=${tune_default}
- else
- with_tune=${tune_pattern}
- fi
- ;;
-
+ "") ;; # OK
*)
if echo "${with_tune}" | grep -E "^${tune_pattern}$" > /dev/null; then
: # OK
@@ -5149,13 +5089,53 @@ case "${target}" in
;;
esac
+ # Handle --with-multilib-default
+ if echo "${with_multilib_default}" \
+ | grep -E -e '[[:space:]]' -e '//' -e '/$' -e '^/' > /dev/null 2>&1; then
+ echo "Invalid argument to --with-multilib-default." 1>&2
+ exit 1
+ fi
+
+ if test x${with_multilib_default} = x; then
+ # Use -march=abi-default by default when building libraries.
+ with_multilib_default="/march=abi-default"
+ else
+ unset parse_state component
+ parse_state=arch
+ for component in $(echo "${with_multilib_default}" | tr '/' ' '); do
+ case ${parse_state},${component} in
+ arch,|arch,abi-default)
+ # ABI-default: use the ABI's default ARCH configuration for
+ # multilib library builds, unless otherwise specified
+ # in --with-multilib-list.
+ with_multilib_default="/march=abi-default" ;;
+ arch,fixed)
+ # Fixed: use the default gcc configuration for all multilib
+ # builds by default.
+ with_multilib_default="" ;;
+ arch,native|arch,loongarch64|arch,la464) # OK, append here.
+ with_multilib_default="/march=${component}" ;;
+ arch,*)
+ with_multilib_default="/march=abi-default"
+ with_multilib_default="${with_multilib_default}/${component}" ;;
+ opts,*)
+ with_multilib_default="${with_multilib_default}/${component}" ;;
+ esac
+
+ if test x${parse_state} = xarch; then
+ parse_state=opt;
+ fi
+ done
+ unset parse_state component
+ fi
+
# Handle --with-multilib-list.
if test x"${with_multilib_list}" = x \
|| test x"${with_multilib_list}" = xno \
|| test x"${with_multilib_list}" = xdefault \
|| test x"${enable_multilib}" != xyes; then
- with_multilib_list="${with_abi}/${with_abiext}"
+ with_multilib_list="${abi_base}/${abi_ext}"
fi
# Check if the configured default ABI combination is included in
@@ -5171,25 +5151,21 @@ case "${target}" in
# ${with_multilib_list} should not contain whitespaces,
# consecutive commas or slashes.
if echo "${with_multilib_list}" \
- | grep -E -e "[[:space:]]" -e '[,/][,/]' -e '[,/]$' -e '^[,/]' > /dev/null; then
+ | grep -E -e "[[:space:]]" -e '[,/][,/]' -e '[,/]$' -e '^[,/]' > /dev/null 2>&1; then
echo "Invalid argument to --with-multilib-list." 1>&2
exit 1
fi
- unset component idx elem_abi_base elem_abi_ext elem_tmp
+ unset component elem_abi_base elem_abi_ext elem_tmp parse_state all_abis
for elem in $(echo "${with_multilib_list}" | tr ',' ' '); do
- idx=0
- while true; do
- idx=$((idx + 1))
- component=$(echo "${elem}" | awk -F'/' '{print $'"${idx}"'}')
-
- case ${idx} in
- 1)
- # Component 1: Base ABI type
+ unset elem_abi_base elem_abi_ext
+ parse_state="abi-base"
+
+ for component in $(echo "${elem}" | tr '/' ' '); do
+ if test x${parse_state} = x"abi-base"; then
+ # Base ABI type
case ${component} in
- lp64d) elem_tmp="ABI_BASE_LP64D,";;
- lp64f) elem_tmp="ABI_BASE_LP64F,";;
- lp64s) elem_tmp="ABI_BASE_LP64S,";;
+ lp64d | lp64f | lp64s) elem_tmp="ABI_BASE_$(tr a-z A-Z <<< ${component}),";;
*)
echo "Unknown base ABI \"${component}\" in --with-multilib-list." 1>&2
exit 1
@@ -5198,57 +5174,111 @@ case "${target}" in
loongarch_multilib_list_c="${loongarch_multilib_list_c}${elem_tmp}"
loongarch_multilib_list_make="${loongarch_multilib_list_make}mabi=${component}"
elem_abi_base="${component}"
- ;;
- 2)
- # Component 2: ABI extension type
+ parse_state="abi-ext"
+ continue
+ fi
+
+ if test x${parse_state} = x"abi-ext"; then
+ # ABI extension type
case ${component} in
- "" | base)
- component="base"
- elem_tmp="ABI_EXT_BASE,"
- ;;
- *)
- echo "Unknown ABI extension \"${component}\" in --with-multilib-list." 1>&2
- exit 1
+ base)
+ elem_abi_ext="base"
+ loongarch_multilib_list_c="${loongarch_multilib_list_c}ABI_EXT_BASE,"
+ loongarch_multilib_list_make="${loongarch_multilib_list_make}" # Add nothing for now.
+ parse_state="arch"
+ continue;
;;
esac
- loongarch_multilib_list_c="${loongarch_multilib_list_c}${elem_tmp}"
+
+ # The default ABI extension is "base" if unspecified.
+ elem_abi_ext="base"
+ loongarch_multilib_list_c="${loongarch_multilib_list_c}ABI_EXT_BASE,"
loongarch_multilib_list_make="${loongarch_multilib_list_make}" # Add nothing for now.
- elem_abi_ext="${component}"
- ;;
+ parse_state="arch"
+ fi
- *)
- # Component 3 and on: optional stuff
+ if test x${parse_state} = x"arch"; then
+ # -march option
case ${component} in
- "")
- # End of component list.
- break
+ native | abi-default | loongarch64 | la464) # OK, append here.
+ # Append -march spec for each multilib variant.
+ loongarch_multilib_list_make="${loongarch_multilib_list_make}/march=${component}"
+ parse_state="opts"
+ continue
+ ;;
+
+ default)
+ # "/default" is equivalent to --with-multilib-default=fixed
+ parse_state="opts"
+ continue
;;
+ esac
+
+ # If ARCH is unspecified for this multilib variant, use ${with_multllib_default}.
+ loongarch_multilib_list_make="${loongarch_multilib_list_make}${with_multilib_default}"
+ parse_state="opts"
+ fi
+
+ if test x${parse_state} = x"opts"; then
+ # Other compiler options for building libraries.
+ # (no static sanity check performed)
+ case ${component} in
*)
- echo "Unknown ABI \"${elem}\" in --with-multilib-list." 1>&2
- exit 1
+ # Append other components as additional build options
+ # (without the prepending dash).
+ # Their validity should be examined by the compiler.
+ loongarch_multilib_list_make="${loongarch_multilib_list_make}/${component}"
;;
esac
- ;;
- esac
+ fi
done
- if test x${elem_abi_base} = x${with_abi} \
- && test x${elem_abi_ext} = x${with_abiext}; then
+ case ${parse_state} in
+ "abi-ext")
+ elem_abi_ext="base"
+ loongarch_multilib_list_c="${loongarch_multilib_list_c}ABI_EXT_BASE,"
+ loongarch_multilib_list_make="${loongarch_multilib_list_make}" # Add nothing for now.
+ loongarch_multilib_list_make="${loongarch_multilib_list_make}${with_multilib_default}"
+ ;;
+ "arch")
+ # If ARCH is unspecified for this multilib variant, use ${with_multllib_default}.
+ loongarch_multilib_list_make="${loongarch_multilib_list_make}${with_multilib_default}"
+ ;;
+ "opts")
+ :
+ ;;
+ esac
+
+ # Check for repeated configuration of the same multilib variant.
+ if echo "${elem_abi_base}/${elem_abi_ext}" \
+ | grep -E "^(${all_abis%|})$" >/dev/null 2>&1; then
+ echo "Repeated multilib config of \"${elem_abi_base}/${elem_abi_ext}\" in --with-multilib-list."
+ exit 1
+ fi
+ all_abis="${all_abis}${elem_abi_base}/${elem_abi_ext}|"
+
+
+ # Check if the default ABI configuration of the GCC binary
+ # is included in the enabled multilib variants.
+ if test x${elem_abi_base} = x${abi_base} \
+ && test x${elem_abi_ext} = x${abi_ext}; then
loongarch_multilib_list_sane=yes
fi
loongarch_multilib_list_make="${loongarch_multilib_list_make},"
done
+ unset component elem_abi_base elem_abi_ext elem_tmp parse_state all_abis
+
# Check if the default ABI combination is in the default list.
if test x${loongarch_multilib_list_sane} = xno; then
- if test x${with_abiext} = xbase; then
- with_abiext=""
+ if test x${abi_ext} = xbase; then
+ abi_ext=""
else
- with_abiext="/${with_abiext}"
+ abi_ext="/${abi_ext}"
fi
- echo "Default ABI combination (${with_abi}${with_abiext})" \
+ echo "Default ABI combination (${abi_base}${abi_ext})" \
"not found in --with-multilib-list." 1>&2
exit 1
fi
@@ -5739,34 +5769,37 @@ case ${target} in
# Let --with- flags initialize the enum variables from loongarch.opt.
# 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" ;;
- 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" ;;
- la464) tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_LA464" ;;
- loongarch64) tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_LOONGARCH64" ;;
- esac
+ # Architecture
+ tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_$(echo ${with_arch} | tr a-z- A-Z_)"
- case ${with_abi} in
- 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" ;;
- esac
+ # Base ABI type
+ tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_$(echo ${abi_base} | tr a-z- A-Z_)"
- case ${with_abiext} in
+ # ABI Extension
+ case ${abi_ext} in
base) tm_defines="${tm_defines} DEFAULT_ABI_EXT=ABI_EXT_BASE" ;;
esac
+ # Microarchitecture
+ if test x${with_tune} != x; then
+ tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_$(echo ${with_tune} | tr a-z- A-Z_)"
+ fi
+
+ # FPU adjustment
case ${with_fpu} in
- none) tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_NOFPU" ;;
+ none) tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_NONE" ;;
32) tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_FPU32" ;;
64) tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_FPU64" ;;
esac
+ # SIMD extensions
+ case ${with_simd} in
+ none) tm_defines="$tm_defines DEFAULT_ISA_EXT_SIMD=ISA_EXT_NONE" ;;
+ lsx) tm_defines="$tm_defines DEFAULT_ISA_EXT_SIMD=ISA_EXT_SIMD_LSX" ;;
+ lasx) tm_defines="$tm_defines DEFAULT_ISA_EXT_SIMD=ISA_EXT_SIMD_LASX" ;;
+ esac
+
tmake_file="loongarch/t-loongarch $tmake_file"
;;
diff --git a/gcc/config/loongarch/genopts/loongarch-strings b/gcc/config/loongarch/genopts/loongarch-strings
index a40998ead975a..adecaec3eda5e 100644
--- a/gcc/config/loongarch/genopts/loongarch-strings
+++ b/gcc/config/loongarch/genopts/loongarch-strings
@@ -23,6 +23,7 @@ OPTSTR_ARCH arch
OPTSTR_TUNE tune
STR_CPU_NATIVE native
+STR_CPU_ABI_DEFAULT abi-default
STR_CPU_LOONGARCH64 loongarch64
STR_CPU_LA464 la464
@@ -31,7 +32,7 @@ STR_ISA_BASE_LA64V100 la64
# -mfpu
OPTSTR_ISA_EXT_FPU fpu
-STR_ISA_EXT_NOFPU none
+STR_NONE none
STR_ISA_EXT_FPU0 0
STR_ISA_EXT_FPU32 32
STR_ISA_EXT_FPU64 64
@@ -40,6 +41,11 @@ OPTSTR_SOFT_FLOAT soft-float
OPTSTR_SINGLE_FLOAT single-float
OPTSTR_DOUBLE_FLOAT double-float
+# SIMD extensions
+OPTSTR_ISA_EXT_SIMD simd
+STR_ISA_EXT_LSX lsx
+STR_ISA_EXT_LASX lasx
+
# -mabi=
OPTSTR_ABI_BASE abi
STR_ABI_BASE_LP64D lp64d
diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in
index 4b9b4ac273e91..f3567b279358d 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -17,22 +17,12 @@
; .
;
-; Variables (macros) that should be exported by loongarch.opt:
-; la_opt_switches,
-; la_opt_abi_base, la_opt_abi_ext,
-; la_opt_cpu_arch, la_opt_cpu_tune,
-; la_opt_fpu,
-; la_cmodel.
-
HeaderInclude
config/loongarch/loongarch-opts.h
HeaderInclude
config/loongarch/loongarch-str.h
-Variable
-HOST_WIDE_INT la_opt_switches = 0
-
; ISA related options
;; Base ISA
Enum
@@ -42,14 +32,13 @@ Basic ISAs of LoongArch:
EnumValue
Enum(isa_base) String(@@STR_ISA_BASE_LA64V100@@) Value(ISA_BASE_LA64V100)
-
;; ISA extensions / adjustments
Enum
Name(isa_ext_fpu) Type(int)
FPU types of LoongArch:
EnumValue
-Enum(isa_ext_fpu) String(@@STR_ISA_EXT_NOFPU@@) Value(ISA_EXT_NOFPU)
+Enum(isa_ext_fpu) String(@@STR_NONE@@) Value(ISA_EXT_NONE)
EnumValue
Enum(isa_ext_fpu) String(@@STR_ISA_EXT_FPU32@@) Value(ISA_EXT_FPU32)
@@ -58,24 +47,48 @@ EnumValue
Enum(isa_ext_fpu) String(@@STR_ISA_EXT_FPU64@@) Value(ISA_EXT_FPU64)
m@@OPTSTR_ISA_EXT_FPU@@=
-Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPT_UNSET)
-m@@OPTSTR_ISA_EXT_FPU@@=FPU Generate code for the given FPU.
m@@OPTSTR_ISA_EXT_FPU@@=@@STR_ISA_EXT_FPU0@@
-Target RejectNegative Alias(m@@OPTSTR_ISA_EXT_FPU@@=,@@STR_ISA_EXT_NOFPU@@)
+Target RejectNegative Alias(m@@OPTSTR_ISA_EXT_FPU@@=,@@STR_NONE@@)
m@@OPTSTR_SOFT_FLOAT@@
-Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_SOFTF) Negative(m@@OPTSTR_SINGLE_FLOAT@@)
+Target Driver Defer Var(la_deferred_options) RejectNegative Negative(m@@OPTSTR_SINGLE_FLOAT@@)
Prevent the use of all hardware floating-point instructions.
m@@OPTSTR_SINGLE_FLOAT@@
-Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F32) Negative(m@@OPTSTR_DOUBLE_FLOAT@@)
+Target Driver Defer Var(la_deferred_options) RejectNegative Negative(m@@OPTSTR_DOUBLE_FLOAT@@)
Restrict the use of hardware floating-point instructions to 32-bit operations.
m@@OPTSTR_DOUBLE_FLOAT@@
-Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F64) Negative(m@@OPTSTR_SOFT_FLOAT@@)
+Target Driver Defer Var(la_deferred_options) RejectNegative Negative(m@@OPTSTR_SOFT_FLOAT@@)
Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations.
+Enum
+Name(isa_ext_simd) Type(int)
+SIMD extension levels of LoongArch:
+
+EnumValue
+Enum(isa_ext_simd) String(@@STR_NONE@@) Value(ISA_EXT_NONE)
+
+EnumValue
+Enum(isa_ext_simd) String(@@STR_ISA_EXT_LSX@@) Value(ISA_EXT_SIMD_LSX)
+
+EnumValue
+Enum(isa_ext_simd) String(@@STR_ISA_EXT_LASX@@) Value(ISA_EXT_SIMD_LASX)
+
+m@@OPTSTR_ISA_EXT_SIMD@@=
+Target RejectNegative Joined ToLower Enum(isa_ext_simd) Var(la_opt_simd) Init(M_OPT_UNSET)
+-m@@OPTSTR_ISA_EXT_SIMD@@=SIMD Generate code for the given SIMD extension.
+
+m@@STR_ISA_EXT_LSX@@
+Target Driver Defer Var(la_deferred_options)
+Enable LoongArch SIMD Extension (LSX, 128-bit).
+
+m@@STR_ISA_EXT_LASX@@
+Target Driver Defer Var(la_deferred_options)
+Enable LoongArch Advanced SIMD Extension (LASX, 256-bit).
;; Base target models (implies ISA & tune parameters)
Enum
@@ -85,6 +98,9 @@ LoongArch CPU types:
EnumValue
Enum(cpu_type) String(@@STR_CPU_NATIVE@@) Value(CPU_NATIVE)
+EnumValue
+Enum(cpu_type) String(@@STR_CPU_ABI_DEFAULT@@) Value(CPU_ABI_DEFAULT)
+
EnumValue
Enum(cpu_type) String(@@STR_CPU_LOONGARCH64@@) Value(CPU_LOONGARCH64)
@@ -92,11 +108,11 @@ EnumValue
Enum(cpu_type) String(@@STR_CPU_LA464@@) Value(CPU_LA464)
m@@OPTSTR_ARCH@@=
-Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPT_UNSET)
-m@@OPTSTR_ARCH@@=PROCESSOR Generate code for the given PROCESSOR ISA.
m@@OPTSTR_TUNE@@=
-Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPT_UNSET)
-m@@OPTSTR_TUNE@@=PROCESSOR Generate optimized code for PROCESSOR.
@@ -118,13 +134,13 @@ EnumValue
Enum(abi_base) String(@@STR_ABI_BASE_LP64S@@) Value(ABI_BASE_LP64S)
m@@OPTSTR_ABI_BASE@@=
-Target RejectNegative Joined ToLower Enum(abi_base) Var(la_opt_abi_base) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined ToLower Enum(abi_base) Var(la_opt_abi_base) Init(M_OPT_UNSET)
-m@@OPTSTR_ABI_BASE@@=BASEABI Generate code that conforms to the given BASEABI.
+
;; ABI Extension
Variable
-int la_opt_abi_ext = M_OPTION_NOT_SEEN
-
+int la_opt_abi_ext = M_OPT_UNSET
mbranch-cost=
Target RejectNegative Joined UInteger Var(loongarch_branch_cost)
@@ -182,7 +198,7 @@ EnumValue
Enum(cmodel) String(@@STR_CMODEL_EXTREME@@) Value(CMODEL_EXTREME)
mcmodel=
-Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(CMODEL_NORMAL)
+Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(M_OPT_UNSET)
Specify the code model.
mdirect-extern-access
diff --git a/gcc/config/loongarch/la464.md b/gcc/config/loongarch/la464.md
index 541040fdfa864..3b4d14f0b3cb3 100644
--- a/gcc/config/loongarch/la464.md
+++ b/gcc/config/loongarch/la464.md
@@ -43,88 +43,88 @@
;; Describe instruction reservations.
(define_insn_reservation "la464_arith" 1
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "arith,clz,const,logical,
move,nop,shift,signext,slt"))
"la464_alu1 | la464_alu2")
(define_insn_reservation "la464_branch" 1
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "branch,jump,call,condmove,trap"))
"la464_alu1 | la464_alu2")
(define_insn_reservation "la464_imul" 7
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "imul"))
"la464_alu1 | la464_alu2")
(define_insn_reservation "la464_idiv_si" 12
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(and (eq_attr "type" "idiv")
(eq_attr "mode" "SI")))
"la464_alu1 | la464_alu2")
(define_insn_reservation "la464_idiv_di" 25
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(and (eq_attr "type" "idiv")
(eq_attr "mode" "DI")))
"la464_alu1 | la464_alu2")
(define_insn_reservation "la464_load" 4
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "load"))
"la464_mem1 | la464_mem2")
(define_insn_reservation "la464_gpr_fp" 16
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "mftg,mgtf"))
"la464_mem1")
(define_insn_reservation "la464_fpload" 4
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "fpload"))
"la464_mem1 | la464_mem2")
(define_insn_reservation "la464_prefetch" 0
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "prefetch,prefetchx"))
"la464_mem1 | la464_mem2")
(define_insn_reservation "la464_store" 0
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "store,fpstore,fpidxstore"))
"la464_mem1 | la464_mem2")
(define_insn_reservation "la464_fadd" 4
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "fadd,fmul,fmadd"))
"la464_falu1 | la464_falu2")
(define_insn_reservation "la464_fcmp" 2
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "fabs,fcmp,fmove,fneg"))
"la464_falu1 | la464_falu2")
(define_insn_reservation "la464_fcvt" 4
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "fcvt"))
"la464_falu1 | la464_falu2")
(define_insn_reservation "la464_fdiv_sf" 12
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(and (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt")
(eq_attr "mode" "SF")))
"la464_falu1 | la464_falu2")
(define_insn_reservation "la464_fdiv_df" 19
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(and (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt")
(eq_attr "mode" "DF")))
"la464_falu1 | la464_falu2")
;; Force single-dispatch for unknown or multi.
(define_insn_reservation "la464_unknown" 1
- (and (match_test "TARGET_TUNE_LA464")
+ (and (match_test "TARGET_uARCH_LA464")
(eq_attr "type" "unknown,multi,atomic,syncloop"))
"la464_alu1 + la464_alu2 + la464_falu1
+ la464_falu2 + la464_mem1 + la464_mem2")
diff --git a/gcc/config/loongarch/loongarch-c.cc b/gcc/config/loongarch/loongarch-c.cc
index 6ffbf74831613..f5a966a1d1c7b 100644
--- a/gcc/config/loongarch/loongarch-c.cc
+++ b/gcc/config/loongarch/loongarch-c.cc
@@ -61,8 +61,8 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile)
builtin_assert ("cpu=loongarch");
builtin_define ("__loongarch__");
- LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_ARCH", LARCH_ACTUAL_ARCH);
- LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_TUNE", LARCH_ACTUAL_TUNE);
+ LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_ARCH", la_target.cpu_arch);
+ LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_TUNE", la_target.cpu_tune);
/* Base architecture / ABI. */
if (TARGET_64BIT)
@@ -99,6 +99,21 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile)
else
builtin_define ("__loongarch_frlen=0");
+ if (ISA_HAS_LSX)
+ {
+ builtin_define ("__loongarch_simd");
+ builtin_define ("__loongarch_sx");
+
+ if (!ISA_HAS_LASX)
+ builtin_define ("__loongarch_simd_width=128");
+ }
+
+ if (ISA_HAS_LASX)
+ {
+ builtin_define ("__loongarch_asx");
+ builtin_define ("__loongarch_simd_width=256");
+ }
+
/* Add support for FLOAT128_TYPE on the LoongArch architecture. */
builtin_define ("__FLOAT128_TYPE__");
diff --git a/gcc/config/loongarch/loongarch-cpu.cc b/gcc/config/loongarch/loongarch-cpu.cc
index 34905f3de30e1..7a2866f60f98c 100644
--- a/gcc/config/loongarch/loongarch-cpu.cc
+++ b/gcc/config/loongarch/loongarch-cpu.cc
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "diagnostic-core.h"
+#include "loongarch-def.h"
#include "loongarch-opts.h"
#include "loongarch-cpu.h"
#include "loongarch-str.h"
@@ -80,127 +81,191 @@ get_native_prid_str (void)
}
/* Fill property tables for CPU_NATIVE. */
-unsigned int
-fill_native_cpu_config (int p_arch_native, int p_tune_native)
+void
+fill_native_cpu_config (struct loongarch_target *tgt)
{
- int ret_cpu_type;
+ int arch_native_p = tgt->cpu_arch == CPU_NATIVE;
+ int tune_native_p = tgt->cpu_tune == CPU_NATIVE;
+ int native_cpu_type = CPU_NATIVE;
/* Nothing needs to be done unless "-march/tune=native"
is given or implied. */
- if (!(p_arch_native || p_tune_native))
- return CPU_NATIVE;
+ if (!arch_native_p && !tune_native_p)
+ return;
/* Fill cpucfg_cache with the "cpucfg" instruction. */
cache_cpucfg ();
-
- /* Fill: loongarch_cpu_default_isa[CPU_NATIVE].base
- With: base architecture (ARCH)
- At: cpucfg_words[1][1:0] */
-
- #define NATIVE_BASE_ISA (loongarch_cpu_default_isa[CPU_NATIVE].base)
- switch (cpucfg_cache[1] & 0x3)
- {
- case 0x02:
- NATIVE_BASE_ISA = ISA_BASE_LA64V100;
- break;
-
- default:
- if (p_arch_native)
- fatal_error (UNKNOWN_LOCATION,
- "unknown base architecture %<0x%x%>, %qs failed",
- (unsigned int) (cpucfg_cache[1] & 0x3),
- "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
- }
-
- /* Fill: loongarch_cpu_default_isa[CPU_NATIVE].fpu
- With: FPU type (FP, FP_SP, FP_DP)
- At: cpucfg_words[2][2:0] */
-
- #define NATIVE_FPU (loongarch_cpu_default_isa[CPU_NATIVE].fpu)
- switch (cpucfg_cache[2] & 0x7)
- {
- case 0x07:
- NATIVE_FPU = ISA_EXT_FPU64;
- break;
-
- case 0x03:
- NATIVE_FPU = ISA_EXT_FPU32;
- break;
-
- case 0x00:
- NATIVE_FPU = ISA_EXT_NOFPU;
- break;
-
- default:
- if (p_arch_native)
- fatal_error (UNKNOWN_LOCATION,
- "unknown FPU type %<0x%x%>, %qs failed",
- (unsigned int) (cpucfg_cache[2] & 0x7),
- "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
- }
-
- /* Fill: loongarch_cpu_cache[CPU_NATIVE]
- With: cache size info
- At: cpucfg_words[16:20][31:0] */
-
- int l1d_present = 0, l1u_present = 0;
- int l2d_present = 0;
- uint32_t l1_szword, l2_szword;
-
- l1u_present |= cpucfg_cache[16] & 3; /* bit[1:0]: unified l1 cache */
- l1d_present |= cpucfg_cache[16] & 4; /* bit[2:2]: l1 dcache */
- l1_szword = l1d_present ? 18 : (l1u_present ? 17 : 0);
- l1_szword = l1_szword ? cpucfg_cache[l1_szword]: 0;
-
- l2d_present |= cpucfg_cache[16] & 24; /* bit[4:3]: unified l2 cache */
- l2d_present |= cpucfg_cache[16] & 128; /* bit[7:7]: l2 dcache */
- l2_szword = l2d_present ? cpucfg_cache[19]: 0;
-
- loongarch_cpu_cache[CPU_NATIVE].l1d_line_size
- = 1 << ((l1_szword & 0x7f000000) >> 24); /* bit[30:24]: log2(linesize) */
-
- loongarch_cpu_cache[CPU_NATIVE].l1d_size
- = (1 << ((l1_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */
- * ((l1_szword & 0x0000ffff) + 1) /* bit[15:0]: sets - 1 */
- * (1 << ((l1_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(linesize) */
- >> 10; /* in kilobytes */
-
- loongarch_cpu_cache[CPU_NATIVE].l2d_size
- = (1 << ((l2_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */
- * ((l2_szword & 0x0000ffff) + 1) /* bit[15:0]: sets - 1 */
- * (1 << ((l2_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(linesize) */
- >> 10; /* in kilobytes */
-
- /* Fill: ret_cpu_type
+ /* Fill: tgt->cpu_arch | tgt->cpu_tune
With: processor ID (PRID)
At: cpucfg_words[0][31:0] */
switch (cpucfg_cache[0] & 0x00ffff00)
{
case 0x0014c000: /* LA464 */
- ret_cpu_type = CPU_LA464;
+ native_cpu_type = CPU_LA464;
break;
default:
- /* Unknown PRID. This is generally harmless as long as
- the properties above can be obtained via "cpucfg". */
- if (p_tune_native)
+ /* Unknown PRID. */
+ if (tune_native_p)
inform (UNKNOWN_LOCATION, "unknown processor ID %<0x%x%>, "
"some tuning parameters will fall back to default",
cpucfg_cache[0]);
break;
}
- /* Properties that cannot be looked up directly using cpucfg. */
- loongarch_cpu_issue_rate[CPU_NATIVE]
- = loongarch_cpu_issue_rate[ret_cpu_type];
-
- loongarch_cpu_multipass_dfa_lookahead[CPU_NATIVE]
- = loongarch_cpu_multipass_dfa_lookahead[ret_cpu_type];
-
- loongarch_cpu_rtx_cost_data[CPU_NATIVE]
- = loongarch_cpu_rtx_cost_data[ret_cpu_type];
+ /* if -march=native */
+ if (arch_native_p)
+ {
+ int tmp;
+ tgt->cpu_arch = native_cpu_type;
+
+ /* Fill: loongarch_cpu_default_isa[tgt->cpu_arch].base
+ With: base architecture (ARCH)
+ At: cpucfg_words[1][1:0] */
+
+ #define PRESET_ARCH (loongarch_cpu_default_isa[tgt->cpu_arch].base)
+ switch (cpucfg_cache[1] & 0x3)
+ {
+ case 0x02:
+ tmp = ISA_BASE_LA64V100;
+ break;
+
+ default:
+ fatal_error (UNKNOWN_LOCATION,
+ "unknown native base architecture %<0x%x%>, "
+ "%qs failed", (unsigned int) (cpucfg_cache[1] & 0x3),
+ "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
+ }
+
+ /* Check consistency with PRID presets. */
+ if (native_cpu_type != CPU_NATIVE && tmp != PRESET_ARCH)
+ warning (0, "base architecture %qs differs from PRID preset %qs",
+ loongarch_isa_base_strings[tmp],
+ loongarch_isa_base_strings[PRESET_ARCH]);
+
+ /* Use the native value anyways. */
+ PRESET_ARCH = tmp;
+
+ /* Fill: loongarch_cpu_default_isa[tgt->cpu_arch].fpu
+ With: FPU type (FP, FP_SP, FP_DP)
+ At: cpucfg_words[2][2:0] */
+
+ #define PRESET_FPU (loongarch_cpu_default_isa[tgt->cpu_arch].fpu)
+ switch (cpucfg_cache[2] & 0x7)
+ {
+ case 0x07:
+ tmp = ISA_EXT_FPU64;
+ break;
+
+ case 0x03:
+ tmp = ISA_EXT_FPU32;
+ break;
+
+ case 0x00:
+ tmp = ISA_EXT_NONE;
+ break;
+
+ default:
+ fatal_error (UNKNOWN_LOCATION,
+ "unknown native FPU type %<0x%x%>, %qs failed",
+ (unsigned int) (cpucfg_cache[2] & 0x7),
+ "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
+ }
+
+ /* Check consistency with PRID presets. */
+ if (native_cpu_type != CPU_NATIVE && tmp != PRESET_FPU)
+ warning (0, "floating-point unit %qs differs from PRID preset %qs",
+ loongarch_isa_ext_strings[tmp],
+ loongarch_isa_ext_strings[PRESET_FPU]);
+
+ /* Use the native value anyways. */
+ PRESET_FPU = tmp;
+
+
+ /* Fill: loongarch_cpu_default_isa[CPU_NATIVE].simd
+ With: SIMD extension type (LSX, LASX)
+ At: cpucfg_words[2][7:6] */
+
+ #define PRESET_SIMD (loongarch_cpu_default_isa[tgt->cpu_arch].simd)
+ switch (cpucfg_cache[2] & 0xc0)
+ {
+ case 0xc0:
+ tmp = ISA_EXT_SIMD_LASX;
+ break;
+
+ case 0x40:
+ tmp = ISA_EXT_SIMD_LSX;
+ break;
+
+ case 0x80:
+ tmp = 0;
+ warning (0, "unknown SIMD extension "
+ "(%qs disabled while %qs is enabled), disabling SIMD",
+ loongarch_isa_ext_strings[ISA_EXT_SIMD_LSX],
+ loongarch_isa_ext_strings[ISA_EXT_SIMD_LASX]);
+ break;
+
+ case 0x00:
+ tmp = 0;
+ break;
+ }
+
+ /* Check consistency with PRID presets. */
+
+ /*
+ if (native_cpu_type != CPU_NATIVE && tmp != PRESET_SIMD)
+ warning (0, "SIMD extension %qs differs from PRID preset %qs",
+ loongarch_isa_ext_strings[tmp],
+ loongarch_isa_ext_strings[PRESET_SIMD]);
+ */
+
+ /* Use the native value anyways. */
+ PRESET_SIMD = tmp;
+ }
- return ret_cpu_type;
+ if (tune_native_p)
+ {
+ tgt->cpu_tune = native_cpu_type;
+
+ /* Fill: loongarch_cpu_cache[tgt->cpu_tune]
+ With: cache size info
+ At: cpucfg_words[16:20][31:0] */
+
+ #define PRESET_CACHE (loongarch_cpu_cache[tgt->cpu_tune])
+ struct loongarch_cache native_cache;
+ int l1d_present = 0, l1u_present = 0;
+ int l2d_present = 0;
+ uint32_t l1_szword, l2_szword;
+
+ l1u_present |= cpucfg_cache[16] & 3; /* bit[1:0]: unified l1 */
+ l1d_present |= cpucfg_cache[16] & 4; /* bit[2:2]: l1d */
+ l1_szword = l1d_present ? 18 : (l1u_present ? 17 : 0);
+ l1_szword = l1_szword ? cpucfg_cache[l1_szword]: 0;
+
+ l2d_present |= cpucfg_cache[16] & 24; /* bit[4:3]: unified l2 */
+ l2d_present |= cpucfg_cache[16] & 128; /* bit[7:7]: l2d */
+ l2_szword = l2d_present ? cpucfg_cache[19]: 0;
+
+ native_cache.l1d_line_size
+ = 1 << ((l1_szword & 0x7f000000) >> 24); /* bit[30:24]: log2(line) */
+
+ native_cache.l1d_size
+ = (1 << ((l1_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */
+ * ((l1_szword & 0x0000ffff) + 1) /* bit[15:0]: sets - 1 */
+ * (1 << ((l1_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(line) */
+ >> 10; /* in kibibytes */
+
+ native_cache.l2d_size
+ = (1 << ((l2_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */
+ * ((l2_szword & 0x0000ffff) + 1) /* bit[15:0]: sets - 1 */
+ * (1 << ((l2_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(linesz) */
+ >> 10; /* in kibibytes */
+
+ /* Use the native value anyways. */
+ PRESET_CACHE.l1d_line_size = native_cache.l1d_line_size;
+ PRESET_CACHE.l1d_size = native_cache.l1d_size;
+ PRESET_CACHE.l2d_size = native_cache.l2d_size;
+ }
}
diff --git a/gcc/config/loongarch/loongarch-cpu.h b/gcc/config/loongarch/loongarch-cpu.h
index 57ad8456ffa76..28618f3cf6cb0 100644
--- a/gcc/config/loongarch/loongarch-cpu.h
+++ b/gcc/config/loongarch/loongarch-cpu.h
@@ -21,9 +21,10 @@ along with GCC; see the file COPYING3. If not see
#define LOONGARCH_CPU_H
#include "system.h"
+#include "loongarch-def.h"
void cache_cpucfg (void);
-unsigned int fill_native_cpu_config (int p_arch_native, int p_tune_native);
+void fill_native_cpu_config (struct loongarch_target *tgt);
uint32_t get_native_prid (void);
const char* get_native_prid_str (void);
diff --git a/gcc/config/loongarch/loongarch-def.c b/gcc/config/loongarch/loongarch-def.c
index 6729c857f7c4b..e744ee01d6d76 100644
--- a/gcc/config/loongarch/loongarch-def.c
+++ b/gcc/config/loongarch/loongarch-def.c
@@ -21,25 +21,11 @@ along with GCC; see the file COPYING3. If not see
#include "loongarch-def.h"
#include "loongarch-str.h"
-/* Default RTX cost initializer. */
-#define COSTS_N_INSNS(N) ((N) * 4)
-#define DEFAULT_COSTS \
- .fp_add = COSTS_N_INSNS (1), \
- .fp_mult_sf = COSTS_N_INSNS (2), \
- .fp_mult_df = COSTS_N_INSNS (4), \
- .fp_div_sf = COSTS_N_INSNS (6), \
- .fp_div_df = COSTS_N_INSNS (8), \
- .int_mult_si = COSTS_N_INSNS (1), \
- .int_mult_di = COSTS_N_INSNS (1), \
- .int_div_si = COSTS_N_INSNS (4), \
- .int_div_di = COSTS_N_INSNS (6), \
- .branch_cost = 2, \
- .memory_latency = 4
-
/* CPU property tables. */
const char*
loongarch_cpu_strings[N_TUNE_TYPES] = {
[CPU_NATIVE] = STR_CPU_NATIVE,
+ [CPU_ABI_DEFAULT] = STR_CPU_ABI_DEFAULT,
[CPU_LOONGARCH64] = STR_CPU_LOONGARCH64,
[CPU_LA464] = STR_CPU_LA464,
};
@@ -49,10 +35,12 @@ loongarch_cpu_default_isa[N_ARCH_TYPES] = {
[CPU_LOONGARCH64] = {
.base = ISA_BASE_LA64V100,
.fpu = ISA_EXT_FPU64,
+ .simd = 0,
},
[CPU_LA464] = {
.base = ISA_BASE_LA64V100,
.fpu = ISA_EXT_FPU64,
+ .simd = ISA_EXT_SIMD_LASX,
},
};
@@ -84,6 +72,22 @@ loongarch_cpu_align[N_TUNE_TYPES] = {
},
};
+
+/* Default RTX cost initializer. */
+#define COSTS_N_INSNS(N) ((N) * 4)
+#define DEFAULT_COSTS \
+ .fp_add = COSTS_N_INSNS (1), \
+ .fp_mult_sf = COSTS_N_INSNS (2), \
+ .fp_mult_df = COSTS_N_INSNS (4), \
+ .fp_div_sf = COSTS_N_INSNS (6), \
+ .fp_div_df = COSTS_N_INSNS (8), \
+ .int_mult_si = COSTS_N_INSNS (1), \
+ .int_mult_di = COSTS_N_INSNS (1), \
+ .int_div_si = COSTS_N_INSNS (4), \
+ .int_div_di = COSTS_N_INSNS (6), \
+ .branch_cost = 2, \
+ .memory_latency = 4
+
/* The following properties cannot be looked up directly using "cpucfg".
So it is necessary to provide a default value for "unknown native"
tune targets (i.e. -mtune=native while PRID does not correspond to
@@ -103,7 +107,7 @@ loongarch_cpu_rtx_cost_data[N_TUNE_TYPES] = {
};
/* RTX costs to use when optimizing for size. */
-extern const struct loongarch_rtx_cost_data
+const struct loongarch_rtx_cost_data
loongarch_rtx_cost_optimize_size = {
.fp_add = 4,
.fp_mult_sf = 4,
@@ -144,9 +148,11 @@ loongarch_isa_base_strings[N_ISA_BASE_TYPES] = {
const char*
loongarch_isa_ext_strings[N_ISA_EXT_TYPES] = {
- [ISA_EXT_FPU64] = STR_ISA_EXT_FPU64,
+ [ISA_EXT_NONE] = STR_NONE,
[ISA_EXT_FPU32] = STR_ISA_EXT_FPU32,
- [ISA_EXT_NOFPU] = STR_ISA_EXT_NOFPU,
+ [ISA_EXT_FPU64] = STR_ISA_EXT_FPU64,
+ [ISA_EXT_SIMD_LSX] = STR_ISA_EXT_LSX,
+ [ISA_EXT_SIMD_LASX] = STR_ISA_EXT_LASX,
};
const char*
@@ -171,24 +177,29 @@ loongarch_cmodel_strings[] = {
[CMODEL_EXTREME] = STR_CMODEL_EXTREME,
};
-const char*
-loongarch_switch_strings[] = {
- [SW_SOFT_FLOAT] = OPTSTR_SOFT_FLOAT,
- [SW_SINGLE_FLOAT] = OPTSTR_SINGLE_FLOAT,
- [SW_DOUBLE_FLOAT] = OPTSTR_DOUBLE_FLOAT,
-};
-
/* ABI-related definitions. */
const struct loongarch_isa
abi_minimal_isa[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES] = {
[ABI_BASE_LP64D] = {
- [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU64},
+ [ABI_EXT_BASE] = {
+ .base = ISA_BASE_LA64V100,
+ .fpu = ISA_EXT_FPU64,
+ .simd = 0
+ },
},
[ABI_BASE_LP64F] = {
- [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU32},
+ [ABI_EXT_BASE] = {
+ .base = ISA_BASE_LA64V100,
+ .fpu = ISA_EXT_FPU32,
+ .simd = 0
+ },
},
[ABI_BASE_LP64S] = {
- [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_NOFPU},
+ [ABI_EXT_BASE] = {
+ .base = ISA_BASE_LA64V100,
+ .fpu = ISA_EXT_NONE,
+ .simd = 0
+ },
},
};
diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h
index fb8bb88eb52ff..769efcb70fb89 100644
--- a/gcc/config/loongarch/loongarch-def.h
+++ b/gcc/config/loongarch/loongarch-def.h
@@ -59,11 +59,13 @@ extern const char* loongarch_isa_base_strings[];
/* enum isa_ext_* */
extern const char* loongarch_isa_ext_strings[];
-#define ISA_EXT_NOFPU 0
+#define ISA_EXT_NONE 0
#define ISA_EXT_FPU32 1
#define ISA_EXT_FPU64 2
#define N_ISA_EXT_FPU_TYPES 3
-#define N_ISA_EXT_TYPES 3
+#define ISA_EXT_SIMD_LSX 3
+#define ISA_EXT_SIMD_LASX 4
+#define N_ISA_EXT_TYPES 5
/* enum abi_base */
extern const char* loongarch_abi_base_strings[];
@@ -72,6 +74,16 @@ extern const char* loongarch_abi_base_strings[];
#define ABI_BASE_LP64S 2
#define N_ABI_BASE_TYPES 3
+#define TO_LP64_ABI_BASE(C) (C)
+
+#define ABI_FPU_64(abi_base) \
+ (abi_base == ABI_BASE_LP64D)
+#define ABI_FPU_32(abi_base) \
+ (abi_base == ABI_BASE_LP64F)
+#define ABI_FPU_NONE(abi_base) \
+ (abi_base == ABI_BASE_LP64S)
+
+
/* enum abi_ext */
extern const char* loongarch_abi_ext_strings[];
#define ABI_EXT_BASE 0
@@ -87,55 +99,44 @@ extern const char* loongarch_cmodel_strings[];
#define CMODEL_EXTREME 5
#define N_CMODEL_TYPES 6
-/* enum switches */
-/* The "SW_" codes represent command-line switches (options that
- accept no parameters). Definition for other switches that affects
- the target ISA / ABI configuration will also be appended here
- in the future. */
-
-extern const char* loongarch_switch_strings[];
-#define SW_SOFT_FLOAT 0
-#define SW_SINGLE_FLOAT 1
-#define SW_DOUBLE_FLOAT 2
-#define N_SWITCH_TYPES 3
-
/* The common default value for variables whose assignments
are triggered by command-line options. */
-#define M_OPTION_NOT_SEEN -1
-#define M_OPT_ABSENT(opt_enum) ((opt_enum) == M_OPTION_NOT_SEEN)
+#define M_OPT_UNSET -1
+#define M_OPT_ABSENT(opt_enum) ((opt_enum) == M_OPT_UNSET)
/* Internal representation of the target. */
struct loongarch_isa
{
- unsigned char base; /* ISA_BASE_ */
- unsigned char fpu; /* ISA_EXT_FPU_ */
+ int base; /* ISA_BASE_ */
+ int fpu; /* ISA_EXT_FPU_ */
+ int simd; /* ISA_EXT_SIMD_ */
};
struct loongarch_abi
{
- unsigned char base; /* ABI_BASE_ */
- unsigned char ext; /* ABI_EXT_ */
+ int base; /* ABI_BASE_ */
+ int ext; /* ABI_EXT_ */
};
struct loongarch_target
{
struct loongarch_isa isa;
struct loongarch_abi abi;
- unsigned char cpu_arch; /* CPU_ */
- unsigned char cpu_tune; /* same */
- unsigned char cpu_native; /* same */
- unsigned char cmodel; /* CMODEL_ */
+ int cpu_arch; /* CPU_ */
+ int cpu_tune; /* same */
+ int cmodel; /* CMODEL_ */
};
/* 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_ABI_DEFAULT 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.cc b/gcc/config/loongarch/loongarch-driver.cc
index 11ce082417f98..bafd27e67a5f7 100644
--- a/gcc/config/loongarch/loongarch-driver.cc
+++ b/gcc/config/loongarch/loongarch-driver.cc
@@ -26,122 +26,137 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "obstack.h"
#include "diagnostic-core.h"
+#include "opts.h"
#include "loongarch-opts.h"
#include "loongarch-driver.h"
-static int
- opt_arch_driver = M_OPTION_NOT_SEEN,
- opt_tune_driver = M_OPTION_NOT_SEEN,
- opt_fpu_driver = M_OPTION_NOT_SEEN,
- opt_abi_base_driver = M_OPTION_NOT_SEEN,
- opt_abi_ext_driver = M_OPTION_NOT_SEEN,
- opt_cmodel_driver = M_OPTION_NOT_SEEN;
-
-int opt_switches = 0;
-
/* This flag is set to 1 if we believe that the user might be avoiding
linking (implicitly) against something from the startfile search paths. */
static int no_link = 0;
-#define LARCH_DRIVER_SET_M_FLAG(OPTS_ARRAY, N_OPTS, FLAG, STR) \
- for (int i = 0; i < (N_OPTS); i++) \
- { \
- if ((OPTS_ARRAY)[i] != 0) \
- if (strcmp ((STR), (OPTS_ARRAY)[i]) == 0) \
- (FLAG) = i; \
- }
-
/* Use the public obstack from the gcc driver (defined in gcc.c).
This is for allocating space for the returned string. */
extern struct obstack opts_obstack;
-#define APPEND_LTR(S) \
- obstack_grow (&opts_obstack, (const void*) (S), \
- sizeof ((S)) / sizeof (char) -1)
-
-#define APPEND_VAL(S) \
- obstack_grow (&opts_obstack, (const void*) (S), strlen ((S)))
+const char*
+la_driver_init (int argc ATTRIBUTE_UNUSED, const char **argv ATTRIBUTE_UNUSED)
+{
+ /* Initialize all fields of la_target to -1 */
+ loongarch_init_target (&la_target, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET,
+ M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET);
+ return "";
+}
+const char*
+driver_set_no_link (int argc ATTRIBUTE_UNUSED,
+ const char **argv ATTRIBUTE_UNUSED)
+{
+ no_link = 1;
+ return "";
+}
const char*
-driver_set_m_flag (int argc, const char **argv)
+driver_set_m_parm (int argc, const char **argv)
{
- int parm_off = 0;
+ gcc_assert (argc == 2);
+
+#define LARCH_DRIVER_PARSE_PARM(OPT_IDX, NAME, OPTSTR_LIST, \
+ OPT_IDX_LO, OPT_IDX_HI) \
+ if (strcmp (argv[0], OPTSTR_##NAME) == 0) \
+ for (int i = (OPT_IDX_LO); i < (OPT_IDX_HI); i++) \
+ { \
+ if ((OPTSTR_LIST)[i] != 0) \
+ if (strcmp (argv[1], (OPTSTR_LIST)[i]) == 0) \
+ { \
+ (OPT_IDX) = i; \
+ return 0; \
+ } \
+ }
- if (argc != 1)
- return "%eset_m_flag requires exactly 1 argument.";
+ LARCH_DRIVER_PARSE_PARM (la_target.abi.base, ABI_BASE, \
+ loongarch_abi_base_strings, 0, N_ABI_BASE_TYPES)
-#undef PARM
-#define PARM (argv[0] + parm_off)
+ LARCH_DRIVER_PARSE_PARM (la_target.isa.fpu, ISA_EXT_FPU, \
+ loongarch_isa_ext_strings, 0, N_ISA_EXT_FPU_TYPES)
-/* Note: sizeof (OPTSTR_##NAME) equals the length of "