From patchwork Mon Aug 7 04:01:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chenxiaolong X-Patchwork-Id: 131657 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c44e:0:b0:3f2:4152:657d with SMTP id w14csp1213199vqr; Sun, 6 Aug 2023 21:02:24 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHETiF1ciXK+fzoIWhXb6b/3BEKjdhKIYEsGMbvj//XmfoOGswYnSgGDjJkEwOQucP/3tpo X-Received: by 2002:a17:907:78c8:b0:98f:8481:24b3 with SMTP id kv8-20020a17090778c800b0098f848124b3mr6167166ejc.37.1691380944322; Sun, 06 Aug 2023 21:02:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691380944; cv=none; d=google.com; s=arc-20160816; b=jkgjbacPVoIK1DUfZDsM5Jp6Vkb+RVa/PHpRnKfXaMqD+merfufRoIPy5O6n2X7zKD aUx70Or7q7cbNFsFFkKm8AA7NPQNcWp+DsURR1a7UM4LmU1/Oa0unPtOexh+NzPRi3gh izGvsAj0LwiZM1JiyOn6NL+H+A4S6HX6ANYsO06DBMC4OmSoh66SrBZkJa9FNBZz3Mbn KKj+ZrkFM4pWYEMnhLPB+VF/FukDOCizg4cB93LGUuCH7RQrI9H0QDd4ZpokE2UjKh+T 0K5z8AR4Om6SSFuAzAL/Q4Xi+SoT8+4chhgWRYP0Dpq5+SPOFfv8Zcc4ABKW1Rmpx8uK +XSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dmarc-filter :delivered-to; bh=TqAVi6WaU2dr+oEYcVoW/P65eOIFdrWU375YGrHy83U=; fh=EA5O8KfilzF8dRcBzuMRLLAQVVl0lh6Dyjca16d0P5Q=; b=0bmkn5ghZbrdt6SkuxdLi2Mu3sNc1xnKWpLrVAMTNHlWASlulq1/U4aYalXoWZ8uVI XQp7ezuGVddMpHUdtf3wTUZfT/nLsCtQHHB3JnPSahJmaKRZUmwGlPlG6c8Dtmre4ge+ ixLxO+CI9bYe1dJ/fhsPvM2VOYSbgrOu1X0ZY9VCi4P47QeMGJ6KGXq/zPDpPQ3f/FEZ YXAcr+7yWQAvMGucPBkniLtRNu1id3+wqMnNxBC0pnZj/lg3O6VkvUzygDcbitw8HIPP lJrZIjm9Cvv+hQ8mcVMFinaENK3tXejSGp/CoLjbqxq34Q//cQ/PSUlx0ptsB4y+eNQV jong== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id a2-20020a170906274200b00992beea60c2si5071845ejd.826.2023.08.06.21.02.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 06 Aug 2023 21:02:24 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D38AE3857705 for ; Mon, 7 Aug 2023 04:02:16 +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 588063858D28 for ; Mon, 7 Aug 2023 04:01:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 588063858D28 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 [10.10.130.252]) by gateway (Coremail) with SMTP id _____8DxVuiobNBkRc4RAA--.4209S3; Mon, 07 Aug 2023 12:01:44 +0800 (CST) Received: from slurm-master.loongson.cn (unknown [10.10.130.252]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxriOmbNBkq6pMAA--.23310S4; Mon, 07 Aug 2023 12:01:42 +0800 (CST) From: chenxiaolong To: gcc-patches@gcc.gnu.org Cc: xry111@xry111.site, i@xen0n.name, xuchenghua@loongson.cn, chenglulu@loongson.cn, Xiaolong Chen Subject: [PATCH v1] LoongArch:Implement 128-bit floating point functions in gcc. Date: Mon, 7 Aug 2023 12:01:40 +0800 Message-Id: <20230807040140.14796-1-chenxiaolong@loongson.cn> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-CM-TRANSID: AQAAf8CxriOmbNBkq6pMAA--.23310S4 X-CM-SenderInfo: hfkh05xldrz0tqj6z05rqj20fqof0/1tbiAQAQBWTPHbEFRQAAsT X-Coremail-Antispam: 1Uk129KBj9fXoW3KF1ktr4xWw1fAF4UAr4UJrc_yoW8Aw47Ao W3AF1jq3Z5Wr1Iva4agwnIgryYvF18ArWkAryav3WrC3Z7Jr15Ca4qgw4Fy347trs3WF4U Ca45Gr93JFWxJF1kl-sFpf9Il3svdjkaLaAFLSUrUUUUUb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUYb7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUGVWUXwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r1j6r4UM28EF7xvwVC2z280aVAFwI0_Cr0_Gr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx 1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv 67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6x kF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x07j8yCJUUUUU= X-Spam-Status: No, score=-13.6 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+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773541465050422315 X-GMAIL-MSGID: 1773541465050422315 From: Xiaolong Chen In the implementation process, the "q" suffix function is Re-register and associate the "__float128" type with the "long double" type so that the compiler can handle the corresponding function correctly. The functions implemented include __builtin_{huge_valq infq, fabsq, copysignq, nanq, nansq}. gcc/ChangeLog: * config/loongarch/loongarch-builtins.cc (DEF_LARCH_FTYPE): (MATHQ_NUMS=):Add the type of the builtin(q) function. (enum loongarch_builtin_type):Add the type of the function. (FLOAT_BUILTIN_HUGE): (FLOAT_BUILTIN_INFQ): (FLOAT_BUILTIN_FABSQ): (FLOAT_BUILTIN_COPYSIGNQ): (FLOAT_BUILTIN_NANQ): (FLOAT_BUILTIN_NANSQ): (loongarch_init_builtins): (loongarch_fold_builtin): (loongarch_expand_builtin): * config/loongarch/loongarch-protos.h (loongarch_fold_builtin): (loongarch_c_mode_for_suffix):Add the declaration of the function. * config/loongarch/loongarch.cc (loongarch_c_mode_for_suffix): Add the definition of the function. (TARGET_FOLD_BUILTIN): (TARGET_C_MODE_FOR_SUFFIX): * config/loongarch/loongarch.md (infq): ():Add an instruction template to the machine description file to generate information such as the icode used by the function and the constructor. libgcc/ChangeLog: * config/loongarch/t-softfp-tf: * config/loongarch/tf-signs.c: New file. --- gcc/config/loongarch/loongarch-builtins.cc | 196 ++++++++++++++++++++- gcc/config/loongarch/loongarch-protos.h | 2 + gcc/config/loongarch/loongarch.cc | 14 ++ gcc/config/loongarch/loongarch.md | 25 +++ libgcc/config/loongarch/t-softfp-tf | 3 + libgcc/config/loongarch/tf-signs.c | 99 +++++++++++ 6 files changed, 337 insertions(+), 2 deletions(-) create mode 100644 libgcc/config/loongarch/tf-signs.c diff --git a/gcc/config/loongarch/loongarch-builtins.cc b/gcc/config/loongarch/loongarch-builtins.cc index b929f224dfa..cb7f0e60674 100644 --- a/gcc/config/loongarch/loongarch-builtins.cc +++ b/gcc/config/loongarch/loongarch-builtins.cc @@ -36,6 +36,8 @@ along with GCC; see the file COPYING3. If not see #include "fold-const.h" #include "expr.h" #include "langhooks.h" +#include "calls.h" +#include "explow.h" /* Macros to create an enumeration identifier for a function prototype. */ #define LARCH_FTYPE_NAME1(A, B) LARCH_##A##_FTYPE_##B @@ -48,9 +50,18 @@ enum loongarch_function_type #define DEF_LARCH_FTYPE(NARGS, LIST) LARCH_FTYPE_NAME##NARGS LIST, #include "config/loongarch/loongarch-ftypes.def" #undef DEF_LARCH_FTYPE + LARCH_BUILTIN_HUGE_VALQ, + LARCH_BUILTIN_INFQ, + LARCH_BUILTIN_FABSQ, + LARCH_BUILTIN_COPYSIGNQ, + LARCH_BUILTIN_NANQ, + LARCH_BUILTIN_NANSQ, LARCH_MAX_FTYPE_MAX }; +/* Count the number of functions with "q" as the suffix */ +static int MATHQ_NUMS=(int)LARCH_MAX_FTYPE_MAX-(int)LARCH_BUILTIN_HUGE_VALQ; + /* Specifies how a built-in function should be converted into rtl. */ enum loongarch_builtin_type { @@ -62,7 +73,25 @@ enum loongarch_builtin_type /* The function corresponds directly to an .md pattern. There is no return value and the arguments are mapped to operands 0 and above. */ LARCH_BUILTIN_DIRECT_NO_TARGET, + + /*The function corresponds to an __builtin_huge_valq */ + LARCH_BUILTIN_HUGE_DIRECT , + + /*Define the type of the __builtin_infq function */ + LARCH_BUILTIN_INFQ_DIRECT , + + /*Define the type of the __builtin_fabsq function*/ + LARCH_BUILTIN_FABSQ_DIRECT , + /*Define the type of the __builtin_copysignq function */ + LARCH_BUILTIN_COPYSIGNQ_DIRECT , + + + /*Define the type of the __builtin_copysignq function */ + LARCH_BUILTIN_NANQ_DIRECT , + + /*Define the type of the __builtin_copysignq function */ + LARCH_BUILTIN_NANSQ_DIRECT , }; /* Declare an availability predicate for built-in functions that require @@ -135,6 +164,41 @@ AVAIL_ALL (hard_float, TARGET_HARD_FLOAT_ABI) #define DIRECT_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE, AVAIL) \ LARCH_BUILTIN (INSN, #INSN, LARCH_BUILTIN_DIRECT_NO_TARGET, \ FUNCTION_TYPE, AVAIL) +/* Define an float to do funciton huge_valq*/ +#define FLOAT_BUILTIN_HUGE(INSN, FUNCTION_TYPE) \ + { CODE_FOR_ ## INSN, \ + "__builtin_" #INSN, LARCH_BUILTIN_HUGE_DIRECT, \ + FUNCTION_TYPE, loongarch_builtin_avail_default } + +/* Define an float to do funciton infq*/ +#define FLOAT_BUILTIN_INFQ(INSN, FUNCTION_TYPE) \ + { CODE_FOR_ ## INSN, \ + "__builtin_" #INSN, LARCH_BUILTIN_INFQ_DIRECT, \ + FUNCTION_TYPE, loongarch_builtin_avail_default } + +/* Define an float to do funciton fabsq*/ +#define FLOAT_BUILTIN_FABSQ(INSN, FUNCTION_TYPE) \ + { CODE_FOR_ ## INSN, \ + "__builtin_" #INSN, LARCH_BUILTIN_FABSQ_DIRECT, \ + FUNCTION_TYPE, loongarch_builtin_avail_default } + +/* Define an float to do funciton copysignq*/ +#define FLOAT_BUILTIN_COPYSIGNQ(INSN, FUNCTION_TYPE) \ + { CODE_FOR_ ## INSN, \ + "__builtin_" #INSN, LARCH_BUILTIN_COPYSIGNQ_DIRECT, \ + FUNCTION_TYPE, loongarch_builtin_avail_default } + +/* Define an float to do funciton nanq*/ +#define FLOAT_BUILTIN_NANQ(INSN, FUNCTION_TYPE) \ + { CODE_FOR_ ## INSN, \ + "__builtin_" #INSN, LARCH_BUILTIN_NANQ_DIRECT, \ + FUNCTION_TYPE, loongarch_builtin_avail_default } + +/* Define an float to do funciton nansq*/ +#define FLOAT_BUILTIN_NANSQ(INSN, FUNCTION_TYPE) \ + { CODE_FOR_ ## INSN, \ + "__builtin_" #INSN, LARCH_BUILTIN_NANSQ_DIRECT, \ + FUNCTION_TYPE, loongarch_builtin_avail_default } static const struct loongarch_builtin_description loongarch_builtins[] = { #define LARCH_MOVFCSR2GR 0 @@ -183,6 +247,14 @@ static const struct loongarch_builtin_description loongarch_builtins[] = { DIRECT_NO_TARGET_BUILTIN (asrtgt_d, LARCH_VOID_FTYPE_DI_DI, default), DIRECT_NO_TARGET_BUILTIN (syscall, LARCH_VOID_FTYPE_USI, default), DIRECT_NO_TARGET_BUILTIN (break, LARCH_VOID_FTYPE_USI, default), + + FLOAT_BUILTIN_HUGE (huge_valq, LARCH_BUILTIN_HUGE_VALQ), + FLOAT_BUILTIN_INFQ (infq, LARCH_BUILTIN_INFQ), + FLOAT_BUILTIN_FABSQ (fabsq, LARCH_BUILTIN_FABSQ), + FLOAT_BUILTIN_NANQ (nanq, LARCH_BUILTIN_NANQ), + FLOAT_BUILTIN_NANSQ (nansq, LARCH_BUILTIN_NANSQ), + FLOAT_BUILTIN_COPYSIGNQ (copysignq, LARCH_BUILTIN_COPYSIGNQ), + }; /* Index I is the function declaration for loongarch_builtins[I], or null if @@ -254,11 +326,13 @@ loongarch_init_builtins (void) { const struct loongarch_builtin_description *d; unsigned int i; - tree type; + tree type,ftype; + tree const_string_type + =build_pointer_type(build_qualified_type(char_type_node,TYPE_QUAL_CONST)); /* Iterate through all of the bdesc arrays, initializing all of the builtin functions. */ - for (i = 0; i < ARRAY_SIZE (loongarch_builtins); i++) + for (i = 0; i < ARRAY_SIZE (loongarch_builtins)-MATHQ_NUMS; i++) { d = &loongarch_builtins[i]; if (d->avail ()) @@ -270,6 +344,63 @@ loongarch_init_builtins (void) loongarch_get_builtin_decl_index[d->icode] = i; } } + /*Register the type long_double_type_node as a built-in type and + give it an alias "__float128" */ + (*lang_hooks.types.register_builtin_type)(long_double_type_node,"__float128"); + + ftype = build_function_type_list (long_double_type_node,NULL_TREE); + d = &loongarch_builtins[i]; + loongarch_builtin_decls[i] + =add_builtin_function("__builtin_huge_valq",ftype, + i,BUILT_IN_MD,NULL,NULL_TREE); + loongarch_get_builtin_decl_index[d->icode]=i++; + + + ftype = build_function_type_list (long_double_type_node,NULL_TREE); + d = &loongarch_builtins[i]; + loongarch_builtin_decls[i] + =add_builtin_function("__builtin_infq",ftype, + i,BUILT_IN_MD,NULL,NULL_TREE); + loongarch_get_builtin_decl_index[d->icode]=i++; + + ftype = build_function_type_list (long_double_type_node, + long_double_type_node, + NULL_TREE); + d = &loongarch_builtins[i]; + loongarch_builtin_decls[i] + =add_builtin_function("__builtin_fabsq",ftype, + i,BUILT_IN_MD,"__fabstf2",NULL_TREE); + TREE_READONLY (loongarch_builtin_decls[i]) =1; + loongarch_get_builtin_decl_index[d->icode]=i++; + + ftype = build_function_type_list (long_double_type_node, + long_double_type_node, + long_double_type_node, + NULL_TREE); + d = &loongarch_builtins[i]; + loongarch_builtin_decls[i] + =add_builtin_function("__builtin_copysignq",ftype, + i,BUILT_IN_MD,"__copysigntf3",NULL_TREE); + TREE_READONLY (loongarch_builtin_decls[i]) =1; + loongarch_get_builtin_decl_index[d->icode]=i++; + + ftype=build_function_type_list(long_double_type_node, + const_string_type, + NULL_TREE); + d = &loongarch_builtins[i]; + loongarch_builtin_decls[i] + =add_builtin_function("__builtin_nanq",ftype, + i,BUILT_IN_MD,"nanq",NULL_TREE); + TREE_READONLY (loongarch_builtin_decls[i]) =1; + loongarch_get_builtin_decl_index[d->icode]=i++; + + d = &loongarch_builtins[i]; + loongarch_builtin_decls[i] + =add_builtin_function("__builtin_nansq",ftype, + i,BUILT_IN_MD,"nansq",NULL_TREE); + TREE_READONLY (loongarch_builtin_decls[i]) =1; + loongarch_get_builtin_decl_index[d->icode]=i; + } /* Implement TARGET_BUILTIN_DECL. */ @@ -282,6 +413,42 @@ loongarch_builtin_decl (unsigned int code, bool initialize_p ATTRIBUTE_UNUSED) return loongarch_builtin_decls[code]; } +tree +loongarch_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, + tree *args, bool ignore ATTRIBUTE_UNUSED) +{ + if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) + { + enum loongarch_function_type fn_code + = (enum loongarch_function_type) DECL_MD_FUNCTION_CODE (fndecl); + switch (fn_code) + { + case LARCH_BUILTIN_NANQ: + case LARCH_BUILTIN_NANSQ: + { + tree type = TREE_TYPE (TREE_TYPE (fndecl)); + const char *str = c_getstr (*args); + int quiet = fn_code == LARCH_BUILTIN_NANQ; + REAL_VALUE_TYPE real; + + if (str && real_nan (&real, str, quiet, TYPE_MODE (type))) + return build_real (type, real); + return NULL_TREE; + } + + default: + break; + } + } + +#ifdef SUBTARGET_FOLD_BUILTIN + return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore); +#endif + + return NULL_TREE; +} + + /* Take argument ARGNO from EXP's argument list and convert it into an expand operand. Store the operand in *OP. */ @@ -366,7 +533,32 @@ loongarch_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, case LARCH_BUILTIN_DIRECT_NO_TARGET: return loongarch_expand_builtin_direct (d->icode, target, exp, false); + + case LARCH_BUILTIN_NANQ_DIRECT: + case LARCH_BUILTIN_NANSQ_DIRECT: + case LARCH_BUILTIN_FABSQ_DIRECT: + case LARCH_BUILTIN_COPYSIGNQ_DIRECT: + return expand_call ( exp ,target , ignore); + + case LARCH_BUILTIN_HUGE_DIRECT: + case LARCH_BUILTIN_INFQ_DIRECT: + { + machine_mode target_mode = TYPE_MODE(TREE_TYPE(exp)); + REAL_VALUE_TYPE inf; + rtx tmp; + + real_inf(&inf); + tmp = const_double_from_real_value(inf, target_mode); + + tmp=validize_mem (force_const_mem (target_mode,tmp)); + + if(target ==0) + target =gen_reg_rtx (target_mode); + emit_move_insn(target,tmp); + + return target; } + } gcc_unreachable (); } diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h index b71b188507a..6fa0d10f20c 100644 --- a/gcc/config/loongarch/loongarch-protos.h +++ b/gcc/config/loongarch/loongarch-protos.h @@ -175,11 +175,13 @@ extern void loongarch_register_frame_header_opt (void); /* Routines implemented in loongarch-c.c. */ void loongarch_cpu_cpp_builtins (cpp_reader *); +extern tree loongarch_fold_builtin(tree,int,tree*,bool); extern void loongarch_init_builtins (void); extern void loongarch_atomic_assign_expand_fenv (tree *, tree *, tree *); extern tree loongarch_builtin_decl (unsigned int, bool); extern rtx loongarch_expand_builtin (tree, rtx, rtx subtarget ATTRIBUTE_UNUSED, machine_mode, int); extern tree loongarch_build_builtin_va_list (void); +extern machine_mode loongarch_c_mode_for_suffix (char suffix); #endif /* ! GCC_LOONGARCH_PROTOS_H */ diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 5b8b93eb24b..0da147358b1 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -6789,6 +6789,16 @@ loongarch_set_handled_components (sbitmap components) cfun->machine->reg_is_wrapped_separately[regno] = true; } +/* Target hook for c_mode_for_suffix. */ +machine_mode +loongarch_c_mode_for_suffix (char suffix) +{ + if (suffix == 'q') + return TFmode; + + return VOIDmode; +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -6900,6 +6910,10 @@ loongarch_set_handled_components (sbitmap components) #define TARGET_BUILTIN_DECL loongarch_builtin_decl #undef TARGET_EXPAND_BUILTIN #define TARGET_EXPAND_BUILTIN loongarch_expand_builtin +#undef TARGET_FOLD_BUILTIN +#define TARGET_FOLD_BUILTIN loongarch_fold_builtin +#undef TARGET_C_MODE_FOR_SUFFIX +#define TARGET_C_MODE_FOR_SUFFIX loongarch_c_mode_for_suffix /* The generic ELF target does not always have TLS support. */ #ifdef HAVE_AS_TLS diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index b37e070660f..d7a5922f33d 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -43,6 +43,13 @@ (define_c_enum "unspec" [ UNSPEC_FTINTRP UNSPEC_FSCALEB UNSPEC_FLOGB + + UNSPEC_INFQ + UNSPEC_HUGE_VALQ + UNSPEC_FABSQ + UNSPEC_COPYSIGNQ + UNSPEC_NANQ + UNSPEC_NANSQ ;; Override return address for exception handling. UNSPEC_EH_RETURN @@ -563,6 +570,17 @@ (define_int_attr bytepick_imm [(8 "1") (48 "6") (56 "7")]) +;; mathq function +(define_int_iterator MATHQ [UNSPEC_INFQ UNSPEC_HUGE_VALQ UNSPEC_FABSQ UNSPEC_COPYSIGNQ + UNSPEC_NANQ UNSPEC_NANSQ]) +(define_int_attr mathq_pattern [(UNSPEC_INFQ "infq") + (UNSPEC_HUGE_VALQ "huge_valq") + (UNSPEC_FABSQ "fabsq") + (UNSPEC_COPYSIGNQ "copysignq") + (UNSPEC_NANQ "nanq") + (UNSPEC_NANSQ "nansq")] +) + ;; ;; .................... ;; @@ -2008,6 +2026,13 @@ (define_insn "movfcc" "" "movgr2cf\t%0,$r0") +;; Implements functions with a "q" suffix + +(define_insn "" + [(unspec:SI [(const_int 0)]MATHQ)] + "" + " ") + ;; Conditional move instructions. (define_insn "*sel_using_" diff --git a/libgcc/config/loongarch/t-softfp-tf b/libgcc/config/loongarch/t-softfp-tf index 306677b1255..0e7c2b4cabe 100644 --- a/libgcc/config/loongarch/t-softfp-tf +++ b/libgcc/config/loongarch/t-softfp-tf @@ -1,3 +1,6 @@ softfp_float_modes += tf softfp_extensions += sftf dftf softfp_truncations += tfsf tfdf +#Used to implement a special 128-bit function with a q suffix +LIB2ADD += $(srcdir)/config/loongarch/tf-signs.c + diff --git a/libgcc/config/loongarch/tf-signs.c b/libgcc/config/loongarch/tf-signs.c new file mode 100644 index 00000000000..5ba0c8dea65 --- /dev/null +++ b/libgcc/config/loongarch/tf-signs.c @@ -0,0 +1,99 @@ +/* Copyright (C) 2008-2023 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. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ +#include +#include + +union _FP_UNION_Q +{ + __float128 flt; + struct + { + unsigned long frac0 : 64; + unsigned long frac1 : 48; + unsigned exp : 15; + unsigned sign : 1; + } bits __attribute__((packed)); +}; + +__float128 __copysigntf3 (__float128, __float128); +__float128 __fabstf2 (__float128); +int __signbittf2 (__float128); +__float128 nanq(const char *str); +__float128 nansq(const char *str); + +__float128 +__copysigntf3 (__float128 a, __float128 b) +{ + union _FP_UNION_Q A, B; + + A.flt = a; + B.flt = b; + A.bits.sign = B.bits.sign; + + return A.flt; +} + +__float128 +__fabstf2 (__float128 a) +{ + union _FP_UNION_Q A; + + A.flt = a; + A.bits.sign = 0; + + return A.flt; +} + +int +__signbittf2 (__float128 a) +{ + union _FP_UNION_Q A; + + A.flt = a; + + return A.bits.sign; +} + +__float128 nanq(const char * str) +{ + union _FP_UNION_Q nan; + nan.bits.frac0 = 0; + nan.bits.frac1 = 0; + nan.bits.exp = 0x7FFF; // Exponent field set to all 1's for NaN + nan.bits.sign = 1; // Set the quiet NaN flag to 1 + if(str!=NULL && strlen(str)>0) + return nan.flt; + return 0; +} +__float128 nansq(const char *str) +{ + union _FP_UNION_Q nan; + nan.bits.frac0 = 0; + nan.bits.frac1 = 0; + nan.bits.exp = 0x7FFF; // Exponent field set to all 1's for NaN + nan.bits.sign = 1; // Set the quiet NaN flag to 1 + if(str!=NULL && strlen(str)>0) + return nan.flt; +return 0; +} +