From patchwork Mon Aug 14 03:57:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Yujie X-Patchwork-Id: 1820837 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RPLHR1j1Rz1yfS for ; Mon, 14 Aug 2023 13:58:59 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 45B253830B76 for ; Mon, 14 Aug 2023 03:58:57 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from eggs.gnu.org (eggs.gnu.org [IPv6:2001:470:142:3::10]) by sourceware.org (Postfix) with ESMTPS id A51033858C3A for ; Mon, 14 Aug 2023 03:57:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A51033858C3A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=loongson.cn Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qVOi1-0004wj-HR for gcc-patches@gcc.gnu.org; Sun, 13 Aug 2023 23:57:40 -0400 Received: from loongson.cn (unknown [192.168.100.1]) by gateway (Coremail) with SMTP id _____8CxLOslptlk9uUXAA--.44108S3; Mon, 14 Aug 2023 11:57:26 +0800 (CST) Received: from localhost.localdomain (unknown [192.168.100.1]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxTs8jptlkPVFZAA--.25099S2; Mon, 14 Aug 2023 11:57:23 +0800 (CST) From: Yang Yujie To: gcc-patches@gcc.gnu.org Cc: xry111@xry111.site, xuchenghua@loongson.cn, panchenghui@loongson.cn, chenglulu@loongson.cn, Yang Yujie Subject: [PATCH v1 1/6] LoongArch: a symmetric multilib subdir layout Date: Mon, 14 Aug 2023 11:57:02 +0800 Message-Id: <20230814035707.11272-1-yangyujie@loongson.cn> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxTs8jptlkPVFZAA--.25099S2 X-CM-SenderInfo: 51dqw5pxmlvqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBj93XoWxZFyfGFy3tFykZw17tw1DJwc_yoW7Gryrpr W7u3W5AFs5XFn3Gws3A3yfX3WrGFZ5Gry7ZFy3K3y7CrsxGwnFvF4kt347WF1DCrs5AFWa gwnYga43uFs8CacCm3ZEXasCq-sJn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUkFb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Gr0_Xr1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx 1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv 67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6x kF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x07j8sqAUUUUU= Received-SPF: pass client-ip=114.242.206.163; envelope-from=yangyujie@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Status: No, score=-15.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_FAIL, SPF_HELO_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Multilib in gcc is asymmetric. i.e. a "default" / "toplevel" library variant is always built and installed, and: * it is installed directly under the gcc libdir (with no suffix); * it is selected / searched / linked against when the gcc driver does not receive any option from MULTILIB_OPTIONS. Meanwhile, multilib options from MULTILIB_OPTIONS may add suffixes (--print-multi-lib) to this base directory and find compatible library variants there. However, for LoongArch, we do not want such a "toplevel" library installation since the default ABI may change. We expect all multilib variants of libraries to be installed to their designated ABI-specific subdirs (e.g. base/lp64d) of the GCC libdir, so that the default ABI can be configured arbitrarily (with --with-abi) while the gcc libdir layout stays consistent. This could be helpful for the distribution packaging of GCC libraries. This patch achieves this by overriding ${with_multisubdir} of the "toplevel" library and disabling the duplicate "multilib" variant (which exists because LA's driver always generates a normalized "-mabi=" option from self_spec even if it is not given on the command line, causing the semantics of "toplevel" library to be duplicate with a non-toplevel one). Other architectures stay unaffected as long as they do not override ${with_multisubdir} in config-ml.in. ChangeLog: * config-ml.in: add loongarch support. Allow overriding toplevel multisubdir. libgcc/ChangeLog: * config/loongarch/t-loongarch: make symlinks of toplevel libgcc.a under gcc/ for passing regression tests. --- config-ml.in | 39 ++++++++++++++++++++++++++++- libgcc/config/loongarch/t-loongarch | 16 ++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/config-ml.in b/config-ml.in index 68854a4f16c..914cafb4b50 100644 --- a/config-ml.in +++ b/config-ml.in @@ -383,6 +383,18 @@ mips*-*-*) done fi ;; +loongarch*-*-*) + old_multidirs="${multidirs}" + multidirs="" + for x in ${old_multidirs}; do + case "$x" in + `${CC-gcc} --print-multi-directory`) : ;; + *) multidirs="${multidirs} ${x}" ;; + esac + done + + with_multisubdir=`${CC-gcc} --print-multi-directory` + ;; msp430-*-*) if [ x$enable_no_exceptions = xno ] then @@ -509,7 +521,7 @@ multi-do: compiler="$(CC)"; \ for i in `$${compiler} --print-multi-lib 2>/dev/null`; do \ dir=`echo $$i | sed -e 's/;.*$$//'`; \ - if [ "$${dir}" = "." ]; then \ + if [ "$${dir}" = "." ] || [ "/$${dir}" = "$(MULTISUBDIR)" ]; then \ true; \ else \ if [ -d ../$${dir}/$${lib} ]; then \ @@ -595,6 +607,12 @@ if [ -z "${with_multisubdir}" ]; then ml_subdir= ml_builddotdot= : # ml_srcdotdot= # already set +elif [ "${ml_toplevel_p}" = yes ]; then + : # When ml_* is set by ${host}. + ml_subdir="/${with_multisubdir}" + ml_builddotdot= + ml_builddotdot_link=`echo ${with_multisubdir} | sed -e 's:[^/][^/]*:..:g'`/ + : # ml_srcdotdot= # already set else ml_subdir="/${with_multisubdir}" # The '[^/][^/]*' appears that way to work around a SunOS sed bug. @@ -654,6 +672,25 @@ mv Makefile.tem ${Makefile} if [ "${ml_toplevel_p}" = yes ]; then +# If multisubdir is set on the top level, create a symbolic link +# to cope with in-tree regression tests (see dejagnu: libgloss.exp). + +if [ -n "${with_multisubdir}" ]; then + if [ "${ml_verbose}" = --verbose ]; then + echo "Creating multilib link (${with_multisubdir}) for the default library." + echo "pwd: `${PWDCMD-pwd}`" + fi + + ml_origdir=`${PWDCMD-pwd}` + ml_libdir=`echo "$ml_origdir" | sed -e 's,^.*/,,'` + # cd to top-level-build-dir/${with_target_subdir} + cd .. + + mkdir -p "${with_multisubdir}" + ln -sf "${ml_builddotdot_link}${ml_libdir}" "${with_multisubdir}/" + cd "${ml_origdir}" +fi + # We must freshly configure each subdirectory. This bit of code is # actually partially stolen from the main configure script. FIXME. diff --git a/libgcc/config/loongarch/t-loongarch b/libgcc/config/loongarch/t-loongarch index 2a7dbf6ca83..791a8c52f24 100644 --- a/libgcc/config/loongarch/t-loongarch +++ b/libgcc/config/loongarch/t-loongarch @@ -5,3 +5,19 @@ softfp_int_modes := si di softfp_extensions := softfp_truncations := softfp_exclude_libgcc2 := n + +# Since we employ a symmetric multilib layout, i.e. the default lib +# always gets installed to its ${multisubdir} (see config-ml.in), +# we need to copy it (again) into the GCC directory +# (without the multilib suffix) in order to keep some regression +# tests working (libstdc++), because "too many things knows +# about the layout of the build tree" for now (libgcc/Makefile.in). + +# If we are on the top level (default library), +# copy libgcc into gcc build directory. +ifneq ($(MULTIDO),true) +all: install-default-lib +.PHONY: install-default-lib +install-default-lib: libgcc.a + -$(LN_S) .$(MULTISUBDIR)/libgcc.a $(gcc_objdir)/libgcc.a +endif From patchwork Mon Aug 14 03:57:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yang Yujie X-Patchwork-Id: 1820834 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RPLGG0xtFz1yfS for ; Mon, 14 Aug 2023 13:57:58 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 27DA53854831 for ; Mon, 14 Aug 2023 03:57:56 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 2F5523858CDA for ; Mon, 14 Aug 2023 03:57:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2F5523858CDA Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [192.168.100.1]) by gateway (Coremail) with SMTP id _____8AxlPAoptlk+OUXAA--.49473S3; Mon, 14 Aug 2023 11:57:28 +0800 (CST) Received: from localhost.localdomain (unknown [192.168.100.1]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxTs8jptlkPVFZAA--.25099S3; Mon, 14 Aug 2023 11:57:25 +0800 (CST) From: Yang Yujie To: gcc-patches@gcc.gnu.org Cc: xry111@xry111.site, xuchenghua@loongson.cn, panchenghui@loongson.cn, chenglulu@loongson.cn, Yang Yujie Subject: [PATCH v1 2/6] LoongArch: improved target configuration interface Date: Mon, 14 Aug 2023 11:57:03 +0800 Message-Id: <20230814035707.11272-2-yangyujie@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20230814035707.11272-1-yangyujie@loongson.cn> References: <20230814035707.11272-1-yangyujie@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxTs8jptlkPVFZAA--.25099S3 X-CM-SenderInfo: 51dqw5pxmlvqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBj9fXoWDKFW3WryrXw4rGr4xur1UXFc_yoWfuF43Ko WSyFy3Ww1xGrWFg3s8twnIqrWDtr1vyr47Aa9ruw4UGFn3XFn8Xry8C3WrZFy3XrZ3GrWD Aa4jga9rZas7JFnxl-sFpf9Il3svdjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUY17kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUGVWUXwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI 0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUGVWUXwAv7VC2z280 aVAFwI0_Gr0_Cr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28Icx kI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2Iq xVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42 IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY 6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aV CY1x0267AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjxU2ID7UUUUU X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" The configure script and the GCC driver are updated so that it is easier to customize and control GCC builds for targeting different LoongArch implementations. * Support options for LoongArch SIMD extensions: new configure options --with-simd={none,lsx,lasx}; new driver options -m[no]-l[a]sx / -msimd={none,lsx,lasx}. * Mark some LoongArch-specific "flags" with overlapping state-changing semantics as "driver deferred" so that they could be processed in the order they appear in the GCC driver. In this way, the final result can be canonicalized into "parameters" (options with "=") for reliable use in specs rules or by the compiler proper. * Enforce the priority of configuration paths (for ={fpu,tune,simd}): -m > -march-implied > --with- > --with-arch-implied. * Allow the user to control the compiler options used when building GCC libraries for each multilib variant via --with-multilib-list and --with-multilib-default. This could become more useful when we have 32-bit support later. Example 1: the following configure option --with-multilib-list=lp64d/la464/mno-strict-align/msimd=lsx,lp64s/mfpu=32 | | | | -mabi=ABI -march=ARCH a list of other options (mandatory) (optional) (optional) builds two sets of libraries: lp64d ABI (the default ABI if no --with-abi is given, built with "-march=la464 -mno-strict-align") lp64s ABI (built with "-march=abi-default -mfpu=32") Example 2: the following 3 configure options --with-arch=loongarch64 --with-multilib-list=lp64d,lp64f,lp64s/la464 --with-multilib-default=fixed/mno-strict-align/mfpu=64 | | | -march=ARCH a list of other options (optional) (optional) is equivalent to (in terms of building libraries): --with-multilib-list=\ lp64d/loongarch64/mno-strict-align/mfpu=64,\ lp64f/loongarch64/mno-strict-align/mfpu=64,\ lp64s/la464 Note: 1. the GCC driver and compiler proper does not support "-march=fixed". "fixed" that appear here acts as a placeholder for "use whatever ARCH in --with-arch=ARCH" (or the default value of --with-arch=ARCH if --with-arch is not explicitly configured). 2. if the ARCH part is omitted, "-march=abi-default" is used for building all library variants, which practically means enabling the minimal ISA features that can support the given ABI. gcc/ChangeLog: * gcc/config.gcc: Add new configuration options --with-arch and --with-multilib-default; slightly adjust the handling of configure-time defaults. * gcc/config/loongarch/genopts/loongarch-strings: Add keyword "abi-default" as in "-march=abi-default". * gcc/config/loongarch/loongarch-str.h: Likewise * gcc/config/loongarch/genopts/loongarch.opt.in: Mark flags as "driver deferred" so that a state machine could be applied. * gcc/config/loongarch/loongarch.opt: Likewise. * gcc/config/loongarch/loongarch-cpu.cc: refactor code for the new internal representation of -march=native. * gcc/config/loongarch/loongarch-cpu.h: Likewise. * gcc/config/loongarch/loongarch-c.cc: Likewise. * gcc/config/loongarch/loongarch-def.c: add SIMD attributes for struct loongarch_target. * gcc/config/loongarch/loongarch-def.h: Likewise. * gcc/config/loongarch/loongarch-driver.cc: Implement a state machine to canonicalize flags into parameters. * gcc/config/loongarch/loongarch-driver.h: Likewise. * gcc/config/loongarch/loongarch-opts.cc: Use the new internal target representation as input as well as the output. * gcc/config/loongarch/loongarch-opts.h: Likewise. * gcc/config/loongarch/loongarch.cc: Likewise * gcc/config/loongarch/t-linux: Support building GCC libraries with customized compiler options using specs. * gcc/doc/invoke.texi: document -m[no-]l[a]sx and -msimd=. * gcc/doc/install.texi: document --with-multilib-default and --with-multilib list. --- gcc/config.gcc | 253 +++++++++---- .../loongarch/genopts/loongarch-strings | 8 +- gcc/config/loongarch/genopts/loongarch.opt.in | 62 +-- gcc/config/loongarch/la464.md | 32 +- gcc/config/loongarch/loongarch-c.cc | 4 +- gcc/config/loongarch/loongarch-cpu.cc | 260 ++++++++----- gcc/config/loongarch/loongarch-cpu.h | 3 +- gcc/config/loongarch/loongarch-def.c | 55 ++- gcc/config/loongarch/loongarch-def.h | 57 +-- gcc/config/loongarch/loongarch-driver.cc | 205 +++++----- gcc/config/loongarch/loongarch-driver.h | 40 +- gcc/config/loongarch/loongarch-opts.cc | 352 +++++++++++++----- gcc/config/loongarch/loongarch-opts.h | 61 +-- gcc/config/loongarch/loongarch-str.h | 7 +- gcc/config/loongarch/loongarch.cc | 87 +++-- gcc/config/loongarch/loongarch.opt | 60 +-- gcc/config/loongarch/t-linux | 25 +- gcc/doc/install.texi | 44 ++- gcc/doc/invoke.texi | 29 +- 19 files changed, 1058 insertions(+), 586 deletions(-) diff --git a/gcc/config.gcc b/gcc/config.gcc index 415e0e1ebc5..9412f73fe35 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -4891,8 +4891,8 @@ case "${target}" in esac ;; - loongarch*-*-*) - supported_defaults="abi arch tune fpu" + loongarch*-*) + supported_defaults="abi arch tune fpu simd multilib-default" # Local variables unset \ @@ -4900,7 +4900,6 @@ case "${target}" in 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. @@ -4937,20 +4936,17 @@ case "${target}" in ;; esac + + # Perform initial sanity checks on --with-* options. case ${with_arch} in - "" | loongarch64 | la464) ;; # OK, append here. + "" | abi-default | loongarch64 | la464) ;; # OK, append here. native) if test x${host} != x${target}; then echo "--with-arch=native is illegal for cross-compiler." 1>&2 exit 1 fi ;; - "") - echo "Please set a default value for \${with_arch}" \ - "according to your target triplet \"${target}\"." 1>&2 - exit 1 - ;; *) echo "Unknown arch in --with-arch=$with_arch" 1>&2 exit 1 @@ -4985,6 +4981,25 @@ case "${target}" in ;; esac + case ${with_simd} in + "" | none) ;; + lsx | lasx) # OK, append here. + case ${with_fpu} in + 64) ;; + "") with_fpu=64 ;; + *) + echo "--with-simd=${with_simd} conflicts with --with-fpu=${with_fpu}" 1>&2 + exit 1 + ;; + esac + ;; + + *) + echo "Unknown SIMD extension in --with-simd=$with_simd" 1>&2 + exit 1 + ;; + esac + # Set default value for with_abi. case ${with_abi} in @@ -5040,9 +5055,9 @@ case "${target}" in case ${with_abi}/${with_abiext} in lp64*/base) # architectures that support lp64* ABI - arch_pattern="native|loongarch64|la464" + arch_pattern="native|abi-default|loongarch64|la464" # default architecture for lp64* ABI - arch_default="loongarch64" + arch_default="abi-default" ;; *) echo "Unsupported ABI type ${with_abi}/${with_abiext}." 1>&2 @@ -5112,32 +5127,19 @@ case "${target}" in esac - # Infer default with_tune from with_arch: pass 1 + # Check default with_tune configuration using with_arch. case ${with_arch} in - native) - tune_pattern="*" - tune_default="native" - ;; loongarch64) - tune_pattern="loongarch64|la464" - tune_default="la464" + tune_pattern="native|abi-default|loongarch64|la464" ;; *) # By default, $with_tune == $with_arch - tune_pattern="$with_arch" + tune_pattern="*" ;; esac - ## Set default value for with_tune. case ${with_tune} in - "") - if test x${tune_default} != x; then - with_tune=${tune_default} - else - with_tune=${tune_pattern} - fi - ;; - + "") ;; # OK *) if echo "${with_tune}" | grep -E "^${tune_pattern}$" > /dev/null; then : # OK @@ -5149,6 +5151,46 @@ case "${target}" in ;; esac + # Handle --with-multilib-default + if echo "${with_multilib_default}" \ + | grep -E -e '[[:space:]]' -e '//' -e '/$' -e '^/' > /dev/null 2>&1; then + echo "Invalid argument to --with-multilib-default." 1>&2 + exit 1 + fi + + if test x${with_multilib_default} = x; then + # Use -march=abi-default by default when building libraries. + with_multilib_default="/march=abi-default" + else + unset parse_state component + parse_state=arch + for component in $(echo "${with_multilib_default}" | tr '/' ' '); do + case ${parse_state},${component} in + arch,|arch,abi-default) + # ABI-default: use the ABI's default ARCH configuration for + # multilib library builds, unless otherwise specified + # in --with-multilib-list. + with_multilib_default="/march=abi-default" ;; + arch,fixed) + # Fixed: use the default gcc configuration for all multilib + # builds by default. + with_multilib_default="" ;; + arch,native|arch,loongarch64|arch,la464) # OK, append here. + with_multilib_default="/march=${component}" ;; + arch,*) + with_multilib_default="/march=abi-default" + with_multilib_default="${with_multilib_default}/${component}" ;; + opts,*) + with_multilib_default="${with_multilib_default}/${component}" ;; + esac + + if test x${parse_state} = xarch; then + parse_state=opt; + fi + done + unset parse_state component + fi + # Handle --with-multilib-list. if test x"${with_multilib_list}" = x \ || test x"${with_multilib_list}" = xno \ @@ -5171,25 +5213,21 @@ case "${target}" in # ${with_multilib_list} should not contain whitespaces, # consecutive commas or slashes. if echo "${with_multilib_list}" \ - | grep -E -e "[[:space:]]" -e '[,/][,/]' -e '[,/]$' -e '^[,/]' > /dev/null; then + | grep -E -e "[[:space:]]" -e '[,/][,/]' -e '[,/]$' -e '^[,/]' > /dev/null 2>&1; then echo "Invalid argument to --with-multilib-list." 1>&2 exit 1 fi - unset component idx elem_abi_base elem_abi_ext elem_tmp + unset component elem_abi_base elem_abi_ext elem_tmp parse_state all_abis for elem in $(echo "${with_multilib_list}" | tr ',' ' '); do - idx=0 - while true; do - idx=$((idx + 1)) - component=$(echo "${elem}" | awk -F'/' '{print $'"${idx}"'}') - - case ${idx} in - 1) - # Component 1: Base ABI type + unset elem_abi_base elem_abi_ext + parse_state="abi-base" + + for component in $(echo "${elem}" | tr '/' ' '); do + if test x${parse_state} = x"abi-base"; then + # Base ABI type case ${component} in - lp64d) elem_tmp="ABI_BASE_LP64D,";; - lp64f) elem_tmp="ABI_BASE_LP64F,";; - lp64s) elem_tmp="ABI_BASE_LP64S,";; + lp64d | lp64f | lp64s) elem_tmp="ABI_BASE_$(tr a-z A-Z <<< ${component}),";; *) echo "Unknown base ABI \"${component}\" in --with-multilib-list." 1>&2 exit 1 @@ -5198,47 +5236,101 @@ case "${target}" in loongarch_multilib_list_c="${loongarch_multilib_list_c}${elem_tmp}" loongarch_multilib_list_make="${loongarch_multilib_list_make}mabi=${component}" elem_abi_base="${component}" - ;; - 2) - # Component 2: ABI extension type + parse_state="abi-ext" + continue + fi + + if test x${parse_state} = x"abi-ext"; then + # ABI extension type case ${component} in - "" | base) - component="base" - elem_tmp="ABI_EXT_BASE," - ;; - *) - echo "Unknown ABI extension \"${component}\" in --with-multilib-list." 1>&2 - exit 1 + base) + elem_abi_ext="base" + loongarch_multilib_list_c="${loongarch_multilib_list_c}ABI_EXT_BASE," + loongarch_multilib_list_make="${loongarch_multilib_list_make}" # Add nothing for now. + parse_state="arch" + continue; ;; esac - loongarch_multilib_list_c="${loongarch_multilib_list_c}${elem_tmp}" + + # The default ABI extension is "base" if unspecified. + elem_abi_ext="base" + loongarch_multilib_list_c="${loongarch_multilib_list_c}ABI_EXT_BASE," loongarch_multilib_list_make="${loongarch_multilib_list_make}" # Add nothing for now. - elem_abi_ext="${component}" - ;; + parse_state="arch" + fi - *) - # Component 3 and on: optional stuff + if test x${parse_state} = x"arch"; then + # -march option case ${component} in - "") - # End of component list. - break + native | abi-default | loongarch64 | la464) # OK, append here. + # Append -march spec for each multilib variant. + loongarch_multilib_list_make="${loongarch_multilib_list_make}/march=${component}" + parse_state="opts" + continue + ;; + + default) + # "/default" is equivalent to --with-multilib-default=fixed + parse_state="opts" + continue ;; + esac + + # If ARCH is unspecified for this multilib variant, use ${with_multllib_default}. + loongarch_multilib_list_make="${loongarch_multilib_list_make}${with_multilib_default}" + parse_state="opts" + fi + + if test x${parse_state} = x"opts"; then + # Other compiler options for building libraries. + # (no static sanity check performed) + case ${component} in *) - echo "Unknown ABI \"${elem}\" in --with-multilib-list." 1>&2 - exit 1 + # Append other components as additional build options + # (without the prepending dash). + # Their validity should be examined by the compiler. + loongarch_multilib_list_make="${loongarch_multilib_list_make}/${component}" ;; esac - ;; - esac + fi done + case ${parse_state} in + "abi-ext") + elem_abi_ext="base" + loongarch_multilib_list_c="${loongarch_multilib_list_c}ABI_EXT_BASE," + loongarch_multilib_list_make="${loongarch_multilib_list_make}" # Add nothing for now. + loongarch_multilib_list_make="${loongarch_multilib_list_make}${with_multilib_default}" + ;; + "arch") + # If ARCH is unspecified for this multilib variant, use ${with_multllib_default}. + loongarch_multilib_list_make="${loongarch_multilib_list_make}${with_multilib_default}" + ;; + "opts") + : + ;; + esac + + # Check for repeated configuration of the same multilib variant. + if echo "${elem_abi_base}/${elem_abi_ext}" \ + | grep -E "^(${all_abis%|})$" >/dev/null 2>&1; then + echo "Repeated multilib config of \"${elem_abi_base}/${elem_abi_ext}\" in --with-multilib-list." + exit 1 + fi + all_abis="${all_abis}${elem_abi_base}/${elem_abi_ext}|" + + + # Check if the default ABI configuration of the GCC binary + # is included in the enabled multilib variants. if test x${elem_abi_base} = x${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 + unset component elem_abi_base elem_abi_ext elem_tmp parse_state all_abis + # Check if the default ABI combination is in the default list. if test x${loongarch_multilib_list_sane} = xno; then @@ -5739,34 +5831,37 @@ case ${target} in # Let --with- flags initialize the enum variables from loongarch.opt. # See macro definitions from loongarch-opts.h and loongarch-cpu.h. - case ${with_arch} in - native) tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_NATIVE" ;; - la464) tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_LA464" ;; - loongarch64) tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_LOONGARCH64" ;; - esac - case ${with_tune} in - native) tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_NATIVE" ;; - la464) tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_LA464" ;; - loongarch64) tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_LOONGARCH64" ;; - esac + # Architecture + tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_$(echo ${with_arch} | tr a-z- A-Z_)" - case ${with_abi} in - lp64d) tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_LP64D" ;; - lp64f) tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_LP64F" ;; - lp64s) tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_LP64S" ;; - esac + # Base ABI type + tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_$(echo ${with_abi} | tr a-z- A-Z_)" + # ABI Extension case ${with_abiext} in base) tm_defines="${tm_defines} DEFAULT_ABI_EXT=ABI_EXT_BASE" ;; esac + # Microarchitecture + if test x${with_tune} != x; then + tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_$(echo ${with_tune} | tr a-z- A-Z_)" + fi + + # FPU adjustment case ${with_fpu} in - none) tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_NOFPU" ;; + none) tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_NONE" ;; 32) tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_FPU32" ;; 64) tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_FPU64" ;; esac + # SIMD extensions + case ${with_simd} in + none) tm_defines="$tm_defines DEFAULT_ISA_EXT_SIMD=ISA_EXT_NONE" ;; + lsx) tm_defines="$tm_defines DEFAULT_ISA_EXT_SIMD=ISA_EXT_SIMD_LSX" ;; + lasx) tm_defines="$tm_defines DEFAULT_ISA_EXT_SIMD=ISA_EXT_SIMD_LASX" ;; + esac + tmake_file="loongarch/t-loongarch $tmake_file" ;; diff --git a/gcc/config/loongarch/genopts/loongarch-strings b/gcc/config/loongarch/genopts/loongarch-strings index a40998ead97..a536be5e708 100644 --- a/gcc/config/loongarch/genopts/loongarch-strings +++ b/gcc/config/loongarch/genopts/loongarch-strings @@ -23,6 +23,7 @@ OPTSTR_ARCH arch OPTSTR_TUNE tune STR_CPU_NATIVE native +STR_CPU_ABI_DEFAULT abi-default STR_CPU_LOONGARCH64 loongarch64 STR_CPU_LA464 la464 @@ -31,7 +32,7 @@ STR_ISA_BASE_LA64V100 la64 # -mfpu OPTSTR_ISA_EXT_FPU fpu -STR_ISA_EXT_NOFPU none +STR_NONE none STR_ISA_EXT_FPU0 0 STR_ISA_EXT_FPU32 32 STR_ISA_EXT_FPU64 64 @@ -40,6 +41,11 @@ OPTSTR_SOFT_FLOAT soft-float OPTSTR_SINGLE_FLOAT single-float OPTSTR_DOUBLE_FLOAT double-float +# SIMD extensions +OPTSTR_ISA_EXT_SIMD simd +STR_ISA_EXT_LSX lsx +STR_ISA_EXT_LASX lasx + # -mabi= OPTSTR_ABI_BASE abi STR_ABI_BASE_LP64D lp64d diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in index 4b9b4ac273e..f3567b27935 100644 --- a/gcc/config/loongarch/genopts/loongarch.opt.in +++ b/gcc/config/loongarch/genopts/loongarch.opt.in @@ -17,22 +17,12 @@ ; . ; -; Variables (macros) that should be exported by loongarch.opt: -; la_opt_switches, -; la_opt_abi_base, la_opt_abi_ext, -; la_opt_cpu_arch, la_opt_cpu_tune, -; la_opt_fpu, -; la_cmodel. - HeaderInclude config/loongarch/loongarch-opts.h HeaderInclude config/loongarch/loongarch-str.h -Variable -HOST_WIDE_INT la_opt_switches = 0 - ; ISA related options ;; Base ISA Enum @@ -42,14 +32,13 @@ Basic ISAs of LoongArch: EnumValue Enum(isa_base) String(@@STR_ISA_BASE_LA64V100@@) Value(ISA_BASE_LA64V100) - ;; ISA extensions / adjustments Enum Name(isa_ext_fpu) Type(int) FPU types of LoongArch: EnumValue -Enum(isa_ext_fpu) String(@@STR_ISA_EXT_NOFPU@@) Value(ISA_EXT_NOFPU) +Enum(isa_ext_fpu) String(@@STR_NONE@@) Value(ISA_EXT_NONE) EnumValue Enum(isa_ext_fpu) String(@@STR_ISA_EXT_FPU32@@) Value(ISA_EXT_FPU32) @@ -58,24 +47,48 @@ EnumValue Enum(isa_ext_fpu) String(@@STR_ISA_EXT_FPU64@@) Value(ISA_EXT_FPU64) m@@OPTSTR_ISA_EXT_FPU@@= -Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPTION_NOT_SEEN) +Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPT_UNSET) -m@@OPTSTR_ISA_EXT_FPU@@=FPU Generate code for the given FPU. m@@OPTSTR_ISA_EXT_FPU@@=@@STR_ISA_EXT_FPU0@@ -Target RejectNegative Alias(m@@OPTSTR_ISA_EXT_FPU@@=,@@STR_ISA_EXT_NOFPU@@) +Target RejectNegative Alias(m@@OPTSTR_ISA_EXT_FPU@@=,@@STR_NONE@@) m@@OPTSTR_SOFT_FLOAT@@ -Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_SOFTF) Negative(m@@OPTSTR_SINGLE_FLOAT@@) +Target Driver Defer Var(la_deferred_options) RejectNegative Negative(m@@OPTSTR_SINGLE_FLOAT@@) Prevent the use of all hardware floating-point instructions. m@@OPTSTR_SINGLE_FLOAT@@ -Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F32) Negative(m@@OPTSTR_DOUBLE_FLOAT@@) +Target Driver Defer Var(la_deferred_options) RejectNegative Negative(m@@OPTSTR_DOUBLE_FLOAT@@) Restrict the use of hardware floating-point instructions to 32-bit operations. m@@OPTSTR_DOUBLE_FLOAT@@ -Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F64) Negative(m@@OPTSTR_SOFT_FLOAT@@) +Target Driver Defer Var(la_deferred_options) RejectNegative Negative(m@@OPTSTR_SOFT_FLOAT@@) Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations. +Enum +Name(isa_ext_simd) Type(int) +SIMD extension levels of LoongArch: + +EnumValue +Enum(isa_ext_simd) String(@@STR_NONE@@) Value(ISA_EXT_NONE) + +EnumValue +Enum(isa_ext_simd) String(@@STR_ISA_EXT_LSX@@) Value(ISA_EXT_SIMD_LSX) + +EnumValue +Enum(isa_ext_simd) String(@@STR_ISA_EXT_LASX@@) Value(ISA_EXT_SIMD_LASX) + +m@@OPTSTR_ISA_EXT_SIMD@@= +Target RejectNegative Joined ToLower Enum(isa_ext_simd) Var(la_opt_simd) Init(M_OPT_UNSET) +-m@@OPTSTR_ISA_EXT_SIMD@@=SIMD Generate code for the given SIMD extension. + +m@@STR_ISA_EXT_LSX@@ +Target Driver Defer Var(la_deferred_options) +Enable LoongArch SIMD Extension (LSX, 128-bit). + +m@@STR_ISA_EXT_LASX@@ +Target Driver Defer Var(la_deferred_options) +Enable LoongArch Advanced SIMD Extension (LASX, 256-bit). ;; Base target models (implies ISA & tune parameters) Enum @@ -85,6 +98,9 @@ LoongArch CPU types: EnumValue Enum(cpu_type) String(@@STR_CPU_NATIVE@@) Value(CPU_NATIVE) +EnumValue +Enum(cpu_type) String(@@STR_CPU_ABI_DEFAULT@@) Value(CPU_ABI_DEFAULT) + EnumValue Enum(cpu_type) String(@@STR_CPU_LOONGARCH64@@) Value(CPU_LOONGARCH64) @@ -92,11 +108,11 @@ EnumValue Enum(cpu_type) String(@@STR_CPU_LA464@@) Value(CPU_LA464) m@@OPTSTR_ARCH@@= -Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPTION_NOT_SEEN) +Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPT_UNSET) -m@@OPTSTR_ARCH@@=PROCESSOR Generate code for the given PROCESSOR ISA. m@@OPTSTR_TUNE@@= -Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPTION_NOT_SEEN) +Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPT_UNSET) -m@@OPTSTR_TUNE@@=PROCESSOR Generate optimized code for PROCESSOR. @@ -118,13 +134,13 @@ EnumValue Enum(abi_base) String(@@STR_ABI_BASE_LP64S@@) Value(ABI_BASE_LP64S) m@@OPTSTR_ABI_BASE@@= -Target RejectNegative Joined ToLower Enum(abi_base) Var(la_opt_abi_base) Init(M_OPTION_NOT_SEEN) +Target RejectNegative Joined ToLower Enum(abi_base) Var(la_opt_abi_base) Init(M_OPT_UNSET) -m@@OPTSTR_ABI_BASE@@=BASEABI Generate code that conforms to the given BASEABI. + ;; ABI Extension Variable -int la_opt_abi_ext = M_OPTION_NOT_SEEN - +int la_opt_abi_ext = M_OPT_UNSET mbranch-cost= Target RejectNegative Joined UInteger Var(loongarch_branch_cost) @@ -182,7 +198,7 @@ EnumValue Enum(cmodel) String(@@STR_CMODEL_EXTREME@@) Value(CMODEL_EXTREME) mcmodel= -Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(CMODEL_NORMAL) +Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(M_OPT_UNSET) Specify the code model. mdirect-extern-access diff --git a/gcc/config/loongarch/la464.md b/gcc/config/loongarch/la464.md index 541040fdfa8..3b4d14f0b3c 100644 --- a/gcc/config/loongarch/la464.md +++ b/gcc/config/loongarch/la464.md @@ -43,88 +43,88 @@ ;; Describe instruction reservations. (define_insn_reservation "la464_arith" 1 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "arith,clz,const,logical, move,nop,shift,signext,slt")) "la464_alu1 | la464_alu2") (define_insn_reservation "la464_branch" 1 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "branch,jump,call,condmove,trap")) "la464_alu1 | la464_alu2") (define_insn_reservation "la464_imul" 7 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "imul")) "la464_alu1 | la464_alu2") (define_insn_reservation "la464_idiv_si" 12 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (and (eq_attr "type" "idiv") (eq_attr "mode" "SI"))) "la464_alu1 | la464_alu2") (define_insn_reservation "la464_idiv_di" 25 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (and (eq_attr "type" "idiv") (eq_attr "mode" "DI"))) "la464_alu1 | la464_alu2") (define_insn_reservation "la464_load" 4 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "load")) "la464_mem1 | la464_mem2") (define_insn_reservation "la464_gpr_fp" 16 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "mftg,mgtf")) "la464_mem1") (define_insn_reservation "la464_fpload" 4 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "fpload")) "la464_mem1 | la464_mem2") (define_insn_reservation "la464_prefetch" 0 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "prefetch,prefetchx")) "la464_mem1 | la464_mem2") (define_insn_reservation "la464_store" 0 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "store,fpstore,fpidxstore")) "la464_mem1 | la464_mem2") (define_insn_reservation "la464_fadd" 4 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "fadd,fmul,fmadd")) "la464_falu1 | la464_falu2") (define_insn_reservation "la464_fcmp" 2 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "fabs,fcmp,fmove,fneg")) "la464_falu1 | la464_falu2") (define_insn_reservation "la464_fcvt" 4 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "fcvt")) "la464_falu1 | la464_falu2") (define_insn_reservation "la464_fdiv_sf" 12 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (and (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt") (eq_attr "mode" "SF"))) "la464_falu1 | la464_falu2") (define_insn_reservation "la464_fdiv_df" 19 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (and (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt") (eq_attr "mode" "DF"))) "la464_falu1 | la464_falu2") ;; Force single-dispatch for unknown or multi. (define_insn_reservation "la464_unknown" 1 - (and (match_test "TARGET_TUNE_LA464") + (and (match_test "TARGET_uARCH_LA464") (eq_attr "type" "unknown,multi,atomic,syncloop")) "la464_alu1 + la464_alu2 + la464_falu1 + la464_falu2 + la464_mem1 + la464_mem2") diff --git a/gcc/config/loongarch/loongarch-c.cc b/gcc/config/loongarch/loongarch-c.cc index 67911b78f28..660c68f0e06 100644 --- a/gcc/config/loongarch/loongarch-c.cc +++ b/gcc/config/loongarch/loongarch-c.cc @@ -61,8 +61,8 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile) builtin_assert ("cpu=loongarch"); builtin_define ("__loongarch__"); - LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_ARCH", LARCH_ACTUAL_ARCH); - LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_TUNE", LARCH_ACTUAL_TUNE); + LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_ARCH", la_target.cpu_arch); + LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_TUNE", la_target.cpu_tune); /* Base architecture / ABI. */ if (TARGET_64BIT) diff --git a/gcc/config/loongarch/loongarch-cpu.cc b/gcc/config/loongarch/loongarch-cpu.cc index 34905f3de30..f76efd7c66f 100644 --- a/gcc/config/loongarch/loongarch-cpu.cc +++ b/gcc/config/loongarch/loongarch-cpu.cc @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "diagnostic-core.h" +#include "loongarch-def.h" #include "loongarch-opts.h" #include "loongarch-cpu.h" #include "loongarch-str.h" @@ -80,127 +81,188 @@ get_native_prid_str (void) } /* Fill property tables for CPU_NATIVE. */ -unsigned int -fill_native_cpu_config (int p_arch_native, int p_tune_native) +void +fill_native_cpu_config (struct loongarch_target *tgt) { - int ret_cpu_type; + int arch_native_p = tgt->cpu_arch == CPU_NATIVE; + int tune_native_p = tgt->cpu_tune == CPU_NATIVE; + int native_cpu_type = CPU_NATIVE; /* Nothing needs to be done unless "-march/tune=native" is given or implied. */ - if (!(p_arch_native || p_tune_native)) - return CPU_NATIVE; + if (!arch_native_p && !tune_native_p) + return; /* Fill cpucfg_cache with the "cpucfg" instruction. */ cache_cpucfg (); - - /* Fill: loongarch_cpu_default_isa[CPU_NATIVE].base - With: base architecture (ARCH) - At: cpucfg_words[1][1:0] */ - - #define NATIVE_BASE_ISA (loongarch_cpu_default_isa[CPU_NATIVE].base) - switch (cpucfg_cache[1] & 0x3) - { - case 0x02: - NATIVE_BASE_ISA = ISA_BASE_LA64V100; - break; - - default: - if (p_arch_native) - fatal_error (UNKNOWN_LOCATION, - "unknown base architecture %<0x%x%>, %qs failed", - (unsigned int) (cpucfg_cache[1] & 0x3), - "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE); - } - - /* Fill: loongarch_cpu_default_isa[CPU_NATIVE].fpu - With: FPU type (FP, FP_SP, FP_DP) - At: cpucfg_words[2][2:0] */ - - #define NATIVE_FPU (loongarch_cpu_default_isa[CPU_NATIVE].fpu) - switch (cpucfg_cache[2] & 0x7) - { - case 0x07: - NATIVE_FPU = ISA_EXT_FPU64; - break; - - case 0x03: - NATIVE_FPU = ISA_EXT_FPU32; - break; - - case 0x00: - NATIVE_FPU = ISA_EXT_NOFPU; - break; - - default: - if (p_arch_native) - fatal_error (UNKNOWN_LOCATION, - "unknown FPU type %<0x%x%>, %qs failed", - (unsigned int) (cpucfg_cache[2] & 0x7), - "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE); - } - - /* Fill: loongarch_cpu_cache[CPU_NATIVE] - With: cache size info - At: cpucfg_words[16:20][31:0] */ - - int l1d_present = 0, l1u_present = 0; - int l2d_present = 0; - uint32_t l1_szword, l2_szword; - - l1u_present |= cpucfg_cache[16] & 3; /* bit[1:0]: unified l1 cache */ - l1d_present |= cpucfg_cache[16] & 4; /* bit[2:2]: l1 dcache */ - l1_szword = l1d_present ? 18 : (l1u_present ? 17 : 0); - l1_szword = l1_szword ? cpucfg_cache[l1_szword]: 0; - - l2d_present |= cpucfg_cache[16] & 24; /* bit[4:3]: unified l2 cache */ - l2d_present |= cpucfg_cache[16] & 128; /* bit[7:7]: l2 dcache */ - l2_szword = l2d_present ? cpucfg_cache[19]: 0; - - loongarch_cpu_cache[CPU_NATIVE].l1d_line_size - = 1 << ((l1_szword & 0x7f000000) >> 24); /* bit[30:24]: log2(linesize) */ - - loongarch_cpu_cache[CPU_NATIVE].l1d_size - = (1 << ((l1_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */ - * ((l1_szword & 0x0000ffff) + 1) /* bit[15:0]: sets - 1 */ - * (1 << ((l1_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(linesize) */ - >> 10; /* in kilobytes */ - - loongarch_cpu_cache[CPU_NATIVE].l2d_size - = (1 << ((l2_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */ - * ((l2_szword & 0x0000ffff) + 1) /* bit[15:0]: sets - 1 */ - * (1 << ((l2_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(linesize) */ - >> 10; /* in kilobytes */ - - /* Fill: ret_cpu_type + /* Fill: tgt->cpu_arch | tgt->cpu_tune With: processor ID (PRID) At: cpucfg_words[0][31:0] */ switch (cpucfg_cache[0] & 0x00ffff00) { case 0x0014c000: /* LA464 */ - ret_cpu_type = CPU_LA464; + native_cpu_type = CPU_LA464; break; default: - /* Unknown PRID. This is generally harmless as long as - the properties above can be obtained via "cpucfg". */ - if (p_tune_native) + /* Unknown PRID. */ + if (tune_native_p) inform (UNKNOWN_LOCATION, "unknown processor ID %<0x%x%>, " "some tuning parameters will fall back to default", cpucfg_cache[0]); break; } - /* Properties that cannot be looked up directly using cpucfg. */ - loongarch_cpu_issue_rate[CPU_NATIVE] - = loongarch_cpu_issue_rate[ret_cpu_type]; - - loongarch_cpu_multipass_dfa_lookahead[CPU_NATIVE] - = loongarch_cpu_multipass_dfa_lookahead[ret_cpu_type]; - - loongarch_cpu_rtx_cost_data[CPU_NATIVE] - = loongarch_cpu_rtx_cost_data[ret_cpu_type]; + /* if -march=native */ + if (arch_native_p) + { + int tmp; + tgt->cpu_arch = native_cpu_type; + + /* Fill: loongarch_cpu_default_isa[tgt->cpu_arch].base + With: base architecture (ARCH) + At: cpucfg_words[1][1:0] */ + + #define PRESET_ARCH (loongarch_cpu_default_isa[tgt->cpu_arch].base) + switch (cpucfg_cache[1] & 0x3) + { + case 0x02: + tmp = ISA_BASE_LA64V100; + break; + + default: + fatal_error (UNKNOWN_LOCATION, + "unknown native base architecture %<0x%x%>, %qs failed", + (unsigned int) (cpucfg_cache[1] & 0x3), + "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE); + } + + /* Check consistency with PRID presets. */ + if (native_cpu_type != CPU_NATIVE && tmp != PRESET_ARCH) + warning (0, "base architecture %qs differs from PRID preset %qs", + loongarch_isa_base_strings[tmp], + loongarch_isa_base_strings[PRESET_ARCH]); + + /* Use the native value anyways. */ + PRESET_ARCH = tmp; + + /* Fill: loongarch_cpu_default_isa[tgt->cpu_arch].fpu + With: FPU type (FP, FP_SP, FP_DP) + At: cpucfg_words[2][2:0] */ + + #define PRESET_FPU (loongarch_cpu_default_isa[tgt->cpu_arch].fpu) + switch (cpucfg_cache[2] & 0x7) + { + case 0x07: + tmp = ISA_EXT_FPU64; + break; + + case 0x03: + tmp = ISA_EXT_FPU32; + break; + + case 0x00: + tmp = ISA_EXT_NONE; + break; + + default: + fatal_error (UNKNOWN_LOCATION, + "unknown native FPU type %<0x%x%>, %qs failed", + (unsigned int) (cpucfg_cache[2] & 0x7), + "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE); + } + + /* Check consistency with PRID presets. */ + if (native_cpu_type != CPU_NATIVE && tmp != PRESET_FPU) + warning (0, "floating-point unit %qs differs from PRID preset %qs", + loongarch_isa_ext_strings[tmp], + loongarch_isa_ext_strings[PRESET_FPU]); + + /* Use the native value anyways. */ + PRESET_FPU = tmp; + + + /* Fill: loongarch_cpu_default_isa[CPU_NATIVE].simd + With: SIMD extension type (LSX, LASX) + At: cpucfg_words[2][7:6] */ + + #define PRESET_SIMD (loongarch_cpu_default_isa[tgt->cpu_arch].simd) + switch (cpucfg_cache[2] & 0xc0) + { + case 0xc0: + tmp = ISA_EXT_SIMD_LASX; + break; + + case 0x40: + tmp = ISA_EXT_SIMD_LSX; + break; + + case 0x80: + warning (0, "unknown SIMD extension " + "(%qs disabled while %qs is enabled), disabling SIMD", + loongarch_isa_ext_strings[ISA_EXT_SIMD_LSX], + loongarch_isa_ext_strings[ISA_EXT_SIMD_LASX]); + + case 0x00: + tmp = 0; + break; + } + + /* Check consistency with PRID presets. */ + /* + if (native_cpu_type != CPU_NATIVE && tmp != PRESET_SIMD) + warning (0, "SIMD extension %qs differs from PRID preset %qs", + loongarch_isa_ext_strings[tmp], + loongarch_isa_ext_strings[PRESET_SIMD]); + */ + + /* Use the native value anyways. */ + PRESET_SIMD = tmp; + } - return ret_cpu_type; + if (tune_native_p) + { + tgt->cpu_tune = native_cpu_type; + + /* Fill: loongarch_cpu_cache[tgt->cpu_tune] + With: cache size info + At: cpucfg_words[16:20][31:0] */ + + #define PRESET_CACHE (loongarch_cpu_cache[tgt->cpu_tune]) + struct loongarch_cache native_cache; + int l1d_present = 0, l1u_present = 0; + int l2d_present = 0; + uint32_t l1_szword, l2_szword; + + l1u_present |= cpucfg_cache[16] & 3; /* bit[1:0]: unified l1 */ + l1d_present |= cpucfg_cache[16] & 4; /* bit[2:2]: l1d */ + l1_szword = l1d_present ? 18 : (l1u_present ? 17 : 0); + l1_szword = l1_szword ? cpucfg_cache[l1_szword]: 0; + + l2d_present |= cpucfg_cache[16] & 24; /* bit[4:3]: unified l2 */ + l2d_present |= cpucfg_cache[16] & 128; /* bit[7:7]: l2d */ + l2_szword = l2d_present ? cpucfg_cache[19]: 0; + + native_cache.l1d_line_size + = 1 << ((l1_szword & 0x7f000000) >> 24); /* bit[30:24]: log2(line) */ + + native_cache.l1d_size + = (1 << ((l1_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */ + * ((l1_szword & 0x0000ffff) + 1) /* bit[15:0]: sets - 1 */ + * (1 << ((l1_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(line) */ + >> 10; /* in kibibytes */ + + native_cache.l2d_size + = (1 << ((l2_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */ + * ((l2_szword & 0x0000ffff) + 1) /* bit[15:0]: sets - 1 */ + * (1 << ((l2_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(linesz) */ + >> 10; /* in kibibytes */ + + /* Use the native value anyways. */ + PRESET_CACHE.l1d_line_size = native_cache.l1d_line_size; + PRESET_CACHE.l1d_size = native_cache.l1d_size; + PRESET_CACHE.l2d_size = native_cache.l2d_size; + } } diff --git a/gcc/config/loongarch/loongarch-cpu.h b/gcc/config/loongarch/loongarch-cpu.h index 57ad8456ffa..28618f3cf6c 100644 --- a/gcc/config/loongarch/loongarch-cpu.h +++ b/gcc/config/loongarch/loongarch-cpu.h @@ -21,9 +21,10 @@ along with GCC; see the file COPYING3. If not see #define LOONGARCH_CPU_H #include "system.h" +#include "loongarch-def.h" void cache_cpucfg (void); -unsigned int fill_native_cpu_config (int p_arch_native, int p_tune_native); +void fill_native_cpu_config (struct loongarch_target *tgt); uint32_t get_native_prid (void); const char* get_native_prid_str (void); diff --git a/gcc/config/loongarch/loongarch-def.c b/gcc/config/loongarch/loongarch-def.c index 6729c857f7c..5bbc6923a7f 100644 --- a/gcc/config/loongarch/loongarch-def.c +++ b/gcc/config/loongarch/loongarch-def.c @@ -21,25 +21,11 @@ along with GCC; see the file COPYING3. If not see #include "loongarch-def.h" #include "loongarch-str.h" -/* Default RTX cost initializer. */ -#define COSTS_N_INSNS(N) ((N) * 4) -#define DEFAULT_COSTS \ - .fp_add = COSTS_N_INSNS (1), \ - .fp_mult_sf = COSTS_N_INSNS (2), \ - .fp_mult_df = COSTS_N_INSNS (4), \ - .fp_div_sf = COSTS_N_INSNS (6), \ - .fp_div_df = COSTS_N_INSNS (8), \ - .int_mult_si = COSTS_N_INSNS (1), \ - .int_mult_di = COSTS_N_INSNS (1), \ - .int_div_si = COSTS_N_INSNS (4), \ - .int_div_di = COSTS_N_INSNS (6), \ - .branch_cost = 2, \ - .memory_latency = 4 - /* CPU property tables. */ const char* loongarch_cpu_strings[N_TUNE_TYPES] = { [CPU_NATIVE] = STR_CPU_NATIVE, + [CPU_ABI_DEFAULT] = STR_CPU_ABI_DEFAULT, [CPU_LOONGARCH64] = STR_CPU_LOONGARCH64, [CPU_LA464] = STR_CPU_LA464, }; @@ -49,10 +35,12 @@ loongarch_cpu_default_isa[N_ARCH_TYPES] = { [CPU_LOONGARCH64] = { .base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU64, + .simd = 0, }, [CPU_LA464] = { .base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU64, + .simd = ISA_EXT_SIMD_LASX, }, }; @@ -84,6 +72,22 @@ loongarch_cpu_align[N_TUNE_TYPES] = { }, }; + +/* Default RTX cost initializer. */ +#define COSTS_N_INSNS(N) ((N) * 4) +#define DEFAULT_COSTS \ + .fp_add = COSTS_N_INSNS (1), \ + .fp_mult_sf = COSTS_N_INSNS (2), \ + .fp_mult_df = COSTS_N_INSNS (4), \ + .fp_div_sf = COSTS_N_INSNS (6), \ + .fp_div_df = COSTS_N_INSNS (8), \ + .int_mult_si = COSTS_N_INSNS (1), \ + .int_mult_di = COSTS_N_INSNS (1), \ + .int_div_si = COSTS_N_INSNS (4), \ + .int_div_di = COSTS_N_INSNS (6), \ + .branch_cost = 2, \ + .memory_latency = 4 + /* The following properties cannot be looked up directly using "cpucfg". So it is necessary to provide a default value for "unknown native" tune targets (i.e. -mtune=native while PRID does not correspond to @@ -103,7 +107,7 @@ loongarch_cpu_rtx_cost_data[N_TUNE_TYPES] = { }; /* RTX costs to use when optimizing for size. */ -extern const struct loongarch_rtx_cost_data +const struct loongarch_rtx_cost_data loongarch_rtx_cost_optimize_size = { .fp_add = 4, .fp_mult_sf = 4, @@ -144,9 +148,11 @@ loongarch_isa_base_strings[N_ISA_BASE_TYPES] = { const char* loongarch_isa_ext_strings[N_ISA_EXT_TYPES] = { - [ISA_EXT_FPU64] = STR_ISA_EXT_FPU64, + [ISA_EXT_NONE] = STR_NONE, [ISA_EXT_FPU32] = STR_ISA_EXT_FPU32, - [ISA_EXT_NOFPU] = STR_ISA_EXT_NOFPU, + [ISA_EXT_FPU64] = STR_ISA_EXT_FPU64, + [ISA_EXT_SIMD_LSX] = STR_ISA_EXT_LSX, + [ISA_EXT_SIMD_LASX] = STR_ISA_EXT_LASX, }; const char* @@ -171,24 +177,17 @@ loongarch_cmodel_strings[] = { [CMODEL_EXTREME] = STR_CMODEL_EXTREME, }; -const char* -loongarch_switch_strings[] = { - [SW_SOFT_FLOAT] = OPTSTR_SOFT_FLOAT, - [SW_SINGLE_FLOAT] = OPTSTR_SINGLE_FLOAT, - [SW_DOUBLE_FLOAT] = OPTSTR_DOUBLE_FLOAT, -}; - /* ABI-related definitions. */ const struct loongarch_isa abi_minimal_isa[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES] = { [ABI_BASE_LP64D] = { - [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU64}, + [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU64, .simd = 0}, }, [ABI_BASE_LP64F] = { - [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU32}, + [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU32, .simd = 0}, }, [ABI_BASE_LP64S] = { - [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_NOFPU}, + [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_NONE, .simd = 0}, }, }; diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h index fb8bb88eb52..769efcb70fb 100644 --- a/gcc/config/loongarch/loongarch-def.h +++ b/gcc/config/loongarch/loongarch-def.h @@ -59,11 +59,13 @@ extern const char* loongarch_isa_base_strings[]; /* enum isa_ext_* */ extern const char* loongarch_isa_ext_strings[]; -#define ISA_EXT_NOFPU 0 +#define ISA_EXT_NONE 0 #define ISA_EXT_FPU32 1 #define ISA_EXT_FPU64 2 #define N_ISA_EXT_FPU_TYPES 3 -#define N_ISA_EXT_TYPES 3 +#define ISA_EXT_SIMD_LSX 3 +#define ISA_EXT_SIMD_LASX 4 +#define N_ISA_EXT_TYPES 5 /* enum abi_base */ extern const char* loongarch_abi_base_strings[]; @@ -72,6 +74,16 @@ extern const char* loongarch_abi_base_strings[]; #define ABI_BASE_LP64S 2 #define N_ABI_BASE_TYPES 3 +#define TO_LP64_ABI_BASE(C) (C) + +#define ABI_FPU_64(abi_base) \ + (abi_base == ABI_BASE_LP64D) +#define ABI_FPU_32(abi_base) \ + (abi_base == ABI_BASE_LP64F) +#define ABI_FPU_NONE(abi_base) \ + (abi_base == ABI_BASE_LP64S) + + /* enum abi_ext */ extern const char* loongarch_abi_ext_strings[]; #define ABI_EXT_BASE 0 @@ -87,55 +99,44 @@ extern const char* loongarch_cmodel_strings[]; #define CMODEL_EXTREME 5 #define N_CMODEL_TYPES 6 -/* enum switches */ -/* The "SW_" codes represent command-line switches (options that - accept no parameters). Definition for other switches that affects - the target ISA / ABI configuration will also be appended here - in the future. */ - -extern const char* loongarch_switch_strings[]; -#define SW_SOFT_FLOAT 0 -#define SW_SINGLE_FLOAT 1 -#define SW_DOUBLE_FLOAT 2 -#define N_SWITCH_TYPES 3 - /* The common default value for variables whose assignments are triggered by command-line options. */ -#define M_OPTION_NOT_SEEN -1 -#define M_OPT_ABSENT(opt_enum) ((opt_enum) == M_OPTION_NOT_SEEN) +#define M_OPT_UNSET -1 +#define M_OPT_ABSENT(opt_enum) ((opt_enum) == M_OPT_UNSET) /* Internal representation of the target. */ struct loongarch_isa { - unsigned char base; /* ISA_BASE_ */ - unsigned char fpu; /* ISA_EXT_FPU_ */ + int base; /* ISA_BASE_ */ + int fpu; /* ISA_EXT_FPU_ */ + int simd; /* ISA_EXT_SIMD_ */ }; struct loongarch_abi { - unsigned char base; /* ABI_BASE_ */ - unsigned char ext; /* ABI_EXT_ */ + int base; /* ABI_BASE_ */ + int ext; /* ABI_EXT_ */ }; struct loongarch_target { struct loongarch_isa isa; struct loongarch_abi abi; - unsigned char cpu_arch; /* CPU_ */ - unsigned char cpu_tune; /* same */ - unsigned char cpu_native; /* same */ - unsigned char cmodel; /* CMODEL_ */ + int cpu_arch; /* CPU_ */ + int cpu_tune; /* same */ + int cmodel; /* CMODEL_ */ }; /* CPU properties. */ /* index */ #define CPU_NATIVE 0 -#define CPU_LOONGARCH64 1 -#define CPU_LA464 2 -#define N_ARCH_TYPES 3 -#define N_TUNE_TYPES 3 +#define CPU_ABI_DEFAULT 1 +#define CPU_LOONGARCH64 2 +#define CPU_LA464 3 +#define N_ARCH_TYPES 4 +#define N_TUNE_TYPES 4 /* parallel tables. */ extern const char* loongarch_cpu_strings[]; diff --git a/gcc/config/loongarch/loongarch-driver.cc b/gcc/config/loongarch/loongarch-driver.cc index 11ce082417f..89ebca59975 100644 --- a/gcc/config/loongarch/loongarch-driver.cc +++ b/gcc/config/loongarch/loongarch-driver.cc @@ -26,122 +26,134 @@ along with GCC; see the file COPYING3. If not see #include "tm.h" #include "obstack.h" #include "diagnostic-core.h" +#include "opts.h" #include "loongarch-opts.h" #include "loongarch-driver.h" -static int - opt_arch_driver = M_OPTION_NOT_SEEN, - opt_tune_driver = M_OPTION_NOT_SEEN, - opt_fpu_driver = M_OPTION_NOT_SEEN, - opt_abi_base_driver = M_OPTION_NOT_SEEN, - opt_abi_ext_driver = M_OPTION_NOT_SEEN, - opt_cmodel_driver = M_OPTION_NOT_SEEN; - -int opt_switches = 0; - /* This flag is set to 1 if we believe that the user might be avoiding linking (implicitly) against something from the startfile search paths. */ static int no_link = 0; -#define LARCH_DRIVER_SET_M_FLAG(OPTS_ARRAY, N_OPTS, FLAG, STR) \ - for (int i = 0; i < (N_OPTS); i++) \ - { \ - if ((OPTS_ARRAY)[i] != 0) \ - if (strcmp ((STR), (OPTS_ARRAY)[i]) == 0) \ - (FLAG) = i; \ - } - /* Use the public obstack from the gcc driver (defined in gcc.c). This is for allocating space for the returned string. */ extern struct obstack opts_obstack; -#define APPEND_LTR(S) \ - obstack_grow (&opts_obstack, (const void*) (S), \ - sizeof ((S)) / sizeof (char) -1) - -#define APPEND_VAL(S) \ - obstack_grow (&opts_obstack, (const void*) (S), strlen ((S))) +const char* +la_driver_init (int argc ATTRIBUTE_UNUSED, const char **argv ATTRIBUTE_UNUSED) +{ + /* Initialize all fields of la_target to -1 */ + loongarch_init_target (&la_target, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET, + M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET); + return ""; +} +const char* +driver_set_no_link (int argc, const char **argv) +{ + no_link = 1; + return ""; +} const char* -driver_set_m_flag (int argc, const char **argv) +driver_set_m_parm (int argc, const char **argv) { - int parm_off = 0; + gcc_assert (argc == 2); + +#define LARCH_DRIVER_PARSE_PARM(OPT_IDX, NAME, OPTSTR_LIST, \ + OPT_IDX_LO, OPT_IDX_HI) \ + if (strcmp (argv[0], OPTSTR_##NAME) == 0) \ + for (int i = (OPT_IDX_LO); i < (OPT_IDX_HI); i++) \ + { \ + if ((OPTSTR_LIST)[i] != 0) \ + if (strcmp (argv[1], (OPTSTR_LIST)[i]) == 0) \ + { \ + (OPT_IDX) = i; \ + return 0; \ + } \ + } - if (argc != 1) - return "%eset_m_flag requires exactly 1 argument."; + LARCH_DRIVER_PARSE_PARM (la_target.abi.base, ABI_BASE, \ + loongarch_abi_base_strings, 0, N_ABI_BASE_TYPES) -#undef PARM -#define PARM (argv[0] + parm_off) + LARCH_DRIVER_PARSE_PARM (la_target.isa.fpu, ISA_EXT_FPU, \ + loongarch_isa_ext_strings, 0, N_ISA_EXT_FPU_TYPES) -/* Note: sizeof (OPTSTR_##NAME) equals the length of "