Okay, thanks for the heads up! I'll try to format the code according to the GNU Coding Standards. I'll double-check every line of the submitted patch to make sure that I don't have such a low-level formatting problem in every future patch, so that I can comply with the code specification.
在 2023-08-15二的 18:48 +0800,Xi Ruoyao写道: > Please fix code style (this is the third time I say it and I'm really > frustrated now). GCC is a project, it's not a student homework so > style > matters. And it's not so difficult to fix the style: for a new file > you > can use "clang-format --style GNU -i filename.c" to do the work > automatically. > > On Tue, 2023-08-15 at 18:39 +0800, chenxiaolong wrote: > > 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. > > (<mathq_pattern>): > > (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 "<mathq_pattern>" > > + [(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<code><GPR:mode>_using_<GPR2:mode>" > > 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 > > +<http://www.gnu.org/licenses/>;. */ > > + > > +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; > > +} > > +