Hi,

Thanks for the submission.  Some comments below on this patch,
but otherwise it looks good.  I hope to get to the other patches
in the series soon.

I haven't followed all of the previous discussion, so some of these
points might already have been discussed.  Sorry in advance if so.

xucheng...@loongson.cn writes:
> diff --git a/contrib/gcc_update b/contrib/gcc_update
> index 1cf15f9b3c2..641ce164775 100755
> --- a/contrib/gcc_update
> +++ b/contrib/gcc_update
> @@ -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
> diff --git a/gcc/common/config/loongarch/loongarch-common.cc 
> b/gcc/common/config/loongarch/loongarch-common.cc
> new file mode 100644
> index 00000000000..5bdfd2a30e1
> --- /dev/null
> +++ b/gcc/common/config/loongarch/loongarch-common.cc
> @@ -0,0 +1,73 @@
> +/* 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 }
> +};
> +
> +/* Implement TARGET_HANDLE_OPTION.  */
> +
> +static bool
> +loongarch_handle_option (struct gcc_options *opts,
> +                      struct gcc_options *opts_set ATTRIBUTE_UNUSED,
> +                      const struct cl_decoded_option *decoded,
> +                      location_t loc ATTRIBUTE_UNUSED)
> +{
> +  size_t code = decoded->opt_index;
> +  int value = decoded->value;
> +
> +  switch (code)
> +    {
> +    case OPT_mmemcpy:
> +      if (value)
> +     {
> +       if (opts->x_optimize_size)
> +         opts->x_target_flags |= MASK_MEMCPY;
> +     }
> +      else
> +     opts->x_target_flags &= ~MASK_MEMCPY;
> +      return true;

I think this will make the option order-dependent: -mmemcpy -Os
could behave differently from -Os -mmemcpy.  I'm also not sure
it would trigger if the optimisation level is changed by the
source code, e.g. using __attribute__((optimize)).

If -mmemcpy is only supposed to have an effect when optimising
for size, it would probably be better to have a preprocessor
macro in loongson.h along the lines of:

#define TARGET_MEMCPY (TARGET_RAW_MEMCPY && optimize_size)

with s/Mask(MEMCPY)/Mask(RAW_MEMCPY)/ in the .opt file.

> +
> +    default:
> +      return true;
> +    }
> +}
> +
> +#undef TARGET_DEFAULT_TARGET_FLAGS
> +#define TARGET_DEFAULT_TARGET_FLAGS  MASK_CHECK_ZERO_DIV
> +#undef TARGET_HANDLE_OPTION
> +#define TARGET_HANDLE_OPTION loongarch_handle_option
> +
> +struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
> […]
> +             # Inferring 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
> +
> […]
> +             ## Setting default value for with_fpu.
> +             if test x${with_fpu} == xnone; then
> +                     with_fpu="0"
> +             fi

I don't understand this.  Won't it always trigger an error…

> +
> +             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}$"; then
> +                             : # OK
> +                     else
> +                             echo "${with_abi}/${with_abiext} ABI cannot be 
> implemented with" \
> +                             "--with-fpu=${with_fpu}." 1>&2
> +                             exit 1

…here?  It looks like the original “none” would have been accepted
for soft-float.

> +                     fi
> +                     ;;
> +             esac
> +
> +
> +             # Inferring default with_tune from with_arch: pass 1
> +             case ${with_arch} in
> +             native)
> +                     tune_pattern="*"
> +                     tune_default="native"
> +                     ;;
> +             loongarch64)
> +                     tune_pattern="loongarch64 | la464"

Does including the spaces work?  The earlier patterns didn't have
spaces, which seems more correct.

