[v1] LoongArch:Implement 128-bit floating point functions in gcc.

Message ID 20230807040140.14796-1-chenxiaolong@loongson.cn
State Accepted
Headers
Series [v1] LoongArch:Implement 128-bit floating point functions in gcc. |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

chenxiaolong Aug. 7, 2023, 4:01 a.m. UTC
  From: Xiaolong Chen <chenxiaolong@loongson.cn>

	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):
	(<mathq_pattern>):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
  

Comments

Xi Ruoyao Aug. 7, 2023, 5:03 a.m. UTC | #1
On Mon, 2023-08-07 at 12:01 +0800, chenxiaolong wrote:
> +/* Count the number of functions with "q" as the suffix */
> +static int MATHQ_NUMS=(int)LARCH_MAX_FTYPE_MAX-(int)LARCH_BUILTIN_HUGE_VALQ;

This is obviously not the GCC coding standard...  It should have some
white spaces:

static int MATHQ_NUMS = (int)LARCH_MAX_FTYPE_MAX - (int)LARCH_BUILTIN_HUGE_VALQ;

And I guess this variable should be declared const.

> +/* 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 }

/* snip */

> +/* 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 }

What's the point to define these macros each is only used once?

> +  tree type,ftype;
> +  tree const_string_type
> +         =build_pointer_type(build_qualified_type(char_type_node,TYPE_QUAL_CONST));

Really bad format.  In GNU coding standard you should have a white space
after '=', and before '(', etc.  Please fix the formatting everywhere.
  

Patch

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 "<mathq_pattern>"
+  [(unspec:SI [(const_int 0)]MATHQ)]
+  ""
+  " ")
+
 ;; 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..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
+<http://www.gnu.org/licenses/>.  */
+#include<stddef.h>
+#include<string.h>
+
+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; 
+}
+