From patchwork Sat Nov 27 08:27:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lulu Cheng X-Patchwork-Id: 48217 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 887B1385842B for ; Sat, 27 Nov 2021 08:33:18 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id D380C3857823 for ; Sat, 27 Nov 2021 08:28:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D380C3857823 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 5.5.5 (unknown [10.2.5.5]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dx78oK7KFhnLkAAA--.2037S3; Sat, 27 Nov 2021 16:28:25 +0800 (CST) From: chenglulu To: gcc-patches@gcc.gnu.org Subject: [PATCH 01/12] LoongArch Port: gcc build Date: Sat, 27 Nov 2021 16:27:24 +0800 Message-Id: <20211127082735.4139682-2-chenglulu@loongson.cn> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211127082735.4139682-1-chenglulu@loongson.cn> References: <20211127082735.4139682-1-chenglulu@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Dx78oK7KFhnLkAAA--.2037S3 X-Coremail-Antispam: 1UD129KBjvAXoWDuF4kKF15tr17Zr4Uuw1UGFg_yoWfCr47Xo WfJFZxZw1xGr4Sv398KrnIqrWUtr1j9rW3A347Zw4UGFykXrn8JryxKw4SvFy3Zr9agrWD Aa42gr9rAF97Jrn3n29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYZ7AC8VAFwI0_Gr0_Xr1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r18M28IrcIa0x kI8VCY1x0267AKxVWUXVWUCwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC jcxK6xIIjxv20xvE14v26r1I6r4UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4j6F4UM2 8EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_Gr1j6F4U JwAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7 IYx2IY67AKxVWUJVWUGwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4U M4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY02Avz4vE-syl42xK82 IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC2 0s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMI IF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF 0xvE42xK8VAvwI8IcIk0rVW8JVW3JwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87 Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjfUONtxUUUUU X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: , Cc: yangyujie@loongson.cn, xuchenghua@loongson.cn, chenglulu@loongson.cn Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" gcc/ * common/config/loongarch/loongarch-common.c: 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/gnu-user.h: New file. * config/loongarch/linux.h: New file. * config/loongarch/loongarch-cpu.c: New file. * config/loongarch/loongarch-cpu.h: New file. * config/loongarch/loongarch-driver.c: New file. * config/loongarch/loongarch-driver.h: New file. * config/loongarch/loongarch-opts.c: 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. --- .../config/loongarch/loongarch-common.c | 63 ++ gcc/config.gcc | 400 +++++++++++- gcc/config/loongarch/genopts/genstr.sh | 91 +++ .../loongarch/genopts/loongarch-strings | 58 ++ gcc/config/loongarch/genopts/loongarch.opt.in | 189 ++++++ gcc/config/loongarch/gnu-user.h | 85 +++ gcc/config/loongarch/linux.h | 48 ++ gcc/config/loongarch/loongarch-cpu.c | 206 +++++++ gcc/config/loongarch/loongarch-cpu.h | 30 + gcc/config/loongarch/loongarch-def.c | 148 +++++ gcc/config/loongarch/loongarch-def.h | 144 +++++ gcc/config/loongarch/loongarch-driver.c | 187 ++++++ gcc/config/loongarch/loongarch-driver.h | 60 ++ gcc/config/loongarch/loongarch-opts.c | 572 ++++++++++++++++++ gcc/config/loongarch/loongarch-opts.h | 90 +++ gcc/config/loongarch/loongarch-str.h | 57 ++ gcc/config/loongarch/loongarch.opt | 189 ++++++ gcc/config/loongarch/t-linux | 53 ++ gcc/config/loongarch/t-loongarch | 59 ++ gcc/configure.ac | 33 +- 20 files changed, 2757 insertions(+), 5 deletions(-) create mode 100644 gcc/common/config/loongarch/loongarch-common.c create mode 100755 gcc/config/loongarch/genopts/genstr.sh create mode 100644 gcc/config/loongarch/genopts/loongarch-strings create mode 100644 gcc/config/loongarch/genopts/loongarch.opt.in create mode 100644 gcc/config/loongarch/gnu-user.h create mode 100644 gcc/config/loongarch/linux.h create mode 100644 gcc/config/loongarch/loongarch-cpu.c create mode 100644 gcc/config/loongarch/loongarch-cpu.h create mode 100644 gcc/config/loongarch/loongarch-def.c create mode 100644 gcc/config/loongarch/loongarch-def.h create mode 100644 gcc/config/loongarch/loongarch-driver.c create mode 100644 gcc/config/loongarch/loongarch-driver.h create mode 100644 gcc/config/loongarch/loongarch-opts.c create mode 100644 gcc/config/loongarch/loongarch-opts.h create mode 100644 gcc/config/loongarch/loongarch-str.h create mode 100644 gcc/config/loongarch/loongarch.opt create mode 100644 gcc/config/loongarch/t-linux create mode 100644 gcc/config/loongarch/t-loongarch diff --git a/gcc/common/config/loongarch/loongarch-common.c b/gcc/common/config/loongarch/loongarch-common.c new file mode 100644 index 00000000000..3f440aef1e7 --- /dev/null +++ b/gcc/common/config/loongarch/loongarch-common.c @@ -0,0 +1,63 @@ +/* Common hooks for LoongArch. + Copyright (C) 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 +. */ + +#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" + +/* 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; + + 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; diff --git a/gcc/config.gcc b/gcc/config.gcc index edd12655c4a..40758f5f01a 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -453,6 +453,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" @@ -2486,6 +2493,20 @@ riscv*-*-freebsd*) # automatically detect that GAS supports it, yet we require it. gcc_cv_initfini_array=yes ;; + +loongarch*-*-linux-gnu*) + 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" @@ -3592,7 +3613,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 @@ -4915,6 +4936,338 @@ 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 + + # Inferring ABI from the triplet: pass 1 + case ${target} in + loongarch64-*) + abiext_pattern="*" + abiext_default="base" + ;; + esac + + # Inferring ABI from the triplet: pass 2 + case ${target} in + loongarch64-*-linux-gnuf64) + la_canonical_triplet="loongarch64-linux-gnuf64" + abi_pattern="lp64d" + ;; + loongarch64-*-linux-gnuf32) + la_canonical_triplet="loongarch64-linux-gnuf32" + abi_pattern="lp64f" + ;; + loongarch64-*-linux-gnusf) + la_canonical_triplet="loongarch64-linux-gnusf" + abi_pattern="lp64s" + ;; + loongarch64-*-linux-gnu) + la_canonical_triplet="loongarch64-linux-gnuf64" + abi_pattern="lp64[dfs]" + abi_default="lp64d" + ;; + *) + echo "Unsupported target ${target}." 1>&2 + exit 1 + esac + + ## Setting 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}$"; then + : # OK + else + echo "Incompatible options:" \ + "--with-abi=${with_abi} and --target=${target}." 1>&2 + exit 1 + fi + ;; + esac + + ## Setting 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}$"; then + : # OK + else + echo "The ABI extension type \"${with_abiext}\"" \ + "is incompatible with --target=${target}." 1>&2 + exit 1 + fi + + ;; + esac + + + # Inferring 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 + + # 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_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}$"; then + : # OK + else + echo "${with_abi}/${with_abiext} ABI cannot be implemented with" \ + "--with-arch=${with_arch}." 1>&2 + exit 1 + fi + ;; + esac + + ## Setting default value for with_fpu. + if test x${with_fpu} == xnone; then + with_fpu="0" + fi + + 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 + 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" + 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} + ;; + nds32*-*-*) supported_defaults="arch cpu nds32_lib float fpu_config" @@ -5352,6 +5705,51 @@ case ${target} in tmake_file="mips/t-mips $tmake_file" ;; + loongarch*-*-*) + # Export canonical triplet. + tm_defines+=" LA_MULTIARCH_TRIPLET=${la_canonical_triplet}" + + # 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 + + # 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+=" DEFAULT_CPU_ARCH=CPU_NATIVE" ;; + la464) tm_defines+=" DEFAULT_CPU_ARCH=CPU_LA464" ;; + loongarch64) tm_defines+=" DEFAULT_CPU_ARCH=CPU_LOONGARCH64" ;; + esac + + case ${with_tune} in + native) tm_defines+=" DEFAULT_CPU_TUNE=CPU_NATIVE" ;; + la464) tm_defines+=" DEFAULT_CPU_TUNE=CPU_LA464" ;; + loongarch64) tm_defines+=" DEFAULT_CPU_TUNE=CPU_LOONGARCH64" ;; + esac + + case ${with_abi} in + lp64d) tm_defines+=" DEFAULT_ABI_BASE=ABI_BASE_LP64D" ;; + lp64f) tm_defines+=" DEFAULT_ABI_BASE=ABI_BASE_LP64F" ;; + lp64s) tm_defines+=" DEFAULT_ABI_BASE=ABI_BASE_LP64S" ;; + esac + + case ${with_abiext} in + base) 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. diff --git a/gcc/config/loongarch/genopts/genstr.sh b/gcc/config/loongarch/genopts/genstr.sh new file mode 100755 index 00000000000..62a0a0770a2 --- /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 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 +# . + +cd "$(dirname "$0")" + +# Generate a header containing definitions from the string table. +gen_defines() { + cat <. */ + +#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 "@@@@" to "" 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 + + # 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 "$@" diff --git a/gcc/config/loongarch/genopts/loongarch-strings b/gcc/config/loongarch/genopts/loongarch-strings new file mode 100644 index 00000000000..553304f9b83 --- /dev/null +++ b/gcc/config/loongarch/genopts/loongarch-strings @@ -0,0 +1,58 @@ +# Defines the key strings for LoongArch compiler options. +# +# Copyright (C) 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 +# . + +# -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 diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in new file mode 100644 index 00000000000..08950a32179 --- /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 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 +; . +; + +; 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) +Don't optimize block moves. + +mlra +Target Var(loongarch_lra_flag) Init(1) Save +Use LRA instead of reload. + +noasmopt +Driver + +mstrict-align +Target Mask(STRICT_ALIGN) Save +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. diff --git a/gcc/config/loongarch/gnu-user.h b/gcc/config/loongarch/gnu-user.h new file mode 100644 index 00000000000..f7b48905801 --- /dev/null +++ b/gcc/config/loongarch/gnu-user.h @@ -0,0 +1,85 @@ +/* Definitions for LoongArch systems using GNU userspace. + Copyright (C) 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 +. */ + +/* 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" + +#define GLIBC_DYNAMIC_LINKER \ + "/lib" ABI_GRLEN_SPEC "/ld-linux-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 " GLIBC_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) + + +/* The glibc _mcount stub will save $v0 for us. Don't mess with saving + it, since ASM_OUTPUT_REG_PUSH/ASM_OUTPUT_REG_POP do not work in the + presence of $gp-relative calls. */ +#undef ASM_OUTPUT_REG_PUSH +#undef ASM_OUTPUT_REG_POP + + +#undef ASM_DECLARE_OBJECT_NAME +#define ASM_DECLARE_OBJECT_NAME loongarch_declare_object_name diff --git a/gcc/config/loongarch/linux.h b/gcc/config/loongarch/linux.h new file mode 100644 index 00000000000..8d8b3de5922 --- /dev/null +++ b/gcc/config/loongarch/linux.h @@ -0,0 +1,48 @@ +/* Definitions for Linux-based systems with libraries in ELF format. + Copyright (C) 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 +. */ + +/* Default system library search paths. + * This ensures that a compiler configured with --disable-multilib + * can work in an multilib environment. */ + +#if defined(__DISABLE_MULTILIB) && defined(__DISABLE_MULTIARCH) + + #if DEFAULT_ABI_INT == ABI_BASE_LP64D + #define ABI_LIBDIR "lib64" + #elif DEFAULT_ABI_INT == ABI_BASE_LP64F + #define ABI_LIBDIR "lib64/f32" + #elif DEFAULT_ABI_INT == 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) diff --git a/gcc/config/loongarch/loongarch-cpu.c b/gcc/config/loongarch/loongarch-cpu.c new file mode 100644 index 00000000000..92e62ae4b04 --- /dev/null +++ b/gcc/config/loongarch/loongarch-cpu.c @@ -0,0 +1,206 @@ +/* Definitions for LoongArch CPU properties. + Copyright (C) 2021 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 +. */ + +#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%>, " + "%<-m" OPTSTR_ARCH "=" STR_CPU_NATIVE "%> failed", + (unsigned int) (cpucfg_cache[1] & 0x3)); + } + + /* 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%>, " + "%<-m" OPTSTR_ARCH "=" STR_CPU_NATIVE "%> failed", + cpucfg_cache[2] & 0x7); + } + + /* 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; +} diff --git a/gcc/config/loongarch/loongarch-cpu.h b/gcc/config/loongarch/loongarch-cpu.h new file mode 100644 index 00000000000..93d656f70f5 --- /dev/null +++ b/gcc/config/loongarch/loongarch-cpu.h @@ -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 +. */ + +#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 */ diff --git a/gcc/config/loongarch/loongarch-def.c b/gcc/config/loongarch/loongarch-def.c new file mode 100644 index 00000000000..d67e08c9b11 --- /dev/null +++ b/gcc/config/loongarch/loongarch-def.c @@ -0,0 +1,148 @@ +/* LoongArch static properties. + Copyright (C) 2021 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 +. */ + +#include "loongarch-def.h" +#include "loongarch-str.h" + +/* 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 + }, +}; + +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}, + }, +}; diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h new file mode 100644 index 00000000000..50d1994fa6c --- /dev/null +++ b/gcc/config/loongarch/loongarch-def.h @@ -0,0 +1,144 @@ +/* LoongArch definitions. + Copyright (C) 2021 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 +. */ + +/* 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" + +/* 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[]; + +#endif /* LOONGARCH_DEF_H */ diff --git a/gcc/config/loongarch/loongarch-driver.c b/gcc/config/loongarch/loongarch-driver.c new file mode 100644 index 00000000000..8d78e2eb98b --- /dev/null +++ b/gcc/config/loongarch/loongarch-driver.c @@ -0,0 +1,187 @@ +/* Subroutines for the gcc driver. + Copyright (C) 2021 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 +. */ + +#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 "