[2/9] Add implementation for copysignl for ppc

Submitted by Khem Raj on Oct. 31, 2015, 6:32 p.m.

Details

Message ID 1446316381-5070-2-git-send-email-raj.khem@gmail.com
State New
Headers show

Commit Message

Khem Raj Oct. 31, 2015, 6:32 p.m.
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
 libc/sysdeps/linux/powerpc/Makefile.arch |  2 +-
 libc/sysdeps/linux/powerpc/copysignl.c   | 89 ++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 1 deletion(-)
 create mode 100644 libc/sysdeps/linux/powerpc/copysignl.c

Patch hide | download patch | download mbox

diff --git a/libc/sysdeps/linux/powerpc/Makefile.arch b/libc/sysdeps/linux/powerpc/Makefile.arch
index 4fbcb11..7c09c87 100644
--- a/libc/sysdeps/linux/powerpc/Makefile.arch
+++ b/libc/sysdeps/linux/powerpc/Makefile.arch
@@ -5,7 +5,7 @@ 
 # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
 #
 
-CSRC-y := __syscall_error.c ioctl.c
+CSRC-y := __syscall_error.c ioctl.c copysignl.c
 
 SSRC-y := \
 	__longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S brk.S \
diff --git a/libc/sysdeps/linux/powerpc/copysignl.c b/libc/sysdeps/linux/powerpc/copysignl.c
new file mode 100644
index 0000000..000f653
--- /dev/null
+++ b/libc/sysdeps/linux/powerpc/copysignl.c
@@ -0,0 +1,89 @@ 
+/* s_copysignl.c -- long double version of s_copysign.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * copysignl(long double x, long double y)
+ * copysignl(x,y) returns a value with the magnitude of x and
+ * with the sign bit of y.
+ */
+
+#include <endian.h>
+#include <stdint.h>
+
+#if __FLOAT_WORD_ORDER == BIG_ENDIAN
+
+typedef union
+{
+  long double value;
+  struct
+  {
+    int sign_exponent:16;
+    unsigned int empty:16;
+    uint32_t msw;
+    uint32_t lsw;
+  } parts;
+} ieee_long_double_shape_type;
+
+#endif
+
+#if __FLOAT_WORD_ORDER == LITTLE_ENDIAN
+
+typedef union
+{
+  long double value;
+  struct
+  {
+    uint32_t lsw;
+    uint32_t msw;
+    int sign_exponent:16;
+    unsigned int empty:16;
+  } parts;
+} ieee_long_double_shape_type;
+
+#endif
+
+/* Get int from the exponent of a long double.  */
+
+#define GET_LDOUBLE_EXP(exp,d)					\
+do {								\
+  ieee_long_double_shape_type ge_u;				\
+  ge_u.value = (d);						\
+  (exp) = ge_u.parts.sign_exponent;				\
+} while (0)
+
+/* Set exponent of a long double from an int.  */
+
+#define SET_LDOUBLE_EXP(d,exp)					\
+do {								\
+  ieee_long_double_shape_type se_u;				\
+  se_u.value = (d);						\
+  se_u.parts.sign_exponent = (exp);				\
+  (d) = se_u.value;						\
+} while (0)
+
+long double copysignl(long double x, long double y);
+libc_hidden_proto(copysignl);
+
+long double copysignl(long double x, long double y)
+{
+	uint32_t es1,es2;
+	GET_LDOUBLE_EXP(es1,x);
+	GET_LDOUBLE_EXP(es2,y);
+	SET_LDOUBLE_EXP(x,(es1&0x7fff)|(es2&0x8000));
+        return x;
+}
+
+libc_hidden_def(copysignl);