> +                     tune_default="la464"
> +                     ;;
> +             *)
> +                     # By default, $with_tune == $with_arch
> +                     tune_pattern="$with_arch"
> +                     ;;
> +             esac
> +
> +             ## Setting 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}$"; 
> then
> +                             : # OK
> +                     else
> +                             echo "Incompatible options: 
> --with-tune=${with_tune}" \
> +                             "and --with-arch=${with_arch}." 1>&2
> +                             exit 1
> +                     fi
> +                     ;;
> +             esac
> +
> +
> +             # Perform final sanity checks.
> +             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.
> +             *)
> +                     echo "Unknown fpu type in --with-fpu=$with_fpu" 1>&2
> +                     exit 1
> +                     ;;
> +             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=""
> +
> +             for e in $(tr ',' ' ' <<< "${with_multilib_list}"); do
> +                     e=($(tr '/' ' ' <<< "$e"))
> +
> +                     # Base ABI type
> +                     case ${e[0]} in
> +                     lp64d) loongarch_multilib_list_c+="ABI_BASE_LP64D,";;
> +                     lp64f) loongarch_multilib_list_c+="ABI_BASE_LP64F,";;
> +                     lp64s) loongarch_multilib_list_c+="ABI_BASE_LP64S,";;
> +                     *)
> +                             echo "Unknown base ABI \"${e[0]}\" in 
> --with-multilib-list." 1>&2
> +                             exit 1
> +                             ;;
> +                     esac
> +                     loongarch_multilib_list_make+="mabi=${e[0]}"
> +
> +                     # ABI extension type
> +                     case ${e[1]} in
> +                     "" | base)
> +                             loongarch_multilib_list_make+=""
> +                             loongarch_multilib_list_c+="ABI_EXT_BASE,"
> +                             e[1]="base"
> +                             ;;
> +                     *)
> +                             echo "Unknown ABI extension \"${e[1]}\" in 
> --with-multilib-list." 1>&2
> +                             exit 1
> +                             ;;
> +                     esac
> +
> +                     case ${e[2]} in
> +                     "") ;; # OK
> +                     *)
> +                             echo "Unknown ABI in --with-multilib-list." 1>&2
> +                             exit 1
> +                             ;;
> +                     esac
> +
> +                     if test x${with_abi} != x && test x${with_abiext} != x; 
> then
> +                             if test x${e[0]} == x${with_abi} \
> +                             && test x${e[1]} == x${with_abiext}; then
> +                                     loongarch_multilib_list_sane=yes
> +                             fi
> +                     fi
> +
> +                     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:0:-1}
> +             
> loongarch_multilib_list_make=${loongarch_multilib_list_make:0:-1}

I think ${…:…:…} is a bash-ism.  And although bash is probably the
system shell on the targets you care about, it's sometimes useful
to test GCC with SHELL=/bin/dash in order to flush out unportable
shell constructs.

Maybe use sed 's/,$//' instead, even though it's much clunkier
than your version.

> +             ;;
> +
>       nds32*-*-*)
>               supported_defaults="arch cpu nds32_lib float fpu_config"
>  
> @@ -5370,6 +5733,51 @@ case ${target} in
>               tmake_file="mips/t-mips $tmake_file"
>               ;;
>  
> +     loongarch*-*-*)
> +             # Export canonical triplet.
> +             tm_defines+=" LA_MULTIARCH_TRIPLET=${la_canonical_triplet}"

Similarly here, += is a bashism.  This unfortunately needs to be:

   tm_defines="${tm_defines} LA_MULTIARCH_TRIPLET=${la_canonical_triplet}"

instead.  Same for the rest of the patch.

> +
> +             # Define macro __DISABLE_MULTILIB if --disable-multilib
> +             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+=" __DISABLE_MULTILIB"
> +             fi

__FOO macros are in the implementation namespace so GCC needs to avoid
defining them itself.  Maybe LA_DISABLE_MULTILIB instead?

> […]
> diff --git a/gcc/config/loongarch/genopts/genstr.sh 
> b/gcc/config/loongarch/genopts/genstr.sh
> new file mode 100755
> index 00000000000..6c1211c9e92
> --- /dev/null
> +++ b/gcc/config/loongarch/genopts/genstr.sh
> @@ -0,0 +1,91 @@
> +#!/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")"

Similarly here we need to avoid bash's $(...).  Would be worth trying
the script with /bin/dash to see whether it works (i.e. produces the same
output as bash).

> diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in 
> b/gcc/config/loongarch/genopts/loongarch.opt.in
> new file mode 100644
> index 00000000000..01c8b3e5308
> --- /dev/null
> +++ b/gcc/config/loongarch/genopts/loongarch.opt.in
> @@ -0,0 +1,189 @@
> +; Generated by "genstr" from the template "loongarch.opt.in"
> +; and definitions from "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(@@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.

For the record: I've not seen this kind of thing (with the @@
replacements) being done before, but I can see that it could be
a way of preventing typos creeping in.  It doesn't contradict the
“global” GCC style and so IMO it's a perfectly valid choice for
target maintainers to make.

> […]
> +mmemcpy
> +Target Mask(MEMCPY)
> +Don't optimize block moves.

Going back to the above, if the intention is that this option
only has an effect when optimising for size, the documentation
ought to say that.

> +
> +mlra
> +Target Var(loongarch_lra_flag) Init(1) Save
> +Use LRA instead of reload.

Please drop this option and only support LRA.  No new code should
use old reload, even as a default-off option.

> +
> +noasmopt
> +Driver

Do you need this?  It looks like a MIPS hangover.

Thanks,
Richard

Reply via email to