LoongArch: improved target configuration interface
The configure script and the GCC driver are updated so that it is easier to customize and control GCC builds for targeting different LoongArch implementations. * Make --with-abi obsolete, since it might cause different default ABI under the same target triplet, which is undesirable. The default ABI is now purely decided by the target triplet. * Support options for LoongArch SIMD extensions: new configure options --with-simd={none,lsx,lasx}; new compiler option -msimd={none,lsx,lasx}; new driver options -m[no]-l[a]sx. * Enforce the priority of configuration paths (for <parm>={fpu,tune,simd}): -m<parm> > -march-implied > --with-<parm> > --with-arch-implied. * Allow the user to control the compiler options used when building GCC libraries for each multilib variant via --with-multilib-list and --with-multilib-default. This could become more useful when we have 32-bit support later. Example 1: the following configure option --with-multilib-list=lp64d/la464/mno-strict-align/msimd=lsx,lp64s/mfpu=32 | | | | -mabi=ABI -march=ARCH a list of other options (mandatory) (optional) (optional) builds two sets of libraries: 1. lp64d/base ABI (built with "-march=la464 -mno-strict-align -msimd=lsx") 2. lp64s/base ABI (built with "-march=abi-default -mfpu=32") Example 2: the following 3 configure options --with-arch=loongarch64 --with-multilib-list=lp64d,lp64f,lp64s/la464 --with-multilib-default=fixed/mno-strict-align/mfpu=64 | | | -march=ARCH a list of other options (optional) (optional) is equivalent to (in terms of building libraries): --with-multilib-list=\ lp64d/loongarch64/mno-strict-align/mfpu=64,\ lp64f/loongarch64/mno-strict-align/mfpu=64,\ lp64s/la464 Note: 1. the GCC driver and compiler proper does not support "-march=fixed". "fixed" that appear here acts as a placeholder for "use whatever ARCH in --with-arch=ARCH" (or the default value of --with-arch=ARCH if --with-arch is not explicitly configured). 2. if the ARCH part is omitted, "-march=abi-default" is used for building all library variants, which practically means enabling the minimal ISA features that can support the given ABI. ChangeLog: * config-ml.in: Do not build the multilib library variant that is duplicate with the toplevel one. gcc/ChangeLog: * config.gcc: Make --with-abi= obsolete, decide the default ABI with target triplet. Allow specifying multilib library build options with --with-multilib-list and --with-multilib-default. * config/loongarch/t-linux: Likewise. * config/loongarch/genopts/loongarch-strings: Likewise. * config/loongarch/loongarch-str.h: Likewise. * doc/install.texi: Likewise. * config/loongarch/genopts/loongarch.opt.in: Introduce -m[no-]l[a]sx options. Only process -m*-float and -m[no-]l[a]sx in the GCC driver. * config/loongarch/loongarch.opt: Likewise. * config/loongarch/la464.md: Likewise. * config/loongarch/loongarch-c.cc: Likewise. * config/loongarch/loongarch-cpu.cc: Likewise. * config/loongarch/loongarch-cpu.h: Likewise. * config/loongarch/loongarch-def.c: Likewise. * config/loongarch/loongarch-def.h: Likewise. * config/loongarch/loongarch-driver.cc: Likewise. * config/loongarch/loongarch-driver.h: Likewise. * config/loongarch/loongarch-opts.cc: Likewise. * config/loongarch/loongarch-opts.h: Likewise. * config/loongarch/loongarch.cc: Likewise. * doc/invoke.texi: Likewise.
This commit is contained in:
parent
33066c903a
commit
bb4a81988c
20 changed files with 1172 additions and 687 deletions
10
config-ml.in
10
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
|
||||
|
|
381
gcc/config.gcc
381
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
|
||||
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
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
*)
|
||||
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
|
||||
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
|
||||
;;
|
||||
|
||||
*)
|
||||
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}"'}')
|
||||
unset elem_abi_base elem_abi_ext
|
||||
parse_state="abi-base"
|
||||
|
||||
case ${idx} in
|
||||
1)
|
||||
# Component 1: Base ABI type
|
||||
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
|
||||
;;
|
||||
*)
|
||||
echo "Unknown ABI \"${elem}\" in --with-multilib-list." 1>&2
|
||||
exit 1
|
||||
|
||||
default)
|
||||
# "/default" is equivalent to --with-multilib-default=fixed
|
||||
parse_state="opts"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
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
|
||||
*)
|
||||
# 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
|
||||
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"
|
||||
;;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,22 +17,12 @@
|
|||
; <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
; 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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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__");
|
||||
|
||||
|
|
|
@ -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];
|
||||
/* if -march=native */
|
||||
if (arch_native_p)
|
||||
{
|
||||
int tmp;
|
||||
tgt->cpu_arch = native_cpu_type;
|
||||
|
||||
loongarch_cpu_multipass_dfa_lookahead[CPU_NATIVE]
|
||||
= loongarch_cpu_multipass_dfa_lookahead[ret_cpu_type];
|
||||
/* Fill: loongarch_cpu_default_isa[tgt->cpu_arch].base
|
||||
With: base architecture (ARCH)
|
||||
At: cpucfg_words[1][1:0] */
|
||||
|
||||
loongarch_cpu_rtx_cost_data[CPU_NATIVE]
|
||||
= loongarch_cpu_rtx_cost_data[ret_cpu_type];
|
||||
#define PRESET_ARCH (loongarch_cpu_default_isa[tgt->cpu_arch].base)
|
||||
switch (cpucfg_cache[1] & 0x3)
|
||||
{
|
||||
case 0x02:
|
||||
tmp = ISA_BASE_LA64V100;
|
||||
break;
|
||||
|
||||
return ret_cpu_type;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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*
|
||||
driver_set_m_flag (int argc, const char **argv)
|
||||
la_driver_init (int argc ATTRIBUTE_UNUSED, const char **argv ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int parm_off = 0;
|
||||
|
||||
if (argc != 1)
|
||||
return "%eset_m_flag requires exactly 1 argument.";
|
||||
|
||||
#undef PARM
|
||||
#define PARM (argv[0] + parm_off)
|
||||
|
||||
/* Note: sizeof (OPTSTR_##NAME) equals the length of "<option>=". */
|
||||
#undef MATCH_OPT
|
||||
#define MATCH_OPT(NAME) \
|
||||
(strncmp (argv[0], OPTSTR_##NAME "=", \
|
||||
(parm_off = sizeof (OPTSTR_##NAME))) == 0)
|
||||
|
||||
if (strcmp (argv[0], "no_link") == 0)
|
||||
{
|
||||
no_link = 1;
|
||||
}
|
||||
else if (MATCH_OPT (ABI_BASE))
|
||||
{
|
||||
LARCH_DRIVER_SET_M_FLAG (
|
||||
loongarch_abi_base_strings, N_ABI_BASE_TYPES,
|
||||
opt_abi_base_driver, PARM)
|
||||
}
|
||||
else if (MATCH_OPT (ISA_EXT_FPU))
|
||||
{
|
||||
LARCH_DRIVER_SET_M_FLAG (loongarch_isa_ext_strings, N_ISA_EXT_FPU_TYPES,
|
||||
opt_fpu_driver, PARM)
|
||||
}
|
||||
else if (MATCH_OPT (ARCH))
|
||||
{
|
||||
LARCH_DRIVER_SET_M_FLAG (loongarch_cpu_strings, N_ARCH_TYPES,
|
||||
opt_arch_driver, PARM)
|
||||
}
|
||||
else if (MATCH_OPT (TUNE))
|
||||
{
|
||||
LARCH_DRIVER_SET_M_FLAG (loongarch_cpu_strings, N_TUNE_TYPES,
|
||||
opt_tune_driver, PARM)
|
||||
}
|
||||
else if (MATCH_OPT (CMODEL))
|
||||
{
|
||||
LARCH_DRIVER_SET_M_FLAG (loongarch_cmodel_strings, N_CMODEL_TYPES,
|
||||
opt_cmodel_driver, PARM)
|
||||
}
|
||||
else /* switches */
|
||||
{
|
||||
int switch_idx = M_OPTION_NOT_SEEN;
|
||||
|
||||
LARCH_DRIVER_SET_M_FLAG (loongarch_switch_strings, N_SWITCH_TYPES,
|
||||
switch_idx, argv[0])
|
||||
|
||||
if (switch_idx != M_OPTION_NOT_SEEN)
|
||||
opt_switches |= loongarch_switch_mask[switch_idx];
|
||||
}
|
||||
/* 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_get_normalized_m_opts (int argc, const char **argv)
|
||||
driver_set_no_link (int argc ATTRIBUTE_UNUSED,
|
||||
const char **argv ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (argc != 0)
|
||||
{
|
||||
(void) argv; /* To make compiler shut up about unused argument. */
|
||||
return " %eget_normalized_m_opts requires no argument.\n";
|
||||
no_link = 1;
|
||||
return "";
|
||||
}
|
||||
|
||||
const char*
|
||||
driver_set_m_parm (int argc, const char **argv)
|
||||
{
|
||||
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; \
|
||||
} \
|
||||
}
|
||||
|
||||
loongarch_config_target (& la_target,
|
||||
opt_switches,
|
||||
opt_arch_driver,
|
||||
opt_tune_driver,
|
||||
opt_fpu_driver,
|
||||
opt_abi_base_driver,
|
||||
opt_abi_ext_driver,
|
||||
opt_cmodel_driver,
|
||||
!no_link /* follow_multilib_list */);
|
||||
LARCH_DRIVER_PARSE_PARM (la_target.abi.base, ABI_BASE, \
|
||||
loongarch_abi_base_strings, 0, N_ABI_BASE_TYPES)
|
||||
|
||||
LARCH_DRIVER_PARSE_PARM (la_target.isa.fpu, ISA_EXT_FPU, \
|
||||
loongarch_isa_ext_strings, 0, N_ISA_EXT_FPU_TYPES)
|
||||
|
||||
LARCH_DRIVER_PARSE_PARM (la_target.isa.simd, ISA_EXT_SIMD, \
|
||||
loongarch_isa_ext_strings, 0, N_ISA_EXT_TYPES)
|
||||
|
||||
LARCH_DRIVER_PARSE_PARM (la_target.cpu_arch, ARCH, \
|
||||
loongarch_cpu_strings, 0, N_ARCH_TYPES)
|
||||
|
||||
LARCH_DRIVER_PARSE_PARM (la_target.cpu_tune, TUNE, \
|
||||
loongarch_cpu_strings, 0, N_TUNE_TYPES)
|
||||
|
||||
LARCH_DRIVER_PARSE_PARM (la_target.cmodel, CMODEL, \
|
||||
loongarch_cmodel_strings, 0, N_CMODEL_TYPES)
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
static void
|
||||
driver_record_deferred_opts (struct loongarch_flags *flags)
|
||||
{
|
||||
unsigned int i;
|
||||
cl_deferred_option *opt;
|
||||
vec<cl_deferred_option> *v = (vec<cl_deferred_option> *) la_deferred_options;
|
||||
|
||||
gcc_assert (flags);
|
||||
|
||||
/* Initialize flags */
|
||||
flags->flt = M_OPT_UNSET;
|
||||
flags->flt_str = NULL;
|
||||
flags->sx[0] = flags->sx[1] = 0;
|
||||
|
||||
int sx_flag_idx = 0;
|
||||
|
||||
if (v)
|
||||
FOR_EACH_VEC_ELT (*v, i, opt)
|
||||
{
|
||||
switch (opt->opt_index)
|
||||
{
|
||||
case OPT_mlsx:
|
||||
flags->sx[sx_flag_idx++] = ISA_EXT_SIMD_LSX
|
||||
* (opt->value ? 1 : -1);
|
||||
break;
|
||||
|
||||
case OPT_mlasx:
|
||||
flags->sx[sx_flag_idx++] = ISA_EXT_SIMD_LASX
|
||||
* (opt->value ? 1 : -1);
|
||||
break;
|
||||
|
||||
case OPT_msoft_float:
|
||||
flags->flt = ISA_EXT_NONE;
|
||||
flags->flt_str = OPTSTR_SOFT_FLOAT;
|
||||
break;
|
||||
|
||||
case OPT_msingle_float:
|
||||
flags->flt = ISA_EXT_FPU32;
|
||||
flags->flt_str = OPTSTR_SINGLE_FLOAT;
|
||||
break;
|
||||
|
||||
case OPT_mdouble_float:
|
||||
flags->flt = ISA_EXT_FPU64;
|
||||
flags->flt_str = OPTSTR_DOUBLE_FLOAT;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
gcc_assert (sx_flag_idx <= 2);
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
driver_get_normalized_m_opts (int argc, const char **argv ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (argc != 0)
|
||||
return " %eget_normalized_m_opts requires no argument.\n";
|
||||
|
||||
struct loongarch_flags flags;
|
||||
driver_record_deferred_opts (&flags);
|
||||
loongarch_config_target (&la_target, &flags, !no_link);
|
||||
|
||||
/* Output normalized option strings. */
|
||||
obstack_blank (&opts_obstack, 0);
|
||||
|
@ -160,11 +175,15 @@ driver_get_normalized_m_opts (int argc, const char **argv)
|
|||
APPEND_LTR (" %<m" OPTSTR_##NAME "=* " \
|
||||
" -m" OPTSTR_##NAME "=")
|
||||
|
||||
for (int i = 0; i < N_SWITCH_TYPES; i++)
|
||||
{
|
||||
APPEND_LTR (" %<m");
|
||||
APPEND_VAL (loongarch_switch_strings[i]);
|
||||
}
|
||||
#undef CLEAR_FLAG
|
||||
#define CLEAR_FLAG(NAME) \
|
||||
APPEND_LTR (" %<m" NAME " %<mno-" NAME)
|
||||
|
||||
CLEAR_FLAG (STR_ISA_EXT_LSX);
|
||||
CLEAR_FLAG (STR_ISA_EXT_LASX);
|
||||
CLEAR_FLAG (OPTSTR_SOFT_FLOAT);
|
||||
CLEAR_FLAG (OPTSTR_SINGLE_FLOAT);
|
||||
CLEAR_FLAG (OPTSTR_DOUBLE_FLOAT);
|
||||
|
||||
APPEND_OPT (ABI_BASE);
|
||||
APPEND_VAL (loongarch_abi_base_strings[la_target.abi.base]);
|
||||
|
@ -175,6 +194,9 @@ driver_get_normalized_m_opts (int argc, const char **argv)
|
|||
APPEND_OPT (ISA_EXT_FPU);
|
||||
APPEND_VAL (loongarch_isa_ext_strings[la_target.isa.fpu]);
|
||||
|
||||
APPEND_OPT (ISA_EXT_SIMD);
|
||||
APPEND_VAL (loongarch_isa_ext_strings[la_target.isa.simd]);
|
||||
|
||||
APPEND_OPT (CMODEL);
|
||||
APPEND_VAL (loongarch_cmodel_strings[la_target.cmodel]);
|
||||
|
||||
|
|
|
@ -24,33 +24,37 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "loongarch-str.h"
|
||||
|
||||
extern const char*
|
||||
driver_set_m_flag (int argc, const char **argv);
|
||||
la_driver_init (int argc, const char **argv);
|
||||
|
||||
extern const char*
|
||||
driver_set_m_parm (int argc, const char **argv);
|
||||
|
||||
extern const char*
|
||||
driver_set_no_link (int argc, const char **argv);
|
||||
|
||||
extern const char*
|
||||
driver_get_normalized_m_opts (int argc, const char **argv);
|
||||
|
||||
#define EXTRA_SPEC_FUNCTIONS \
|
||||
{ "set_m_flag", driver_set_m_flag }, \
|
||||
{ "driver_init", la_driver_init }, \
|
||||
{ "set_m_parm", driver_set_m_parm }, \
|
||||
{ "set_no_link", driver_set_no_link }, \
|
||||
{ "get_normalized_m_opts", driver_get_normalized_m_opts },
|
||||
|
||||
/* Pre-process ABI-related options. */
|
||||
#define LA_SET_PARM_SPEC(NAME) \
|
||||
" %{m" OPTSTR_##NAME "=*: %:set_m_flag(" OPTSTR_##NAME "=%*)}" \
|
||||
" %{m" OPTSTR_##NAME "=*: %:set_m_parm(" OPTSTR_##NAME " %*)}" \
|
||||
|
||||
#define LA_SET_FLAG_SPEC(NAME) \
|
||||
" %{m" OPTSTR_##NAME ": %:set_m_flag(" OPTSTR_##NAME ")}" \
|
||||
|
||||
#define DRIVER_HANDLE_MACHINE_OPTIONS \
|
||||
" %{c|S|E|nostdlib: %:set_m_flag(no_link)}" \
|
||||
" %{nostartfiles: %{nodefaultlibs: %:set_m_flag(no_link)}}" \
|
||||
LA_SET_PARM_SPEC (ABI_BASE) \
|
||||
LA_SET_PARM_SPEC (ARCH) \
|
||||
LA_SET_PARM_SPEC (TUNE) \
|
||||
LA_SET_PARM_SPEC (ISA_EXT_FPU) \
|
||||
LA_SET_PARM_SPEC (CMODEL) \
|
||||
LA_SET_FLAG_SPEC (SOFT_FLOAT) \
|
||||
LA_SET_FLAG_SPEC (SINGLE_FLOAT) \
|
||||
LA_SET_FLAG_SPEC (DOUBLE_FLOAT) \
|
||||
#define DRIVER_HANDLE_MACHINE_OPTIONS \
|
||||
" %:driver_init()" \
|
||||
" %{c|S|E|nostdlib: %:set_no_link()}" \
|
||||
" %{nostartfiles: %{nodefaultlibs: %:set_no_link()}}" \
|
||||
LA_SET_PARM_SPEC (ABI_BASE) \
|
||||
LA_SET_PARM_SPEC (ARCH) \
|
||||
LA_SET_PARM_SPEC (TUNE) \
|
||||
LA_SET_PARM_SPEC (ISA_EXT_FPU) \
|
||||
LA_SET_PARM_SPEC (ISA_EXT_SIMD) \
|
||||
LA_SET_PARM_SPEC (CMODEL) \
|
||||
" %:get_normalized_m_opts()"
|
||||
|
||||
#define DRIVER_SELF_SPECS \
|
||||
|
|
|
@ -26,9 +26,11 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tm.h"
|
||||
#include "obstack.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
#include "loongarch-cpu.h"
|
||||
#include "loongarch-opts.h"
|
||||
#include "loongarch-str.h"
|
||||
#include "loongarch-def.h"
|
||||
|
||||
struct loongarch_target la_target;
|
||||
|
||||
|
@ -76,16 +78,6 @@ init_enabled_abi_types ()
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Switch masks. */
|
||||
#undef M
|
||||
#define M(NAME) OPTION_MASK_##NAME
|
||||
const int loongarch_switch_mask[N_SWITCH_TYPES] = {
|
||||
/* SW_SOFT_FLOAT */ M(FORCE_SOFTF),
|
||||
/* SW_SINGLE_FLOAT */ M(FORCE_F32),
|
||||
/* SW_DOUBLE_FLOAT */ M(FORCE_F64),
|
||||
};
|
||||
#undef M
|
||||
|
||||
/* String processing. */
|
||||
static struct obstack msg_obstack;
|
||||
#define APPEND_STRING(STR) obstack_grow (&msg_obstack, STR, strlen(STR));
|
||||
|
@ -104,9 +96,10 @@ static int isa_fpu_compat_p (const struct loongarch_isa *set1,
|
|||
const struct loongarch_isa *set2);
|
||||
static int abi_compat_p (const struct loongarch_isa *isa,
|
||||
struct loongarch_abi abi);
|
||||
static int abi_default_cpu_arch (struct loongarch_abi abi);
|
||||
static int abi_default_cpu_arch (struct loongarch_abi abi,
|
||||
struct loongarch_isa *isa);
|
||||
|
||||
/* Checking configure-time defaults. */
|
||||
/* Mandatory configure-time defaults. */
|
||||
#ifndef DEFAULT_ABI_BASE
|
||||
#error missing definition of DEFAULT_ABI_BASE in ${tm_defines}.
|
||||
#endif
|
||||
|
@ -119,21 +112,57 @@ static int abi_default_cpu_arch (struct loongarch_abi abi);
|
|||
#error missing definition of DEFAULT_CPU_ARCH in ${tm_defines}.
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_ISA_EXT_FPU
|
||||
#error missing definition of DEFAULT_ISA_EXT_FPU in ${tm_defines}.
|
||||
/* Optional configure-time defaults. */
|
||||
#ifdef DEFAULT_CPU_TUNE
|
||||
static int with_default_tune = 1;
|
||||
#else
|
||||
#define DEFAULT_CPU_TUNE -1
|
||||
static int with_default_tune = 0;
|
||||
#endif
|
||||
|
||||
/* Handle combinations of -m machine option values
|
||||
#ifdef DEFAULT_ISA_EXT_FPU
|
||||
static int with_default_fpu = 1;
|
||||
#else
|
||||
#define DEFAULT_ISA_EXT_FPU -1
|
||||
static int with_default_fpu = 0;
|
||||
#endif
|
||||
|
||||
#ifdef DEFAULT_ISA_EXT_SIMD
|
||||
static int with_default_simd = 1;
|
||||
#else
|
||||
#define DEFAULT_ISA_EXT_SIMD -1
|
||||
static int with_default_simd = 0;
|
||||
#endif
|
||||
|
||||
|
||||
/* Initialize loongarch_target from separate option variables. */
|
||||
|
||||
void
|
||||
loongarch_init_target (struct loongarch_target *target,
|
||||
int cpu_arch, int cpu_tune, int fpu, int simd,
|
||||
int abi_base, int abi_ext, int cmodel)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
target->cpu_arch = cpu_arch;
|
||||
target->cpu_tune = cpu_tune;
|
||||
target->isa.fpu = fpu;
|
||||
target->isa.simd = simd;
|
||||
target->abi.base = abi_base;
|
||||
target->abi.ext = abi_ext;
|
||||
target->cmodel = cmodel;
|
||||
}
|
||||
|
||||
|
||||
/* Handle combinations of -m parameters
|
||||
(see loongarch.opt and loongarch-opts.h). */
|
||||
|
||||
void
|
||||
loongarch_config_target (struct loongarch_target *target,
|
||||
HOST_WIDE_INT opt_switches,
|
||||
int opt_arch, int opt_tune, int opt_fpu,
|
||||
int opt_abi_base, int opt_abi_ext,
|
||||
int opt_cmodel, int follow_multilib_list)
|
||||
struct loongarch_flags *flags,
|
||||
int follow_multilib_list_p)
|
||||
{
|
||||
struct loongarch_target t;
|
||||
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
|
@ -142,67 +171,63 @@ loongarch_config_target (struct loongarch_target *target,
|
|||
obstack_init (&msg_obstack);
|
||||
|
||||
struct {
|
||||
int arch, tune, fpu, abi_base, abi_ext, cmodel;
|
||||
int arch, tune, fpu, simd, abi_base, abi_ext, cmodel, abi_flt;
|
||||
} constrained = {
|
||||
M_OPT_ABSENT(opt_arch) ? 0 : 1,
|
||||
M_OPT_ABSENT(opt_tune) ? 0 : 1,
|
||||
M_OPT_ABSENT(opt_fpu) ? 0 : 1,
|
||||
M_OPT_ABSENT(opt_abi_base) ? 0 : 1,
|
||||
M_OPT_ABSENT(opt_abi_ext) ? 0 : 1,
|
||||
M_OPT_ABSENT(opt_cmodel) ? 0 : 1,
|
||||
M_OPT_ABSENT (target->cpu_arch) ? 0 : 1,
|
||||
M_OPT_ABSENT (target->cpu_tune) ? 0 : 1,
|
||||
M_OPT_ABSENT (target->isa.fpu) ? 0 : 1,
|
||||
M_OPT_ABSENT (target->isa.simd) ? 0 : 1,
|
||||
M_OPT_ABSENT (target->abi.base) ? 0 : 1,
|
||||
M_OPT_ABSENT (target->abi.ext) ? 0 : 1,
|
||||
M_OPT_ABSENT (target->cmodel) ? 0 : 1,
|
||||
M_OPT_ABSENT (target->abi.base) ? 0 : 1,
|
||||
};
|
||||
|
||||
#define on(NAME) ((loongarch_switch_mask[(SW_##NAME)] & opt_switches) \
|
||||
&& (on_switch = (SW_##NAME), 1))
|
||||
int on_switch;
|
||||
|
||||
/* 1. Target ABI */
|
||||
t.abi.base = constrained.abi_base ? opt_abi_base : DEFAULT_ABI_BASE;
|
||||
if (constrained.abi_base)
|
||||
t.abi.base = target->abi.base;
|
||||
else
|
||||
t.abi.base = DEFAULT_ABI_BASE;
|
||||
|
||||
t.abi.ext = constrained.abi_ext ? opt_abi_ext : DEFAULT_ABI_EXT;
|
||||
t.abi.ext = constrained.abi_ext ? target->abi.ext : DEFAULT_ABI_EXT;
|
||||
|
||||
/* Extra switch handling. */
|
||||
if (on (SOFT_FLOAT) || on (SINGLE_FLOAT) || on (DOUBLE_FLOAT))
|
||||
/* Process -m*-float flags */
|
||||
if (flags && !M_OPT_ABSENT (flags->flt))
|
||||
{
|
||||
switch (on_switch)
|
||||
{
|
||||
case SW_SOFT_FLOAT:
|
||||
opt_fpu = ISA_EXT_NOFPU;
|
||||
break;
|
||||
/* Modifying the original "target" here makes it easier to write the
|
||||
t.isa.fpu assignment below, because otherwise there would be three
|
||||
levels of precedence (-m*-float / -mfpu / -march) to be handled
|
||||
(now the first two are merged). */
|
||||
|
||||
case SW_SINGLE_FLOAT:
|
||||
opt_fpu = ISA_EXT_FPU32;
|
||||
break;
|
||||
|
||||
case SW_DOUBLE_FLOAT:
|
||||
opt_fpu = ISA_EXT_FPU64;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable();
|
||||
}
|
||||
target->isa.fpu = flags->flt;
|
||||
constrained.fpu = 1;
|
||||
|
||||
/* The target ISA is not ready yet, but (isa_required (t.abi)
|
||||
+ forced fpu) is enough for computing the forced base ABI. */
|
||||
struct loongarch_isa default_isa = isa_required (t.abi);
|
||||
struct loongarch_isa force_isa = default_isa;
|
||||
struct loongarch_abi force_abi = t.abi;
|
||||
force_isa.fpu = opt_fpu;
|
||||
|
||||
struct loongarch_isa force_isa = isa_required (t.abi);
|
||||
force_isa.fpu = flags->flt;
|
||||
|
||||
struct loongarch_abi force_abi;
|
||||
force_abi.base = isa_default_abi (&force_isa).base;
|
||||
|
||||
if (constrained.abi_base && (t.abi.base != force_abi.base))
|
||||
inform (UNKNOWN_LOCATION,
|
||||
"%<-m%s%> overrides %<-m%s=%s%>, adjusting ABI to %qs",
|
||||
loongarch_switch_strings[on_switch],
|
||||
OPTSTR_ABI_BASE, loongarch_abi_base_strings[t.abi.base],
|
||||
abi_str (force_abi));
|
||||
if (constrained.abi_base && constrained.abi_flt
|
||||
&& (t.abi.base != force_abi.base))
|
||||
{
|
||||
force_abi.ext = t.abi.ext;
|
||||
inform (UNKNOWN_LOCATION,
|
||||
"%<-m%s%> overrides %<-m%s=%s%>, adjusting ABI to %qs",
|
||||
flags->flt_str, OPTSTR_ABI_BASE,
|
||||
loongarch_abi_base_strings[t.abi.base],
|
||||
abi_str (force_abi));
|
||||
}
|
||||
|
||||
t.abi.base = force_abi.base;
|
||||
constrained.abi_flt = 1;
|
||||
}
|
||||
|
||||
#ifdef LA_DISABLE_MULTILIB
|
||||
if (follow_multilib_list)
|
||||
if (follow_multilib_list_p)
|
||||
if (t.abi.base != DEFAULT_ABI_BASE || t.abi.ext != DEFAULT_ABI_EXT)
|
||||
{
|
||||
static const struct loongarch_abi default_abi
|
||||
|
@ -214,18 +239,22 @@ loongarch_config_target (struct loongarch_target *target,
|
|||
#endif
|
||||
|
||||
/* 2. Target CPU */
|
||||
t.cpu_arch = constrained.arch ? opt_arch : DEFAULT_CPU_ARCH;
|
||||
t.cpu_arch = constrained.arch ? target->cpu_arch : DEFAULT_CPU_ARCH;
|
||||
|
||||
t.cpu_tune = constrained.tune ? opt_tune
|
||||
: (constrained.arch ? DEFAULT_CPU_ARCH : DEFAULT_CPU_TUNE);
|
||||
/* If cpu_tune is not set using neither -mtune nor --with-tune,
|
||||
the current cpu_arch is used as its default. */
|
||||
t.cpu_tune = constrained.tune ? target->cpu_tune
|
||||
: (constrained.arch ? target->cpu_arch :
|
||||
(with_default_tune ? DEFAULT_CPU_TUNE : DEFAULT_CPU_ARCH));
|
||||
|
||||
|
||||
/* Handle -march/tune=native */
|
||||
#ifdef __loongarch__
|
||||
/* For native compilers, gather local CPU information
|
||||
and fill the "CPU_NATIVE" index of arrays defined in
|
||||
loongarch-cpu.c. */
|
||||
|
||||
t.cpu_native = fill_native_cpu_config (t.cpu_arch == CPU_NATIVE,
|
||||
t.cpu_tune == CPU_NATIVE);
|
||||
fill_native_cpu_config (&t);
|
||||
|
||||
#else
|
||||
if (t.cpu_arch == CPU_NATIVE)
|
||||
|
@ -239,17 +268,130 @@ loongarch_config_target (struct loongarch_target *target,
|
|||
"-m" OPTSTR_TUNE "=" STR_CPU_NATIVE);
|
||||
#endif
|
||||
|
||||
/* 3. Target ISA */
|
||||
/* Handle -march/tune=abi-default */
|
||||
if (t.cpu_tune == CPU_ABI_DEFAULT)
|
||||
t.cpu_tune = abi_default_cpu_arch (t.abi, NULL);
|
||||
|
||||
if (t.cpu_arch == CPU_ABI_DEFAULT)
|
||||
{
|
||||
t.cpu_arch = abi_default_cpu_arch (t.abi, &(t.isa));
|
||||
loongarch_cpu_default_isa[t.cpu_arch] = t.isa;
|
||||
}
|
||||
|
||||
/* 3. Target base ISA */
|
||||
config_target_isa:
|
||||
|
||||
/* Get default ISA from "-march" or its default value. */
|
||||
t.isa = loongarch_cpu_default_isa[LARCH_ACTUAL_ARCH];
|
||||
t.isa = loongarch_cpu_default_isa[t.cpu_arch];
|
||||
|
||||
/* Apply incremental changes. */
|
||||
/* "-march=native" overrides the default FPU type. */
|
||||
t.isa.fpu = constrained.fpu ? opt_fpu :
|
||||
((t.cpu_arch == CPU_NATIVE && constrained.arch) ?
|
||||
t.isa.fpu : DEFAULT_ISA_EXT_FPU);
|
||||
|
||||
t.isa.fpu = constrained.fpu ? target->isa.fpu :
|
||||
(constrained.arch ? t.isa.fpu :
|
||||
(with_default_fpu ? DEFAULT_ISA_EXT_FPU : t.isa.fpu));
|
||||
|
||||
int simd_base = (constrained.arch ? t.isa.simd :
|
||||
(with_default_simd ? DEFAULT_ISA_EXT_SIMD : t.isa.simd));
|
||||
|
||||
t.isa.simd = constrained.simd ? target->isa.simd : simd_base;
|
||||
|
||||
/* If fallback_lsx is set, using -mno-lasx would cause
|
||||
a fall-back to -msimd=lsx instead of -msimd=none. */
|
||||
|
||||
int fallback_lsx = 0;
|
||||
if (t.isa.simd == ISA_EXT_SIMD_LSX || simd_base != ISA_EXT_NONE)
|
||||
fallback_lsx = 1;
|
||||
|
||||
/* apply -m[no-]lsx and -m[no-]lasx flags */
|
||||
if (flags)
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
switch (SX_FLAG_TYPE (flags->sx[i]))
|
||||
{
|
||||
case ISA_EXT_SIMD_LSX:
|
||||
constrained.simd = 1;
|
||||
|
||||
if (flags->sx[i] > 0)
|
||||
fallback_lsx = 1;
|
||||
|
||||
if (flags->sx[i] > 0 && t.isa.simd != ISA_EXT_SIMD_LASX)
|
||||
t.isa.simd = ISA_EXT_SIMD_LSX;
|
||||
else if (flags->sx[i] < 0)
|
||||
t.isa.simd = ISA_EXT_NONE;
|
||||
break;
|
||||
|
||||
case ISA_EXT_SIMD_LASX:
|
||||
constrained.simd = 1;
|
||||
/* If -mlsx or simd=lsx (msimd or march-default) was not
|
||||
involved, do not fall back to simd=lsx. */
|
||||
if (flags->sx[i] < 0 && t.isa.simd == ISA_EXT_SIMD_LASX)
|
||||
t.isa.simd = fallback_lsx ? ISA_EXT_SIMD_LSX : ISA_EXT_NONE;
|
||||
else if (flags->sx[i] > 0)
|
||||
t.isa.simd = ISA_EXT_SIMD_LASX;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
/* All SIMD extensions imply a 64-bit FPU:
|
||||
- silently adjust t.isa.fpu to "fpu64" if it is unconstrained.
|
||||
- warn if -msingle-float / -msoft-float is on,
|
||||
then disable SIMD extensions (done in driver)
|
||||
- abort if -mfpu=0 / -mfpu=32 is forced. */
|
||||
|
||||
if (t.isa.simd != ISA_EXT_NONE && t.isa.fpu != ISA_EXT_FPU64)
|
||||
{
|
||||
if (!constrained.fpu)
|
||||
{
|
||||
/* As long as the arch-default "t.isa.simd" is set to non-zero
|
||||
for an element "t" in loongarch_cpu_default_isa, "t.isa.fpu"
|
||||
should be set to "ISA_EXT_FPU64" accordingly. Thus reaching
|
||||
here must be the result of forcing -mlsx/-mlasx explicitly. */
|
||||
gcc_assert (constrained.simd);
|
||||
|
||||
inform (UNKNOWN_LOCATION,
|
||||
"enabing %qs promotes %<%s%s%> to %<%s%s%>",
|
||||
loongarch_isa_ext_strings[t.isa.simd],
|
||||
OPTSTR_ISA_EXT_FPU, loongarch_isa_ext_strings[t.isa.fpu],
|
||||
OPTSTR_ISA_EXT_FPU, loongarch_isa_ext_strings[ISA_EXT_FPU64]);
|
||||
|
||||
t.isa.fpu = ISA_EXT_FPU64;
|
||||
}
|
||||
else if (flags && (flags->flt == ISA_EXT_NONE
|
||||
|| flags->flt == ISA_EXT_FPU32))
|
||||
{
|
||||
if (constrained.simd)
|
||||
inform (UNKNOWN_LOCATION,
|
||||
"%qs is disabled by %<-m%s%>, because it requires %<%s%s%>",
|
||||
loongarch_isa_ext_strings[t.isa.simd], flags->flt_str,
|
||||
OPTSTR_ISA_EXT_FPU,
|
||||
loongarch_isa_ext_strings[ISA_EXT_FPU64]);
|
||||
|
||||
t.isa.simd = ISA_EXT_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* -mfpu=0 / -mfpu=32 is set. */
|
||||
if (constrained.simd)
|
||||
fatal_error (UNKNOWN_LOCATION,
|
||||
"%<-m%s=%s%> conflicts with %qs, "
|
||||
"which requires %<%s%s%>",
|
||||
OPTSTR_ISA_EXT_FPU,
|
||||
loongarch_isa_ext_strings[t.isa.fpu],
|
||||
loongarch_isa_ext_strings[t.isa.simd],
|
||||
OPTSTR_ISA_EXT_FPU,
|
||||
loongarch_isa_ext_strings[ISA_EXT_FPU64]);
|
||||
|
||||
/* Same as above. */
|
||||
t.isa.simd = ISA_EXT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 4. ABI-ISA compatibility */
|
||||
|
@ -272,7 +414,7 @@ config_target_isa:
|
|||
{
|
||||
/* Base architecture can only be implied by -march,
|
||||
so we adjust that first if it is not constrained. */
|
||||
int fallback_arch = abi_default_cpu_arch (t.abi);
|
||||
int fallback_arch = abi_default_cpu_arch (t.abi, NULL);
|
||||
|
||||
if (t.cpu_arch == CPU_NATIVE)
|
||||
warning (0, "your native CPU architecture (%qs) "
|
||||
|
@ -319,7 +461,7 @@ fatal:
|
|||
if (abi_tmp.base != t.abi.base || abi_tmp.ext != t.abi.ext)
|
||||
{
|
||||
/* This flag is only set in the GCC driver. */
|
||||
if (follow_multilib_list)
|
||||
if (follow_multilib_list_p)
|
||||
{
|
||||
|
||||
/* Continue falling back until we find a feasible ABI type
|
||||
|
@ -360,7 +502,7 @@ fatal:
|
|||
fallback:
|
||||
t.abi = abi_tmp;
|
||||
}
|
||||
else if (follow_multilib_list)
|
||||
else if (follow_multilib_list_p)
|
||||
{
|
||||
if (!is_multilib_enabled (t.abi))
|
||||
{
|
||||
|
@ -375,7 +517,7 @@ fallback:
|
|||
|
||||
|
||||
/* 5. Target code model */
|
||||
t.cmodel = constrained.cmodel ? opt_cmodel : CMODEL_NORMAL;
|
||||
t.cmodel = constrained.cmodel ? target->cmodel : CMODEL_NORMAL;
|
||||
|
||||
switch (t.cmodel)
|
||||
{
|
||||
|
@ -419,7 +561,7 @@ isa_default_abi (const struct loongarch_isa *isa)
|
|||
abi.base = ABI_BASE_LP64F;
|
||||
break;
|
||||
|
||||
case ISA_EXT_NOFPU:
|
||||
case ISA_EXT_NONE:
|
||||
if (isa->base == ISA_BASE_LA64V100)
|
||||
abi.base = ABI_BASE_LP64S;
|
||||
break;
|
||||
|
@ -459,7 +601,7 @@ isa_fpu_compat_p (const struct loongarch_isa *set1,
|
|||
case ISA_EXT_FPU32:
|
||||
return set1->fpu == ISA_EXT_FPU32 || set1->fpu == ISA_EXT_FPU64;
|
||||
|
||||
case ISA_EXT_NOFPU:
|
||||
case ISA_EXT_NONE:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
|
@ -483,16 +625,22 @@ abi_compat_p (const struct loongarch_isa *isa, struct loongarch_abi abi)
|
|||
/* The behavior of this function should be consistent
|
||||
with config.gcc. */
|
||||
static inline int
|
||||
abi_default_cpu_arch (struct loongarch_abi abi)
|
||||
abi_default_cpu_arch (struct loongarch_abi abi,
|
||||
struct loongarch_isa *isa)
|
||||
{
|
||||
switch (abi.base)
|
||||
{
|
||||
case ABI_BASE_LP64D:
|
||||
case ABI_BASE_LP64F:
|
||||
case ABI_BASE_LP64S:
|
||||
if (abi.ext == ABI_EXT_BASE)
|
||||
static struct loongarch_isa tmp;
|
||||
if (!isa)
|
||||
isa = &tmp;
|
||||
|
||||
if (abi.ext == ABI_EXT_BASE)
|
||||
switch (abi.base)
|
||||
{
|
||||
case ABI_BASE_LP64D:
|
||||
case ABI_BASE_LP64F:
|
||||
case ABI_BASE_LP64S:
|
||||
*isa = isa_required (abi);
|
||||
return CPU_LOONGARCH64;
|
||||
}
|
||||
}
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
|
@ -521,7 +669,7 @@ isa_str (const struct loongarch_isa *isa, char separator)
|
|||
APPEND_STRING (loongarch_isa_base_strings[isa->base])
|
||||
APPEND1 (separator)
|
||||
|
||||
if (isa->fpu == ISA_EXT_NOFPU)
|
||||
if (isa->fpu == ISA_EXT_NONE)
|
||||
{
|
||||
APPEND_STRING ("no" OPTSTR_ISA_EXT_FPU)
|
||||
}
|
||||
|
@ -530,6 +678,18 @@ isa_str (const struct loongarch_isa *isa, char separator)
|
|||
APPEND_STRING (OPTSTR_ISA_EXT_FPU)
|
||||
APPEND_STRING (loongarch_isa_ext_strings[isa->fpu])
|
||||
}
|
||||
|
||||
switch (isa->simd)
|
||||
{
|
||||
case ISA_EXT_SIMD_LSX:
|
||||
case ISA_EXT_SIMD_LASX:
|
||||
APPEND1 (separator);
|
||||
APPEND_STRING (loongarch_isa_ext_strings[isa->simd]);
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_assert (isa->simd == 0);
|
||||
}
|
||||
APPEND1 ('\0')
|
||||
|
||||
/* Add more here. */
|
||||
|
@ -542,18 +702,12 @@ arch_str (const struct loongarch_target *target)
|
|||
{
|
||||
if (target->cpu_arch == CPU_NATIVE)
|
||||
{
|
||||
if (target->cpu_native == CPU_NATIVE)
|
||||
{
|
||||
/* Describe a native CPU with unknown PRID. */
|
||||
const char* isa_string = isa_str (&target->isa, ',');
|
||||
APPEND_STRING ("PRID: 0x")
|
||||
APPEND_STRING (get_native_prid_str ())
|
||||
APPEND_STRING (", ISA features: ")
|
||||
APPEND_STRING (isa_string)
|
||||
APPEND1 ('\0')
|
||||
}
|
||||
else
|
||||
APPEND_STRING (loongarch_cpu_strings[target->cpu_native]);
|
||||
/* Describe a native CPU with unknown PRID. */
|
||||
const char* isa_string = isa_str (&target->isa, ',');
|
||||
APPEND_STRING ("PRID: 0x")
|
||||
APPEND_STRING (get_native_prid_str ())
|
||||
APPEND_STRING (", ISA features: ")
|
||||
APPEND_STRING (isa_string)
|
||||
}
|
||||
else
|
||||
APPEND_STRING (loongarch_cpu_strings[target->cpu_arch]);
|
||||
|
@ -594,3 +748,23 @@ multilib_enabled_abi_list ()
|
|||
|
||||
return XOBFINISH (&msg_obstack, const char *);
|
||||
}
|
||||
|
||||
/* option status feedback for "gcc --help=target -Q" */
|
||||
void
|
||||
loongarch_update_gcc_opt_status (struct loongarch_target *target,
|
||||
struct gcc_options *opts,
|
||||
struct gcc_options *opts_set)
|
||||
{
|
||||
(void) opts_set;
|
||||
|
||||
/* status of -mabi */
|
||||
opts->x_la_opt_abi_base = target->abi.base;
|
||||
|
||||
/* status of -march and -mtune */
|
||||
opts->x_la_opt_cpu_arch = target->cpu_arch;
|
||||
opts->x_la_opt_cpu_tune = target->cpu_tune;
|
||||
|
||||
/* status of -mfpu */
|
||||
opts->x_la_opt_fpu = target->isa.fpu;
|
||||
opts->x_la_opt_simd = target->isa.simd;
|
||||
}
|
||||
|
|
|
@ -21,24 +21,39 @@ along with GCC; see the file COPYING3. If not see
|
|||
#ifndef LOONGARCH_OPTS_H
|
||||
#define LOONGARCH_OPTS_H
|
||||
|
||||
#include "loongarch-def.h"
|
||||
|
||||
/* Target configuration */
|
||||
extern struct loongarch_target la_target;
|
||||
|
||||
/* Switch masks */
|
||||
extern const int loongarch_switch_mask[];
|
||||
|
||||
#include "loongarch-def.h"
|
||||
/* Flag status */
|
||||
struct loongarch_flags {
|
||||
int flt; const char* flt_str;
|
||||
#define SX_FLAG_TYPE(x) ((x) < 0 ? -(x) : (x))
|
||||
int sx[2];
|
||||
};
|
||||
|
||||
#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)
|
||||
|
||||
/* Initialize loongarch_target from separate option variables. */
|
||||
void
|
||||
loongarch_init_target (struct loongarch_target *target,
|
||||
int cpu_arch, int cpu_tune, int fpu, int simd,
|
||||
int abi_base, int abi_ext, int cmodel);
|
||||
|
||||
|
||||
/* Handler for "-m" option combinations,
|
||||
shared by the driver and the compiler proper. */
|
||||
void
|
||||
loongarch_config_target (struct loongarch_target *target,
|
||||
HOST_WIDE_INT opt_switches,
|
||||
int opt_arch, int opt_tune, int opt_fpu,
|
||||
int opt_abi_base, int opt_abi_ext,
|
||||
int opt_cmodel, int follow_multilib_list);
|
||||
struct loongarch_flags *flags,
|
||||
int follow_multilib_list_p);
|
||||
|
||||
/* option status feedback for "gcc --help=target -Q" */
|
||||
void
|
||||
loongarch_update_gcc_opt_status (struct loongarch_target *target,
|
||||
struct gcc_options *opts,
|
||||
struct gcc_options *opts_set);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -50,11 +65,11 @@ loongarch_config_target (struct loongarch_target *target,
|
|||
#define TARGET_CMODEL_LARGE (la_target.cmodel == CMODEL_LARGE)
|
||||
#define TARGET_CMODEL_EXTREME (la_target.cmodel == CMODEL_EXTREME)
|
||||
|
||||
#define TARGET_HARD_FLOAT (la_target.isa.fpu != ISA_EXT_NOFPU)
|
||||
#define TARGET_HARD_FLOAT (la_target.isa.fpu != ISA_EXT_NONE)
|
||||
#define TARGET_HARD_FLOAT_ABI (la_target.abi.base == ABI_BASE_LP64D \
|
||||
|| la_target.abi.base == ABI_BASE_LP64F)
|
||||
|
||||
#define TARGET_SOFT_FLOAT (la_target.isa.fpu == ISA_EXT_NOFPU)
|
||||
#define TARGET_SOFT_FLOAT (la_target.isa.fpu == ISA_EXT_NONE)
|
||||
#define TARGET_SOFT_FLOAT_ABI (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)
|
||||
|
@ -66,30 +81,16 @@ loongarch_config_target (struct loongarch_target *target,
|
|||
|| la_target.abi.base == ABI_BASE_LP64F \
|
||||
|| la_target.abi.base == ABI_BASE_LP64S)
|
||||
|
||||
#define TARGET_ARCH_NATIVE (la_target.cpu_arch == CPU_NATIVE)
|
||||
#define LARCH_ACTUAL_ARCH (TARGET_ARCH_NATIVE \
|
||||
? (la_target.cpu_native < N_ARCH_TYPES \
|
||||
? (la_target.cpu_native) : (CPU_NATIVE)) \
|
||||
: (la_target.cpu_arch))
|
||||
#define ISA_HAS_LSX (la_target.isa.simd == ISA_EXT_SIMD_LSX \
|
||||
|| la_target.isa.simd == ISA_EXT_SIMD_LASX)
|
||||
#define ISA_HAS_LASX (la_target.isa.simd == ISA_EXT_SIMD_LASX)
|
||||
|
||||
#define TARGET_TUNE_NATIVE (la_target.cpu_tune == CPU_NATIVE)
|
||||
#define LARCH_ACTUAL_TUNE (TARGET_TUNE_NATIVE \
|
||||
? (la_target.cpu_native < N_TUNE_TYPES \
|
||||
? (la_target.cpu_native) : (CPU_NATIVE)) \
|
||||
: (la_target.cpu_tune))
|
||||
|
||||
#define TARGET_ARCH_LOONGARCH64 (LARCH_ACTUAL_ARCH == CPU_LOONGARCH64)
|
||||
#define TARGET_ARCH_LA464 (LARCH_ACTUAL_ARCH == CPU_LA464)
|
||||
|
||||
#define TARGET_TUNE_LOONGARCH64 (LARCH_ACTUAL_TUNE == CPU_LOONGARCH64)
|
||||
#define TARGET_TUNE_LA464 (LARCH_ACTUAL_TUNE == CPU_LA464)
|
||||
/* TARGET_ macros for use in *.md template conditionals */
|
||||
#define TARGET_uARCH_LA464 (la_target.cpu_tune == CPU_LA464)
|
||||
|
||||
/* Note: optimize_size may vary across functions,
|
||||
while -m[no]-memcpy imposes a global constraint. */
|
||||
#define TARGET_DO_OPTIMIZE_BLOCK_MOVE_P loongarch_do_optimize_block_move_p()
|
||||
|
||||
#ifndef HAVE_AS_EXPLICIT_RELOCS
|
||||
#define HAVE_AS_EXPLICIT_RELOCS 0
|
||||
#endif
|
||||
|
||||
#endif /* LOONGARCH_OPTS_H */
|
||||
|
|
|
@ -27,13 +27,14 @@ along with GCC; see the file COPYING3. If not see
|
|||
#define OPTSTR_TUNE "tune"
|
||||
|
||||
#define STR_CPU_NATIVE "native"
|
||||
#define STR_CPU_ABI_DEFAULT "abi-default"
|
||||
#define STR_CPU_LOONGARCH64 "loongarch64"
|
||||
#define STR_CPU_LA464 "la464"
|
||||
|
||||
#define STR_ISA_BASE_LA64V100 "la64"
|
||||
|
||||
#define OPTSTR_ISA_EXT_FPU "fpu"
|
||||
#define STR_ISA_EXT_NOFPU "none"
|
||||
#define STR_NONE "none"
|
||||
#define STR_ISA_EXT_FPU0 "0"
|
||||
#define STR_ISA_EXT_FPU32 "32"
|
||||
#define STR_ISA_EXT_FPU64 "64"
|
||||
|
@ -42,6 +43,10 @@ along with GCC; see the file COPYING3. If not see
|
|||
#define OPTSTR_SINGLE_FLOAT "single-float"
|
||||
#define OPTSTR_DOUBLE_FLOAT "double-float"
|
||||
|
||||
#define OPTSTR_ISA_EXT_SIMD "simd"
|
||||
#define STR_ISA_EXT_LSX "lsx"
|
||||
#define STR_ISA_EXT_LASX "lasx"
|
||||
|
||||
#define OPTSTR_ABI_BASE "abi"
|
||||
#define STR_ABI_BASE_LP64D "lp64d"
|
||||
#define STR_ABI_BASE_LP64F "lp64f"
|
||||
|
|
|
@ -2555,7 +2555,7 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0)
|
|||
|
||||
if (flag_plt)
|
||||
{
|
||||
switch (la_opt_cmodel)
|
||||
switch (la_target.cmodel)
|
||||
{
|
||||
case CMODEL_NORMAL:
|
||||
insn = emit_call_insn (gen_call_value_internal (v0,
|
||||
|
@ -2597,7 +2597,7 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0)
|
|||
{
|
||||
rtx dest = gen_reg_rtx (Pmode);
|
||||
|
||||
switch (la_opt_cmodel)
|
||||
switch (la_target.cmodel)
|
||||
{
|
||||
case CMODEL_NORMAL:
|
||||
case CMODEL_MEDIUM:
|
||||
|
@ -6064,8 +6064,8 @@ loongarch_adjust_cost (rtx_insn *, int dep_type, rtx_insn *, int cost,
|
|||
static int
|
||||
loongarch_issue_rate (void)
|
||||
{
|
||||
if ((unsigned long) LARCH_ACTUAL_TUNE < N_TUNE_TYPES)
|
||||
return loongarch_cpu_issue_rate[LARCH_ACTUAL_TUNE];
|
||||
if ((unsigned long) la_target.cpu_tune < N_TUNE_TYPES)
|
||||
return loongarch_cpu_issue_rate[la_target.cpu_tune];
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
@ -6076,8 +6076,8 @@ loongarch_issue_rate (void)
|
|||
static int
|
||||
loongarch_multipass_dfa_lookahead (void)
|
||||
{
|
||||
if ((unsigned long) LARCH_ACTUAL_TUNE < N_ARCH_TYPES)
|
||||
return loongarch_cpu_multipass_dfa_lookahead[LARCH_ACTUAL_TUNE];
|
||||
if ((unsigned long) la_target.cpu_tune < N_ARCH_TYPES)
|
||||
return loongarch_cpu_multipass_dfa_lookahead[la_target.cpu_tune];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -6254,17 +6254,54 @@ loongarch_init_machine_status (void)
|
|||
}
|
||||
|
||||
static void
|
||||
loongarch_option_override_internal (struct gcc_options *opts)
|
||||
loongarch_cpu_option_override (struct loongarch_target *target,
|
||||
struct gcc_options *opts,
|
||||
struct gcc_options *opts_set)
|
||||
{
|
||||
/* alignments */
|
||||
if (opts->x_flag_align_functions && !opts->x_str_align_functions)
|
||||
opts->x_str_align_functions
|
||||
= loongarch_cpu_align[target->cpu_tune].function;
|
||||
|
||||
if (opts->x_flag_align_labels && !opts->x_str_align_labels)
|
||||
opts->x_str_align_labels = loongarch_cpu_align[target->cpu_tune].label;
|
||||
|
||||
/* Set up parameters to be used in prefetching algorithm. */
|
||||
int simultaneous_prefetches
|
||||
= loongarch_cpu_cache[target->cpu_tune].simultaneous_prefetches;
|
||||
|
||||
SET_OPTION_IF_UNSET (opts, opts_set, param_simultaneous_prefetches,
|
||||
simultaneous_prefetches);
|
||||
|
||||
SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_line_size,
|
||||
loongarch_cpu_cache[target->cpu_tune].l1d_line_size);
|
||||
|
||||
SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_size,
|
||||
loongarch_cpu_cache[target->cpu_tune].l1d_size);
|
||||
|
||||
SET_OPTION_IF_UNSET (opts, opts_set, param_l2_cache_size,
|
||||
loongarch_cpu_cache[target->cpu_tune].l2d_size);
|
||||
}
|
||||
|
||||
static void
|
||||
loongarch_option_override_internal (struct gcc_options *opts,
|
||||
struct gcc_options *opts_set)
|
||||
{
|
||||
int i, regno, mode;
|
||||
|
||||
if (flag_pic)
|
||||
g_switch_value = 0;
|
||||
|
||||
loongarch_init_target (&la_target,
|
||||
la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu,
|
||||
la_opt_simd, la_opt_abi_base, la_opt_abi_ext,
|
||||
la_opt_cmodel);
|
||||
|
||||
/* Handle target-specific options: compute defaults/conflicts etc. */
|
||||
loongarch_config_target (&la_target, la_opt_switches,
|
||||
la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu,
|
||||
la_opt_abi_base, la_opt_abi_ext, la_opt_cmodel, 0);
|
||||
loongarch_config_target (&la_target, NULL, 0);
|
||||
|
||||
loongarch_update_gcc_opt_status (&la_target, opts, opts_set);
|
||||
loongarch_cpu_option_override (&la_target, opts, opts_set);
|
||||
|
||||
if (TARGET_ABI_LP64)
|
||||
flag_pcc_struct_return = 0;
|
||||
|
@ -6273,33 +6310,13 @@ loongarch_option_override_internal (struct gcc_options *opts)
|
|||
if (optimize_size)
|
||||
loongarch_cost = &loongarch_rtx_cost_optimize_size;
|
||||
else
|
||||
loongarch_cost = &loongarch_cpu_rtx_cost_data[LARCH_ACTUAL_TUNE];
|
||||
loongarch_cost = &loongarch_cpu_rtx_cost_data[la_target.cpu_tune];
|
||||
|
||||
/* If the user hasn't specified a branch cost, use the processor's
|
||||
default. */
|
||||
if (loongarch_branch_cost == 0)
|
||||
loongarch_branch_cost = loongarch_cost->branch_cost;
|
||||
|
||||
/* Set up parameters to be used in prefetching algorithm. */
|
||||
int simultaneous_prefetches
|
||||
= loongarch_cpu_cache[LARCH_ACTUAL_TUNE].simultaneous_prefetches;
|
||||
|
||||
SET_OPTION_IF_UNSET (opts, &global_options_set,
|
||||
param_simultaneous_prefetches,
|
||||
simultaneous_prefetches);
|
||||
|
||||
SET_OPTION_IF_UNSET (opts, &global_options_set,
|
||||
param_l1_cache_line_size,
|
||||
loongarch_cpu_cache[LARCH_ACTUAL_TUNE].l1d_line_size);
|
||||
|
||||
SET_OPTION_IF_UNSET (opts, &global_options_set,
|
||||
param_l1_cache_size,
|
||||
loongarch_cpu_cache[LARCH_ACTUAL_TUNE].l1d_size);
|
||||
|
||||
SET_OPTION_IF_UNSET (opts, &global_options_set,
|
||||
param_l2_cache_size,
|
||||
loongarch_cpu_cache[LARCH_ACTUAL_TUNE].l2d_size);
|
||||
|
||||
|
||||
/* Enable sw prefetching at -O3 and higher. */
|
||||
if (opts->x_flag_prefetch_loop_arrays < 0
|
||||
|
@ -6307,12 +6324,6 @@ loongarch_option_override_internal (struct gcc_options *opts)
|
|||
&& !opts->x_optimize_size)
|
||||
opts->x_flag_prefetch_loop_arrays = 1;
|
||||
|
||||
if (opts->x_flag_align_functions && !opts->x_str_align_functions)
|
||||
opts->x_str_align_functions = loongarch_cpu_align[LARCH_ACTUAL_TUNE].function;
|
||||
|
||||
if (opts->x_flag_align_labels && !opts->x_str_align_labels)
|
||||
opts->x_str_align_labels = loongarch_cpu_align[LARCH_ACTUAL_TUNE].label;
|
||||
|
||||
if (TARGET_DIRECT_EXTERN_ACCESS && flag_shlib)
|
||||
error ("%qs cannot be used for compiling a shared library",
|
||||
"-mdirect-extern-access");
|
||||
|
@ -6382,7 +6393,7 @@ loongarch_option_override_internal (struct gcc_options *opts)
|
|||
static void
|
||||
loongarch_option_override (void)
|
||||
{
|
||||
loongarch_option_override_internal (&global_options);
|
||||
loongarch_option_override_internal (&global_options, &global_options_set);
|
||||
}
|
||||
|
||||
/* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */
|
||||
|
|
|
@ -24,22 +24,12 @@
|
|||
; <http://www.gnu.org/licenses/>.
|
||||
;
|
||||
|
||||
; 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
|
||||
|
@ -49,14 +39,13 @@ Basic ISAs of LoongArch:
|
|||
EnumValue
|
||||
Enum(isa_base) String(la64) Value(ISA_BASE_LA64V100)
|
||||
|
||||
|
||||
;; ISA extensions / adjustments
|
||||
Enum
|
||||
Name(isa_ext_fpu) Type(int)
|
||||
FPU types of LoongArch:
|
||||
|
||||
EnumValue
|
||||
Enum(isa_ext_fpu) String(none) Value(ISA_EXT_NOFPU)
|
||||
Enum(isa_ext_fpu) String(none) Value(ISA_EXT_NONE)
|
||||
|
||||
EnumValue
|
||||
Enum(isa_ext_fpu) String(32) Value(ISA_EXT_FPU32)
|
||||
|
@ -65,24 +54,48 @@ EnumValue
|
|||
Enum(isa_ext_fpu) String(64) Value(ISA_EXT_FPU64)
|
||||
|
||||
mfpu=
|
||||
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)
|
||||
-mfpu=FPU Generate code for the given FPU.
|
||||
|
||||
mfpu=0
|
||||
Target RejectNegative Alias(mfpu=,none)
|
||||
|
||||
msoft-float
|
||||
Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_SOFTF) Negative(msingle-float)
|
||||
Target Driver Defer Var(la_deferred_options) RejectNegative Negative(msingle-float)
|
||||
Prevent the use of all hardware floating-point instructions.
|
||||
|
||||
msingle-float
|
||||
Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F32) Negative(mdouble-float)
|
||||
Target Driver Defer Var(la_deferred_options) RejectNegative Negative(mdouble-float)
|
||||
Restrict the use of hardware floating-point instructions to 32-bit operations.
|
||||
|
||||
mdouble-float
|
||||
Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F64) Negative(msoft-float)
|
||||
Target Driver Defer Var(la_deferred_options) RejectNegative Negative(msoft-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(none) Value(ISA_EXT_NONE)
|
||||
|
||||
EnumValue
|
||||
Enum(isa_ext_simd) String(lsx) Value(ISA_EXT_SIMD_LSX)
|
||||
|
||||
EnumValue
|
||||
Enum(isa_ext_simd) String(lasx) Value(ISA_EXT_SIMD_LASX)
|
||||
|
||||
msimd=
|
||||
Target RejectNegative Joined ToLower Enum(isa_ext_simd) Var(la_opt_simd) Init(M_OPT_UNSET)
|
||||
-msimd=SIMD Generate code for the given SIMD extension.
|
||||
|
||||
mlsx
|
||||
Target Driver Defer Var(la_deferred_options)
|
||||
Enable LoongArch SIMD Extension (LSX, 128-bit).
|
||||
|
||||
mlasx
|
||||
Target Driver Defer Var(la_deferred_options)
|
||||
Enable LoongArch Advanced SIMD Extension (LASX, 256-bit).
|
||||
|
||||
;; Base target models (implies ISA & tune parameters)
|
||||
Enum
|
||||
|
@ -92,6 +105,9 @@ LoongArch CPU types:
|
|||
EnumValue
|
||||
Enum(cpu_type) String(native) Value(CPU_NATIVE)
|
||||
|
||||
EnumValue
|
||||
Enum(cpu_type) String(abi-default) Value(CPU_ABI_DEFAULT)
|
||||
|
||||
EnumValue
|
||||
Enum(cpu_type) String(loongarch64) Value(CPU_LOONGARCH64)
|
||||
|
||||
|
@ -99,11 +115,11 @@ EnumValue
|
|||
Enum(cpu_type) String(la464) Value(CPU_LA464)
|
||||
|
||||
march=
|
||||
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)
|
||||
-march=PROCESSOR Generate code for the given PROCESSOR ISA.
|
||||
|
||||
mtune=
|
||||
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)
|
||||
-mtune=PROCESSOR Generate optimized code for PROCESSOR.
|
||||
|
||||
|
||||
|
@ -125,13 +141,13 @@ EnumValue
|
|||
Enum(abi_base) String(lp64s) Value(ABI_BASE_LP64S)
|
||||
|
||||
mabi=
|
||||
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)
|
||||
-mabi=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)
|
||||
|
@ -189,7 +205,7 @@ EnumValue
|
|||
Enum(cmodel) String(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
|
||||
|
|
|
@ -23,7 +23,37 @@ MULTILIB_DIRNAMES = base/lp64d base/lp64f base/lp64s
|
|||
# The GCC driver always gets all abi-related options on the command line.
|
||||
# (see loongarch-driver.c:driver_get_normalized_m_opts)
|
||||
comma=,
|
||||
MULTILIB_REQUIRED = $(subst $(comma), ,$(TM_MULTILIB_CONFIG))
|
||||
MULTILIB_REQUIRED = $(foreach mlib,$(subst $(comma), ,$(TM_MULTILIB_CONFIG)),\
|
||||
$(firstword $(subst /, ,$(mlib))))
|
||||
|
||||
SPECS = specs.install
|
||||
|
||||
# temporary self_spec when building libraries (e.g. libgcc)
|
||||
gen_mlib_spec = $(if $(word 2,$1),\
|
||||
%{$(firstword $1):$(patsubst %,-%,$(wordlist 2,$(words $1),$1))})
|
||||
|
||||
# clean up the result of DRIVER_SELF_SPEC to avoid conflict
|
||||
lib_build_self_spec = %<march=* %<mtune=* %<mcmodel=* %<mfpu=* %<msimd=*
|
||||
|
||||
# append user-specified build options from --with-multilib-list
|
||||
lib_build_self_spec += $(foreach mlib,\
|
||||
$(subst $(comma), ,$(TM_MULTILIB_CONFIG)),\
|
||||
$(call gen_mlib_spec,$(subst /, ,$(mlib))))
|
||||
|
||||
specs: specs.install
|
||||
sed '/^*self_spec:$$/{ n;s/^$$/$(lib_build_self_spec)/g; }' $< > $@
|
||||
|
||||
# Do some preparation before regression tests:
|
||||
# remove lib-build-specs / make symlinks for the toplevel multilib variant
|
||||
|
||||
LA_DEFAULT_MULTISUBDIR = $(shell $(GCC_FOR_TARGET) --print-multi-dir)
|
||||
.PHONY: remove-lib-specs
|
||||
check check-host check-target $(CHECK_TARGETS) $(lang_checks): remove-lib-specs
|
||||
remove-lib-specs:
|
||||
-mv -f specs.install specs 2>/dev/null
|
||||
-mv $(LA_DEFAULT_MULTISUBDIR)/* ./
|
||||
-mkdir -p ../$(target_noncanonical)/`dirname $(LA_DEFAULT_MULTISUBDIR)`
|
||||
-$(LN_S) .. ../$(target_noncanonical)/$(LA_DEFAULT_MULTISUBDIR)
|
||||
|
||||
# Multiarch
|
||||
ifneq ($(call if_multiarch,yes),yes)
|
||||
|
|
|
@ -1236,7 +1236,7 @@ sysv, aix.
|
|||
@itemx --without-multilib-list
|
||||
Specify what multilibs to build. @var{list} is a comma separated list of
|
||||
values, possibly consisting of a single value. Currently only implemented
|
||||
for aarch64*-*-*, arm*-*-*, loongarch64-*-*, riscv*-*-*, sh*-*-* and
|
||||
for aarch64*-*-*, arm*-*-*, loongarch*-*-*, riscv*-*-*, sh*-*-* and
|
||||
x86-64-*-linux*. The accepted values and meaning for each target is given
|
||||
below.
|
||||
|
||||
|
@ -1326,12 +1326,33 @@ profile. The union of these options is considered when specifying both
|
|||
@end multitable
|
||||
|
||||
@item loongarch*-*-*
|
||||
@var{list} is a comma-separated list of the following ABI identifiers:
|
||||
@code{lp64d[/base]} @code{lp64f[/base]} @code{lp64d[/base]}, where the
|
||||
@code{/base} suffix may be omitted, to enable their respective run-time
|
||||
libraries. If @var{list} is empty or @code{default},
|
||||
or if @option{--with-multilib-list} is not specified, then the default ABI
|
||||
as specified by @option{--with-abi} or implied by @option{--target} is selected.
|
||||
@var{list} is a comma-separated list, with each of the element starting with
|
||||
the following ABI identifiers: @code{lp64d[/base]} @code{lp64f[/base]}
|
||||
@code{lp64d[/base]} (the @code{/base} suffix may be omitted)
|
||||
to enable their respective run-time libraries.
|
||||
|
||||
A suffix @code{[/@var{arch}][/@var{option}/@dots{}]} may follow immediately
|
||||
after the ABI identifier to customize the compiler options for building the
|
||||
given set of libraries. @var{arch} denotes the architecture name recognized
|
||||
by the @option{-march=@var{arch}} compiler option, which acts as a basic target
|
||||
ISA configuration that can be adjusted using the subsequent @var{option}
|
||||
suffixes, where each @var{option} is a compiler option without a leading dash
|
||||
('-').
|
||||
|
||||
If no such suffix is present for a given multilib variant, the
|
||||
configured value of @option{--with-multilib-default} is appended as a default
|
||||
suffix. If @option{--with-multilib-default} is not given, the default build
|
||||
option @option{-march=abi-default} is applied when building the variants
|
||||
without a suffix.
|
||||
|
||||
As a special case, @code{fixed} may be used in the position of @var{arch},
|
||||
which means using the architecture configured with
|
||||
@option{--with-arch=@var{arch}}, or its default value (e.g. @code{loongarch64}
|
||||
for @code{loongarch64-*} targets).
|
||||
|
||||
If @var{list} is empty or @code{default}, or if @option{--with-multilib-list}
|
||||
is not specified, then only the default variant of the libraries are built,
|
||||
where the default ABI is implied by the configured target triplet.
|
||||
|
||||
@item riscv*-*-*
|
||||
@var{list} is a single ABI name. The target architecture must be either
|
||||
|
@ -1382,6 +1403,19 @@ If @option{--with-multilib-list} is not given, then only 32-bit and
|
|||
64-bit run-time libraries will be enabled.
|
||||
@end table
|
||||
|
||||
@item --with-multilib-default
|
||||
On LoongArch targets, set the default build options for enabled multilibs
|
||||
without build options appended to their corresponding
|
||||
@option{--with-multilib-list} items. The format of this value is
|
||||
@code{[/@var{arch}][/@var{option}/@dots{}]}, where @var{arch} is an
|
||||
architecture name recognized by @option{-march=@var{arch}} compiler option,
|
||||
and subsequent @var{option} suffixes are compiler options minus a leading
|
||||
dash ('-').
|
||||
|
||||
Multiple @var{option}s may appear consecutively while @var{arch} may only
|
||||
appear in the beginning or be omitted (which means @option{-march=abi-default}
|
||||
is applied when building the libraries).
|
||||
|
||||
@item --with-multilib-generator=@var{config}
|
||||
Specify what multilibs to build. @var{config} is a semicolon separated list of
|
||||
values, possibly consisting of a single value. Currently only implemented
|
||||
|
@ -1531,6 +1565,7 @@ x86-64, PowerPC, and SPARC@.
|
|||
@itemx --with-abi=@var{abi}
|
||||
@itemx --with-fpu=@var{type}
|
||||
@itemx --with-float=@var{type}
|
||||
@itemx --with-simd=@var{type}
|
||||
These configure options provide default values for the @option{-mschedule=},
|
||||
@option{-march=}, @option{-mtune=}, @option{-mabi=}, and @option{-mfpu=}
|
||||
options and for @option{-mhard-float} or @option{-msoft-float}. As with
|
||||
|
@ -4505,8 +4540,7 @@ Uses @code{lp64s/base} ABI by default.
|
|||
@end table
|
||||
|
||||
@item loongarch64-linux-gnu
|
||||
Same as @code{loongarch64-linux-gnuf64}, but may be used with
|
||||
@option{--with-abi=*} to configure the default ABI type.
|
||||
Same as @code{loongarch64-linux-gnuf64} for legacy support.
|
||||
@end table
|
||||
|
||||
More information about LoongArch can be found at
|
||||
|
|
|
@ -1030,7 +1030,8 @@ Objective-C and Objective-C++ Dialects}.
|
|||
|
||||
@emph{LoongArch Options}
|
||||
@gccoptlist{-march=@var{cpu-type} -mtune=@var{cpu-type} -mabi=@var{base-abi-type}
|
||||
-mfpu=@var{fpu-type} -msoft-float -msingle-float -mdouble-float
|
||||
-mfpu=@var{fpu-type} -msimd=@var{simd-type}
|
||||
-msoft-float -msingle-float -mdouble-float -mlsx -mno-lsx -mlasx -mno-lasx
|
||||
-mbranch-cost=@var{n} -mcheck-zero-division -mno-check-zero-division
|
||||
-mcond-move-int -mno-cond-move-int
|
||||
-mcond-move-float -mno-cond-move-float
|
||||
|
@ -25997,6 +25998,21 @@ operations.
|
|||
Prevent the use of hardware floating-point instructions.
|
||||
@end table
|
||||
|
||||
@opindex msimd
|
||||
@item -msimd=@var{simd-type}
|
||||
Enable generation of LoongArch SIMD instructions for vectorization
|
||||
and via builtin functions. The value can be one of:
|
||||
@table @samp
|
||||
@item lasx
|
||||
Enable generating instructions from the 256-bit LoongArch Advanced
|
||||
SIMD Extension (LASX) and the 128-bit LoongArch SIMD Extension (LSX).
|
||||
@item lsx
|
||||
Enable generating instructions from the 128-bit LoongArch SIMD
|
||||
Extension (LSX).
|
||||
@item none
|
||||
No LoongArch SIMD instruction may be generated.
|
||||
@end table
|
||||
|
||||
@opindex msoft-float
|
||||
@item -msoft-float
|
||||
Force @option{-mfpu=none} and prevents the use of floating-point
|
||||
|
@ -26015,6 +26031,19 @@ Force @option{-mfpu=64} and allow the use of 32/64-bit floating-point
|
|||
registers for parameter passing. This option may change the target
|
||||
ABI.
|
||||
|
||||
@opindex ml[a]sx
|
||||
@item -mlasx
|
||||
@itemx -mno-lasx
|
||||
@item -mlsx
|
||||
@itemx -mno-lsx
|
||||
Incrementally adjust the scope of the SIMD extensions (none / LSX / LASX)
|
||||
that can be used by the compiler for code generation. Enabling LASX with
|
||||
@option{mlasx} automatically enables LSX, and diabling LSX with @option{mno-lsx}
|
||||
automatically disables LASX. These driver-only options act upon the final
|
||||
@option{msimd} configuration state and make incremental chagnes in the order
|
||||
they appear on the GCC driver's command line, deriving the final / canonicalized
|
||||
@option{msimd} option that is passed to the compiler proper.
|
||||
|
||||
@opindex mbranch-cost
|
||||
@item -mbranch-cost=@var{n}
|
||||
Set the cost of branches to roughly @var{n} instructions.
|
||||
|
@ -26115,6 +26144,7 @@ kernels, executables linked with @option{-static} or @option{-static-pie}.
|
|||
@option{-fpic}.
|
||||
@end table
|
||||
|
||||
|
||||
@node M32C Options
|
||||
@subsection M32C Options
|
||||
@cindex M32C options
|
||||
|
|
Loading…
Add table
Reference in a new issue