blob: d4275c997e9a6fc64d669f4de09bb74602ff9f2d [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001From 5d362074e5975b150a35bcfa77eab1bfa4e30de7 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Sun, 16 Aug 2015 20:50:56 -0700
4Subject: [PATCH 2/7] Add implementation for copysignl for ppc
5
6Signed-off-by: Khem Raj <raj.khem@gmail.com>
7---
8Upstream-Status: Pending
9
10 libc/sysdeps/linux/powerpc/Makefile.arch | 2 +-
11 libc/sysdeps/linux/powerpc/copysignl.c | 89 ++++++++++++++++++++++++++++++++
12 2 files changed, 90 insertions(+), 1 deletion(-)
13 create mode 100644 libc/sysdeps/linux/powerpc/copysignl.c
14
15diff --git a/libc/sysdeps/linux/powerpc/Makefile.arch b/libc/sysdeps/linux/powerpc/Makefile.arch
16index 4fbcb11..7c09c87 100644
17--- a/libc/sysdeps/linux/powerpc/Makefile.arch
18+++ b/libc/sysdeps/linux/powerpc/Makefile.arch
19@@ -5,7 +5,7 @@
20 # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
21 #
22
23-CSRC-y := __syscall_error.c ioctl.c
24+CSRC-y := __syscall_error.c ioctl.c copysignl.c
25
26 SSRC-y := \
27 __longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S brk.S \
28diff --git a/libc/sysdeps/linux/powerpc/copysignl.c b/libc/sysdeps/linux/powerpc/copysignl.c
29new file mode 100644
30index 0000000..000f653
31--- /dev/null
32+++ b/libc/sysdeps/linux/powerpc/copysignl.c
33@@ -0,0 +1,89 @@
34+/* s_copysignl.c -- long double version of s_copysign.c.
35+ * Conversion to long double by Ulrich Drepper,
36+ * Cygnus Support, drepper@cygnus.com.
37+ */
38+
39+/*
40+ * ====================================================
41+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
42+ *
43+ * Developed at SunPro, a Sun Microsystems, Inc. business.
44+ * Permission to use, copy, modify, and distribute this
45+ * software is freely granted, provided that this notice
46+ * is preserved.
47+ * ====================================================
48+ */
49+
50+/*
51+ * copysignl(long double x, long double y)
52+ * copysignl(x,y) returns a value with the magnitude of x and
53+ * with the sign bit of y.
54+ */
55+
56+#include <endian.h>
57+#include <stdint.h>
58+
59+#if __FLOAT_WORD_ORDER == BIG_ENDIAN
60+
61+typedef union
62+{
63+ long double value;
64+ struct
65+ {
66+ int sign_exponent:16;
67+ unsigned int empty:16;
68+ uint32_t msw;
69+ uint32_t lsw;
70+ } parts;
71+} ieee_long_double_shape_type;
72+
73+#endif
74+
75+#if __FLOAT_WORD_ORDER == LITTLE_ENDIAN
76+
77+typedef union
78+{
79+ long double value;
80+ struct
81+ {
82+ uint32_t lsw;
83+ uint32_t msw;
84+ int sign_exponent:16;
85+ unsigned int empty:16;
86+ } parts;
87+} ieee_long_double_shape_type;
88+
89+#endif
90+
91+/* Get int from the exponent of a long double. */
92+
93+#define GET_LDOUBLE_EXP(exp,d) \
94+do { \
95+ ieee_long_double_shape_type ge_u; \
96+ ge_u.value = (d); \
97+ (exp) = ge_u.parts.sign_exponent; \
98+} while (0)
99+
100+/* Set exponent of a long double from an int. */
101+
102+#define SET_LDOUBLE_EXP(d,exp) \
103+do { \
104+ ieee_long_double_shape_type se_u; \
105+ se_u.value = (d); \
106+ se_u.parts.sign_exponent = (exp); \
107+ (d) = se_u.value; \
108+} while (0)
109+
110+long double copysignl(long double x, long double y);
111+libc_hidden_proto(copysignl);
112+
113+long double copysignl(long double x, long double y)
114+{
115+ uint32_t es1,es2;
116+ GET_LDOUBLE_EXP(es1,x);
117+ GET_LDOUBLE_EXP(es2,y);
118+ SET_LDOUBLE_EXP(x,(es1&0x7fff)|(es2&0x8000));
119+ return x;
120+}
121+
122+libc_hidden_def(copysignl);
123--
1242.1.4
125