From patchwork Tue Aug 15 10:39:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chenxiaolong X-Patchwork-Id: 135645 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a888:0:b0:3f2:4152:657d with SMTP id x8csp336712vqo; Tue, 15 Aug 2023 03:40:26 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHDc1zE+uRdACLNuaI/ps0hzO1FQDuII3METiSpHexHDfB5B0Bw21hEIGrqT5VxojO+41kM X-Received: by 2002:a17:907:7757:b0:993:22a2:8158 with SMTP id kx23-20020a170907775700b0099322a28158mr10665837ejc.61.1692096026256; Tue, 15 Aug 2023 03:40:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1692096026; cv=none; d=google.com; s=arc-20160816; b=AM1PP5MM8mp/NoSAQd9v58ImZMmyMIvGiasyJUCvzM7M8KaWQodW402a/7RmfgO/8f PHvHOYQ0atbCMU122PTZv97bE9Rabz52v1FAFbrHZHPpJHPnsZ1W49Om+joNrwpo0Gl7 /fbZhAcoCfLf6Nw8LeA+rMSFS0DUh/9NfkQcHlREZWzONOPWlx38LU40lzW1JdmNCXzo FmDaQg4xejCMWM+kLxMTS+RNZL5dtHuH0nPRY5ZA03r4ezdV6MlSmkiJxpQ+ub0w261I QtCUYzB5tp8fUZncQcUeXaqIQXPuGcdrFePJ23uY7Zw5cxK6VshhqHVnSx7d9pWcMpVC Zn1A== 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=rebodkuubWB1S8ioiJ6pCFxCX4M0Mboo74gFYV+GRUk=; fh=15b3xIwBMw/vKjg0S7vUsSBIdnRkmQvX+/LxpkVzz5g=; b=F82VAfuqIipKYyFqBSbNbKsYp72SylA8azq+q/m1HvZiKbuVK4NTbjYK0ufeR7WOUI Y1UYSNABNS3z5msAPwvITHu1+tSjuzphhfgERK8f2FhzAUDXMNhhJnCjc/EIwHtph9R2 gSa6SIdMgsBpPYaVq8HxqcmE1UW10IPUhp7/hM1K7tpz1/IeDkSU90ovd2Jyyw/xRdT6 k5jX+TgMC12wMkLO1MrKVpFHrsc3ifJuV+vmrruVJnBy62u13654WM2wJgXBWQocU65f X5l2VxB7ClwicD9kK14zU0JiqfA1k9v/YdAejeKrywGj0elNG8j1Ip0auJ8TLrv9notk ylDw== 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 me11-20020a170906aecb00b00988c92d2861si9190964ejb.397.2023.08.15.03.40.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Aug 2023 03:40:26 -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 B13E13856974 for ; Tue, 15 Aug 2023 10:40:19 +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 8AD283858404 for ; Tue, 15 Aug 2023 10:39:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8AD283858404 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 _____8BxuOjzVdtkF7kYAA--.15109S3; Tue, 15 Aug 2023 18:39:47 +0800 (CST) Received: from slurm-master.loongson.cn (unknown [10.10.130.252]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxWM3xVdtkSRdbAA--.29126S4; Tue, 15 Aug 2023 18:39:45 +0800 (CST) From: chenxiaolong To: gcc-patches@gcc.gnu.org Cc: xry111@xry111.site, i@xen0n.name, xuchenghua@loongson.cn, chenglulu@loongson.cn, chenxiaolong Subject: [PATCH v3] LoongArch:Implement 128-bit floating point functions in gcc. Date: Tue, 15 Aug 2023 18:39:43 +0800 Message-Id: <20230815103943.21417-1-chenxiaolong@loongson.cn> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-CM-TRANSID: AQAAf8CxWM3xVdtkSRdbAA--.29126S4 X-CM-SenderInfo: hfkh05xldrz0tqj6z05rqj20fqof0/1tbiAQAEBWTa+zIEuwAAsI X-Coremail-Antispam: 1Uk129KBj9fXoW3CrWxKr4fXr1xKF4DGFyxCrX_yoW8AFykKo WrAF1qq3Z5Gr1Iva4agwnxWryjvF48Ar4kAry3Zw1rCa1kJr15C34qga1rA347tFZ3WF4U Ca47GrZrJrWxJFn5l-sFpf9Il3svdjkaLaAFLSUrUUUUUb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUY17kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUGVWUXwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r1j6r1xM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r1j6r4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI 0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280 aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28Icx kI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2Iq xVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42 IY6xIIjxv20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY 6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aV CY1x0267AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjxU25EfUUUUU X-Spam-Status: No, score=-12.3 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: 1774291283092462791 X-GMAIL-MSGID: 1774291283092462791 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}. On the LoongArch architecture, __builtin_{fabsq,copysignq} can be implemented with the instruction "bstrins.d", so that its optimization effect reaches the optimal value. gcc/ChangeLog: * config/loongarch/loongarch-builtins.cc (DEF_LARCH_FTYPE): (enum loongarch_builtin_type):Increases the type of the function. (FLOAT_BUILTIN_HIQ):__builtin_{huge_valq,infq}. (FLOAT_BUILTIN_FCQ):__builtin_{fabsq,copysignq}. (FLOAT_BUILTIN_NNQ):__builtin_{nanq,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. (): (fabsq): (copysignq): libgcc/ChangeLog: * config/loongarch/t-softfp-tf: * config/loongarch/tf-signs.c: New file. --- gcc/config/loongarch/loongarch-builtins.cc | 168 ++++++++++++++++++++- gcc/config/loongarch/loongarch-protos.h | 2 + gcc/config/loongarch/loongarch.cc | 14 ++ gcc/config/loongarch/loongarch.md | 69 +++++++++ libgcc/config/loongarch/t-softfp-tf | 3 + libgcc/config/loongarch/tf-signs.c | 59 ++++++++ 6 files changed, 313 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..2fb0fde0e3f 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. */ +const 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 { @@ -63,6 +74,15 @@ enum loongarch_builtin_type value and the arguments are mapped to operands 0 and above. */ LARCH_BUILTIN_DIRECT_NO_TARGET, + /* The function corresponds to __builtin_{huge_valq,infq}. */ + LARCH_BUILTIN_HIQ_DIRECT, + + /* The function corresponds to __builtin_{fabsq,copysignq}. */ + LARCH_BUILTIN_FCQ_DIRECT, + + /* Define the type of the __builtin_{nanq,nansq} function. */ + LARCH_BUILTIN_NNQ_DIRECT + }; /* Declare an availability predicate for built-in functions that require @@ -136,6 +156,24 @@ AVAIL_ALL (hard_float, TARGET_HARD_FLOAT_ABI) LARCH_BUILTIN (INSN, #INSN, LARCH_BUILTIN_DIRECT_NO_TARGET, \ FUNCTION_TYPE, AVAIL) +/* Define an float to do funciton {huge_valq,infq}. */ +#define FLOAT_BUILTIN_HIQ (INSN, FUNCTION_TYPE) \ + { CODE_FOR_ ## INSN, \ + "__builtin_" #INSN, LARCH_BUILTIN_HIQ_DIRECT, \ + FUNCTION_TYPE, loongarch_builtin_avail_default } + +/* Define an float to do funciton {fabsq,copysignq}. */ +#define FLOAT_BUILTIN_FCQ (INSN, FUNCTION_TYPE) \ + { CODE_FOR_ ## INSN, \ + "__builtin_" #INSN, LARCH_BUILTIN_FCQ_DIRECT, \ + FUNCTION_TYPE, loongarch_builtin_avail_default } + +/* Define an float to do funciton {nanq,nansq}. */ +#define FLOAT_BUILTIN_NNQ (INSN, FUNCTION_TYPE) \ + { CODE_FOR_ ## INSN, \ + "__builtin_" #INSN, LARCH_BUILTIN_NNQ_DIRECT, \ + FUNCTION_TYPE, loongarch_builtin_avail_default } + static const struct loongarch_builtin_description loongarch_builtins[] = { #define LARCH_MOVFCSR2GR 0 DIRECT_BUILTIN (movfcsr2gr, LARCH_USI_FTYPE_UQI, hard_float), @@ -183,6 +221,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_HIQ (huge_valq, LARCH_BUILTIN_HUGE_VALQ), + FLOAT_BUILTIN_HIQ (infq, LARCH_BUILTIN_INFQ), + FLOAT_BUILTIN_FCQ (fabsq, LARCH_BUILTIN_FABSQ), + FLOAT_BUILTIN_FCQ (copysignq, LARCH_BUILTIN_COPYSIGNQ), + FLOAT_BUILTIN_NNQ (nanq, LARCH_BUILTIN_NANQ), + FLOAT_BUILTIN_NNQ (nansq, LARCH_BUILTIN_NANSQ), + }; /* Index I is the function declaration for loongarch_builtins[I], or null if @@ -255,10 +301,13 @@ loongarch_init_builtins (void) const struct loongarch_builtin_description *d; unsigned int i; tree type; + 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 +319,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"); + + type = build_function_type_list (long_double_type_node, NULL_TREE); + d = &loongarch_builtins[i]; + loongarch_builtin_decls[i] + =add_builtin_function ("__builtin_huge_valq", type, + i, BUILT_IN_MD, NULL, NULL_TREE); + loongarch_get_builtin_decl_index[d->icode]=i++; + + type = build_function_type_list (long_double_type_node, NULL_TREE); + d = &loongarch_builtins[i]; + loongarch_builtin_decls[i] + =add_builtin_function ("__builtin_infq", type, + i, BUILT_IN_MD, NULL, NULL_TREE); + loongarch_get_builtin_decl_index[d->icode]=i++; + + type = 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", type, + i, BUILT_IN_MD, NULL, NULL_TREE); + TREE_READONLY (loongarch_builtin_decls[i]) =1; + loongarch_get_builtin_decl_index[d->icode]=i++; + + type = 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", type, + i, BUILT_IN_MD, NULL, NULL_TREE); + TREE_READONLY (loongarch_builtin_decls[i]) =1; + loongarch_get_builtin_decl_index[d->icode]=i++; + + type=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", type, + 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", type, + 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 +388,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. */ @@ -362,11 +504,33 @@ loongarch_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, switch (d->builtin_type) { case LARCH_BUILTIN_DIRECT: + case LARCH_BUILTIN_FCQ_DIRECT: return loongarch_expand_builtin_direct (d->icode, target, exp, true); case LARCH_BUILTIN_DIRECT_NO_TARGET: return loongarch_expand_builtin_direct (d->icode, target, exp, false); - } + + case LARCH_BUILTIN_NNQ_DIRECT: + return expand_call ( exp ,target , ignore); + + case LARCH_BUILTIN_HIQ_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..35fc2ad7def 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 86d58784113..7a8358c9630 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -6790,6 +6790,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" @@ -6901,6 +6911,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..9fe3faf8b92 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -44,6 +44,13 @@ (define_c_enum "unspec" [ 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,15 @@ (define_int_attr bytepick_imm [(8 "1") (48 "6") (56 "7")]) +;; mathq function +(define_int_iterator MATHQ[UNSPEC_INFQ UNSPEC_HUGE_VALQ + UNSPEC_NANQ UNSPEC_NANSQ]) +(define_int_attr mathq_pattern[(UNSPEC_INFQ "infq") + (UNSPEC_HUGE_VALQ "huge_valq") + (UNSPEC_NANQ "nanq") + (UNSPEC_NANSQ "nansq")] +) + ;; ;; .................... ;; @@ -2008,6 +2024,59 @@ (define_insn "movfcc" "" "movgr2cf\t%0,$r0") +;; Implements functions with a "q" suffix + +(define_insn "" + [(unspec:SI[(const_int 0)] MATHQ)] + "" + "") + +;;Implement __builtin_fabsq function. + +(define_insn_and_split "fabsq" + [(set (match_operand:TF 0 "register_operand" "=r") + (unspec:TF[(match_operand:TF 1 "register_operand" "rG")] + UNSPEC_FABSQ))] + "" + "#" + "reload_completed" +[(set (zero_extract:DI (match_operand:DI 0 "register_operand") + (match_operand:SI 3 "const_int_operand") + (match_operand:SI 4 "const_int_operand")) + (match_operand:DI 2 "const_int_operand"))] +{ + operands[0] = gen_rtx_REG (Pmode, REGNO (operands[0])+1); + operands[2] = GEN_INT (0); + operands[3] = GEN_INT (1); + operands[4] = GEN_INT (63); +} +) + +;;Implement __builtin_copysignq function. + +(define_insn_and_split "copysignq" + [(set (match_operand:TF 0 "register_operand" "=r") + (unspec:TF[(match_operand:TF 1 "register_operand" "rG") + (match_operand:TF 2 "register_operand" "rG")] + UNSPEC_COPYSIGNQ))] + "" + "#" + "reload_completed" + [(set (match_operand:DI 2 "register_operand") + (lshiftrt :DI (match_operand:DI 2 "register_operand") + (match_operand:SI 4 "arith_operand"))) + (set (zero_extract:DI (match_operand:DI 0 "register_operand") + (match_operand:SI 3 "const_int_operand") + (match_operand:SI 4 "const_int_operand")) + (match_operand:DI 2 "register_operand"))] +{ + operands[0] = gen_rtx_REG (Pmode,REGNO (operands[0])+1); + operands[2] = gen_rtx_REG (Pmode,REGNO (operands[2])+1); + operands[3] = GEN_INT (1); + operands[4] = GEN_INT (63); +} +) + ;; 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..68db1729372 --- /dev/null +++ b/libgcc/config/loongarch/tf-signs.c @@ -0,0 +1,59 @@ +/* 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 +. */ + +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 __nanq (const char *str); +__float128 __nansq (const char *str); + +__float128 __nanq (const char * str) +{ + union _FP_UNION_Q nan; + nan.bits.frac0 = 0; + nan.bits.frac1 = 0; + nan.bits.exp = 0x7FFF; + nan.bits.sign = 0; + + return nan.flt; +} +__float128 __nansq (const char *str) +{ + union _FP_UNION_Q nan; + nan.bits.frac0 = 0xFFFFFFFFFFFFFFFFUL; + nan.bits.frac1 = 0x0000FFFFFFFFFFFFUL; + nan.bits.exp = 0x7FFF; + nan.bits.sign = 0; + + return nan.flt; +} +