LoongArch Port: gcc build
2022-03-29 Chenghua Xu <xuchenghua@loongson.cn> Lulu Cheng <chenglulu@loongson.cn> gcc/ChangeLog: * common/config/loongarch/loongarch-common.cc: New file. * config/loongarch/genopts/genstr.sh: New file. * config/loongarch/genopts/loongarch-strings: New file. * config/loongarch/genopts/loongarch.opt.in: New file. * config/loongarch/loongarch-str.h: New file. * config/loongarch/gnu-user.h: New file. * config/loongarch/linux.h: New file. * config/loongarch/loongarch-cpu.cc: New file. * config/loongarch/loongarch-cpu.h: New file. * config/loongarch/loongarch-def.c: New file. * config/loongarch/loongarch-def.h: New file. * config/loongarch/loongarch-driver.cc: New file. * config/loongarch/loongarch-driver.h: New file. * config/loongarch/loongarch-opts.cc: New file. * config/loongarch/loongarch-opts.h: New file. * config/loongarch/loongarch.opt: New file. * config/loongarch/t-linux: New file. * config/loongarch/t-loongarch: New file. * config.gcc: Add LoongArch support. * configure.ac: Add LoongArch support. contrib/ChangeLog: * gcc_update (files_and_dependencies): Add config/loongarch/loongarch.opt and config/loongarch/loongarch-str.h.
This commit is contained in:
parent
c6c0594ef8
commit
b44786f640
21 changed files with 2836 additions and 5 deletions
|
@ -86,6 +86,8 @@ gcc/config/arm/arm-tables.opt: gcc/config/arm/arm-cpus.in gcc/config/arm/parsecp
|
|||
gcc/config/c6x/c6x-tables.opt: gcc/config/c6x/c6x-isas.def gcc/config/c6x/genopt.sh
|
||||
gcc/config/c6x/c6x-sched.md: gcc/config/c6x/c6x-sched.md.in gcc/config/c6x/gensched.sh
|
||||
gcc/config/c6x/c6x-mult.md: gcc/config/c6x/c6x-mult.md.in gcc/config/c6x/genmult.sh
|
||||
gcc/config/loongarch/loongarch-str.h: gcc/config/loongarch/genopts/genstr.sh gcc/config/loongarch/genopts/loongarch-string
|
||||
gcc/config/loongarch/loongarch.opt: gcc/config/loongarch/genopts/genstr.sh gcc/config/loongarch/genopts/loongarch.opt.in
|
||||
gcc/config/m68k/m68k-tables.opt: gcc/config/m68k/m68k-devices.def gcc/config/m68k/m68k-isas.def gcc/config/m68k/m68k-microarchs.def gcc/config/m68k/genopt.sh
|
||||
gcc/config/mips/mips-tables.opt: gcc/config/mips/mips-cpus.def gcc/config/mips/genopt.sh
|
||||
gcc/config/rs6000/rs6000-tables.opt: gcc/config/rs6000/rs6000-cpus.def gcc/config/rs6000/genopt.sh
|
||||
|
|
43
gcc/common/config/loongarch/loongarch-common.cc
Normal file
43
gcc/common/config/loongarch/loongarch-common.cc
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* Common hooks for LoongArch.
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "common/common-target.h"
|
||||
#include "common/common-target-def.h"
|
||||
#include "opts.h"
|
||||
#include "flags.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
#undef TARGET_OPTION_OPTIMIZATION_TABLE
|
||||
#define TARGET_OPTION_OPTIMIZATION_TABLE loongarch_option_optimization_table
|
||||
|
||||
/* Set default optimization options. */
|
||||
static const struct default_options loongarch_option_optimization_table[] =
|
||||
{
|
||||
{ OPT_LEVELS_ALL, OPT_fasynchronous_unwind_tables, NULL, 1 },
|
||||
{ OPT_LEVELS_NONE, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
#undef TARGET_DEFAULT_TARGET_FLAGS
|
||||
#define TARGET_DEFAULT_TARGET_FLAGS MASK_CHECK_ZERO_DIV
|
||||
|
||||
struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
|
435
gcc/config.gcc
435
gcc/config.gcc
|
@ -454,6 +454,13 @@ mips*-*-*)
|
|||
extra_objs="frame-header-opt.o"
|
||||
extra_options="${extra_options} g.opt fused-madd.opt mips/mips-tables.opt"
|
||||
;;
|
||||
loongarch*-*-*)
|
||||
cpu_type=loongarch
|
||||
extra_headers="larchintrin.h"
|
||||
extra_objs="loongarch-c.o loongarch-builtins.o loongarch-cpu.o loongarch-opts.o loongarch-def.o"
|
||||
extra_gcc_objs="loongarch-driver.o loongarch-cpu.o loongarch-opts.o loongarch-def.o"
|
||||
extra_options="${extra_options} g.opt fused-madd.opt"
|
||||
;;
|
||||
nds32*)
|
||||
cpu_type=nds32
|
||||
extra_headers="nds32_intrinsic.h nds32_isr.h nds32_init.inc"
|
||||
|
@ -2495,6 +2502,20 @@ riscv*-*-freebsd*)
|
|||
# automatically detect that GAS supports it, yet we require it.
|
||||
gcc_cv_initfini_array=yes
|
||||
;;
|
||||
|
||||
loongarch*-*-linux*)
|
||||
tm_file="dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h ${tm_file}"
|
||||
tm_file="${tm_file} loongarch/gnu-user.h loongarch/linux.h"
|
||||
extra_options="${extra_options} linux-android.opt"
|
||||
tmake_file="${tmake_file} loongarch/t-linux"
|
||||
gnu_ld=yes
|
||||
gas=yes
|
||||
|
||||
# Force .init_array support. The configure script cannot always
|
||||
# automatically detect that GAS supports it, yet we require it.
|
||||
gcc_cv_initfini_array=yes
|
||||
;;
|
||||
|
||||
mips*-*-netbsd*) # NetBSD/mips, either endian.
|
||||
target_cpu_default="MASK_ABICALLS"
|
||||
tm_file="elfos.h ${tm_file} mips/elf.h ${nbsd_tm_file} mips/netbsd.h"
|
||||
|
@ -3601,7 +3622,7 @@ case ${target} in
|
|||
;;
|
||||
*-*-linux* | *-*-gnu*)
|
||||
case ${target} in
|
||||
aarch64*-* | arm*-* | i[34567]86-* | powerpc*-* | s390*-* | sparc*-* | x86_64-*)
|
||||
aarch64*-* | arm*-* | i[34567]86-* | powerpc*-* | s390*-* | sparc*-* | x86_64-* | loongarch*-*)
|
||||
default_gnu_indirect_function=yes
|
||||
;;
|
||||
esac
|
||||
|
@ -4933,6 +4954,373 @@ case "${target}" in
|
|||
esac
|
||||
;;
|
||||
|
||||
loongarch*-*-*)
|
||||
supported_defaults="abi arch tune fpu"
|
||||
|
||||
# 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
|
||||
|
||||
# Infer ABI from the triplet.
|
||||
case ${target} in
|
||||
loongarch64-*-*-*f64)
|
||||
abi_pattern="lp64d"
|
||||
triplet_abi="f64"
|
||||
;;
|
||||
loongarch64-*-*-*f32)
|
||||
abi_pattern="lp64f"
|
||||
triplet_abi="f32"
|
||||
;;
|
||||
loongarch64-*-*-*sf)
|
||||
abi_pattern="lp64s"
|
||||
triplet_abi="sf"
|
||||
;;
|
||||
loongarch64-*-*-*)
|
||||
abi_pattern="lp64[dfs]"
|
||||
abi_default="lp64d"
|
||||
triplet_abi=""
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported target ${target}." 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
abiext_pattern="*"
|
||||
abiext_default="base"
|
||||
|
||||
# Get the canonical triplet (multiarch specifier).
|
||||
case ${target} in
|
||||
*-linux-gnu*) triplet_os="linux-gnu";;
|
||||
*-linux-musl*) triplet_os="linux-musl";;
|
||||
*)
|
||||
echo "Unsupported target ${target}." 1>&2
|
||||
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.
|
||||
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.
|
||||
0)
|
||||
# Convert "0" to "none" for upcoming checks.
|
||||
with_fpu="none"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown fpu type in --with-fpu=$with_fpu" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Set default value for with_abi.
|
||||
case ${with_abi} in
|
||||
"")
|
||||
if test x${abi_default} != x; then
|
||||
with_abi=${abi_default}
|
||||
else
|
||||
with_abi=${abi_pattern}
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
if echo "${with_abi}" | grep -E "^${abi_pattern}$" > /dev/null; then
|
||||
: # OK
|
||||
else
|
||||
echo "Incompatible options:" \
|
||||
"--with-abi=${with_abi} and --target=${target}." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# 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
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
# Infer ISA-related default options from the ABI: pass 1
|
||||
case ${with_abi}/${with_abiext} in
|
||||
lp64*/base)
|
||||
# architectures that support lp64* ABI
|
||||
arch_pattern="native|loongarch64|la464"
|
||||
# default architecture for lp64* ABI
|
||||
arch_default="loongarch64"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported ABI type ${with_abi}/${with_abiext}." 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Infer ISA-related default options from the ABI: pass 2
|
||||
case ${with_abi}/${with_abiext} in
|
||||
lp64d/base)
|
||||
fpu_pattern="64"
|
||||
;;
|
||||
lp64f/base)
|
||||
fpu_pattern="32|64"
|
||||
fpu_default="32"
|
||||
;;
|
||||
lp64s/base)
|
||||
fpu_pattern="none|32|64"
|
||||
fpu_default="none"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported ABI type ${with_abi}/${with_abiext}." 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
## Set default value for with_arch.
|
||||
case ${with_arch} in
|
||||
"")
|
||||
if test x${arch_default} != x; then
|
||||
with_arch=${arch_default}
|
||||
else
|
||||
with_arch=${arch_pattern}
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
if echo "${with_arch}" | grep -E "^${arch_pattern}$" > /dev/null; then
|
||||
: # OK
|
||||
else
|
||||
echo "${with_abi}/${with_abiext} ABI cannot be implemented with" \
|
||||
"--with-arch=${with_arch}." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
## Set default value for with_fpu.
|
||||
case ${with_fpu} in
|
||||
"")
|
||||
if test x${fpu_default} != x; then
|
||||
with_fpu=${fpu_default}
|
||||
else
|
||||
with_fpu=${fpu_pattern}
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
if echo "${with_fpu}" | grep -E "^${fpu_pattern}$" > /dev/null; then
|
||||
: # OK
|
||||
else
|
||||
echo "${with_abi}/${with_abiext} ABI cannot be implemented with" \
|
||||
"--with-fpu=${with_fpu}." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# Infer default with_tune from with_arch: pass 1
|
||||
case ${with_arch} in
|
||||
native)
|
||||
tune_pattern="*"
|
||||
tune_default="native"
|
||||
;;
|
||||
loongarch64)
|
||||
tune_pattern="loongarch64|la464"
|
||||
tune_default="la464"
|
||||
;;
|
||||
*)
|
||||
# By default, $with_tune == $with_arch
|
||||
tune_pattern="$with_arch"
|
||||
;;
|
||||
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
|
||||
;;
|
||||
|
||||
*)
|
||||
if echo "${with_tune}" | grep -E "^${tune_pattern}$" > /dev/null; then
|
||||
: # OK
|
||||
else
|
||||
echo "Incompatible options: --with-tune=${with_tune}" \
|
||||
"and --with-arch=${with_arch}." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# 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}"
|
||||
fi
|
||||
|
||||
# Check if the configured default ABI combination is included in
|
||||
# ${with_multilib_list}.
|
||||
loongarch_multilib_list_sane=no
|
||||
|
||||
# This one goes to TM_MULTILIB_CONFIG, for use in t-linux.
|
||||
loongarch_multilib_list_make=""
|
||||
|
||||
# This one goes to tm_defines, for use in loongarch-driver.c.
|
||||
loongarch_multilib_list_c=""
|
||||
|
||||
# ${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
|
||||
echo "Invalid argument to --with-multilib-list." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
unset component idx elem_abi_base elem_abi_ext elem_tmp
|
||||
for elem in $(echo "${with_multilib_list}" | tr ',' ' '); do
|
||||
idx=0
|
||||
while true; do
|
||||
idx=$((idx + 1))
|
||||
component=$(echo "${elem}" | awk -F'/' '{print $'"${idx}"'}')
|
||||
|
||||
case ${idx} in
|
||||
1)
|
||||
# Component 1: Base ABI type
|
||||
case ${component} in
|
||||
lp64d) elem_tmp="ABI_BASE_LP64D,";;
|
||||
lp64f) elem_tmp="ABI_BASE_LP64F,";;
|
||||
lp64s) elem_tmp="ABI_BASE_LP64S,";;
|
||||
*)
|
||||
echo "Unknown base ABI \"${component}\" in --with-multilib-list." 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
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
|
||||
case ${component} in
|
||||
"" | base)
|
||||
component="base"
|
||||
elem_tmp="ABI_EXT_BASE,"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown ABI extension \"${component}\" in --with-multilib-list." 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
loongarch_multilib_list_c="${loongarch_multilib_list_c}${elem_tmp}"
|
||||
loongarch_multilib_list_make="${loongarch_multilib_list_make}" # Add nothing for now.
|
||||
elem_abi_ext="${component}"
|
||||
;;
|
||||
|
||||
*)
|
||||
# Component 3 and on: optional stuff
|
||||
case ${component} in
|
||||
"")
|
||||
# End of component list.
|
||||
break
|
||||
;;
|
||||
*)
|
||||
echo "Unknown ABI \"${elem}\" in --with-multilib-list." 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test x${elem_abi_base} = x${with_abi} \
|
||||
&& test x${elem_abi_ext} = x${with_abiext}; then
|
||||
loongarch_multilib_list_sane=yes
|
||||
fi
|
||||
loongarch_multilib_list_make="${loongarch_multilib_list_make},"
|
||||
done
|
||||
|
||||
# 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=""
|
||||
else
|
||||
with_abiext="/${with_abiext}"
|
||||
fi
|
||||
|
||||
echo "Default ABI combination (${with_abi}${with_abiext})" \
|
||||
"not found in --with-multilib-list." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove the excessive appending comma.
|
||||
loongarch_multilib_list_c=${loongarch_multilib_list_c%,}
|
||||
loongarch_multilib_list_make=${loongarch_multilib_list_make%,}
|
||||
;;
|
||||
|
||||
nds32*-*-*)
|
||||
supported_defaults="arch cpu nds32_lib float fpu_config"
|
||||
|
||||
|
@ -5370,6 +5758,51 @@ case ${target} in
|
|||
tmake_file="mips/t-mips $tmake_file"
|
||||
;;
|
||||
|
||||
loongarch*-*-*)
|
||||
# Export canonical triplet.
|
||||
tm_defines="${tm_defines} LA_MULTIARCH_TRIPLET=${la_canonical_triplet}"
|
||||
|
||||
# Define macro LA_DISABLE_MULTILIB if --disable-multilib
|
||||
tm_defines="${tm_defines} TM_MULTILIB_LIST=${loongarch_multilib_list_c}"
|
||||
if test x$enable_multilib = xyes; then
|
||||
TM_MULTILIB_CONFIG="${loongarch_multilib_list_make}"
|
||||
else
|
||||
tm_defines="${tm_defines} LA_DISABLE_MULTILIB"
|
||||
fi
|
||||
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
case ${with_abiext} in
|
||||
base) tm_defines="${tm_defines} DEFAULT_ABI_EXT=ABI_EXT_BASE" ;;
|
||||
esac
|
||||
|
||||
case ${with_fpu} in
|
||||
none) tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_NOFPU" ;;
|
||||
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
|
||||
|
||||
tmake_file="loongarch/t-loongarch $tmake_file"
|
||||
;;
|
||||
|
||||
powerpc*-*-* | rs6000-*-*)
|
||||
# FIXME: The PowerPC port uses the value set at compile time,
|
||||
# although it's only cosmetic.
|
||||
|
|
104
gcc/config/loongarch/genopts/genstr.sh
Executable file
104
gcc/config/loongarch/genopts/genstr.sh
Executable file
|
@ -0,0 +1,104 @@
|
|||
#!/bin/sh
|
||||
# A simple script that generates loongarch-str.h and loongarch.opt
|
||||
# from genopt/loongarch-optstr.
|
||||
#
|
||||
# Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# GCC is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
# Generate a header containing definitions from the string table.
|
||||
gen_defines() {
|
||||
cat <<EOF
|
||||
/* Generated automatically by "genstr" from "loongarch-strings".
|
||||
Please do not edit this file directly.
|
||||
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
Contributed by Loongson Ltd.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef LOONGARCH_STR_H
|
||||
#define LOONGARCH_STR_H
|
||||
EOF
|
||||
|
||||
sed -e '/^$/n' -e 's@#.*$@@' -e '/^$/d' \
|
||||
-e 's@^\([^ \t]\+\)[ \t]*\([^ \t]*\)@#define \1 "\2"@' \
|
||||
loongarch-strings
|
||||
|
||||
echo
|
||||
echo "#endif /* LOONGARCH_STR_H */"
|
||||
}
|
||||
|
||||
|
||||
# Substitute all "@@<KEY>@@" to "<VALUE>" in loongarch.opt.in
|
||||
# according to the key-value pairs defined in loongarch-strings.
|
||||
|
||||
gen_options() {
|
||||
|
||||
sed -e '/^$/n' -e 's@#.*$@@' -e '/^$/d' \
|
||||
-e 's@^\([^ \t]\+\)[ \t]*\([^ \t]*\)@\1="\2"@' \
|
||||
loongarch-strings | { \
|
||||
|
||||
# read the definitions
|
||||
while read -r line; do
|
||||
eval "$line"
|
||||
done
|
||||
|
||||
# print a header
|
||||
cat << EOF
|
||||
; Generated by "genstr" from the template "loongarch.opt.in"
|
||||
; and definitions from "loongarch-strings".
|
||||
;
|
||||
; Please do not edit this file directly.
|
||||
; It will be automatically updated during a gcc build
|
||||
; if you change "loongarch.opt.in" or "loongarch-strings".
|
||||
;
|
||||
EOF
|
||||
|
||||
# make the substitutions
|
||||
sed -e 's@"@\\"@g' -e 's/@@\([^@]\+\)@@/${\1}/g' loongarch.opt.in | \
|
||||
while read -r line; do
|
||||
eval "echo \"$line\""
|
||||
done
|
||||
}
|
||||
}
|
||||
|
||||
main() {
|
||||
case "$1" in
|
||||
header) gen_defines;;
|
||||
opt) gen_options;;
|
||||
*) echo "Unknown Command: \"$1\". Available: header, opt"; exit 1;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
58
gcc/config/loongarch/genopts/loongarch-strings
Normal file
58
gcc/config/loongarch/genopts/loongarch-strings
Normal file
|
@ -0,0 +1,58 @@
|
|||
# Defines the key strings for LoongArch compiler options.
|
||||
#
|
||||
# Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# GCC is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 3, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# -march= / -mtune=
|
||||
OPTSTR_ARCH arch
|
||||
OPTSTR_TUNE tune
|
||||
|
||||
STR_CPU_NATIVE native
|
||||
STR_CPU_LOONGARCH64 loongarch64
|
||||
STR_CPU_LA464 la464
|
||||
|
||||
# Base architecture
|
||||
STR_ISA_BASE_LA64V100 la64
|
||||
|
||||
# -mfpu
|
||||
OPTSTR_ISA_EXT_FPU fpu
|
||||
STR_ISA_EXT_NOFPU none
|
||||
STR_ISA_EXT_FPU0 0
|
||||
STR_ISA_EXT_FPU32 32
|
||||
STR_ISA_EXT_FPU64 64
|
||||
|
||||
OPTSTR_SOFT_FLOAT soft-float
|
||||
OPTSTR_SINGLE_FLOAT single-float
|
||||
OPTSTR_DOUBLE_FLOAT double-float
|
||||
|
||||
# -mabi=
|
||||
OPTSTR_ABI_BASE abi
|
||||
STR_ABI_BASE_LP64D lp64d
|
||||
STR_ABI_BASE_LP64F lp64f
|
||||
STR_ABI_BASE_LP64S lp64s
|
||||
|
||||
# ABI extension types
|
||||
STR_ABI_EXT_BASE base
|
||||
|
||||
# -mcmodel=
|
||||
OPTSTR_CMODEL cmodel
|
||||
STR_CMODEL_NORMAL normal
|
||||
STR_CMODEL_TINY tiny
|
||||
STR_CMODEL_TS tiny-static
|
||||
STR_CMODEL_LARGE large
|
||||
STR_CMODEL_EXTREME extreme
|
179
gcc/config/loongarch/genopts/loongarch.opt.in
Normal file
179
gcc/config/loongarch/genopts/loongarch.opt.in
Normal file
|
@ -0,0 +1,179 @@
|
|||
; Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
;
|
||||
; This file is part of GCC.
|
||||
;
|
||||
; GCC is free software; you can redistribute it and/or modify it under
|
||||
; the terms of the GNU General Public License as published by the Free
|
||||
; Software Foundation; either version 3, or (at your option) any later
|
||||
; version.
|
||||
;
|
||||
; GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
; License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with GCC; see the file COPYING3. If not see
|
||||
; <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
|
||||
Name(isa_base) Type(int)
|
||||
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)
|
||||
|
||||
EnumValue
|
||||
Enum(isa_ext_fpu) String(@@STR_ISA_EXT_FPU32@@) Value(ISA_EXT_FPU32)
|
||||
|
||||
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)
|
||||
-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@@)
|
||||
|
||||
m@@OPTSTR_SOFT_FLOAT@@
|
||||
Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_SOFTF) 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@@)
|
||||
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@@)
|
||||
Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations.
|
||||
|
||||
|
||||
;; Base target models (implies ISA & tune parameters)
|
||||
Enum
|
||||
Name(cpu_type) Type(int)
|
||||
LoongArch CPU types:
|
||||
|
||||
EnumValue
|
||||
Enum(cpu_type) String(@@STR_CPU_NATIVE@@) Value(CPU_NATIVE)
|
||||
|
||||
EnumValue
|
||||
Enum(cpu_type) String(@@STR_CPU_LOONGARCH64@@) Value(CPU_LOONGARCH64)
|
||||
|
||||
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)
|
||||
-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)
|
||||
-m@@OPTSTR_TUNE@@=PROCESSOR Generate optimized code for PROCESSOR.
|
||||
|
||||
|
||||
; ABI related options
|
||||
; (ISA constraints on ABI are handled dynamically)
|
||||
|
||||
;; Base ABI
|
||||
Enum
|
||||
Name(abi_base) Type(int)
|
||||
Base ABI types for LoongArch:
|
||||
|
||||
EnumValue
|
||||
Enum(abi_base) String(@@STR_ABI_BASE_LP64D@@) Value(ABI_BASE_LP64D)
|
||||
|
||||
EnumValue
|
||||
Enum(abi_base) String(@@STR_ABI_BASE_LP64F@@) Value(ABI_BASE_LP64F)
|
||||
|
||||
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)
|
||||
-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
|
||||
|
||||
|
||||
mbranch-cost=
|
||||
Target RejectNegative Joined UInteger Var(loongarch_branch_cost)
|
||||
-mbranch-cost=COST Set the cost of branches to roughly COST instructions.
|
||||
|
||||
mcheck-zero-division
|
||||
Target Mask(CHECK_ZERO_DIV)
|
||||
Trap on integer divide by zero.
|
||||
|
||||
mcond-move-int
|
||||
Target Var(TARGET_COND_MOVE_INT) Init(1)
|
||||
Conditional moves for integral are enabled.
|
||||
|
||||
mcond-move-float
|
||||
Target Var(TARGET_COND_MOVE_FLOAT) Init(1)
|
||||
Conditional moves for float are enabled.
|
||||
|
||||
mmemcpy
|
||||
Target Mask(MEMCPY)
|
||||
Prevent optimizing block moves, which is also the default behavior of -Os.
|
||||
|
||||
mstrict-align
|
||||
Target Var(TARGET_STRICT_ALIGN) Init(0)
|
||||
Do not generate unaligned memory accesses.
|
||||
|
||||
mmax-inline-memcpy-size=
|
||||
Target Joined RejectNegative UInteger Var(loongarch_max_inline_memcpy_size) Init(1024)
|
||||
-mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024.
|
||||
|
||||
; The code model option names for -mcmodel.
|
||||
Enum
|
||||
Name(cmodel) Type(int)
|
||||
The code model option names for -mcmodel:
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(@@STR_CMODEL_NORMAL@@) Value(CMODEL_NORMAL)
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(@@STR_CMODEL_TINY@@) Value(CMODEL_TINY)
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(@@STR_CMODEL_TS@@) Value(CMODEL_TINY_STATIC)
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(@@STR_CMODEL_LARGE@@) Value(CMODEL_LARGE)
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(@@STR_CMODEL_EXTREME@@) Value(CMODEL_EXTREME)
|
||||
|
||||
mcmodel=
|
||||
Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(CMODEL_NORMAL)
|
||||
Specify the code model.
|
80
gcc/config/loongarch/gnu-user.h
Normal file
80
gcc/config/loongarch/gnu-user.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* Definitions for LoongArch systems using GNU (glibc-based) userspace,
|
||||
or other userspace with libc derived from glibc.
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Define the size of the wide character type. */
|
||||
#undef WCHAR_TYPE
|
||||
#define WCHAR_TYPE "int"
|
||||
|
||||
#undef WCHAR_TYPE_SIZE
|
||||
#define WCHAR_TYPE_SIZE 32
|
||||
|
||||
|
||||
/* GNU-specific SPEC definitions. */
|
||||
#define GNU_USER_LINK_EMULATION "elf" ABI_GRLEN_SPEC "loongarch"
|
||||
|
||||
#undef GLIBC_DYNAMIC_LINKER
|
||||
#define GLIBC_DYNAMIC_LINKER \
|
||||
"/lib" ABI_GRLEN_SPEC "/ld-linux-loongarch-" ABI_SPEC ".so.1"
|
||||
|
||||
#undef MUSL_DYNAMIC_LINKER
|
||||
#define MUSL_DYNAMIC_LINKER \
|
||||
"/lib" ABI_GRLEN_SPEC "/ld-musl-loongarch-" ABI_SPEC ".so.1"
|
||||
|
||||
#undef GNU_USER_TARGET_LINK_SPEC
|
||||
#define GNU_USER_TARGET_LINK_SPEC \
|
||||
"%{G*} %{shared} -m " GNU_USER_LINK_EMULATION \
|
||||
"%{!shared: %{static} %{!static: %{rdynamic:-export-dynamic} " \
|
||||
"-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}}"
|
||||
|
||||
|
||||
/* Similar to standard Linux, but adding -ffast-math support. */
|
||||
#undef GNU_USER_TARGET_MATHFILE_SPEC
|
||||
#define GNU_USER_TARGET_MATHFILE_SPEC \
|
||||
"%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
|
||||
|
||||
#undef LIB_SPEC
|
||||
#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC
|
||||
|
||||
#undef LINK_SPEC
|
||||
#define LINK_SPEC GNU_USER_TARGET_LINK_SPEC
|
||||
|
||||
#undef ENDFILE_SPEC
|
||||
#define ENDFILE_SPEC \
|
||||
GNU_USER_TARGET_MATHFILE_SPEC " " \
|
||||
GNU_USER_TARGET_ENDFILE_SPEC
|
||||
|
||||
#undef SUBTARGET_CPP_SPEC
|
||||
#define SUBTARGET_CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}"
|
||||
|
||||
/* A standard GNU/Linux mapping. On most targets, it is included in
|
||||
CC1_SPEC itself by config/linux.h, but loongarch.h overrides CC1_SPEC
|
||||
and provides this hook instead. */
|
||||
#undef SUBTARGET_CC1_SPEC
|
||||
#define SUBTARGET_CC1_SPEC GNU_USER_TARGET_CC1_SPEC
|
||||
|
||||
#define TARGET_OS_CPP_BUILTINS() \
|
||||
do \
|
||||
{ \
|
||||
GNU_USER_TARGET_OS_CPP_BUILTINS (); \
|
||||
/* The GNU C++ standard library requires this. */ \
|
||||
if (c_dialect_cxx ()) \
|
||||
builtin_define ("_GNU_SOURCE"); \
|
||||
} \
|
||||
while (0)
|
50
gcc/config/loongarch/linux.h
Normal file
50
gcc/config/loongarch/linux.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* Definitions for Linux-based systems with libraries in ELF format.
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Default system library search paths.
|
||||
* This ensures that a compiler configured with --disable-multilib
|
||||
* can work in a multilib environment. */
|
||||
|
||||
#if defined(LA_DISABLE_MULTILIB) && defined(LA_DISABLE_MULTIARCH)
|
||||
|
||||
#if DEFAULT_ABI_BASE == ABI_BASE_LP64D
|
||||
#define ABI_LIBDIR "lib64"
|
||||
#elif DEFAULT_ABI_BASE == ABI_BASE_LP64F
|
||||
#define ABI_LIBDIR "lib64/f32"
|
||||
#elif DEFAULT_ABI_BASE == ABI_BASE_LP64S
|
||||
#define ABI_LIBDIR "lib64/sf"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef ABI_LIBDIR
|
||||
#define ABI_LIBDIR "lib"
|
||||
#endif
|
||||
|
||||
#define STANDARD_STARTFILE_PREFIX_1 "/" ABI_LIBDIR "/"
|
||||
#define STANDARD_STARTFILE_PREFIX_2 "/usr/" ABI_LIBDIR "/"
|
||||
|
||||
|
||||
/* Define this to be nonzero if static stack checking is supported. */
|
||||
#define STACK_CHECK_STATIC_BUILTIN 1
|
||||
|
||||
/* The default value isn't sufficient in 64-bit mode. */
|
||||
#define STACK_CHECK_PROTECT (TARGET_64BIT ? 16 * 1024 : 12 * 1024)
|
||||
|
||||
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
|
206
gcc/config/loongarch/loongarch-cpu.cc
Normal file
206
gcc/config/loongarch/loongarch-cpu.cc
Normal file
|
@ -0,0 +1,206 @@
|
|||
/* Definitions for LoongArch CPU properties.
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
Contributed by Loongson Ltd.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define IN_TARGET_CODE 1
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
#include "loongarch-opts.h"
|
||||
#include "loongarch-cpu.h"
|
||||
#include "loongarch-str.h"
|
||||
|
||||
/* Native CPU detection with "cpucfg" */
|
||||
#define N_CPUCFG_WORDS 0x15
|
||||
static uint32_t cpucfg_cache[N_CPUCFG_WORDS] = { 0 };
|
||||
static const int cpucfg_useful_idx[] = {0, 1, 2, 16, 17, 18, 19};
|
||||
|
||||
static uint32_t
|
||||
read_cpucfg_word (int wordno)
|
||||
{
|
||||
/* To make cross-compiler shut up. */
|
||||
(void) wordno;
|
||||
uint32_t ret = 0;
|
||||
|
||||
#ifdef __loongarch__
|
||||
__asm__ __volatile__ ("cpucfg %0,%1\n\t"
|
||||
:"=r"(ret)
|
||||
:"r"(wordno)
|
||||
:);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
cache_cpucfg (void)
|
||||
{
|
||||
for (unsigned int i = 0; i < sizeof (cpucfg_useful_idx) / sizeof (int); i++)
|
||||
{
|
||||
cpucfg_cache[cpucfg_useful_idx[i]]
|
||||
= read_cpucfg_word (cpucfg_useful_idx[i]);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
get_native_prid (void)
|
||||
{
|
||||
/* Fill loongarch_cpu_default_config[CPU_NATIVE] with cpucfg data,
|
||||
see "Loongson Architecture Reference Manual"
|
||||
(Volume 1, Section 2.2.10.5) */
|
||||
return cpucfg_cache[0];
|
||||
}
|
||||
|
||||
const char*
|
||||
get_native_prid_str (void)
|
||||
{
|
||||
static char prid_str[9];
|
||||
sprintf (prid_str, "%08x", cpucfg_cache[0]);
|
||||
return (const char*) prid_str;
|
||||
}
|
||||
|
||||
/* Fill property tables for CPU_NATIVE. */
|
||||
unsigned int
|
||||
fill_native_cpu_config (int p_arch_native, int p_tune_native)
|
||||
{
|
||||
int ret_cpu_type;
|
||||
|
||||
/* Nothing needs to be done unless "-march/tune=native"
|
||||
is given or implied. */
|
||||
if (!(p_arch_native || p_tune_native))
|
||||
return CPU_NATIVE;
|
||||
|
||||
/* 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
|
||||
With: processor ID (PRID)
|
||||
At: cpucfg_words[0][31:0] */
|
||||
|
||||
switch (cpucfg_cache[0] & 0x00ffff00)
|
||||
{
|
||||
case 0x0014c000: /* LA464 */
|
||||
ret_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)
|
||||
inform (UNKNOWN_LOCATION, "unknown processor ID %<0x%x%>, "
|
||||
"some tuning parameters will fall back to default",
|
||||
cpucfg_cache[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Properties that cannot be looked up directly using cpucfg. */
|
||||
loongarch_cpu_issue_rate[CPU_NATIVE]
|
||||
= loongarch_cpu_issue_rate[ret_cpu_type];
|
||||
|
||||
loongarch_cpu_multipass_dfa_lookahead[CPU_NATIVE]
|
||||
= loongarch_cpu_multipass_dfa_lookahead[ret_cpu_type];
|
||||
|
||||
loongarch_cpu_rtx_cost_data[CPU_NATIVE]
|
||||
= loongarch_cpu_rtx_cost_data[ret_cpu_type];
|
||||
|
||||
return ret_cpu_type;
|
||||
}
|
30
gcc/config/loongarch/loongarch-cpu.h
Normal file
30
gcc/config/loongarch/loongarch-cpu.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* Definitions for loongarch native cpu property detection routines.
|
||||
Copyright (C) 2020-2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef LOONGARCH_CPU_H
|
||||
#define LOONGARCH_CPU_H
|
||||
|
||||
#include "system.h"
|
||||
|
||||
void cache_cpucfg (void);
|
||||
unsigned int fill_native_cpu_config (int p_arch_native, int p_tune_native);
|
||||
uint32_t get_native_prid (void);
|
||||
const char* get_native_prid_str (void);
|
||||
|
||||
#endif /* LOONGARCH_CPU_H */
|
179
gcc/config/loongarch/loongarch-def.c
Normal file
179
gcc/config/loongarch/loongarch-def.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* LoongArch static properties.
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
Contributed by Loongson Ltd.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#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_LOONGARCH64] = STR_CPU_LOONGARCH64,
|
||||
[CPU_LA464] = STR_CPU_LA464,
|
||||
};
|
||||
|
||||
struct loongarch_isa
|
||||
loongarch_cpu_default_isa[N_ARCH_TYPES] = {
|
||||
[CPU_LOONGARCH64] = {
|
||||
.base = ISA_BASE_LA64V100,
|
||||
.fpu = ISA_EXT_FPU64,
|
||||
},
|
||||
[CPU_LA464] = {
|
||||
.base = ISA_BASE_LA64V100,
|
||||
.fpu = ISA_EXT_FPU64,
|
||||
},
|
||||
};
|
||||
|
||||
struct loongarch_cache
|
||||
loongarch_cpu_cache[N_TUNE_TYPES] = {
|
||||
[CPU_LOONGARCH64] = {
|
||||
.l1d_line_size = 64,
|
||||
.l1d_size = 64,
|
||||
.l2d_size = 256,
|
||||
},
|
||||
[CPU_LA464] = {
|
||||
.l1d_line_size = 64,
|
||||
.l1d_size = 64,
|
||||
.l2d_size = 256,
|
||||
},
|
||||
};
|
||||
|
||||
/* 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
|
||||
any known "-mtune" type). */
|
||||
|
||||
struct loongarch_rtx_cost_data
|
||||
loongarch_cpu_rtx_cost_data[N_TUNE_TYPES] = {
|
||||
[CPU_NATIVE] = {
|
||||
DEFAULT_COSTS
|
||||
},
|
||||
[CPU_LOONGARCH64] = {
|
||||
DEFAULT_COSTS
|
||||
},
|
||||
[CPU_LA464] = {
|
||||
DEFAULT_COSTS
|
||||
},
|
||||
};
|
||||
|
||||
/* RTX costs to use when optimizing for size. */
|
||||
extern const struct loongarch_rtx_cost_data
|
||||
loongarch_rtx_cost_optimize_size = {
|
||||
.fp_add = 4,
|
||||
.fp_mult_sf = 4,
|
||||
.fp_mult_df = 4,
|
||||
.fp_div_sf = 4,
|
||||
.fp_div_df = 4,
|
||||
.int_mult_si = 4,
|
||||
.int_mult_di = 4,
|
||||
.int_div_si = 4,
|
||||
.int_div_di = 4,
|
||||
.branch_cost = 2,
|
||||
.memory_latency = 4,
|
||||
};
|
||||
|
||||
int
|
||||
loongarch_cpu_issue_rate[N_TUNE_TYPES] = {
|
||||
[CPU_NATIVE] = 4,
|
||||
[CPU_LOONGARCH64] = 4,
|
||||
[CPU_LA464] = 4,
|
||||
};
|
||||
|
||||
int
|
||||
loongarch_cpu_multipass_dfa_lookahead[N_TUNE_TYPES] = {
|
||||
[CPU_NATIVE] = 4,
|
||||
[CPU_LOONGARCH64] = 4,
|
||||
[CPU_LA464] = 4,
|
||||
};
|
||||
|
||||
/* Wiring string definitions from loongarch-str.h to global arrays
|
||||
with standard index values from loongarch-opts.h, so we can
|
||||
print config-related messages and do ABI self-spec filtering
|
||||
from the driver in a self-consistent manner. */
|
||||
|
||||
const char*
|
||||
loongarch_isa_base_strings[N_ISA_BASE_TYPES] = {
|
||||
[ISA_BASE_LA64V100] = STR_ISA_BASE_LA64V100,
|
||||
};
|
||||
|
||||
const char*
|
||||
loongarch_isa_ext_strings[N_ISA_EXT_TYPES] = {
|
||||
[ISA_EXT_FPU64] = STR_ISA_EXT_FPU64,
|
||||
[ISA_EXT_FPU32] = STR_ISA_EXT_FPU32,
|
||||
[ISA_EXT_NOFPU] = STR_ISA_EXT_NOFPU,
|
||||
};
|
||||
|
||||
const char*
|
||||
loongarch_abi_base_strings[N_ABI_BASE_TYPES] = {
|
||||
[ABI_BASE_LP64D] = STR_ABI_BASE_LP64D,
|
||||
[ABI_BASE_LP64F] = STR_ABI_BASE_LP64F,
|
||||
[ABI_BASE_LP64S] = STR_ABI_BASE_LP64S,
|
||||
};
|
||||
|
||||
const char*
|
||||
loongarch_abi_ext_strings[N_ABI_EXT_TYPES] = {
|
||||
[ABI_EXT_BASE] = STR_ABI_EXT_BASE,
|
||||
};
|
||||
|
||||
const char*
|
||||
loongarch_cmodel_strings[] = {
|
||||
[CMODEL_NORMAL] = STR_CMODEL_NORMAL,
|
||||
[CMODEL_TINY] = STR_CMODEL_TINY,
|
||||
[CMODEL_TINY_STATIC] = STR_CMODEL_TS,
|
||||
[CMODEL_LARGE] = STR_CMODEL_LARGE,
|
||||
[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_BASE_LP64F] = {
|
||||
[ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU32},
|
||||
},
|
||||
[ABI_BASE_LP64S] = {
|
||||
[ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_NOFPU},
|
||||
},
|
||||
};
|
151
gcc/config/loongarch/loongarch-def.h
Normal file
151
gcc/config/loongarch/loongarch-def.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
/* LoongArch definitions.
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
Contributed by Loongson Ltd.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Definition of standard codes for:
|
||||
- base architecture types (isa_base),
|
||||
- ISA extensions (isa_ext),
|
||||
- base ABI types (abi_base),
|
||||
- ABI extension types (abi_ext).
|
||||
|
||||
- code models (cmodel)
|
||||
- other command-line switches (switch)
|
||||
|
||||
These values are primarily used for implementing option handling
|
||||
logic in "loongarch.opt", "loongarch-driver.c" and "loongarch-opt.c".
|
||||
|
||||
As for the result of this option handling process, the following
|
||||
scheme is adopted to represent the final configuration:
|
||||
|
||||
- The target ABI is encoded with a tuple (abi_base, abi_ext)
|
||||
using the code defined below.
|
||||
|
||||
- The target ISA is encoded with a "struct loongarch_isa" defined
|
||||
in loongarch-cpu.h.
|
||||
|
||||
- The target microarchitecture is represented with a cpu model
|
||||
index defined in loongarch-cpu.h.
|
||||
*/
|
||||
|
||||
#ifndef LOONGARCH_DEF_H
|
||||
#define LOONGARCH_DEF_H
|
||||
|
||||
#include "loongarch-tune.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* enum isa_base */
|
||||
extern const char* loongarch_isa_base_strings[];
|
||||
#define ISA_BASE_LA64V100 0
|
||||
#define N_ISA_BASE_TYPES 1
|
||||
|
||||
/* enum isa_ext_* */
|
||||
extern const char* loongarch_isa_ext_strings[];
|
||||
#define ISA_EXT_NOFPU 0
|
||||
#define ISA_EXT_FPU32 1
|
||||
#define ISA_EXT_FPU64 2
|
||||
#define N_ISA_EXT_FPU_TYPES 3
|
||||
#define N_ISA_EXT_TYPES 3
|
||||
|
||||
/* enum abi_base */
|
||||
extern const char* loongarch_abi_base_strings[];
|
||||
#define ABI_BASE_LP64D 0
|
||||
#define ABI_BASE_LP64F 1
|
||||
#define ABI_BASE_LP64S 2
|
||||
#define N_ABI_BASE_TYPES 3
|
||||
|
||||
/* enum abi_ext */
|
||||
extern const char* loongarch_abi_ext_strings[];
|
||||
#define ABI_EXT_BASE 0
|
||||
#define N_ABI_EXT_TYPES 1
|
||||
|
||||
/* enum cmodel */
|
||||
extern const char* loongarch_cmodel_strings[];
|
||||
#define CMODEL_NORMAL 0
|
||||
#define CMODEL_TINY 1
|
||||
#define CMODEL_TINY_STATIC 2
|
||||
#define CMODEL_LARGE 3
|
||||
#define CMODEL_EXTREME 4
|
||||
#define N_CMODEL_TYPES 5
|
||||
|
||||
/* 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)
|
||||
|
||||
|
||||
/* Internal representation of the target. */
|
||||
struct loongarch_isa
|
||||
{
|
||||
unsigned char base; /* ISA_BASE_ */
|
||||
unsigned char fpu; /* ISA_EXT_FPU_ */
|
||||
};
|
||||
|
||||
struct loongarch_abi
|
||||
{
|
||||
unsigned char base; /* ABI_BASE_ */
|
||||
unsigned char 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_ */
|
||||
};
|
||||
|
||||
/* 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
|
||||
|
||||
/* parallel tables. */
|
||||
extern const char* loongarch_cpu_strings[];
|
||||
extern struct loongarch_isa loongarch_cpu_default_isa[];
|
||||
extern int loongarch_cpu_issue_rate[];
|
||||
extern int loongarch_cpu_multipass_dfa_lookahead[];
|
||||
|
||||
extern struct loongarch_cache loongarch_cpu_cache[];
|
||||
extern struct loongarch_rtx_cost_data loongarch_cpu_rtx_cost_data[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* LOONGARCH_DEF_H */
|
187
gcc/config/loongarch/loongarch-driver.cc
Normal file
187
gcc/config/loongarch/loongarch-driver.cc
Normal file
|
@ -0,0 +1,187 @@
|
|||
/* Subroutines for the gcc driver.
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
Contributed by Loongson Ltd.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define IN_TARGET_CODE 1
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "obstack.h"
|
||||
#include "diagnostic-core.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)
|
||||
{
|
||||
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];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
const char*
|
||||
driver_get_normalized_m_opts (int argc, const char **argv)
|
||||
{
|
||||
if (argc != 0)
|
||||
{
|
||||
(void) argv; /* To make compiler shut up about unused argument. */
|
||||
return " %eget_normalized_m_opts requires no argument.\n";
|
||||
}
|
||||
|
||||
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 */);
|
||||
|
||||
/* Output normalized option strings. */
|
||||
obstack_blank (&opts_obstack, 0);
|
||||
|
||||
#undef APPEND_LTR
|
||||
#define APPEND_LTR(S) \
|
||||
obstack_grow (&opts_obstack, (const void*) (S), \
|
||||
sizeof ((S)) / sizeof (char) -1)
|
||||
|
||||
#undef APPEND_VAL
|
||||
#define APPEND_VAL(S) \
|
||||
obstack_grow (&opts_obstack, (const void*) (S), strlen ((S)))
|
||||
|
||||
#undef APPEND_OPT
|
||||
#define APPEND_OPT(NAME) \
|
||||
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]);
|
||||
}
|
||||
|
||||
APPEND_OPT (ABI_BASE);
|
||||
APPEND_VAL (loongarch_abi_base_strings[la_target.abi.base]);
|
||||
|
||||
APPEND_OPT (ARCH);
|
||||
APPEND_VAL (loongarch_cpu_strings[la_target.cpu_arch]);
|
||||
|
||||
APPEND_OPT (ISA_EXT_FPU);
|
||||
APPEND_VAL (loongarch_isa_ext_strings[la_target.isa.fpu]);
|
||||
|
||||
APPEND_OPT (CMODEL);
|
||||
APPEND_VAL (loongarch_cmodel_strings[la_target.cmodel]);
|
||||
|
||||
APPEND_OPT (TUNE);
|
||||
APPEND_VAL (loongarch_cpu_strings[la_target.cpu_tune]);
|
||||
|
||||
obstack_1grow (&opts_obstack, '\0');
|
||||
|
||||
return XOBFINISH (&opts_obstack, const char *);
|
||||
}
|
68
gcc/config/loongarch/loongarch-driver.h
Normal file
68
gcc/config/loongarch/loongarch-driver.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* Subroutine headers for the gcc driver.
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
Contributed by Loongson Ltd.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef LOONGARCH_DRIVER_H
|
||||
#define LOONGARCH_DRIVER_H
|
||||
|
||||
#include "loongarch-str.h"
|
||||
|
||||
extern const char*
|
||||
driver_set_m_flag (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 }, \
|
||||
{ "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 "=%*)}" \
|
||||
|
||||
#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) \
|
||||
" %:get_normalized_m_opts()"
|
||||
|
||||
#define DRIVER_SELF_SPECS \
|
||||
DRIVER_HANDLE_MACHINE_OPTIONS
|
||||
|
||||
/* ABI spec strings. */
|
||||
#define ABI_GRLEN_SPEC \
|
||||
"%{mabi=lp64*:64}" \
|
||||
|
||||
#define ABI_SPEC \
|
||||
"%{mabi=lp64d:lp64d}" \
|
||||
"%{mabi=lp64f:lp64f}" \
|
||||
"%{mabi=lp64s:lp64s}" \
|
||||
|
||||
#endif /* LOONGARCH_DRIVER_H */
|
577
gcc/config/loongarch/loongarch-opts.cc
Normal file
577
gcc/config/loongarch/loongarch-opts.cc
Normal file
|
@ -0,0 +1,577 @@
|
|||
/* Subroutines for loongarch-specific option handling.
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
Contributed by Loongson Ltd.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define IN_TARGET_CODE 1
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "obstack.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "loongarch-cpu.h"
|
||||
#include "loongarch-opts.h"
|
||||
#include "loongarch-str.h"
|
||||
|
||||
struct loongarch_target la_target;
|
||||
|
||||
/* ABI-related configuration. */
|
||||
#define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi))
|
||||
static const struct loongarch_abi
|
||||
abi_priority_list[] = {
|
||||
{ABI_BASE_LP64D, ABI_EXT_BASE},
|
||||
{ABI_BASE_LP64F, ABI_EXT_BASE},
|
||||
{ABI_BASE_LP64S, ABI_EXT_BASE},
|
||||
};
|
||||
|
||||
/* Initialize enabled_abi_types from TM_MULTILIB_LIST. */
|
||||
#ifdef LA_DISABLE_MULTILIB
|
||||
#define MULTILIB_LIST_LEN 1
|
||||
#else
|
||||
#define MULTILIB_LIST_LEN (sizeof (tm_multilib_list) / sizeof (int) / 2)
|
||||
static const int tm_multilib_list[] = { TM_MULTILIB_LIST };
|
||||
#endif
|
||||
static int enabled_abi_types[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES] = { 0 };
|
||||
|
||||
#define isa_required(ABI) (abi_minimal_isa[(ABI).base][(ABI).ext])
|
||||
extern "C" const struct loongarch_isa
|
||||
abi_minimal_isa[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES];
|
||||
|
||||
static inline int
|
||||
is_multilib_enabled (struct loongarch_abi abi)
|
||||
{
|
||||
return enabled_abi_types[abi.base][abi.ext];
|
||||
}
|
||||
|
||||
static void
|
||||
init_enabled_abi_types ()
|
||||
{
|
||||
#ifdef LA_DISABLE_MULTILIB
|
||||
enabled_abi_types[DEFAULT_ABI_BASE][DEFAULT_ABI_EXT] = 1;
|
||||
#else
|
||||
int abi_base, abi_ext;
|
||||
for (unsigned int i = 0; i < MULTILIB_LIST_LEN; i++)
|
||||
{
|
||||
abi_base = tm_multilib_list[i << 1];
|
||||
abi_ext = tm_multilib_list[(i << 1) + 1];
|
||||
enabled_abi_types[abi_base][abi_ext] = 1;
|
||||
}
|
||||
#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));
|
||||
#define APPEND1(CH) obstack_1grow(&msg_obstack, CH);
|
||||
|
||||
static const char* abi_str (struct loongarch_abi abi);
|
||||
static const char* isa_str (const struct loongarch_isa *isa, char separator);
|
||||
static const char* arch_str (const struct loongarch_target *target);
|
||||
static const char* multilib_enabled_abi_list ();
|
||||
|
||||
/* Misc */
|
||||
static struct loongarch_abi isa_default_abi (const struct loongarch_isa *isa);
|
||||
static int isa_base_compat_p (const struct loongarch_isa *set1,
|
||||
const struct loongarch_isa *set2);
|
||||
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);
|
||||
|
||||
/* Checking configure-time defaults. */
|
||||
#ifndef DEFAULT_ABI_BASE
|
||||
#error missing definition of DEFAULT_ABI_BASE in ${tm_defines}.
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_ABI_EXT
|
||||
#error missing definition of DEFAULT_ABI_EXT in ${tm_defines}.
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_CPU_ARCH
|
||||
#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}.
|
||||
#endif
|
||||
|
||||
/* Handle combinations of -m machine option values
|
||||
(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_target t;
|
||||
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
/* Initialization */
|
||||
init_enabled_abi_types ();
|
||||
obstack_init (&msg_obstack);
|
||||
|
||||
struct {
|
||||
int arch, tune, fpu, abi_base, abi_ext, cmodel;
|
||||
} 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,
|
||||
};
|
||||
|
||||
#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;
|
||||
|
||||
t.abi.ext = constrained.abi_ext ? opt_abi_ext : DEFAULT_ABI_EXT;
|
||||
|
||||
/* Extra switch handling. */
|
||||
if (on (SOFT_FLOAT) || on (SINGLE_FLOAT) || on (DOUBLE_FLOAT))
|
||||
{
|
||||
switch (on_switch)
|
||||
{
|
||||
case SW_SOFT_FLOAT:
|
||||
opt_fpu = ISA_EXT_NOFPU;
|
||||
break;
|
||||
|
||||
case SW_SINGLE_FLOAT:
|
||||
opt_fpu = ISA_EXT_FPU32;
|
||||
break;
|
||||
|
||||
case SW_DOUBLE_FLOAT:
|
||||
opt_fpu = ISA_EXT_FPU64;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable();
|
||||
}
|
||||
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;
|
||||
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));
|
||||
|
||||
t.abi.base = force_abi.base;
|
||||
}
|
||||
|
||||
#ifdef LA_DISABLE_MULTILIB
|
||||
if (follow_multilib_list)
|
||||
if (t.abi.base != DEFAULT_ABI_BASE || t.abi.ext != DEFAULT_ABI_EXT)
|
||||
{
|
||||
static const struct loongarch_abi default_abi
|
||||
= {DEFAULT_ABI_BASE, DEFAULT_ABI_EXT};
|
||||
|
||||
warning (0, "ABI changed (%qs to %qs) while multilib is disabled",
|
||||
abi_str (default_abi), abi_str (t.abi));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 2. Target CPU */
|
||||
t.cpu_arch = constrained.arch ? opt_arch : DEFAULT_CPU_ARCH;
|
||||
|
||||
t.cpu_tune = constrained.tune ? opt_tune
|
||||
: (constrained.arch ? DEFAULT_CPU_ARCH : DEFAULT_CPU_TUNE);
|
||||
|
||||
#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);
|
||||
|
||||
#else
|
||||
if (t.cpu_arch == CPU_NATIVE)
|
||||
fatal_error (UNKNOWN_LOCATION,
|
||||
"%qs does not work on a cross compiler",
|
||||
"-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
|
||||
|
||||
else if (t.cpu_tune == CPU_NATIVE)
|
||||
fatal_error (UNKNOWN_LOCATION,
|
||||
"%qs does not work on a cross compiler",
|
||||
"-m" OPTSTR_TUNE "=" STR_CPU_NATIVE);
|
||||
#endif
|
||||
|
||||
/* 3. Target ISA */
|
||||
config_target_isa:
|
||||
|
||||
/* Get default ISA from "-march" or its default value. */
|
||||
t.isa = loongarch_cpu_default_isa[LARCH_ACTUAL_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);
|
||||
|
||||
|
||||
/* 4. ABI-ISA compatibility */
|
||||
/* Note:
|
||||
- There IS a unique default -march value for each ABI type
|
||||
(config.gcc: triplet -> abi -> default arch).
|
||||
|
||||
- If the base ABI is incompatible with the default arch,
|
||||
try using the default -march it implies (and mark it
|
||||
as "constrained" this time), then re-apply step 3. */
|
||||
|
||||
struct loongarch_abi abi_tmp;
|
||||
const struct loongarch_isa* isa_min;
|
||||
|
||||
abi_tmp = t.abi;
|
||||
isa_min = &isa_required (abi_tmp);
|
||||
|
||||
if (isa_base_compat_p (&t.isa, isa_min)); /* OK. */
|
||||
else if (!constrained.arch)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
if (t.cpu_arch == CPU_NATIVE)
|
||||
warning (0, "your native CPU architecture (%qs) "
|
||||
"does not support %qs ABI, falling back to %<-m%s=%s%>",
|
||||
arch_str (&t), abi_str (t.abi), OPTSTR_ARCH,
|
||||
loongarch_cpu_strings[fallback_arch]);
|
||||
else
|
||||
warning (0, "default CPU architecture (%qs) "
|
||||
"does not support %qs ABI, falling back to %<-m%s=%s%>",
|
||||
arch_str (&t), abi_str (t.abi), OPTSTR_ARCH,
|
||||
loongarch_cpu_strings[fallback_arch]);
|
||||
|
||||
t.cpu_arch = fallback_arch;
|
||||
constrained.arch = 1;
|
||||
goto config_target_isa;
|
||||
}
|
||||
else if (!constrained.abi_base)
|
||||
{
|
||||
/* If -march is given while -mabi is not,
|
||||
try selecting another base ABI type. */
|
||||
abi_tmp.base = isa_default_abi (&t.isa).base;
|
||||
}
|
||||
else
|
||||
goto fatal;
|
||||
|
||||
if (isa_fpu_compat_p (&t.isa, isa_min)); /* OK. */
|
||||
else if (!constrained.fpu)
|
||||
t.isa.fpu = isa_min->fpu;
|
||||
else if (!constrained.abi_base)
|
||||
/* If -march is compatible with the default ABI
|
||||
while -mfpu is not. */
|
||||
abi_tmp.base = isa_default_abi (&t.isa).base;
|
||||
else
|
||||
goto fatal;
|
||||
|
||||
if (0)
|
||||
fatal:
|
||||
fatal_error (UNKNOWN_LOCATION,
|
||||
"unable to implement ABI %qs with instruction set %qs",
|
||||
abi_str (t.abi), isa_str (&t.isa, '/'));
|
||||
|
||||
|
||||
/* Using the fallback ABI. */
|
||||
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)
|
||||
{
|
||||
|
||||
/* Continue falling back until we find a feasible ABI type
|
||||
enabled by TM_MULTILIB_LIST. */
|
||||
if (!is_multilib_enabled (abi_tmp))
|
||||
{
|
||||
for (unsigned int i = 0; i < ABI_COUNT; i++)
|
||||
{
|
||||
if (is_multilib_enabled (abi_priority_list[i])
|
||||
&& abi_compat_p (&t.isa, abi_priority_list[i]))
|
||||
{
|
||||
abi_tmp = abi_priority_list[i];
|
||||
|
||||
warning (0, "ABI %qs cannot be implemented due to "
|
||||
"limited instruction set %qs, "
|
||||
"falling back to %qs", abi_str (t.abi),
|
||||
isa_str (&t.isa, '/'), abi_str (abi_tmp));
|
||||
|
||||
goto fallback;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, keep using abi_tmp with a warning. */
|
||||
#ifdef LA_DISABLE_MULTILIB
|
||||
warning (0, "instruction set %qs cannot implement "
|
||||
"default ABI %qs, falling back to %qs",
|
||||
isa_str (&t.isa, '/'), abi_str (t.abi),
|
||||
abi_str (abi_tmp));
|
||||
#else
|
||||
warning (0, "no multilib-enabled ABI (%qs) can be implemented "
|
||||
"with instruction set %qs, falling back to %qs",
|
||||
multilib_enabled_abi_list (),
|
||||
isa_str (&t.isa, '/'), abi_str (abi_tmp));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
fallback:
|
||||
t.abi = abi_tmp;
|
||||
}
|
||||
else if (follow_multilib_list)
|
||||
{
|
||||
if (!is_multilib_enabled (t.abi))
|
||||
{
|
||||
inform (UNKNOWN_LOCATION,
|
||||
"ABI %qs is not enabled at configure-time, "
|
||||
"the linker might report an error", abi_str (t.abi));
|
||||
|
||||
inform (UNKNOWN_LOCATION, "ABI with startfiles: %s",
|
||||
multilib_enabled_abi_list ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 5. Target code model */
|
||||
t.cmodel = constrained.cmodel ? opt_cmodel : CMODEL_NORMAL;
|
||||
|
||||
/* Cleanup and return. */
|
||||
obstack_free (&msg_obstack, NULL);
|
||||
*target = t;
|
||||
}
|
||||
|
||||
/* Returns the default ABI for the given instruction set. */
|
||||
static inline struct loongarch_abi
|
||||
isa_default_abi (const struct loongarch_isa *isa)
|
||||
{
|
||||
struct loongarch_abi abi;
|
||||
|
||||
switch (isa->fpu)
|
||||
{
|
||||
case ISA_EXT_FPU64:
|
||||
if (isa->base == ISA_BASE_LA64V100)
|
||||
abi.base = ABI_BASE_LP64D;
|
||||
break;
|
||||
|
||||
case ISA_EXT_FPU32:
|
||||
if (isa->base == ISA_BASE_LA64V100)
|
||||
abi.base = ABI_BASE_LP64F;
|
||||
break;
|
||||
|
||||
case ISA_EXT_NOFPU:
|
||||
if (isa->base == ISA_BASE_LA64V100)
|
||||
abi.base = ABI_BASE_LP64S;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
abi.ext = ABI_EXT_BASE;
|
||||
return abi;
|
||||
}
|
||||
|
||||
/* Check if set2 is a subset of set1. */
|
||||
static inline int
|
||||
isa_base_compat_p (const struct loongarch_isa *set1,
|
||||
const struct loongarch_isa *set2)
|
||||
{
|
||||
switch (set2->base)
|
||||
{
|
||||
case ISA_BASE_LA64V100:
|
||||
return (set1->base == ISA_BASE_LA64V100);
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
isa_fpu_compat_p (const struct loongarch_isa *set1,
|
||||
const struct loongarch_isa *set2)
|
||||
{
|
||||
switch (set2->fpu)
|
||||
{
|
||||
case ISA_EXT_FPU64:
|
||||
return set1->fpu == ISA_EXT_FPU64;
|
||||
|
||||
case ISA_EXT_FPU32:
|
||||
return set1->fpu == ISA_EXT_FPU32 || set1->fpu == ISA_EXT_FPU64;
|
||||
|
||||
case ISA_EXT_NOFPU:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static inline int
|
||||
abi_compat_p (const struct loongarch_isa *isa, struct loongarch_abi abi)
|
||||
{
|
||||
int compatible = 1;
|
||||
const struct loongarch_isa *isa2 = &isa_required (abi);
|
||||
|
||||
/* Append conditionals for new ISA components below. */
|
||||
compatible = compatible && isa_base_compat_p (isa, isa2);
|
||||
compatible = compatible && isa_fpu_compat_p (isa, isa2);
|
||||
return compatible;
|
||||
}
|
||||
|
||||
/* The behavior of this function should be consistent
|
||||
with config.gcc. */
|
||||
static inline int
|
||||
abi_default_cpu_arch (struct loongarch_abi abi)
|
||||
{
|
||||
switch (abi.base)
|
||||
{
|
||||
case ABI_BASE_LP64D:
|
||||
case ABI_BASE_LP64F:
|
||||
case ABI_BASE_LP64S:
|
||||
if (abi.ext == ABI_EXT_BASE)
|
||||
return CPU_LOONGARCH64;
|
||||
}
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
static const char*
|
||||
abi_str (struct loongarch_abi abi)
|
||||
{
|
||||
/* "/base" can be omitted. */
|
||||
if (abi.ext == ABI_EXT_BASE)
|
||||
return (const char*)
|
||||
obstack_copy0 (&msg_obstack, loongarch_abi_base_strings[abi.base],
|
||||
strlen (loongarch_abi_base_strings[abi.base]));
|
||||
else
|
||||
{
|
||||
APPEND_STRING (loongarch_abi_base_strings[abi.base])
|
||||
APPEND1 ('/')
|
||||
APPEND_STRING (loongarch_abi_ext_strings[abi.ext])
|
||||
APPEND1 ('\0')
|
||||
|
||||
return XOBFINISH (&msg_obstack, const char *);
|
||||
}
|
||||
}
|
||||
|
||||
static const char*
|
||||
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)
|
||||
{
|
||||
APPEND_STRING ("no" OPTSTR_ISA_EXT_FPU)
|
||||
}
|
||||
else
|
||||
{
|
||||
APPEND_STRING (OPTSTR_ISA_EXT_FPU)
|
||||
APPEND_STRING (loongarch_isa_ext_strings[isa->fpu])
|
||||
}
|
||||
APPEND1 ('\0')
|
||||
|
||||
/* Add more here. */
|
||||
|
||||
return XOBFINISH (&msg_obstack, const char *);
|
||||
}
|
||||
|
||||
static const char*
|
||||
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]);
|
||||
}
|
||||
else
|
||||
APPEND_STRING (loongarch_cpu_strings[target->cpu_arch]);
|
||||
|
||||
APPEND1 ('\0')
|
||||
return XOBFINISH (&msg_obstack, const char *);
|
||||
}
|
||||
|
||||
static const char*
|
||||
multilib_enabled_abi_list ()
|
||||
{
|
||||
int enabled_abi_idx[MULTILIB_LIST_LEN] = { 0 };
|
||||
const char* enabled_abi_str[MULTILIB_LIST_LEN] = { NULL };
|
||||
unsigned int j = 0;
|
||||
|
||||
for (unsigned int i = 0; i < ABI_COUNT && j < MULTILIB_LIST_LEN; i++)
|
||||
{
|
||||
if (enabled_abi_types[abi_priority_list[i].base]
|
||||
[abi_priority_list[i].ext])
|
||||
{
|
||||
enabled_abi_idx[j++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int k = 0; k < j; k++)
|
||||
{
|
||||
enabled_abi_str[k] = abi_str (abi_priority_list[enabled_abi_idx[k]]);
|
||||
}
|
||||
|
||||
for (unsigned int k = 0; k < j - 1; k++)
|
||||
{
|
||||
APPEND_STRING (enabled_abi_str[k])
|
||||
APPEND1 (',')
|
||||
APPEND1 (' ')
|
||||
}
|
||||
APPEND_STRING (enabled_abi_str[j - 1])
|
||||
APPEND1 ('\0')
|
||||
|
||||
return XOBFINISH (&msg_obstack, const char *);
|
||||
}
|
90
gcc/config/loongarch/loongarch-opts.h
Normal file
90
gcc/config/loongarch/loongarch-opts.h
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* Definitions for loongarch-specific option handling.
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
Contributed by Loongson Ltd.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef LOONGARCH_OPTS_H
|
||||
#define LOONGARCH_OPTS_H
|
||||
|
||||
|
||||
/* Target configuration */
|
||||
extern struct loongarch_target la_target;
|
||||
|
||||
/* Switch masks */
|
||||
extern const int loongarch_switch_mask[];
|
||||
|
||||
#include "loongarch-def.h"
|
||||
|
||||
#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)
|
||||
/* 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);
|
||||
#endif
|
||||
|
||||
|
||||
/* Macros for common conditional expressions used in loongarch.{c,h,md} */
|
||||
#define TARGET_CMODEL_NORMAL (la_target.cmodel == CMODEL_NORMAL)
|
||||
#define TARGET_CMODEL_TINY (la_target.cmodel == CMODEL_TINY)
|
||||
#define TARGET_CMODEL_TINY_STATIC (la_target.cmodel == CMODEL_TINY_STATIC)
|
||||
#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_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_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)
|
||||
#define TARGET_DOUBLE_FLOAT (la_target.isa.fpu == ISA_EXT_FPU64)
|
||||
#define TARGET_DOUBLE_FLOAT_ABI (la_target.abi.base == ABI_BASE_LP64D)
|
||||
|
||||
#define TARGET_64BIT (la_target.isa.base == ISA_BASE_LA64V100)
|
||||
#define TARGET_ABI_LP64 (la_target.abi.base == ABI_BASE_LP64D \
|
||||
|| 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 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)
|
||||
|
||||
/* 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()
|
||||
|
||||
#endif /* LOONGARCH_OPTS_H */
|
59
gcc/config/loongarch/loongarch-str.h
Normal file
59
gcc/config/loongarch/loongarch-str.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Generated automatically by "genstr" from "loongarch-strings".
|
||||
Please do not edit this file directly.
|
||||
|
||||
Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
Contributed by Loongson Ltd.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef LOONGARCH_STR_H
|
||||
#define LOONGARCH_STR_H
|
||||
|
||||
#define OPTSTR_ARCH "arch"
|
||||
#define OPTSTR_TUNE "tune"
|
||||
|
||||
#define STR_CPU_NATIVE "native"
|
||||
#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_ISA_EXT_FPU0 "0"
|
||||
#define STR_ISA_EXT_FPU32 "32"
|
||||
#define STR_ISA_EXT_FPU64 "64"
|
||||
|
||||
#define OPTSTR_SOFT_FLOAT "soft-float"
|
||||
#define OPTSTR_SINGLE_FLOAT "single-float"
|
||||
#define OPTSTR_DOUBLE_FLOAT "double-float"
|
||||
|
||||
#define OPTSTR_ABI_BASE "abi"
|
||||
#define STR_ABI_BASE_LP64D "lp64d"
|
||||
#define STR_ABI_BASE_LP64F "lp64f"
|
||||
#define STR_ABI_BASE_LP64S "lp64s"
|
||||
|
||||
#define STR_ABI_EXT_BASE "base"
|
||||
|
||||
#define OPTSTR_CMODEL "cmodel"
|
||||
#define STR_CMODEL_NORMAL "normal"
|
||||
#define STR_CMODEL_TINY "tiny"
|
||||
#define STR_CMODEL_TS "tiny-static"
|
||||
#define STR_CMODEL_LARGE "large"
|
||||
#define STR_CMODEL_EXTREME "extreme"
|
||||
|
||||
#endif /* LOONGARCH_STR_H */
|
186
gcc/config/loongarch/loongarch.opt
Normal file
186
gcc/config/loongarch/loongarch.opt
Normal file
|
@ -0,0 +1,186 @@
|
|||
; Generated by "genstr" from the template "loongarch.opt.in"
|
||||
; and definitions from "loongarch-strings".
|
||||
;
|
||||
; Please do not edit this file directly.
|
||||
; It will be automatically updated during a gcc build
|
||||
; if you change "loongarch.opt.in" or "loongarch-strings".
|
||||
;
|
||||
; Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
;
|
||||
; This file is part of GCC.
|
||||
;
|
||||
; GCC is free software; you can redistribute it and/or modify it under
|
||||
; the terms of the GNU General Public License as published by the Free
|
||||
; Software Foundation; either version 3, or (at your option) any later
|
||||
; version.
|
||||
;
|
||||
; GCC is distributed in the hope that it will be useful, but WITHOUT
|
||||
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
; License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with GCC; see the file COPYING3. If not see
|
||||
; <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
|
||||
Name(isa_base) Type(int)
|
||||
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)
|
||||
|
||||
EnumValue
|
||||
Enum(isa_ext_fpu) String(32) Value(ISA_EXT_FPU32)
|
||||
|
||||
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)
|
||||
-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)
|
||||
Prevent the use of all hardware floating-point instructions.
|
||||
|
||||
msingle-float
|
||||
Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F32) 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)
|
||||
Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations.
|
||||
|
||||
|
||||
;; Base target models (implies ISA & tune parameters)
|
||||
Enum
|
||||
Name(cpu_type) Type(int)
|
||||
LoongArch CPU types:
|
||||
|
||||
EnumValue
|
||||
Enum(cpu_type) String(native) Value(CPU_NATIVE)
|
||||
|
||||
EnumValue
|
||||
Enum(cpu_type) String(loongarch64) Value(CPU_LOONGARCH64)
|
||||
|
||||
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)
|
||||
-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)
|
||||
-mtune=PROCESSOR Generate optimized code for PROCESSOR.
|
||||
|
||||
|
||||
; ABI related options
|
||||
; (ISA constraints on ABI are handled dynamically)
|
||||
|
||||
;; Base ABI
|
||||
Enum
|
||||
Name(abi_base) Type(int)
|
||||
Base ABI types for LoongArch:
|
||||
|
||||
EnumValue
|
||||
Enum(abi_base) String(lp64d) Value(ABI_BASE_LP64D)
|
||||
|
||||
EnumValue
|
||||
Enum(abi_base) String(lp64f) Value(ABI_BASE_LP64F)
|
||||
|
||||
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)
|
||||
-mabi=BASEABI Generate code that conforms to the given BASEABI.
|
||||
|
||||
;; ABI Extension
|
||||
Variable
|
||||
int la_opt_abi_ext = M_OPTION_NOT_SEEN
|
||||
|
||||
|
||||
mbranch-cost=
|
||||
Target RejectNegative Joined UInteger Var(loongarch_branch_cost)
|
||||
-mbranch-cost=COST Set the cost of branches to roughly COST instructions.
|
||||
|
||||
mcheck-zero-division
|
||||
Target Mask(CHECK_ZERO_DIV)
|
||||
Trap on integer divide by zero.
|
||||
|
||||
mcond-move-int
|
||||
Target Var(TARGET_COND_MOVE_INT) Init(1)
|
||||
Conditional moves for integral are enabled.
|
||||
|
||||
mcond-move-float
|
||||
Target Var(TARGET_COND_MOVE_FLOAT) Init(1)
|
||||
Conditional moves for float are enabled.
|
||||
|
||||
mmemcpy
|
||||
Target Mask(MEMCPY)
|
||||
Prevent optimizing block moves, which is also the default behavior of -Os.
|
||||
|
||||
mstrict-align
|
||||
Target Var(TARGET_STRICT_ALIGN) Init(0)
|
||||
Do not generate unaligned memory accesses.
|
||||
|
||||
mmax-inline-memcpy-size=
|
||||
Target Joined RejectNegative UInteger Var(loongarch_max_inline_memcpy_size) Init(1024)
|
||||
-mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024.
|
||||
|
||||
; The code model option names for -mcmodel.
|
||||
Enum
|
||||
Name(cmodel) Type(int)
|
||||
The code model option names for -mcmodel:
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(normal) Value(CMODEL_NORMAL)
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(tiny) Value(CMODEL_TINY)
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(tiny-static) Value(CMODEL_TINY_STATIC)
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(large) Value(CMODEL_LARGE)
|
||||
|
||||
EnumValue
|
||||
Enum(cmodel) String(extreme) Value(CMODEL_EXTREME)
|
||||
|
||||
mcmodel=
|
||||
Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(CMODEL_NORMAL)
|
||||
Specify the code model.
|
53
gcc/config/loongarch/t-linux
Normal file
53
gcc/config/loongarch/t-linux
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# GCC is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Multilib
|
||||
MULTILIB_OPTIONS = mabi=lp64d/mabi=lp64f/mabi=lp64s
|
||||
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))
|
||||
|
||||
# Multiarch
|
||||
ifneq ($(call if_multiarch,yes),yes)
|
||||
# Define LA_DISABLE_MULTIARCH if multiarch is disabled.
|
||||
tm_defines += LA_DISABLE_MULTIARCH
|
||||
else
|
||||
# Only define MULTIARCH_DIRNAME when multiarch is enabled,
|
||||
# or it would always introduce ${target} into the search path.
|
||||
MULTIARCH_DIRNAME = $(LA_MULTIARCH_TRIPLET)
|
||||
endif
|
||||
|
||||
# Don't define MULTILIB_OSDIRNAMES if multilib is disabled.
|
||||
ifeq ($(filter LA_DISABLE_MULTILIB,$(tm_defines)),)
|
||||
|
||||
MULTILIB_OSDIRNAMES = \
|
||||
mabi.lp64d=../lib64$\
|
||||
$(call if_multiarch,:loongarch64-linux-gnuf64)
|
||||
|
||||
MULTILIB_OSDIRNAMES += \
|
||||
mabi.lp64f=../lib64/f32$\
|
||||
$(call if_multiarch,:loongarch64-linux-gnuf32)
|
||||
|
||||
MULTILIB_OSDIRNAMES += \
|
||||
mabi.lp64s=../lib64/sf$\
|
||||
$(call if_multiarch,:loongarch64-linux-gnusf)
|
||||
|
||||
endif
|
71
gcc/config/loongarch/t-loongarch
Normal file
71
gcc/config/loongarch/t-loongarch
Normal file
|
@ -0,0 +1,71 @@
|
|||
# Copyright (C) 2021-2022 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GCC.
|
||||
#
|
||||
# GCC is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GCC is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Canonical target triplet from config.gcc
|
||||
LA_MULTIARCH_TRIPLET = $(patsubst LA_MULTIARCH_TRIPLET=%,%,$\
|
||||
$(filter LA_MULTIARCH_TRIPLET=%,$(tm_defines)))
|
||||
|
||||
# String definition header
|
||||
LA_STR_H = $(srcdir)/config/loongarch/loongarch-str.h
|
||||
|
||||
# String definition header
|
||||
$(LA_STR_H): s-loongarch-str ; @true
|
||||
s-loongarch-str: $(srcdir)/config/loongarch/genopts/genstr.sh \
|
||||
$(srcdir)/config/loongarch/genopts/loongarch-strings
|
||||
$(SHELL) $(srcdir)/config/loongarch/genopts/genstr.sh header \
|
||||
$(srcdir)/config/loongarch/genopts/loongarch-strings > \
|
||||
tmp-loongarch-str.h
|
||||
$(SHELL) $(srcdir)/../move-if-change tmp-loongarch-str.h \
|
||||
$(LA_STR_H)
|
||||
$(STAMP) s-loongarch-str
|
||||
|
||||
loongarch-c.o: $(srcdir)/config/loongarch/loongarch-c.cc $(CONFIG_H) $(SYSTEM_H) \
|
||||
coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H) $(TARGET_H)
|
||||
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
|
||||
$(srcdir)/config/loongarch/loongarch-c.cc
|
||||
|
||||
loongarch-builtins.o: $(srcdir)/config/loongarch/loongarch-builtins.cc $(CONFIG_H) \
|
||||
$(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) $(RECOG_H) langhooks.h \
|
||||
$(DIAGNOSTIC_CORE_H) $(OPTABS_H) $(srcdir)/config/loongarch/loongarch-ftypes.def \
|
||||
$(srcdir)/config/loongarch/loongarch-modes.def
|
||||
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
|
||||
$(srcdir)/config/loongarch/loongarch-builtins.cc
|
||||
|
||||
loongarch-driver.o : $(srcdir)/config/loongarch/loongarch-driver.cc $(LA_STR_H) \
|
||||
$(CONFIG_H) $(SYSTEM_H)
|
||||
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
|
||||
|
||||
loongarch-opts.o: $(srcdir)/config/loongarch/loongarch-opts.cc $(LA_STR_H)
|
||||
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
|
||||
|
||||
loongarch-cpu.o: $(srcdir)/config/loongarch/loongarch-cpu.cc $(LA_STR_H)
|
||||
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
|
||||
|
||||
loongarch-def.o: $(srcdir)/config/loongarch/loongarch-def.c $(LA_STR_H)
|
||||
$(CC) -c $(ALL_CFLAGS) $(INCLUDES) $<
|
||||
|
||||
$(srcdir)/config/loongarch/loongarch.opt: s-loongarch-opt ; @true
|
||||
s-loongarch-opt: $(srcdir)/config/loongarch/genopts/genstr.sh \
|
||||
$(srcdir)/config/loongarch/genopts/loongarch.opt.in \
|
||||
$(srcdir)/config/loongarch/genopts/loongarch-strings $(LA_STR_H)
|
||||
$(SHELL) $(srcdir)/config/loongarch/genopts/genstr.sh opt \
|
||||
$(srcdir)/config/loongarch/genopts/loongarch.opt.in \
|
||||
> tmp-loongarch.opt
|
||||
$(SHELL) $(srcdir)/../move-if-change tmp-loongarch.opt \
|
||||
$(srcdir)/config/loongarch/loongarch.opt
|
||||
$(STAMP) s-loongarch-opt
|
|
@ -951,6 +951,9 @@ AC_ARG_ENABLE(fixed-point,
|
|||
mips*-*-*)
|
||||
enable_fixed_point=yes
|
||||
;;
|
||||
loongarch*-*-*)
|
||||
enable_fixed_point=yes
|
||||
;;
|
||||
*)
|
||||
AC_MSG_WARN([fixed-point is not supported for this target, ignored])
|
||||
enable_fixed_point=no
|
||||
|
@ -3838,6 +3841,17 @@ foo: data8 25
|
|||
movl r24 = @tprel(foo#)'
|
||||
tls_as_opt=--fatal-warnings
|
||||
;;
|
||||
loongarch*-*-*)
|
||||
conftest_s='
|
||||
.section .tdata,"awT",@progbits
|
||||
x: .word 2
|
||||
.text
|
||||
la.tls.gd $a0,x
|
||||
bl __tls_get_addr'
|
||||
tls_first_major=0
|
||||
tls_first_minor=0
|
||||
tls_as_opt='--fatal-warnings'
|
||||
;;
|
||||
microblaze*-*-*)
|
||||
conftest_s='
|
||||
.section .tdata,"awT",@progbits
|
||||
|
@ -5300,6 +5314,17 @@ configured with --enable-newlib-nano-formatted-io.])
|
|||
[AC_DEFINE(HAVE_AS_MARCH_ZIFENCEI, 1,
|
||||
[Define if the assembler understands -march=rv*_zifencei.])])
|
||||
;;
|
||||
loongarch*-*-*)
|
||||
gcc_GAS_CHECK_FEATURE([.dtprelword support],
|
||||
gcc_cv_as_loongarch_dtprelword, [2,18,0],,
|
||||
[.section .tdata,"awT",@progbits
|
||||
x:
|
||||
.word 2
|
||||
.text
|
||||
.dtprelword x+0x8000],,
|
||||
[AC_DEFINE(HAVE_AS_DTPRELWORD, 1,
|
||||
[Define if your assembler supports .dtprelword.])])
|
||||
;;
|
||||
s390*-*-*)
|
||||
gcc_GAS_CHECK_FEATURE([.gnu_attribute support],
|
||||
gcc_cv_as_s390_gnu_attribute,,
|
||||
|
@ -5333,11 +5358,11 @@ configured with --enable-newlib-nano-formatted-io.])
|
|||
;;
|
||||
esac
|
||||
|
||||
# Mips and HP-UX need the GNU assembler.
|
||||
# Mips, LoongArch and HP-UX need the GNU assembler.
|
||||
# Linux on IA64 might be able to use the Intel assembler.
|
||||
|
||||
case "$target" in
|
||||
mips*-*-* | *-*-hpux* )
|
||||
mips*-*-* | loongarch*-*-* | *-*-hpux* )
|
||||
if test x$gas_flag = xyes \
|
||||
|| test x"$host" != x"$build" \
|
||||
|| test ! -x "$gcc_cv_as" \
|
||||
|
@ -5494,8 +5519,8 @@ esac
|
|||
# ??? Once 2.11 is released, probably need to add first known working
|
||||
# version to the per-target configury.
|
||||
case "$cpu_type" in
|
||||
aarch64 | alpha | arc | arm | avr | bfin | cris | csky | i386 | m32c | m68k \
|
||||
| microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc \
|
||||
aarch64 | alpha | arc | arm | avr | bfin | cris | csky | i386 | loongarch | m32c \
|
||||
| m68k | microblaze | mips | nds32 | nios2 | pa | riscv | rs6000 | score | sparc \
|
||||
| tilegx | tilepro | visium | xstormy16 | xtensa)
|
||||
insn="nop"
|
||||
;;
|
||||
|
|
Loading…
Add table
Reference in a new issue